summaryrefslogtreecommitdiff
path: root/chromium/net
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/net
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net')
-rw-r--r--chromium/net/BUILD.gn48
-rw-r--r--chromium/net/OWNERS1
-rw-r--r--chromium/net/android/BUILD.gn3
-rw-r--r--chromium/net/base/address_tracker_linux.cc13
-rw-r--r--chromium/net/base/address_tracker_linux_unittest.cc17
-rw-r--r--chromium/net/base/backoff_entry_serializer_fuzzer.cc80
-rw-r--r--chromium/net/base/backoff_entry_serializer_fuzzer_input.proto4
-rw-r--r--chromium/net/base/features.cc78
-rw-r--r--chromium/net/base/features.h103
-rw-r--r--chromium/net/base/file_stream_context.cc1
-rw-r--r--chromium/net/base/file_stream_context.h1
-rw-r--r--chromium/net/base/ip_address.cc12
-rw-r--r--chromium/net/base/ip_address.h4
-rw-r--r--chromium/net/base/ip_address_unittest.cc10
-rw-r--r--chromium/net/base/load_timing_info.h19
-rw-r--r--chromium/net/base/load_timing_info_test_util.cc1
-rw-r--r--chromium/net/base/net_error_list.h6
-rw-r--r--chromium/net/base/net_errors.cc11
-rw-r--r--chromium/net/base/net_errors.h3
-rw-r--r--chromium/net/base/net_errors_posix.cc3
-rw-r--r--chromium/net/base/network_change_notifier_fuchsia.cc11
-rw-r--r--chromium/net/base/network_change_notifier_fuchsia_unittest.cc1
-rw-r--r--chromium/net/base/network_change_notifier_mac.cc1
-rw-r--r--chromium/net/base/network_config_watcher_mac.cc1
-rw-r--r--chromium/net/base/network_delegate.cc3
-rw-r--r--chromium/net/base/network_delegate.h2
-rw-r--r--chromium/net/base/network_delegate_impl.cc1
-rw-r--r--chromium/net/base/network_delegate_impl.h1
-rw-r--r--chromium/net/base/network_interfaces.cc1
-rw-r--r--chromium/net/base/network_interfaces_fuchsia.cc5
-rw-r--r--chromium/net/base/network_interfaces_getifaddrs.cc26
-rw-r--r--chromium/net/base/network_interfaces_getifaddrs.h7
-rw-r--r--chromium/net/base/network_interfaces_linux.cc17
-rw-r--r--chromium/net/base/network_interfaces_win_unittest.cc1
-rw-r--r--chromium/net/base/priority_queue.h2
-rw-r--r--chromium/net/base/privacy_mode.h4
-rw-r--r--chromium/net/base/upload_data_stream.cc4
-rw-r--r--chromium/net/base/upload_data_stream.h4
-rw-r--r--chromium/net/cert/cert_verifier.cc6
-rw-r--r--chromium/net/cert/cert_verifier.h6
-rw-r--r--chromium/net/cert/cert_verify_proc.cc17
-rw-r--r--chromium/net/cert/cert_verify_proc_ios.cc1
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc3
-rw-r--r--chromium/net/cert/ct_log_verifier.cc1
-rw-r--r--chromium/net/cert/ct_sct_to_string.cc1
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.cc399
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.h19
-rw-r--r--chromium/net/cert/ev_root_ca_metadata_unittest.cc149
-rw-r--r--chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc1
-rw-r--r--chromium/net/cert/internal/parsed_certificate.h2
-rw-r--r--chromium/net/cert/internal/path_builder.cc1
-rw-r--r--chromium/net/cert/internal/path_builder_pkits_unittest.cc90
-rw-r--r--chromium/net/cert/internal/system_trust_store.cc1
-rw-r--r--chromium/net/cert/internal/trust_store_mac_unittest.cc1
-rw-r--r--chromium/net/cert/internal/trust_store_nss.cc1
-rw-r--r--chromium/net/cert/known_roots_mac.cc1
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc19
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h12
-rw-r--r--chromium/net/cert/test_keychain_search_list_mac.h2
-rw-r--r--chromium/net/cert/test_root_certs.h50
-rw-r--r--chromium/net/cert/test_root_certs_builtin.cc (renamed from chromium/net/cert/test_root_certs_fuchsia.cc)0
-rw-r--r--chromium/net/cert/test_root_certs_nss.cc120
-rw-r--r--chromium/net/cert/test_root_certs_unittest.cc45
-rw-r--r--chromium/net/cert/x509_cert_types.h1
-rw-r--r--chromium/net/cert/x509_util.cc1
-rw-r--r--chromium/net/cert/x509_util_ios_and_mac.cc1
-rw-r--r--chromium/net/cookies/canonical_cookie.cc359
-rw-r--r--chromium/net/cookies/canonical_cookie.h262
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc535
-rw-r--r--chromium/net/cookies/cookie_access_result.cc25
-rw-r--r--chromium/net/cookies/cookie_access_result.h34
-rw-r--r--chromium/net/cookies/cookie_deletion_info.cc2
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.cc290
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.h275
-rw-r--r--chromium/net/cookies/cookie_inclusion_status_unittest.cc200
-rw-r--r--chromium/net/cookies/cookie_monster.cc93
-rw-r--r--chromium/net/cookies/cookie_monster.h29
-rw-r--r--chromium/net/cookies/cookie_monster_change_dispatcher.cc2
-rw-r--r--chromium/net/cookies/cookie_monster_perftest.cc8
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc449
-rw-r--r--chromium/net/cookies/cookie_store.h7
-rw-r--r--chromium/net/cookies/cookie_store_test_callbacks.cc9
-rw-r--r--chromium/net/cookies/cookie_store_test_callbacks.h17
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.cc20
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.h11
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h39
-rw-r--r--chromium/net/cookies/cookie_util.cc59
-rw-r--r--chromium/net/cookies/cookie_util.h47
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc143
-rw-r--r--chromium/net/data/ssl/certificates/398_days_1_second_after_2020_09_01.pem85
-rw-r--r--chromium/net/data/ssl/certificates/398_days_after_2020_09_01.pem85
-rw-r--r--chromium/net/data/ssl/certificates/399_days_after_2020_09_01.pem85
-rw-r--r--chromium/net/data/ssl/certificates/quic-short-lived.pem80
-rw-r--r--chromium/net/data/ssl/ev_roots/08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178.pem71
-rw-r--r--chromium/net/data/ssl/ev_roots/0f993c8aef97baaf5687140ed59ad1821bb4afacf0aa9a58b5d57a338a3afbcb.pem86
-rw-r--r--chromium/net/data/ssl/ev_roots/136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca.pem137
-rw-r--r--chromium/net/data/ssl/ev_roots/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem83
-rw-r--r--chromium/net/data/ssl/ev_roots/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem56
-rw-r--r--chromium/net/data/ssl/ev_roots/2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c.pem87
-rw-r--r--chromium/net/data/ssl/ev_roots/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem124
-rw-r--r--chromium/net/data/ssl/ev_roots/37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c.pem78
-rw-r--r--chromium/net/data/ssl/ev_roots/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem79
-rw-r--r--chromium/net/data/ssl/ev_roots/4b03f45807ad70f21bfc2cae71c9fde4604c064cf5ffb686bae5dbaad7fdd34c.pem82
-rw-r--r--chromium/net/data/ssl/ev_roots/58d017279cd4dc63abddb196a6c9906c30c4e08783eae8c1609954d69355596b.pem51
-rw-r--r--chromium/net/data/ssl/ev_roots/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem125
-rw-r--r--chromium/net/data/ssl/ev_roots/5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766.pem54
-rw-r--r--chromium/net/data/ssl/ev_roots/62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50.pem86
-rw-r--r--chromium/net/data/ssl/ev_roots/69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79.pem60
-rw-r--r--chromium/net/data/ssl/ev_roots/6ea54741d004667eed1b4816634aa3a79e6e4b96950f8279dafc8d9bd8812137.pem90
-rw-r--r--chromium/net/data/ssl/ev_roots/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem79
-rw-r--r--chromium/net/data/ssl/ev_roots/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem53
-rw-r--r--chromium/net/data/ssl/ev_roots/8d722f81a9c113c0791df136a2966db26c950a971db46b4199f4ea54b78bfb9f.pem82
-rw-r--r--chromium/net/data/ssl/ev_roots/9acfab7e43c8d880d06b262a94deeee4b4659989c3d0caf19baf6405e41ab7df.pem87
-rw-r--r--chromium/net/data/ssl/ev_roots/a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37.pem77
-rw-r--r--chromium/net/data/ssl/ev_roots/a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557.pem53
-rw-r--r--chromium/net/data/ssl/ev_roots/a53125188d2110aa964b02c7b7c6da3203170894e5fb71fffb6667d5e6810a36.pem48
-rw-r--r--chromium/net/data/ssl/ev_roots/a71272aeaaa3cfe8727f7fb39f0fb3d1e5426e9060b06ee6f13e9a3c5833cd43.pem94
-rw-r--r--chromium/net/data/ssl/ev_roots/ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72.pem55
-rw-r--r--chromium/net/data/ssl/ev_roots/b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4.pem81
-rw-r--r--chromium/net/data/ssl/ev_roots/b7b12b171f821daa990cd0fe5087b128448ba8e5184f84c51e02b5c8fb962b24.pem76
-rw-r--r--chromium/net/data/ssl/ev_roots/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem46
-rw-r--r--chromium/net/data/ssl/ev_roots/c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea.pem152
-rw-r--r--chromium/net/data/ssl/ev_roots/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem87
-rw-r--r--chromium/net/data/ssl/ev_roots/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem119
-rw-r--r--chromium/net/data/ssl/ev_roots/d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d.pem127
-rw-r--r--chromium/net/data/ssl/ev_roots/e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70.pem48
-rwxr-xr-xchromium/net/data/ssl/scripts/generate-test-certs.sh40
-rw-r--r--chromium/net/data/websocket/close_observer.html12
-rw-r--r--chromium/net/der/tag.h2
-rw-r--r--chromium/net/disk_cache/backend_unittest.cc35
-rw-r--r--chromium/net/disk_cache/blockfile/addr.h2
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.cc1
-rw-r--r--chromium/net/disk_cache/blockfile/in_flight_io.h2
-rw-r--r--chromium/net/disk_cache/blockfile/mapped_file_posix.cc8
-rw-r--r--chromium/net/disk_cache/blockfile/stress_support.h3
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc390
-rw-r--r--chromium/net/disk_cache/memory/mem_backend_impl.cc1
-rw-r--r--chromium/net/disk_cache/simple/post_doom_waiter.cc8
-rw-r--r--chromium/net/disk_cache/simple/post_doom_waiter.h2
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc81
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.h5
-rw-r--r--chromium/net/disk_cache/simple/simple_histogram_enums.h20
-rw-r--r--chromium/net/disk_cache/simple/simple_index.cc29
-rw-r--r--chromium/net/disk_cache/simple/simple_index.h9
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.cc25
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.h7
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file_unittest.cc12
-rw-r--r--chromium/net/disk_cache/simple/simple_index_unittest.cc40
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.cc88
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.h21
-rw-r--r--chromium/net/dns/BUILD.gn16
-rw-r--r--chromium/net/dns/address_info.cc1
-rw-r--r--chromium/net/dns/context_host_resolver.cc10
-rw-r--r--chromium/net/dns/dns_config.h1
-rw-r--r--chromium/net/dns/dns_hosts.cc4
-rw-r--r--chromium/net/dns/dns_response.cc5
-rw-r--r--chromium/net/dns/dns_response.h8
-rw-r--r--chromium/net/dns/dns_test_util.cc125
-rw-r--r--chromium/net/dns/dns_test_util.h22
-rw-r--r--chromium/net/dns/dns_transaction.cc48
-rw-r--r--chromium/net/dns/dns_transaction.h7
-rw-r--r--chromium/net/dns/dns_transaction_unittest.cc93
-rw-r--r--chromium/net/dns/dns_util.cc75
-rw-r--r--chromium/net/dns/dns_util_unittest.cc25
-rw-r--r--chromium/net/dns/esni_content.cc63
-rw-r--r--chromium/net/dns/esni_content.h84
-rw-r--r--chromium/net/dns/esni_content_unittest.cc170
-rw-r--r--chromium/net/dns/host_cache.cc130
-rw-r--r--chromium/net/dns/host_cache.h57
-rw-r--r--chromium/net/dns/host_cache_unittest.cc235
-rw-r--r--chromium/net/dns/host_resolver.cc19
-rw-r--r--chromium/net/dns/host_resolver.h19
-rw-r--r--chromium/net/dns/host_resolver_manager.cc394
-rw-r--r--chromium/net/dns/host_resolver_manager.h6
-rw-r--r--chromium/net/dns/host_resolver_manager_fuzzer.cc4
-rw-r--r--chromium/net/dns/host_resolver_manager_unittest.cc1303
-rw-r--r--chromium/net/dns/host_resolver_mdns_listener_impl.cc2
-rw-r--r--chromium/net/dns/host_resolver_mdns_task.cc4
-rw-r--r--chromium/net/dns/httpssvc_metrics.cc254
-rw-r--r--chromium/net/dns/httpssvc_metrics.h112
-rw-r--r--chromium/net/dns/httpssvc_metrics_unittest.cc554
-rw-r--r--chromium/net/dns/mock_host_resolver.cc10
-rw-r--r--chromium/net/dns/public/BUILD.gn6
-rw-r--r--chromium/net/dns/public/dns_protocol.h5
-rw-r--r--chromium/net/dns/public/dns_query_type.h7
-rw-r--r--chromium/net/dns/public/doh_provider_entry.cc (renamed from chromium/net/dns/public/doh_provider_list.cc)219
-rw-r--r--chromium/net/dns/public/doh_provider_entry.h (renamed from chromium/net/dns/public/doh_provider_list.h)63
-rw-r--r--chromium/net/dns/public/doh_provider_entry_unittest.cc (renamed from chromium/net/dns/public/doh_provider_list_unittest.cc)4
-rw-r--r--chromium/net/dns/record_parsed.cc3
-rw-r--r--chromium/net/dns/record_rdata.cc154
-rw-r--r--chromium/net/dns/record_rdata.h45
-rw-r--r--chromium/net/dns/record_rdata_unittest.cc466
-rw-r--r--chromium/net/dns/resolve_context.cc94
-rw-r--r--chromium/net/dns/resolve_context.h13
-rw-r--r--chromium/net/dns/resolve_context_unittest.cc42
-rw-r--r--chromium/net/dns/test_dns_config_service.h2
-rw-r--r--chromium/net/docs/bug-triage-labels.md11
-rw-r--r--chromium/net/docs/bug-triage-suggested-workflow.md112
-rw-r--r--chromium/net/docs/bug-triage.md191
-rw-r--r--chromium/net/docs/certificate_lifetimes.md78
-rw-r--r--chromium/net/docs/net-log.md7
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc28
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc19
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc2
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc75
-rw-r--r--chromium/net/http/alternative_service.cc12
-rw-r--r--chromium/net/http/alternative_service.h3
-rw-r--r--chromium/net/http/failing_http_transaction_factory.cc211
-rw-r--r--chromium/net/http/failing_http_transaction_factory.h43
-rw-r--r--chromium/net/http/http_auth.cc4
-rw-r--r--chromium/net/http/http_auth.h1
-rw-r--r--chromium/net/http/http_auth_controller.cc11
-rw-r--r--chromium/net/http/http_auth_controller_unittest.cc5
-rw-r--r--chromium/net/http/http_auth_handler.cc14
-rw-r--r--chromium/net/http/http_auth_handler.h9
-rw-r--r--chromium/net/http/http_auth_handler_basic.cc12
-rw-r--r--chromium/net/http/http_auth_handler_basic.h4
-rw-r--r--chromium/net/http/http_auth_handler_basic_fuzzer.cc8
-rw-r--r--chromium/net/http/http_auth_handler_basic_unittest.cc13
-rw-r--r--chromium/net/http/http_auth_handler_digest.cc12
-rw-r--r--chromium/net/http/http_auth_handler_digest.h4
-rw-r--r--chromium/net/http/http_auth_handler_digest_fuzzer.cc8
-rw-r--r--chromium/net/http/http_auth_handler_digest_unittest.cc21
-rw-r--r--chromium/net/http/http_auth_handler_factory.cc20
-rw-r--r--chromium/net/http/http_auth_handler_factory.h39
-rw-r--r--chromium/net/http/http_auth_handler_factory_unittest.cc93
-rw-r--r--chromium/net/http/http_auth_handler_mock.cc12
-rw-r--r--chromium/net/http/http_auth_handler_mock.h4
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.cc18
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.h7
-rw-r--r--chromium/net/http/http_auth_handler_negotiate_unittest.cc85
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.cc6
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.h5
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_portable.cc5
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc5
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_win.cc5
-rw-r--r--chromium/net/http/http_auth_handler_unittest.cc4
-rw-r--r--chromium/net/http/http_auth_sspi_win.cc7
-rw-r--r--chromium/net/http/http_auth_sspi_win_unittest.cc12
-rw-r--r--chromium/net/http/http_auth_unittest.cc15
-rw-r--r--chromium/net/http/http_basic_stream.cc1
-rw-r--r--chromium/net/http/http_cache_transaction.cc7
-rw-r--r--chromium/net/http/http_network_session.cc6
-rw-r--r--chromium/net/http/http_network_session.h2
-rw-r--r--chromium/net/http/http_network_transaction.cc29
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc48
-rw-r--r--chromium/net/http/http_proxy_connect_job.h3
-rw-r--r--chromium/net/http/http_request_headers.cc1
-rw-r--r--chromium/net/http/http_response_info.cc8
-rw-r--r--chromium/net/http/http_response_info.h2
-rw-r--r--chromium/net/http/http_server_properties.cc3
-rw-r--r--chromium/net/http/http_server_properties_manager.cc18
-rw-r--r--chromium/net/http/http_server_properties_manager_unittest.cc30
-rw-r--r--chromium/net/http/http_stream_factory_job.cc14
-rw-r--r--chromium/net/http/http_stream_factory_job.h1
-rw-r--r--chromium/net/http/http_stream_factory_job_controller.cc21
-rw-r--r--chromium/net/http/http_stream_factory_job_controller.h2
-rw-r--r--chromium/net/http/http_stream_factory_job_controller_unittest.cc47
-rw-r--r--chromium/net/http/http_stream_factory_test_util.cc6
-rw-r--r--chromium/net/http/http_stream_factory_unittest.cc83
-rw-r--r--chromium/net/http/http_stream_parser.cc6
-rw-r--r--chromium/net/http/http_stream_parser.h4
-rw-r--r--chromium/net/http/http_stream_parser_unittest.cc33
-rw-r--r--chromium/net/http/structured_headers.cc1
-rw-r--r--chromium/net/http/test_upload_data_stream_not_allow_http1.cc32
-rw-r--r--chromium/net/http/test_upload_data_stream_not_allow_http1.h33
-rw-r--r--chromium/net/http/transport_security_persister.cc371
-rw-r--r--chromium/net/http/transport_security_persister.h20
-rw-r--r--chromium/net/http/transport_security_persister_unittest.cc462
-rw-r--r--chromium/net/http/transport_security_state.cc442
-rw-r--r--chromium/net/http/transport_security_state.h123
-rw-r--r--chromium/net/http/transport_security_state_static.json4007
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc1071
-rw-r--r--chromium/net/http/url_security_manager_win.cc1
-rw-r--r--chromium/net/http2/platform/impl/http2_logging_impl.h2
-rw-r--r--chromium/net/http2/platform/impl/http2_macros_impl.h2
-rw-r--r--chromium/net/log/file_net_log_observer.cc3
-rw-r--r--chromium/net/log/file_net_log_observer_unittest.cc10
-rw-r--r--chromium/net/log/net_log.cc12
-rw-r--r--chromium/net/log/net_log_entry.cc20
-rw-r--r--chromium/net/log/net_log_event_type_list.h44
-rw-r--r--chromium/net/log/net_log_source.cc4
-rw-r--r--chromium/net/log/net_log_source.h3
-rw-r--r--chromium/net/log/net_log_source_type_list.h3
-rw-r--r--chromium/net/log/net_log_util.cc128
-rw-r--r--chromium/net/log/net_log_util.h4
-rw-r--r--chromium/net/log/net_log_util_unittest.cc2
-rw-r--r--chromium/net/log/net_log_values.cc6
-rw-r--r--chromium/net/log/net_log_with_source.cc6
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.cc87
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.h34
-rw-r--r--chromium/net/proxy_resolution/configured_proxy_resolution_service.cc33
-rw-r--r--chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc91
-rw-r--r--chromium/net/proxy_resolution/network_delegate_error_observer_unittest.cc1
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl.cc3
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl.h6
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc60
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver.h1
-rw-r--r--chromium/net/quic/OWNERS2
-rw-r--r--chromium/net/quic/bidirectional_stream_quic_impl_unittest.cc157
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium.cc10
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium.h6
-rw-r--r--chromium/net/quic/crypto/proof_verifier_chromium_test.cc216
-rw-r--r--chromium/net/quic/crypto_test_utils_chromium.cc4
-rw-r--r--chromium/net/quic/mock_crypto_client_stream.cc121
-rw-r--r--chromium/net/quic/mock_quic_data.cc1
-rw-r--r--chromium/net/quic/network_connection.cc1
-rw-r--r--chromium/net/quic/platform/impl/quic_default_proof_providers_impl.cc6
-rw-r--r--chromium/net/quic/platform/impl/quic_socket_utils.cc1
-rw-r--r--chromium/net/quic/platform/impl/quic_test_impl.h2
-rw-r--r--chromium/net/quic/quic_chromium_client_session.cc356
-rw-r--r--chromium/net/quic/quic_chromium_client_session.h63
-rw-r--r--chromium/net/quic/quic_chromium_client_session_peer.cc5
-rw-r--r--chromium/net/quic/quic_chromium_client_session_peer.h2
-rw-r--r--chromium/net/quic/quic_chromium_client_session_test.cc359
-rw-r--r--chromium/net/quic/quic_chromium_client_stream.h2
-rw-r--r--chromium/net/quic/quic_chromium_packet_writer.cc4
-rw-r--r--chromium/net/quic/quic_chromium_packet_writer.h2
-rw-r--r--chromium/net/quic/quic_client_session_cache.cc18
-rw-r--r--chromium/net/quic/quic_client_session_cache.h2
-rw-r--r--chromium/net/quic/quic_client_session_cache_unittests.cc170
-rw-r--r--chromium/net/quic/quic_connection_logger.cc30
-rw-r--r--chromium/net/quic/quic_connection_logger.h4
-rw-r--r--chromium/net/quic/quic_connectivity_monitor.cc71
-rw-r--r--chromium/net/quic/quic_connectivity_monitor.h74
-rw-r--r--chromium/net/quic/quic_connectivity_probing_manager.cc48
-rw-r--r--chromium/net/quic/quic_connectivity_probing_manager.h13
-rw-r--r--chromium/net/quic/quic_connectivity_probing_manager_test.cc83
-rw-r--r--chromium/net/quic/quic_context.h11
-rw-r--r--chromium/net/quic/quic_flags_list.h235
-rw-r--r--chromium/net/quic/quic_http3_logger.cc84
-rw-r--r--chromium/net/quic/quic_http_stream.cc13
-rw-r--r--chromium/net/quic/quic_http_stream_test.cc11
-rw-r--r--chromium/net/quic/quic_http_utils.cc5
-rw-r--r--chromium/net/quic/quic_http_utils_test.cc19
-rw-r--r--chromium/net/quic/quic_network_transaction_unittest.cc695
-rw-r--r--chromium/net/quic/quic_proxy_client_socket.cc18
-rw-r--r--chromium/net/quic/quic_proxy_client_socket.h6
-rw-r--r--chromium/net/quic/quic_proxy_client_socket_unittest.cc4
-rw-r--r--chromium/net/quic/quic_session_key.cc7
-rw-r--r--chromium/net/quic/quic_stream_factory.cc183
-rw-r--r--chromium/net/quic/quic_stream_factory.h22
-rw-r--r--chromium/net/quic/quic_stream_factory_peer.cc5
-rw-r--r--chromium/net/quic/quic_stream_factory_peer.h2
-rw-r--r--chromium/net/quic/quic_stream_factory_test.cc448
-rw-r--r--chromium/net/quic/quic_test_packet_maker.cc124
-rw-r--r--chromium/net/quic/quic_test_packet_maker.h26
-rw-r--r--chromium/net/quic/quic_test_packet_printer.cc4
-rw-r--r--chromium/net/quic/quic_transport_client.cc132
-rw-r--r--chromium/net/quic/quic_transport_client.h68
-rw-r--r--chromium/net/quic/quic_transport_end_to_end_test.cc164
-rw-r--r--chromium/net/quic/quic_transport_error.cc24
-rw-r--r--chromium/net/quic/quic_transport_error.h53
-rw-r--r--chromium/net/quic/quic_transport_parameters_fuzzer.cc10
-rw-r--r--chromium/net/quic/quic_utils_chromium.cc31
-rw-r--r--chromium/net/quic/quic_utils_chromium.h26
-rw-r--r--chromium/net/quic/quic_utils_chromium_test.cc35
-rw-r--r--chromium/net/quiche/common/platform/impl/quiche_logging_impl.h2
-rw-r--r--chromium/net/quiche/common/platform/impl/quiche_optional_impl.h2
-rw-r--r--chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.cc50
-rw-r--r--chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.h25
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover.cc7
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover.h5
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover_unittest.cc22
-rw-r--r--chromium/net/reporting/reporting_cache_impl.cc4
-rw-r--r--chromium/net/reporting/reporting_delivery_agent.cc290
-rw-r--r--chromium/net/reporting/reporting_delivery_agent.h41
-rw-r--r--chromium/net/reporting/reporting_delivery_agent_unittest.cc315
-rw-r--r--chromium/net/reporting/reporting_header_parser.cc147
-rw-r--r--chromium/net/reporting/reporting_header_parser.h58
-rw-r--r--chromium/net/reporting/reporting_report.cc12
-rw-r--r--chromium/net/reporting/reporting_report.h12
-rw-r--r--chromium/net/reporting/reporting_service.cc17
-rw-r--r--chromium/net/reporting/reporting_service.h4
-rw-r--r--chromium/net/reporting/reporting_service_unittest.cc6
-rw-r--r--chromium/net/reporting/reporting_test_util.cc4
-rw-r--r--chromium/net/reporting/reporting_test_util.h4
-rw-r--r--chromium/net/reporting/reporting_uploader.cc34
-rw-r--r--chromium/net/reporting/reporting_uploader_unittest.cc4
-rw-r--r--chromium/net/socket/client_socket_handle.h2
-rw-r--r--chromium/net/socket/client_socket_pool_base_unittest.cc6
-rw-r--r--chromium/net/socket/socket_posix.cc8
-rw-r--r--chromium/net/socket/socket_test_util.h2
-rw-r--r--chromium/net/socket/ssl_client_socket_impl.cc22
-rw-r--r--chromium/net/socket/ssl_client_socket_unittest.cc65
-rw-r--r--chromium/net/socket/transport_client_socket_pool.cc7
-rw-r--r--chromium/net/socket/udp_socket_posix.cc26
-rw-r--r--chromium/net/socket/udp_socket_posix.h3
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager.h1
-rw-r--r--chromium/net/spdy/OWNERS1
-rw-r--r--chromium/net/spdy/platform/impl/spdy_logging_impl.h2
-rw-r--r--chromium/net/spdy/platform/impl/spdy_macros_impl.h1
-rw-r--r--chromium/net/spdy/spdy_network_transaction_unittest.cc99
-rw-r--r--chromium/net/spdy/spdy_session.cc156
-rw-r--r--chromium/net/spdy/spdy_session.h7
-rw-r--r--chromium/net/spdy/spdy_session_unittest.cc212
-rw-r--r--chromium/net/spdy/spdy_stream.cc13
-rw-r--r--chromium/net/spdy/spdy_stream.h4
-rw-r--r--chromium/net/spdy/spdy_stream_test_util.cc6
-rw-r--r--chromium/net/spdy/spdy_stream_test_util.h6
-rw-r--r--chromium/net/spdy/spdy_stream_unittest.cc63
-rw-r--r--chromium/net/ssl/openssl_ssl_util.cc1
-rw-r--r--chromium/net/ssl/ssl_client_session_cache.cc6
-rw-r--r--chromium/net/ssl/ssl_config_service.h5
-rw-r--r--chromium/net/ssl/ssl_connection_status_flags.h2
-rw-r--r--chromium/net/test/cert_test_util_nss.cc1
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.cc93
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.h83
-rw-r--r--chromium/net/test/embedded_test_server/request_handler_util.cc4
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.cc15
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server.cc1
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server_win.cc1
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.cc283
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.h102
-rw-r--r--chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp1
-rw-r--r--chromium/net/third_party/quiche/BUILD.gn62
-rw-r--r--chromium/net/third_party/quiche/src/common/platform/api/quiche_optional.h3
-rw-r--r--chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h31
-rw-r--r--chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc53
-rw-r--r--chromium/net/third_party/quiche/src/common/quiche_data_reader.cc10
-rw-r--r--chromium/net/third_party/quiche/src/common/quiche_data_reader.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc177
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h149
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc154
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h95
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc281
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc78
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h284
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc122
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h114
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc461
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc83
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h35
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/chlo_extractor.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc57
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_misc.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_probe_bw.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_sender.cc14
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr2_simulator_test.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.cc87
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/bbr_sender_test.cc118
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc24
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm_test.cc30
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm_test.cc140
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc101
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.h14
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view_test.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_server_test.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/crypto_utils.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/proof_source_x509.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config_test.cc48
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.cc22
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.cc464
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h36
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters_test.cc390
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h45
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc23
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc23
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/handshaker_delegate_interface.h17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/end_to_end_test.cc609
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/http_constants.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_client_promised_info_test.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.cc22
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base_test.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc60
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h7
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc572
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc66
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.cc117
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session.h55
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_session_test.cc58
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_test.cc16
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h16
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_send_stream_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.cc195
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config.h69
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_config_test.cc63
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.cc1021
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection.h183
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_stats.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_connection_test.cc1368
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.cc13
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_handshaker.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h10
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_client_stream_test.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_crypto_stream_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.cc239
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher.h56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_dispatcher_test.cc174
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.cc181
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer.h18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_framer_test.cc121
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc145
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc109
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc314
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h298
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc329
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.cc154
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator.h32
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_creator_test.cc377
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h21
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_packets.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.cc111
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_sent_packet_manager_test.cc290
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.cc713
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session.h165
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_session_test.cc92
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream.cc99
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream.h21
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_stream_test.cc76
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h49
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag.h12
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_time.h8
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_trace_visitor.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_types.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_types.h75
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h11
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc27
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_test.cc82
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils.cc55
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils.h18
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_utils_test.cc47
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.cc42
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h14
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc56
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.cc115
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions.h127
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/quic_versions_test.cc270
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_chlo_extractor_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.cc71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_client_handshaker_test.cc81
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_handshaker_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.cc106
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker.h24
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/tls_server_handshaker_test.cc71
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc26
-rw-r--r--chromium/net/third_party/quiche/src/quic/masque/masque_encapsulated_epoll_client.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_session.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_client_test.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quic/qbone/qbone_stream_test.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/counting_packet_filter.h43
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.cc25
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h34
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.cc160
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h128
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.cc87
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h72
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.cc190
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.h203
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint_test.cc251
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.cc219
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.h68
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_fakes.h162
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h122
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter_test.cc108
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.cc271
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h190
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer_test.cc496
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.cc78
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h113
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_session.cc470
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_session.h339
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_session_test.cc680
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.cc170
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.h142
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/quartc_stream_test.cc656
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.cc98
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h84
-rw-r--r--chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport_test.cc163
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc221
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h119
-rw-r--r--chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc183
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/crypto_test_utils.cc23
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_config_peer.h13
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h2
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc22
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_session_peer.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.cc49
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_client.h21
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.cc24
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/quic_test_utils.h37
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_quic_framer.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h3
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.cc16
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h8
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h5
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quic/test_tools/test_certificates.h4
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_base.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_base.h15
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_client_interop_test_bin.cc131
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h1
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_packet_printer_bin.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_session.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_simple_server_stream_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc50
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h14
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h1
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler.h41
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler_test.cc18
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.cc13
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/hpack/hpack_encoder_test.cc16
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h56
-rw-r--r--chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc18
-rw-r--r--chromium/net/tools/cert_verify_tool/cert_verify_tool_util.cc1
-rw-r--r--chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc1
-rw-r--r--chromium/net/tools/epoll_server/platform/impl/epoll_logging_impl.h2
-rw-r--r--chromium/net/tools/quic/quic_http_proxy_backend.h1
-rw-r--r--chromium/net/tools/quic/quic_http_proxy_backend_stream.h1
-rw-r--r--chromium/net/tools/quic/quic_simple_client.cc3
-rw-r--r--chromium/net/tools/quic/quic_simple_client.h1
-rw-r--r--chromium/net/tools/quic/quic_simple_client_bin.cc3
-rw-r--r--chromium/net/tools/quic/quic_simple_client_test.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_server.cc25
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.cc4
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.h2
-rw-r--r--chromium/net/tools/testserver/testserver_base.py20
-rw-r--r--chromium/net/traffic_annotation/network_traffic_annotation.h5
-rw-r--r--chromium/net/url_request/url_fetcher_response_writer.cc3
-rw-r--r--chromium/net/url_request/url_request.cc12
-rw-r--r--chromium/net/url_request/url_request.h28
-rw-r--r--chromium/net/url_request/url_request_context_builder.cc1
-rw-r--r--chromium/net/url_request/url_request_context_builder_unittest.cc36
-rw-r--r--chromium/net/url_request/url_request_http_job.cc154
-rw-r--r--chromium/net/url_request/url_request_http_job.h7
-rw-r--r--chromium/net/url_request/url_request_http_job_unittest.cc83
-rw-r--r--chromium/net/url_request/url_request_job.cc107
-rw-r--r--chromium/net/url_request/url_request_job.h2
-rw-r--r--chromium/net/url_request/url_request_job_unittest.cc115
-rw-r--r--chromium/net/url_request/url_request_netlog_params.cc18
-rw-r--r--chromium/net/url_request/url_request_quic_unittest.cc110
-rw-r--r--chromium/net/url_request/url_request_test_util.cc1
-rw-r--r--chromium/net/url_request/url_request_test_util.h1
-rw-r--r--chromium/net/url_request/url_request_unittest.cc691
-rw-r--r--chromium/net/websockets/websocket_channel.cc42
-rw-r--r--chromium/net/websockets/websocket_channel.h17
-rw-r--r--chromium/net/websockets/websocket_channel_test.cc251
-rw-r--r--chromium/net/websockets/websocket_deflate_parameters.h2
-rw-r--r--chromium/net/websockets/websocket_end_to_end_test.cc10
-rw-r--r--chromium/net/websockets/websocket_event_interface.h9
-rw-r--r--chromium/net/websockets/websocket_stream_cookie_test.cc16
-rw-r--r--chromium/net/websockets/websocket_stream_test.cc40
721 files changed, 29983 insertions, 22863 deletions
diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn
index 9712bc3e46a..81f30ec6213 100644
--- a/chromium/net/BUILD.gn
+++ b/chromium/net/BUILD.gn
@@ -87,10 +87,6 @@ buildflag_header("buildflags") {
config("net_internal_config") {
defines = [ "NET_IMPLEMENTATION" ]
- if (use_kerberos && is_android) {
- include_dirs = [ "/usr/include/kerberosV" ]
- }
-
if (enable_built_in_dns) {
defines += [ "ENABLE_BUILT_IN_DNS" ]
}
@@ -546,12 +542,16 @@ component("net") {
"cookies/canonical_cookie.h",
"cookies/cookie_access_delegate.cc",
"cookies/cookie_access_delegate.h",
+ "cookies/cookie_access_result.cc",
+ "cookies/cookie_access_result.h",
"cookies/cookie_change_dispatcher.cc",
"cookies/cookie_change_dispatcher.h",
"cookies/cookie_constants.cc",
"cookies/cookie_constants.h",
"cookies/cookie_deletion_info.cc",
"cookies/cookie_deletion_info.h",
+ "cookies/cookie_inclusion_status.cc",
+ "cookies/cookie_inclusion_status.h",
"cookies/cookie_monster.cc",
"cookies/cookie_monster.h",
"cookies/cookie_monster_change_dispatcher.cc",
@@ -667,8 +667,6 @@ component("net") {
"http/bidirectional_stream_request_info.h",
"http/broken_alternative_services.cc",
"http/broken_alternative_services.h",
- "http/failing_http_transaction_factory.cc",
- "http/failing_http_transaction_factory.h",
"http/http_auth.cc",
"http/http_auth.h",
"http/http_auth_cache.cc",
@@ -916,6 +914,8 @@ component("net") {
"quic/quic_clock_skew_detector.h",
"quic/quic_connection_logger.cc",
"quic/quic_connection_logger.h",
+ "quic/quic_connectivity_monitor.cc",
+ "quic/quic_connectivity_monitor.h",
"quic/quic_connectivity_probing_manager.cc",
"quic/quic_connectivity_probing_manager.h",
"quic/quic_context.cc",
@@ -941,8 +941,8 @@ component("net") {
"quic/quic_stream_factory.h",
"quic/quic_transport_client.cc",
"quic/quic_transport_client.h",
- "quic/quic_utils_chromium.cc",
- "quic/quic_utils_chromium.h",
+ "quic/quic_transport_error.cc",
+ "quic/quic_transport_error.h",
"quiche/common/platform/impl/quiche_arraysize_impl.h",
"quiche/common/platform/impl/quiche_endian_impl.h",
"quiche/common/platform/impl/quiche_export_impl.h",
@@ -953,6 +953,8 @@ component("net") {
"quiche/common/platform/impl/quiche_str_cat_impl.h",
"quiche/common/platform/impl/quiche_string_piece_impl.h",
"quiche/common/platform/impl/quiche_text_utils_impl.h",
+ "quiche/common/platform/impl/quiche_time_utils_impl.cc",
+ "quiche/common/platform/impl/quiche_time_utils_impl.h",
"quiche/common/platform/impl/quiche_unordered_containers_impl.h",
"socket/client_socket_factory.cc",
"socket/client_socket_factory.h",
@@ -1413,8 +1415,8 @@ component("net") {
]
}
- # Use getifaddrs() on POSIX platforms, except Linux and Android.
- if (is_posix && !is_linux && !is_android) {
+ # Use getifaddrs() on POSIX platforms, except Linux.
+ if (is_posix && !is_linux) {
sources += [
"base/network_interfaces_getifaddrs.cc",
"base/network_interfaces_getifaddrs.h",
@@ -1430,18 +1432,15 @@ component("net") {
"cert/known_roots_nss.h",
"cert/nss_cert_database.cc",
"cert/nss_cert_database.h",
+ "cert/test_root_certs_builtin.cc",
+ "cert/x509_util_nss.cc",
+ "cert/x509_util_nss.h",
"third_party/mozilla_security_manager/nsNSSCertificateDB.cpp",
"third_party/mozilla_security_manager/nsNSSCertificateDB.h",
"third_party/mozilla_security_manager/nsPKCS12Blob.cpp",
"third_party/mozilla_security_manager/nsPKCS12Blob.h",
"third_party/nss/ssl/cmpcert.cc",
"third_party/nss/ssl/cmpcert.h",
-
- # These files are part of the partial implementation of NSS for
- # cert verification, so keep them in that case.
- "cert/test_root_certs_nss.cc",
- "cert/x509_util_nss.cc",
- "cert/x509_util_nss.h",
]
if (!is_chromecast) {
sources += [
@@ -1461,7 +1460,7 @@ component("net") {
"base/network_interfaces_fuchsia.cc",
"base/network_interfaces_fuchsia.h",
"base/platform_mime_util_fuchsia.cc",
- "cert/test_root_certs_fuchsia.cc",
+ "cert/test_root_certs_builtin.cc",
]
}
@@ -1868,6 +1867,9 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/2048-rsa-ee-by-prime256v1-ecdsa-intermediate.pem",
"data/ssl/certificates/2048-rsa-intermediate.pem",
"data/ssl/certificates/2048-rsa-root.pem",
+ "data/ssl/certificates/398_days_1_second_after_2020_09_01.pem",
+ "data/ssl/certificates/398_days_after_2020_09_01.pem",
+ "data/ssl/certificates/399_days_after_2020_09_01.pem",
"data/ssl/certificates/39_months_after_2015_04.pem",
"data/ssl/certificates/39_months_based_on_last_day.pem",
"data/ssl/certificates/40_months_after_2015_04.pem",
@@ -1928,6 +1930,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/crlset_by_leaf_spki.raw",
"data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw",
"data/ssl/certificates/crlset_by_root_serial.raw",
+ "data/ssl/certificates/crlset_by_root_spki.raw",
"data/ssl/certificates/crlset_by_root_subject.raw",
"data/ssl/certificates/crlset_by_root_subject_no_spki.raw",
"data/ssl/certificates/crlset_known_interception_by_root.raw",
@@ -2029,6 +2032,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem",
"data/ssl/certificates/quic-leaf-cert.key.sct",
"data/ssl/certificates/quic-root.pem",
+ "data/ssl/certificates/quic-short-lived.pem",
"data/ssl/certificates/redundant-server-chain.pem",
"data/ssl/certificates/redundant-validated-chain-root.pem",
"data/ssl/certificates/redundant-validated-chain.pem",
@@ -2196,8 +2200,6 @@ static_library("test_support") {
"test/url_request/url_request_hanging_read_job.h",
"test/url_request/url_request_mock_data_job.cc",
"test/url_request/url_request_mock_data_job.h",
- "test/url_request/url_request_slow_download_job.cc",
- "test/url_request/url_request_slow_download_job.h",
"url_request/test_url_fetcher_factory.cc",
"url_request/test_url_fetcher_factory.h",
"url_request/url_request_test_util.cc",
@@ -3112,6 +3114,7 @@ bundle_data("net_unittests_bundle_data") {
"data/url_request_unittest/308-without-location-header",
"data/url_request_unittest/308-without-location-header.mock-http-headers",
"data/url_request_unittest/BullRunSpeech.txt",
+ "data/url_request_unittest/BullRunSpeech.txt.deflate",
"data/url_request_unittest/content-type-normalization.html",
"data/url_request_unittest/content-type-normalization.html.mock-http-headers",
"data/url_request_unittest/expect-ct-header-multiple.html",
@@ -4205,6 +4208,7 @@ test("net_unittests") {
"cookies/canonical_cookie_unittest.cc",
"cookies/cookie_constants_unittest.cc",
"cookies/cookie_deletion_info_unittest.cc",
+ "cookies/cookie_inclusion_status_unittest.cc",
"cookies/cookie_monster_unittest.cc",
"cookies/cookie_util_unittest.cc",
"cookies/parsed_cookie_unittest.cc",
@@ -4280,6 +4284,8 @@ test("net_unittests") {
"http/mock_allow_http_auth_preferences.h",
"http/structured_headers_generated_unittest.cc",
"http/structured_headers_unittest.cc",
+ "http/test_upload_data_stream_not_allow_http1.cc",
+ "http/test_upload_data_stream_not_allow_http1.h",
"http/transport_security_persister_unittest.cc",
"http/transport_security_state_unittest.cc",
"http/url_security_manager_unittest.cc",
@@ -4344,7 +4350,6 @@ test("net_unittests") {
"quic/quic_test_packet_maker.cc",
"quic/quic_test_packet_maker.h",
"quic/quic_transport_end_to_end_test.cc",
- "quic/quic_utils_chromium_test.cc",
"quic/test_quic_crypto_client_config_handle.cc",
"quic/test_quic_crypto_client_config_handle.h",
"socket/client_socket_pool_base_unittest.cc",
@@ -4799,6 +4804,9 @@ test("net_unittests") {
"//testing/android/native_test:native_test_native_code",
]
android_manifest = "//net/android/unittest_support/AndroidManifest.xml"
+
+ # Cronet still supports kitkat.
+ min_sdk_version = 19
sources += [
"base/address_tracker_linux_unittest.cc",
"base/network_interfaces_linux_unittest.cc",
diff --git a/chromium/net/OWNERS b/chromium/net/OWNERS
index 46e4d5e3448..2ee09fd6d7c 100644
--- a/chromium/net/OWNERS
+++ b/chromium/net/OWNERS
@@ -9,7 +9,6 @@ mmenke@chromium.org
morlovich@chromium.org
nharper@chromium.org
pauljensen@chromium.org
-rch@chromium.org
rsleevi@chromium.org
zhongyi@chromium.org
diff --git a/chromium/net/android/BUILD.gn b/chromium/net/android/BUILD.gn
index 8547015246c..33030438765 100644
--- a/chromium/net/android/BUILD.gn
+++ b/chromium/net/android/BUILD.gn
@@ -139,6 +139,9 @@ android_apk("net_test_support_apk") {
# just disable it.
enable_multidex = false
+ # Cronet still supports kitkat.
+ min_sdk_version = 19
+
deps = [
":net_java_test_support",
":net_java_test_support_provider",
diff --git a/chromium/net/base/address_tracker_linux.cc b/chromium/net/base/address_tracker_linux.cc
index ffb6e6ef211..b9e76f900ef 100644
--- a/chromium/net/base/address_tracker_linux.cc
+++ b/chromium/net/base/address_tracker_linux.cc
@@ -17,8 +17,13 @@
#include "base/optional.h"
#include "base/posix/eintr_wrapper.h"
#include "base/threading/scoped_blocking_call.h"
+#include "build/build_config.h"
#include "net/base/network_interfaces_linux.h"
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
namespace net {
namespace internal {
@@ -177,6 +182,14 @@ AddressTrackerLinux::AddressTrackerLinux(
AddressTrackerLinux::~AddressTrackerLinux() = default;
void AddressTrackerLinux::Init() {
+#if defined(OS_ANDROID)
+ // RTM_GETLINK stopped working in Android 11 (see
+ // https://developer.android.com/preview/privacy/mac-address),
+ // so AddressTrackerLinux should not be used in later versions
+ // of Android. Chromium code doesn't need it past Android P.
+ DCHECK_LT(base::android::BuildInfo::GetInstance()->sdk_int(),
+ base::android::SDK_VERSION_P);
+#endif
netlink_fd_.reset(socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
if (!netlink_fd_.is_valid()) {
PLOG(ERROR) << "Could not create NETLINK socket";
diff --git a/chromium/net/base/address_tracker_linux_unittest.cc b/chromium/net/base/address_tracker_linux_unittest.cc
index 0ad83bf0363..eff90ed009e 100644
--- a/chromium/net/base/address_tracker_linux_unittest.cc
+++ b/chromium/net/base/address_tracker_linux_unittest.cc
@@ -16,9 +16,14 @@
#include "base/test/spin_wait.h"
#include "base/test/task_environment.h"
#include "base/threading/simple_thread.h"
+#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
#ifndef IFA_F_HOMEADDRESS
#define IFA_F_HOMEADDRESS 0x10
#endif
@@ -685,6 +690,12 @@ TEST_F(AddressTrackerLinuxTest, NonTrackingMode) {
}
TEST_F(AddressTrackerLinuxTest, NonTrackingModeInit) {
+#if defined(OS_ANDROID)
+ // Calling Init() on Android P+ isn't supported.
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_P)
+ return;
+#endif
AddressTrackerLinux tracker;
tracker.Init();
}
@@ -721,6 +732,12 @@ class GetCurrentConnectionTypeRunner
};
TEST_F(AddressTrackerLinuxTest, BroadcastInit) {
+#if defined(OS_ANDROID)
+ // Calling Init() on Android P+ isn't supported.
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_P)
+ return;
+#endif
base::test::TaskEnvironment task_environment(
base::test::TaskEnvironment::MainThreadType::IO);
InitializeAddressTracker(true);
diff --git a/chromium/net/base/backoff_entry_serializer_fuzzer.cc b/chromium/net/base/backoff_entry_serializer_fuzzer.cc
index d66eacbd443..2ec426af293 100644
--- a/chromium/net/base/backoff_entry_serializer_fuzzer.cc
+++ b/chromium/net/base/backoff_entry_serializer_fuzzer.cc
@@ -8,8 +8,10 @@
#include <memory>
#include "base/json/json_reader.h"
+#include "base/logging.h"
#include "base/optional.h"
#include "base/strings/string_piece_forward.h"
+#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "net/base/backoff_entry_serializer.h"
@@ -32,11 +34,18 @@ class ProtoTranslator {
BackoffEntry::Policy policy() const {
return PolicyFromProto(input_.policy());
}
- base::Time parse_time() const { return TimeFromProto(input_.parse_time()); }
+ base::Time parse_time() const {
+ return base::Time() +
+ base::TimeDelta::FromMicroseconds(input_.parse_time());
+ }
base::Time serialize_time() const {
- return TimeFromProto(input_.serialize_time());
+ return base::Time() +
+ base::TimeDelta::FromMicroseconds(input_.serialize_time());
+ }
+ base::TimeTicks now_ticks() const {
+ return base::TimeTicks() +
+ base::TimeDelta::FromMicroseconds(input_.now_ticks());
}
-
base::Optional<base::Value> serialized_entry() const {
json_proto::JsonProtoConverter converter;
std::string json_array = converter.Convert(input_.serialized_entry());
@@ -49,24 +58,33 @@ class ProtoTranslator {
static BackoffEntry::Policy PolicyFromProto(
const fuzz_proto::BackoffEntryPolicy& policy) {
- return BackoffEntry::Policy{
- .num_errors_to_ignore = policy.num_errors_to_ignore(),
- .initial_delay_ms = policy.initial_delay_ms(),
- .multiply_factor = policy.multiply_factor(),
- .jitter_factor = policy.jitter_factor(),
- .maximum_backoff_ms = policy.maximum_backoff_ms(),
- .entry_lifetime_ms = policy.entry_lifetime_ms(),
- .always_use_initial_delay = policy.always_use_initial_delay(),
- };
+ BackoffEntry::Policy new_policy;
+ new_policy.num_errors_to_ignore = policy.num_errors_to_ignore();
+ new_policy.initial_delay_ms = policy.initial_delay_ms();
+ new_policy.multiply_factor = policy.multiply_factor();
+ new_policy.jitter_factor = policy.jitter_factor();
+ new_policy.maximum_backoff_ms = policy.maximum_backoff_ms();
+ new_policy.entry_lifetime_ms = policy.entry_lifetime_ms();
+ new_policy.always_use_initial_delay = policy.always_use_initial_delay();
+ return new_policy;
}
+};
- static base::Time TimeFromProto(uint64_t raw_time) {
- return base::Time() + base::TimeDelta::FromMicroseconds(raw_time);
- }
+class MockClock : public base::TickClock {
+ public:
+ MockClock() = default;
+ ~MockClock() override = default;
+
+ void SetNow(base::TimeTicks now) { now_ = now; }
+ base::TimeTicks NowTicks() const override { return now_; }
+
+ private:
+ base::TimeTicks now_;
};
// Tests the "deserialize-reserialize" property. Deserializes a BackoffEntry
-// from JSON, reserializes it, and checks that the JSON values match.
+// from JSON, reserializes it, then deserializes again. Holding time constant,
+// we check that the parsed BackoffEntry values are equivalent.
void TestDeserialize(const ProtoTranslator& translator) {
// Attempt to convert the json_proto.ArrayValue to a base::Value.
base::Optional<base::Value> value = translator.serialized_entry();
@@ -76,19 +94,30 @@ void TestDeserialize(const ProtoTranslator& translator) {
BackoffEntry::Policy policy = translator.policy();
+ MockClock clock;
+ clock.SetNow(translator.now_ticks());
+
// Attempt to deserialize a BackoffEntry.
std::unique_ptr<BackoffEntry> entry =
- BackoffEntrySerializer::DeserializeFromValue(*value, &policy, nullptr,
+ BackoffEntrySerializer::DeserializeFromValue(*value, &policy, &clock,
translator.parse_time());
if (!entry)
return;
- // Serializing |entry| it should recreate the original JSON input!
std::unique_ptr<base::Value> reserialized =
- BackoffEntrySerializer::SerializeToValue(*entry,
- translator.serialize_time());
+ BackoffEntrySerializer::SerializeToValue(*entry, translator.parse_time());
CHECK(reserialized);
- CHECK_EQ(*reserialized, *value);
+
+ // Due to fuzzy interpretation in BackoffEntrySerializer::
+ // DeserializeFromValue, we cannot assert that |*reserialized == *value|.
+ // Rather, we can deserialize |reserialized| and check that the result is
+ // equivalent to |entry|.
+ std::unique_ptr<BackoffEntry> entry_reparsed =
+ BackoffEntrySerializer::DeserializeFromValue(
+ *reserialized, &policy, &clock, translator.parse_time());
+ CHECK(entry_reparsed);
+ CHECK_EQ(entry->failure_count(), entry_reparsed->failure_count());
+ CHECK_EQ(entry->GetReleaseTime(), entry_reparsed->GetReleaseTime());
}
// Tests the "serialize-deserialize" property. Serializes an arbitrary
@@ -105,10 +134,13 @@ void TestSerialize(const ProtoTranslator& translator) {
translator.serialize_time());
CHECK(serialized);
+ MockClock clock;
+ clock.SetNow(translator.now_ticks());
+
// Deserialize it.
std::unique_ptr<BackoffEntry> deserialized_entry =
- BackoffEntrySerializer::DeserializeFromValue(
- *serialized, &policy, nullptr, translator.parse_time());
+ BackoffEntrySerializer::DeserializeFromValue(*serialized, &policy, &clock,
+ translator.parse_time());
// Even though SerializeToValue was successful, we're not guaranteed to have a
// |deserialized_entry|. One reason deserialization may fail is if the parsed
// |absolute_release_time_us| is below zero.
@@ -134,8 +166,8 @@ DEFINE_PROTO_FUZZER(const fuzz_proto::FuzzerInput& input) {
}
ProtoTranslator translator(input);
- TestSerialize(translator);
TestDeserialize(translator);
+ TestSerialize(translator);
}
} // namespace net
diff --git a/chromium/net/base/backoff_entry_serializer_fuzzer_input.proto b/chromium/net/base/backoff_entry_serializer_fuzzer_input.proto
index d92f72eca9b..06cb247dd2a 100644
--- a/chromium/net/base/backoff_entry_serializer_fuzzer_input.proto
+++ b/chromium/net/base/backoff_entry_serializer_fuzzer_input.proto
@@ -9,9 +9,11 @@ package fuzz_proto;
import "testing/libfuzzer/proto/json.proto";
message FuzzerInput {
- // Using int64 to match base::Time's internal representation.
+ // Using int64 to match internal representation of base::Time and
+ // base::TimeTicks.
required int64 parse_time = 1;
required int64 serialize_time = 2;
+ required int64 now_ticks = 5;
required BackoffEntryPolicy policy = 3;
required json_proto.ArrayValue serialized_entry = 4;
}
diff --git a/chromium/net/base/features.cc b/chromium/net/base/features.cc
index b6b6c2dedd5..1b97b20d324 100644
--- a/chromium/net/base/features.cc
+++ b/chromium/net/base/features.cc
@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "net/base/features.h"
+
+#include <vector>
+
#include "build/build_config.h"
namespace net {
@@ -11,6 +14,9 @@ namespace features {
const base::Feature kAcceptLanguageHeader{"AcceptLanguageHeader",
base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kCapReferrerToOriginOnCrossOrigin{
+ "CapReferrerToOriginOnCrossOrigin", base::FEATURE_DISABLED_BY_DEFAULT};
+
const base::Feature kDnsHttpssvc{"DnsHttpssvc",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -20,12 +26,34 @@ const base::FeatureParam<bool> kDnsHttpssvcUseHttpssvc{
const base::FeatureParam<bool> kDnsHttpssvcUseIntegrity{
&kDnsHttpssvc, "DnsHttpssvcUseIntegrity", false};
+const base::FeatureParam<bool> kDnsHttpssvcEnableQueryOverInsecure{
+ &kDnsHttpssvc, "DnsHttpssvcEnableQueryOverInsecure", false};
+
const base::FeatureParam<int> kDnsHttpssvcExtraTimeMs{
&kDnsHttpssvc, "DnsHttpssvcExtraTimeMs", 10};
const base::FeatureParam<int> kDnsHttpssvcExtraTimePercent{
&kDnsHttpssvc, "DnsHttpssvcExtraTimePercent", 5};
+const base::FeatureParam<std::string> kDnsHttpssvcExperimentDomains{
+ &kDnsHttpssvc, "DnsHttpssvcExperimentDomains", ""};
+
+const base::FeatureParam<std::string> kDnsHttpssvcControlDomains{
+ &kDnsHttpssvc, "DnsHttpssvcControlDomains", ""};
+
+const base::FeatureParam<bool> kDnsHttpssvcControlDomainWildcard{
+ &kDnsHttpssvc, "DnsHttpssvcControlDomainWildcard", false};
+
+const base::Feature kAvoidH2Reprioritization{"AvoidH2Reprioritization",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+namespace dns_httpssvc_experiment {
+base::TimeDelta GetExtraTimeAbsolute() {
+ DCHECK(base::FeatureList::IsEnabled(features::kDnsHttpssvc));
+ return base::TimeDelta::FromMilliseconds(kDnsHttpssvcExtraTimeMs.Get());
+}
+} // namespace dns_httpssvc_experiment
+
const base::Feature kEnableTLS13EarlyData{"EnableTLS13EarlyData",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -50,6 +78,28 @@ const base::Feature kPartitionSSLSessionsByNetworkIsolationKey{
"PartitionSSLSessionsByNetworkIsolationKey",
base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kPartitionExpectCTStateByNetworkIsolationKey{
+ "PartitionExpectCTStateByNetworkIsolationKey",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kExpectCTPruning{"ExpectCTPruning",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+NET_EXPORT extern const base::FeatureParam<int>
+ kExpectCTPruneMax(&kExpectCTPruning, "ExpectCTPruneMax", 2000);
+NET_EXPORT extern const base::FeatureParam<int>
+ kExpectCTPruneMin(&kExpectCTPruning, "ExpectCTPruneMin", 1800);
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTSafeFromPruneDays(
+ &kExpectCTPruning,
+ "ExpectCTSafeFromPruneDays",
+ 40);
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTMaxEntriesPerNik(
+ &kExpectCTPruning,
+ "ExpectCTMaxEntriesPerNik",
+ 20);
+NET_EXPORT extern const base::FeatureParam<int>
+ kExpectCTPruneDelaySecs(&kExpectCTPruning, "ExpectCTPruneDelaySecs", 60);
+
const base::Feature kTLS13KeyUpdate{"TLS13KeyUpdate",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -59,24 +109,11 @@ const base::Feature kPostQuantumCECPQ2{"PostQuantumCECPQ2",
const base::Feature kNetUnusedIdleSocketTimeout{
"NetUnusedIdleSocketTimeout", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kRequestEsniDnsRecords{"RequestEsniDnsRecords",
- base::FEATURE_DISABLED_BY_DEFAULT};
-base::TimeDelta EsniDnsMaxAbsoluteAdditionalWait() {
- DCHECK(base::FeatureList::IsEnabled(kRequestEsniDnsRecords));
- return base::TimeDelta::FromMilliseconds(
- kEsniDnsMaxAbsoluteAdditionalWaitMilliseconds.Get());
-}
-const base::FeatureParam<int> kEsniDnsMaxAbsoluteAdditionalWaitMilliseconds{
- &kRequestEsniDnsRecords, "EsniDnsMaxAbsoluteAdditionalWaitMilliseconds",
- 10};
-const base::FeatureParam<int> kEsniDnsMaxRelativeAdditionalWaitPercent{
- &kRequestEsniDnsRecords, "EsniDnsMaxRelativeAdditionalWaitPercent", 5};
-
-const base::Feature kSameSiteByDefaultCookies{
- "SameSiteByDefaultCookies", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kSameSiteByDefaultCookies{"SameSiteByDefaultCookies",
+ base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCookiesWithoutSameSiteMustBeSecure{
- "CookiesWithoutSameSiteMustBeSecure", base::FEATURE_DISABLED_BY_DEFAULT};
+ "CookiesWithoutSameSiteMustBeSecure", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kShortLaxAllowUnsafeThreshold{
"ShortLaxAllowUnsafeThreshold", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -100,10 +137,6 @@ const base::FeatureParam<int>
&kRecentCreationTimeGrantsLegacyCookieSemantics,
"RecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds", 0};
-const base::Feature kBlockExternalRequestsFromNonSecureInitiators{
- "BlockExternalRequestsFromNonSecureInitiators",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
const base::Feature kCertVerifierBuiltinFeature{
"CertVerifierBuiltin", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -114,7 +147,7 @@ const base::Feature kAppendFrameOriginToNetworkIsolationKey{
const base::Feature kUseRegistrableDomainInNetworkIsolationKey{
"UseRegistrableDomainInNetworkIsolationKey",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kTurnOffStreamingMediaCaching{
"TurnOffStreamingMediaCaching", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -128,5 +161,8 @@ const base::Feature kSchemefulSameSite{"SchemefulSameSite",
const base::Feature kTLSLegacyCryptoFallbackForMetrics{
"TLSLegacyCryptoFallbackForMetrics", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kUseLookalikesForNavigationSuggestions{
+ "UseLookalikesForNavigationSuggestions", base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace features
} // namespace net
diff --git a/chromium/net/base/features.h b/chromium/net/base/features.h
index b6b2a4cccf7..a6767bfbe57 100644
--- a/chromium/net/base/features.h
+++ b/chromium/net/base/features.h
@@ -5,8 +5,12 @@
#ifndef NET_BASE_FEATURES_H_
#define NET_BASE_FEATURES_H_
+#include <string>
+
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/net_buildflags.h"
@@ -17,6 +21,10 @@ namespace features {
// https://github.com/WICG/lang-client-hint proposes that we deprecate.
NET_EXPORT extern const base::Feature kAcceptLanguageHeader;
+// When kCapReferrerToOriginOnCrossOrigin is enabled, HTTP referrers on cross-
+// origin requests are restricted to contain at most the source origin.
+NET_EXPORT extern const base::Feature kCapReferrerToOriginOnCrossOrigin;
+
// Enables TLS 1.3 early data.
NET_EXPORT extern const base::Feature kEnableTLS13EarlyData;
@@ -25,6 +33,9 @@ NET_EXPORT extern const base::Feature kEnableTLS13EarlyData;
// cause us to upgrade the URL to HTTPS and/or to attempt QUIC.
NET_EXPORT extern const base::Feature kDnsHttpssvc;
+// Disable H2 reprioritization, in order to measure its impact.
+NET_EXPORT extern const base::Feature kAvoidH2Reprioritization;
+
// Determine which kind of record should be queried: HTTPSSVC or INTEGRITY. No
// more than one of these feature parameters should be enabled at once. In the
// event that both are enabled, |kDnsHttpssvcUseIntegrity| takes priority, and
@@ -32,6 +43,10 @@ NET_EXPORT extern const base::Feature kDnsHttpssvc;
NET_EXPORT extern const base::FeatureParam<bool> kDnsHttpssvcUseHttpssvc;
NET_EXPORT extern const base::FeatureParam<bool> kDnsHttpssvcUseIntegrity;
+// Enable HTTPSSVC or INTEGRITY to be queried over insecure DNS.
+NET_EXPORT extern const base::FeatureParam<bool>
+ kDnsHttpssvcEnableQueryOverInsecure;
+
// If we are still waiting for an HTTPSSVC or INTEGRITY query after all the
// other queries in a DnsTask have completed, we will compute a timeout for the
// remaining query. The timeout will be the min of:
@@ -41,6 +56,35 @@ NET_EXPORT extern const base::FeatureParam<bool> kDnsHttpssvcUseIntegrity;
NET_EXPORT extern const base::FeatureParam<int> kDnsHttpssvcExtraTimeMs;
NET_EXPORT extern const base::FeatureParam<int> kDnsHttpssvcExtraTimePercent;
+// These parameters, respectively, are the list of experimental and control
+// domains for which we will query HTTPSSVC or INTEGRITY records. We expect
+// valid INTEGRITY results for experiment domains. We expect no INTEGRITY
+// results for control domains.
+//
+// The format of both parameters is a comma-separated list of domains.
+// Whitespace around domain names is permitted. Trailing comma is optional.
+//
+// See helper functions:
+// |dns_httpssvc_experiment::GetDnsHttpssvcExperimentDomains| and
+// |dns_httpssvc_experiment::GetDnsHttpssvcControlDomains|.
+NET_EXPORT extern const base::FeatureParam<std::string>
+ kDnsHttpssvcExperimentDomains;
+NET_EXPORT extern const base::FeatureParam<std::string>
+ kDnsHttpssvcControlDomains;
+
+// This param controls how we determine whether a domain is an experimental or
+// control domain. When false, domains must be in |kDnsHttpssvcControlDomains|
+// to be considered a control. When true, we ignore |kDnsHttpssvcControlDomains|
+// and any non-experiment domain (not in |kDnsHttpssvcExperimentDomains|) is
+// considered a control domain.
+NET_EXPORT extern const base::FeatureParam<bool>
+ kDnsHttpssvcControlDomainWildcard;
+
+namespace dns_httpssvc_experiment {
+// Get the value of |kDnsHttpssvcExtraTimeMs|.
+NET_EXPORT base::TimeDelta GetExtraTimeAbsolute();
+} // namespace dns_httpssvc_experiment
+
// Enables optimizing the network quality estimation algorithms in network
// quality estimator (NQE).
NET_EXPORT extern const base::Feature kNetworkQualityEstimator;
@@ -72,6 +116,36 @@ NET_EXPORT extern const base::Feature
NET_EXPORT extern const base::Feature
kPartitionSSLSessionsByNetworkIsolationKey;
+// Partitions Expect-CT data by NetworkIsolationKey. This only affects the
+// Expect-CT data itself. Regardless of this value, reports will be uploaded
+// using the associated NetworkIsolationKey, when one's available.
+//
+// This feature requires kPartitionConnectionsByNetworkIsolationKey,
+// kPartitionHttpServerPropertiesByNetworkIsolationKey, and
+// kPartitionConnectionsByNetworkIsolationKey to all be enabled to work.
+NET_EXPORT extern const base::Feature
+ kPartitionExpectCTStateByNetworkIsolationKey;
+
+// Enables limiting the size of Expect-CT table.
+NET_EXPORT extern const base::Feature kExpectCTPruning;
+
+// FeatureParams associated with kExpectCTPruning.
+
+// Expect-CT pruning runs when this many entries are hit.
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTPruneMax;
+// The Expect-CT pruning logic attempts to reduce entries to at most this many.
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTPruneMin;
+// Non-transient entries with |enforce| set are safe from being pruned if
+// they're less than this many days old, unless the number of entries exceeds
+// |kExpectCTMaxEntriesPerNik|.
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTSafeFromPruneDays;
+// If, after pruning transient, non-enforced, old Expect-CT entries,
+// kExpectCTPruneMin is still exceeded, then all NetworkIsolationKeys will be
+// capped to this many entries, based on last observation date.
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTMaxEntriesPerNik;
+// Minimum delay between successive prunings of Expect-CT entries, in seconds.
+NET_EXPORT extern const base::FeatureParam<int> kExpectCTPruneDelaySecs;
+
// Enables sending TLS 1.3 Key Update messages on TLS 1.3 connections in order
// to ensure that this corner of the spec is exercised. This is currently
// disabled by default because we discovered incompatibilities with some
@@ -84,25 +158,6 @@ NET_EXPORT extern const base::Feature kPostQuantumCECPQ2;
// Changes the timeout after which unused sockets idle sockets are cleaned up.
NET_EXPORT extern const base::Feature kNetUnusedIdleSocketTimeout;
-// Enables the built-in resolver requesting ESNI (TLS 1.3 Encrypted
-// Server Name Indication) records alongside IPv4 and IPv6 address records
-// during DNS over HTTPS (DoH) host resolution.
-NET_EXPORT extern const base::Feature kRequestEsniDnsRecords;
-// Returns a TimeDelta of value kEsniDnsMaxAbsoluteAdditionalWaitMilliseconds
-// milliseconds (see immediately below).
-NET_EXPORT base::TimeDelta EsniDnsMaxAbsoluteAdditionalWait();
-// The following two parameters specify the amount of extra time to wait for a
-// long-running ESNI DNS transaction after the successful conclusion of
-// concurrent A and AAAA transactions. This timeout will have value
-// min{kEsniDnsMaxAbsoluteAdditionalWaitMilliseconds,
-// (100% + kEsniDnsMaxRelativeAdditionalWaitPercent)
-// * max{time elapsed for the concurrent A query,
-// time elapsed for the concurrent AAAA query}}.
-NET_EXPORT extern const base::FeatureParam<int>
- kEsniDnsMaxAbsoluteAdditionalWaitMilliseconds;
-NET_EXPORT extern const base::FeatureParam<int>
- kEsniDnsMaxRelativeAdditionalWaitPercent;
-
// When enabled, makes cookies without a SameSite attribute behave like
// SameSite=Lax cookies by default, and requires SameSite=None to be specified
// in order to make cookies available in a third-party context. When disabled,
@@ -158,12 +213,6 @@ NET_EXPORT extern const base::Feature
NET_EXPORT extern const base::FeatureParam<int>
kRecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds;
-// When enabled, blocks external requests coming from non-secure contexts. An
-// external request is a request that crosses a network boundary from a more
-// public address space into a less public address space.
-NET_EXPORT extern const base::Feature
- kBlockExternalRequestsFromNonSecureInitiators;
-
#if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
// When enabled, use the builtin cert verifier instead of the platform verifier.
NET_EXPORT extern const base::Feature kCertVerifierBuiltinFeature;
@@ -192,6 +241,10 @@ NET_EXPORT extern const base::Feature kSchemefulSameSite;
// those algorithms. If disabled, the algorithms will always be offered.
NET_EXPORT extern const base::Feature kTLSLegacyCryptoFallbackForMetrics;
+// When enabled, DNS_PROBE_FINISHED_NXDOMAIN error pages may show
+// locally-generated suggestions to visit similar domains.
+NET_EXPORT extern const base::Feature kUseLookalikesForNavigationSuggestions;
+
} // namespace features
} // namespace net
diff --git a/chromium/net/base/file_stream_context.cc b/chromium/net/base/file_stream_context.cc
index 73e4843b902..f2009c8aef5 100644
--- a/chromium/net/base/file_stream_context.cc
+++ b/chromium/net/base/file_stream_context.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/location.h"
+#include "base/logging.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
diff --git a/chromium/net/base/file_stream_context.h b/chromium/net/base/file_stream_context.h
index dcd5b3fae1a..7aae431b4d1 100644
--- a/chromium/net/base/file_stream_context.h
+++ b/chromium/net/base/file_stream_context.h
@@ -30,6 +30,7 @@
#include <stdint.h>
#include "base/files/file.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_pump_for_io.h"
diff --git a/chromium/net/base/ip_address.cc b/chromium/net/base/ip_address.cc
index 03a4df02dfc..ec095c44934 100644
--- a/chromium/net/base/ip_address.cc
+++ b/chromium/net/base/ip_address.cc
@@ -22,6 +22,8 @@
namespace net {
namespace {
+bool g_consider_loopback_ip_to_be_publicly_routable_for_testing = false;
+
// The prefix for IPv6 mapped IPv4 addresses.
// https://tools.ietf.org/html/rfc4291#section-2.5.5.2
constexpr uint8_t kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0,
@@ -234,6 +236,11 @@ bool IPAddress::IsValid() const {
}
bool IPAddress::IsPubliclyRoutable() const {
+ if (g_consider_loopback_ip_to_be_publicly_routable_for_testing &&
+ IsLoopback()) {
+ return true;
+ }
+
if (IsIPv4()) {
return IsPubliclyRoutableIPv4(ip_address_);
} else if (IsIPv6()) {
@@ -242,6 +249,11 @@ bool IPAddress::IsPubliclyRoutable() const {
return true;
}
+// static
+void IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting() {
+ g_consider_loopback_ip_to_be_publicly_routable_for_testing = true;
+}
+
bool IPAddress::IsZero() const {
for (auto x : ip_address_) {
if (x != 0)
diff --git a/chromium/net/base/ip_address.h b/chromium/net/base/ip_address.h
index 829095bc3a4..c3249b7c88d 100644
--- a/chromium/net/base/ip_address.h
+++ b/chromium/net/base/ip_address.h
@@ -157,6 +157,10 @@ class NET_EXPORT IPAddress {
// IPv4-mapped-to-IPv6 addresses are considered publicly routable.
bool IsPubliclyRoutable() const;
+ // Let future IsPubliclyRoutable() calls in the current process always return
+ // true for a loopback ip.
+ static void ConsiderLoopbackIPToBePubliclyRoutableForTesting();
+
// Returns true if the IP is "zero" (e.g. the 0.0.0.0 IPv4 address).
bool IsZero() const;
diff --git a/chromium/net/base/ip_address_unittest.cc b/chromium/net/base/ip_address_unittest.cc
index 6ec78d6c38e..8a9b90022b1 100644
--- a/chromium/net/base/ip_address_unittest.cc
+++ b/chromium/net/base/ip_address_unittest.cc
@@ -302,6 +302,16 @@ TEST(IPAddressTest, IsPubliclyRoutableIPv6) {
}
}
+TEST(IPAddressTest, ConsiderLoopbackIPToBePubliclyRoutableForTestingMethod) {
+ IPAddress address;
+ EXPECT_TRUE(address.AssignFromIPLiteral("127.0.0.1"));
+ ASSERT_TRUE(address.IsValid());
+ EXPECT_FALSE(address.IsPubliclyRoutable());
+
+ IPAddress::ConsiderLoopbackIPToBePubliclyRoutableForTesting();
+ EXPECT_TRUE(address.IsPubliclyRoutable());
+}
+
TEST(IPAddressTest, IsZero) {
uint8_t address1[4] = {};
IPAddress zero_ipv4_address(address1);
diff --git a/chromium/net/base/load_timing_info.h b/chromium/net/base/load_timing_info.h
index e3ff12e34da..6952fc557ce 100644
--- a/chromium/net/base/load_timing_info.h
+++ b/chromium/net/base/load_timing_info.h
@@ -27,7 +27,6 @@ namespace net {
// The general order for events is:
// request_start
// service_worker_start_time
-// service_worker_ready_time
// proxy_start
// proxy_end
// dns_start
@@ -38,6 +37,10 @@ namespace net {
// connect_end
// send_start
// send_end
+// service_worker_ready_time
+// service_worker_fetch_start
+// service_worker_respond_with_settled
+// first_early_hints_time
// receive_headers_start
// receive_headers_end
//
@@ -149,7 +152,16 @@ struct NET_EXPORT LoadTimingInfo {
// if this is greater than |request_start|.
base::TimeTicks service_worker_ready_time;
- // The time spent determing which proxy to use. Null when there is no PAC.
+ // The time when serviceworker fetch event was popped off the event queue
+ // and fetch event handler started running.
+ // If the response is not provided by the ServiceWorker, kept empty.
+ base::TimeTicks service_worker_fetch_start;
+
+ // The time when serviceworker's fetch event's respondWith promise was
+ // settled. If the response is not provided by the ServiceWorker, kept empty.
+ base::TimeTicks service_worker_respond_with_settled;
+
+ // The time spent determining which proxy to use. Null when there is no PAC.
base::TimeTicks proxy_resolve_start;
base::TimeTicks proxy_resolve_end;
@@ -167,6 +179,9 @@ struct NET_EXPORT LoadTimingInfo {
base::TimeTicks receive_headers_start;
base::TimeTicks receive_headers_end;
+ // The time that the first 103 Early Hints response is received.
+ base::TimeTicks first_early_hints_time;
+
// In case the resource was proactively pushed by the server, these are
// the times that push started and ended. Note that push_end will be null
// if the request is still being transmitted, i.e. the underlying h2 stream
diff --git a/chromium/net/base/load_timing_info_test_util.cc b/chromium/net/base/load_timing_info_test_util.cc
index 84410d560b9..e84d4bd127b 100644
--- a/chromium/net/base/load_timing_info_test_util.cc
+++ b/chromium/net/base/load_timing_info_test_util.cc
@@ -54,6 +54,7 @@ void ExpectLoadTimingHasOnlyConnectionTimes(
EXPECT_TRUE(load_timing_info.send_start.is_null());
EXPECT_TRUE(load_timing_info.send_end.is_null());
EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
+ EXPECT_TRUE(load_timing_info.first_early_hints_time.is_null());
EXPECT_TRUE(load_timing_info.push_start.is_null());
EXPECT_TRUE(load_timing_info.push_end.is_null());
}
diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h
index 758c9b18350..7682241352a 100644
--- a/chromium/net/base/net_error_list.h
+++ b/chromium/net/base/net_error_list.h
@@ -121,6 +121,12 @@ NET_ERROR(BLOCKED_BY_RESPONSE, -27)
// requests. Used for NetworkSecurityPolicy on Android.
NET_ERROR(CLEARTEXT_NOT_PERMITTED, -29)
+// The request was blocked by a Content Security Policy
+NET_ERROR(BLOCKED_BY_CSP, -30)
+
+// The request was blocked because of no H/2 or QUIC session.
+NET_ERROR(H2_OR_QUIC_REQUIRED, -31)
+
// A connection was closed (corresponding to a TCP FIN).
NET_ERROR(CONNECTION_CLOSED, -100)
diff --git a/chromium/net/base/net_errors.cc b/chromium/net/base/net_errors.cc
index 25d46b434d0..06ba2d9174c 100644
--- a/chromium/net/base/net_errors.cc
+++ b/chromium/net/base/net_errors.cc
@@ -69,6 +69,17 @@ bool IsHostnameResolutionError(int error) {
return error == ERR_NAME_NOT_RESOLVED;
}
+bool IsRequestBlockedError(int error) {
+ switch (error) {
+ case ERR_BLOCKED_BY_CLIENT:
+ case ERR_BLOCKED_BY_ADMINISTRATOR:
+ case ERR_BLOCKED_BY_CSP:
+ return true;
+ default:
+ return false;
+ }
+}
+
Error FileErrorToNetError(base::File::Error file_error) {
switch (file_error) {
case base::File::FILE_OK:
diff --git a/chromium/net/base/net_errors.h b/chromium/net/base/net_errors.h
index bbd870e1c16..d2807f53999 100644
--- a/chromium/net/base/net_errors.h
+++ b/chromium/net/base/net_errors.h
@@ -50,6 +50,9 @@ NET_EXPORT bool IsClientCertificateError(int error);
// Returns true if |error| is an error from hostname resolution.
NET_EXPORT bool IsHostnameResolutionError(int error);
+// Returns true if |error| means that the request has been blocked.
+NET_EXPORT bool IsRequestBlockedError(int error);
+
// Map system error code to Error.
NET_EXPORT Error MapSystemError(logging::SystemErrorCode os_error);
diff --git a/chromium/net/base/net_errors_posix.cc b/chromium/net/base/net_errors_posix.cc
index 13e14a736c8..2e4fd240aaa 100644
--- a/chromium/net/base/net_errors_posix.cc
+++ b/chromium/net/base/net_errors_posix.cc
@@ -17,7 +17,8 @@ namespace net {
Error MapSystemError(logging::SystemErrorCode os_error) {
if (os_error != 0)
- DVLOG(2) << "Error " << os_error;
+ DVLOG(2) << "Error " << os_error << ": "
+ << logging::SystemErrorCodeToString(os_error);
// There are numerous posix error codes, but these are the ones we thus far
// find interesting.
diff --git a/chromium/net/base/network_change_notifier_fuchsia.cc b/chromium/net/base/network_change_notifier_fuchsia.cc
index a6d67e35f42..e5cde0787f8 100644
--- a/chromium/net/base/network_change_notifier_fuchsia.cc
+++ b/chromium/net/base/network_change_notifier_fuchsia.cc
@@ -11,8 +11,8 @@
#include <vector>
#include "base/bind.h"
-#include "base/fuchsia/default_context.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "net/base/network_interfaces.h"
@@ -22,11 +22,10 @@ namespace net {
NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia(
uint32_t required_features)
- : NetworkChangeNotifierFuchsia(
- base::fuchsia::ComponentContextForCurrentProcess()
- ->svc()
- ->Connect<fuchsia::netstack::Netstack>(),
- required_features) {}
+ : NetworkChangeNotifierFuchsia(base::ComponentContextForProcess()
+ ->svc()
+ ->Connect<fuchsia::netstack::Netstack>(),
+ required_features) {}
NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia(
fuchsia::netstack::NetstackPtr netstack,
diff --git a/chromium/net/base/network_change_notifier_fuchsia_unittest.cc b/chromium/net/base/network_change_notifier_fuchsia_unittest.cc
index e5ca7faa080..f6354fadb8e 100644
--- a/chromium/net/base/network_change_notifier_fuchsia_unittest.cc
+++ b/chromium/net/base/network_change_notifier_fuchsia_unittest.cc
@@ -12,6 +12,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/logging.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/threading/sequence_bound.h"
diff --git a/chromium/net/base/network_change_notifier_mac.cc b/chromium/net/base/network_change_notifier_mac.cc
index 91cf418ef43..23cc7fd3536 100644
--- a/chromium/net/base/network_change_notifier_mac.cc
+++ b/chromium/net/base/network_change_notifier_mac.cc
@@ -8,6 +8,7 @@
#include <resolv.h>
#include "base/bind.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
diff --git a/chromium/net/base/network_config_watcher_mac.cc b/chromium/net/base/network_config_watcher_mac.cc
index fb6362c832e..ea499cf3126 100644
--- a/chromium/net/base/network_config_watcher_mac.cc
+++ b/chromium/net/base/network_config_watcher_mac.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_pump_type.h"
diff --git a/chromium/net/base/network_delegate.cc b/chromium/net/base/network_delegate.cc
index a98b95e8e8c..80592ea985d 100644
--- a/chromium/net/base/network_delegate.cc
+++ b/chromium/net/base/network_delegate.cc
@@ -101,11 +101,10 @@ void NetworkDelegate::NotifyPACScriptError(int line_number,
}
bool NetworkDelegate::CanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!(request.load_flags() & LOAD_DO_NOT_SEND_COOKIES));
- return OnCanGetCookies(request, cookie_list, allowed_from_caller);
+ return OnCanGetCookies(request, allowed_from_caller);
}
bool NetworkDelegate::CanSetCookie(const URLRequest& request,
diff --git a/chromium/net/base/network_delegate.h b/chromium/net/base/network_delegate.h
index c06f365312e..c00f0ccd3b5 100644
--- a/chromium/net/base/network_delegate.h
+++ b/chromium/net/base/network_delegate.h
@@ -73,7 +73,6 @@ class NET_EXPORT NetworkDelegate {
void NotifyURLRequestDestroyed(URLRequest* request);
void NotifyPACScriptError(int line_number, const base::string16& error);
bool CanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller);
bool CanSetCookie(const URLRequest& request,
const net::CanonicalCookie& cookie,
@@ -206,7 +205,6 @@ class NET_EXPORT NetworkDelegate {
// allowed from any higher level delegates (for example, in a
// LayeredNetworkDelegate). Any custom logic should be ANDed with this bool.
virtual bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) = 0;
// Called when a cookie is set to allow the network delegate to block access
diff --git a/chromium/net/base/network_delegate_impl.cc b/chromium/net/base/network_delegate_impl.cc
index 44a232b5a60..822bedc22a8 100644
--- a/chromium/net/base/network_delegate_impl.cc
+++ b/chromium/net/base/network_delegate_impl.cc
@@ -49,7 +49,6 @@ void NetworkDelegateImpl::OnPACScriptError(int line_number,
}
bool NetworkDelegateImpl::OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) {
return allowed_from_caller;
}
diff --git a/chromium/net/base/network_delegate_impl.h b/chromium/net/base/network_delegate_impl.h
index 46554d70035..323dade2a5a 100644
--- a/chromium/net/base/network_delegate_impl.h
+++ b/chromium/net/base/network_delegate_impl.h
@@ -62,7 +62,6 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
void OnPACScriptError(int line_number, const base::string16& error) override;
bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) override;
bool OnCanSetCookie(const URLRequest& request,
diff --git a/chromium/net/base/network_interfaces.cc b/chromium/net/base/network_interfaces.cc
index 8ba3df11e2f..29df129a49b 100644
--- a/chromium/net/base/network_interfaces.cc
+++ b/chromium/net/base/network_interfaces.cc
@@ -4,6 +4,7 @@
#include "net/base/network_interfaces.h"
+#include "base/logging.h"
#include "build/build_config.h"
#if defined(OS_POSIX)
diff --git a/chromium/net/base/network_interfaces_fuchsia.cc b/chromium/net/base/network_interfaces_fuchsia.cc
index 794f6d157fe..864f68ab8b5 100644
--- a/chromium/net/base/network_interfaces_fuchsia.cc
+++ b/chromium/net/base/network_interfaces_fuchsia.cc
@@ -13,8 +13,8 @@
#include <utility>
#include "base/format_macros.h"
-#include "base/fuchsia/default_context.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/process_context.h"
#include "base/strings/stringprintf.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_interfaces.h"
@@ -107,8 +107,7 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
DCHECK(networks);
fuchsia::netstack::NetstackSyncPtr netstack;
- base::fuchsia::ComponentContextForCurrentProcess()->svc()->Connect(
- netstack.NewRequest());
+ base::ComponentContextForProcess()->svc()->Connect(netstack.NewRequest());
// TODO(kmarshall): Use NetworkChangeNotifier's cached interface list.
std::vector<fuchsia::netstack::NetInterface> interfaces;
diff --git a/chromium/net/base/network_interfaces_getifaddrs.cc b/chromium/net/base/network_interfaces_getifaddrs.cc
index c340cced979..7ce0429489e 100644
--- a/chromium/net/base/network_interfaces_getifaddrs.cc
+++ b/chromium/net/base/network_interfaces_getifaddrs.cc
@@ -30,6 +30,16 @@
#include <sys/ioctl.h>
#endif // !OS_IOS
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+// Declare getifaddrs() and freeifaddrs() weakly as they're only available
+// on Android N+.
+extern "C" {
+int getifaddrs(struct ifaddrs** __list_ptr) __attribute__((weak_import));
+void freeifaddrs(struct ifaddrs* __ptr) __attribute__((weak_import));
+}
+#endif // OS_ANDROID
+
namespace net {
namespace internal {
@@ -209,7 +219,18 @@ bool IfaddrsToNetworkInterfaceList(int policy,
} // namespace internal
+// This version of GetNetworkList() can only be called on Android N+, so give it
+// a different and internal name so it isn't invoked mistakenly.
+#if defined(OS_ANDROID)
+namespace internal {
+bool GetNetworkListUsingGetifaddrs(NetworkInterfaceList* networks, int policy) {
+ DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
+ base::android::SDK_VERSION_NOUGAT);
+ DCHECK(getifaddrs);
+ DCHECK(freeifaddrs);
+#else
bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+#endif
if (networks == NULL)
return false;
@@ -235,9 +256,14 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
return result;
}
+#if defined(OS_ANDROID)
+} // namespace internal
+// For Android use GetWifiSSID() impl in network_interfaces_linux.cc.
+#else
std::string GetWifiSSID() {
NOTIMPLEMENTED();
return std::string();
}
+#endif
} // namespace net
diff --git a/chromium/net/base/network_interfaces_getifaddrs.h b/chromium/net/base/network_interfaces_getifaddrs.h
index 7ec8081a648..f2d9ae1578c 100644
--- a/chromium/net/base/network_interfaces_getifaddrs.h
+++ b/chromium/net/base/network_interfaces_getifaddrs.h
@@ -13,6 +13,7 @@
// This file defines IfaddrsToNetworkInterfaceList() so it can be called in
// unittests.
+#include "build/build_config.h"
#include "net/base/net_export.h"
#include "net/base/network_interfaces.h"
@@ -51,6 +52,12 @@ NET_EXPORT_PRIVATE bool IfaddrsToNetworkInterfaceList(
IPAttributesGetter* ip_attributes_getter,
NetworkInterfaceList* networks);
+#if defined(OS_ANDROID)
+// A version of GetNetworkList() that uses getifaddrs(). Only callable on
+// Android N+ where getifaddrs() was available.
+bool GetNetworkListUsingGetifaddrs(NetworkInterfaceList* networks, int policy);
+#endif
+
} // namespace internal
} // namespace net
diff --git a/chromium/net/base/network_interfaces_linux.cc b/chromium/net/base/network_interfaces_linux.cc
index 616e77a83be..cad5f1d8721 100644
--- a/chromium/net/base/network_interfaces_linux.cc
+++ b/chromium/net/base/network_interfaces_linux.cc
@@ -22,6 +22,7 @@
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "net/base/address_tracker_linux.h"
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
@@ -30,7 +31,9 @@
#include "url/gurl.h"
#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
#include "net/android/network_library.h"
+#include "net/base/network_interfaces_getifaddrs.h"
#endif
namespace net {
@@ -211,6 +214,20 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
if (networks == NULL)
return false;
+#if defined(OS_ANDROID)
+ // On Android 11 RTM_GETLINK (used by AddressTrackerLinux) no longer works as
+ // per https://developer.android.com/preview/privacy/mac-address so instead
+ // use getifaddrs() which is supported since Android N.
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_NOUGAT) {
+ bool ret = internal::GetNetworkListUsingGetifaddrs(networks, policy);
+ // Use GetInterfaceConnectionType() to sharpen up interface types.
+ for (NetworkInterface& network : *networks)
+ network.type = internal::GetInterfaceConnectionType(network.name);
+ return ret;
+ }
+#endif
+
internal::AddressTrackerLinux tracker;
tracker.Init();
diff --git a/chromium/net/base/network_interfaces_win_unittest.cc b/chromium/net/base/network_interfaces_win_unittest.cc
index 51417189fa0..32763aa95d2 100644
--- a/chromium/net/base/network_interfaces_win_unittest.cc
+++ b/chromium/net/base/network_interfaces_win_unittest.cc
@@ -11,6 +11,7 @@
#include <string>
#include <unordered_set>
+#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "net/base/ip_endpoint.h"
diff --git a/chromium/net/base/priority_queue.h b/chromium/net/base/priority_queue.h
index ab8ee22a019..c4c30fa45c0 100644
--- a/chromium/net/base/priority_queue.h
+++ b/chromium/net/base/priority_queue.h
@@ -13,7 +13,7 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/net/base/privacy_mode.h b/chromium/net/base/privacy_mode.h
index c3d128d83ac..90e99dd3bcc 100644
--- a/chromium/net/base/privacy_mode.h
+++ b/chromium/net/base/privacy_mode.h
@@ -12,6 +12,10 @@ namespace net {
enum PrivacyMode {
PRIVACY_MODE_DISABLED = 0,
PRIVACY_MODE_ENABLED = 1,
+
+ // Due to http://crbug.com/775438, PRIVACY_MODE_ENABLED still sends client
+ // certs. This mode ensures that the request is sent without client certs.
+ PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS = 2,
};
} // namespace net
diff --git a/chromium/net/base/upload_data_stream.cc b/chromium/net/base/upload_data_stream.cc
index edcba234fc5..bd5aea1bf31 100644
--- a/chromium/net/base/upload_data_stream.cc
+++ b/chromium/net/base/upload_data_stream.cc
@@ -190,4 +190,8 @@ UploadProgress UploadDataStream::GetUploadProgress() const {
return UploadProgress(current_position_, total_size_);
}
+bool UploadDataStream::AllowHTTP1() const {
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/base/upload_data_stream.h b/chromium/net/base/upload_data_stream.h
index b9645ec5a09..807efa13978 100644
--- a/chromium/net/base/upload_data_stream.h
+++ b/chromium/net/base/upload_data_stream.h
@@ -95,6 +95,10 @@ class NET_EXPORT UploadDataStream {
// empty UploadProgress.
virtual UploadProgress GetUploadProgress() const;
+ // Indicates whether fetch upload streaming is allowed/rejected over H/1.
+ // Even if this is false but there is a QUIC/H2 stream, the upload is allowed.
+ virtual bool AllowHTTP1() const;
+
protected:
// Must be called by subclasses when InitInternal and ReadInternal complete
// asynchronously.
diff --git a/chromium/net/cert/cert_verifier.cc b/chromium/net/cert/cert_verifier.cc
index 580c7212d65..6504721e2fa 100644
--- a/chromium/net/cert/cert_verifier.cc
+++ b/chromium/net/cert/cert_verifier.cc
@@ -120,11 +120,13 @@ bool operator==(const CertVerifier::Config& lhs,
return std::tie(
lhs.enable_rev_checking, lhs.require_rev_checking_local_anchors,
lhs.enable_sha1_local_anchors, lhs.disable_symantec_enforcement,
- lhs.crl_set, lhs.additional_trust_anchors) ==
+ lhs.crl_set, lhs.additional_trust_anchors,
+ lhs.additional_untrusted_authorities) ==
std::tie(
rhs.enable_rev_checking, rhs.require_rev_checking_local_anchors,
rhs.enable_sha1_local_anchors, rhs.disable_symantec_enforcement,
- rhs.crl_set, rhs.additional_trust_anchors);
+ rhs.crl_set, rhs.additional_trust_anchors,
+ rhs.additional_untrusted_authorities);
}
bool operator!=(const CertVerifier::Config& lhs,
diff --git a/chromium/net/cert/cert_verifier.h b/chromium/net/cert/cert_verifier.h
index 5c9c3798925..bcb768a353e 100644
--- a/chromium/net/cert/cert_verifier.h
+++ b/chromium/net/cert/cert_verifier.h
@@ -65,6 +65,12 @@ class NET_EXPORT CertVerifier {
// system store. This is implementation-specific plumbing for passing
// additional anchors through.
CertificateList additional_trust_anchors;
+
+ // Additional temporary certs to consider as intermediates during path
+ // validation. Ordinarily, implementations of CertVerifier use intermediate
+ // certs from the configured system store. This is implementation-specific
+ // plumbing for passing additional intermediates through.
+ CertificateList additional_untrusted_authorities;
};
class Request {
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index b6502664174..0b7e5f9d1a4 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -935,6 +935,9 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1519862400);
const base::Time time_2019_07_01 =
base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1561939200);
+ // From Chrome Root Certificate Policy
+ const base::Time time_2020_09_01 =
+ base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1598918400);
// Compute the maximally permissive interpretations, accounting for leap
// years.
@@ -957,21 +960,27 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
return true;
}
- // For certificates issued after the BR effective date of 1 July 2012: 60
- // months.
+ // For certificates issued on-or-after the BR effective date of 1 July 2012:
+ // 60 months.
if (start >= time_2012_07_01 && validity_duration > kSixtyMonths)
return true;
- // For certificates issued after 1 April 2015: 39 months.
+ // For certificates issued on-or-after 1 April 2015: 39 months.
if (start >= time_2015_04_01 && validity_duration > kThirtyNineMonths)
return true;
- // For certificates issued after 1 March 2018: 825 days.
+ // For certificates issued on-or-after 1 March 2018: 825 days.
if (start >= time_2018_03_01 &&
validity_duration > base::TimeDelta::FromDays(825)) {
return true;
}
+ // For certificates issued on-or-after 1 September 2020: 398 days.
+ if (start >= time_2020_09_01 &&
+ validity_duration > base::TimeDelta::FromDays(398)) {
+ return true;
+ }
+
return false;
}
diff --git a/chromium/net/cert/cert_verify_proc_ios.cc b/chromium/net/cert/cert_verify_proc_ios.cc
index 59624eb894d..ed9234dd80e 100644
--- a/chromium/net/cert/cert_verify_proc_ios.cc
+++ b/chromium/net/cert/cert_verify_proc_ios.cc
@@ -10,6 +10,7 @@
#include "base/mac/foundation_util.h"
#include "base/mac/mac_logging.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/notreached.h"
#include "crypto/sha2.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index e8cbe147cee..ffb85e65fce 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -1499,6 +1499,9 @@ TEST(CertVerifyProcTest, TestHasTooLongValidity) {
{"826_days_after_2018_03_01.pem", true},
{"825_days_1_second_after_2018_03_01.pem", true},
{"39_months_based_on_last_day.pem", false},
+ {"398_days_after_2020_09_01.pem", false},
+ {"399_days_after_2020_09_01.pem", true},
+ {"398_days_1_second_after_2020_09_01.pem", true},
};
base::FilePath certs_dir = GetTestCertsDirectory();
diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc
index e255cae67ef..70cc5e1001f 100644
--- a/chromium/net/cert/ct_log_verifier.cc
+++ b/chromium/net/cert/ct_log_verifier.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/notreached.h"
#include "crypto/openssl_util.h"
#include "crypto/sha2.h"
#include "net/cert/ct_log_verifier_util.h"
diff --git a/chromium/net/cert/ct_sct_to_string.cc b/chromium/net/cert/ct_sct_to_string.cc
index adbb712af75..211f7ea264a 100644
--- a/chromium/net/cert/ct_sct_to_string.cc
+++ b/chromium/net/cert/ct_sct_to_string.cc
@@ -5,6 +5,7 @@
#include "net/cert/ct_sct_to_string.h"
#include "base/logging.h"
+#include "base/notreached.h"
namespace net {
diff --git a/chromium/net/cert/ev_root_ca_metadata.cc b/chromium/net/cert/ev_root_ca_metadata.cc
index 052161a3498..13b5a55d77c 100644
--- a/chromium/net/cert/ev_root_ca_metadata.cc
+++ b/chromium/net/cert/ev_root_ca_metadata.cc
@@ -4,12 +4,7 @@
#include "net/cert/ev_root_ca_metadata.h"
-#if defined(USE_NSS_CERTS)
-#include <cert.h>
-#include <pkcs11n.h>
-#include <secerr.h>
-#include <secoid.h>
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
#include <stdlib.h>
#endif
@@ -19,9 +14,7 @@
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "net/der/input.h"
-#if defined(USE_NSS_CERTS)
-#include "crypto/nss_util.h"
-#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA) || defined(OS_WIN)
+#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#endif
@@ -57,19 +50,8 @@ static const EVMetadata kEvRootCaMetadata[] = {
{
// AC Camerfirma uses the last two arcs to track how the private key
// is managed - the effective verification policy is the same.
- "1.3.6.1.4.1.17326.10.14.2.1.2", "1.3.6.1.4.1.17326.10.14.2.2.2",
- },
- },
- // AC Camerfirma S.A. Global Chambersign Root - 2008
- // https://server2.camerfirma.com:8082
- {
- {{0x13, 0x63, 0x35, 0x43, 0x93, 0x34, 0xa7, 0x69, 0x80, 0x16, 0xa0,
- 0xd3, 0x24, 0xde, 0x72, 0x28, 0x4e, 0x07, 0x9d, 0x7b, 0x52, 0x20,
- 0xbb, 0x8f, 0xbd, 0x74, 0x78, 0x16, 0xee, 0xbe, 0xba, 0xca}},
- {
- // AC Camerfirma uses the last two arcs to track how the private key
- // is managed - the effective verification policy is the same.
- "1.3.6.1.4.1.17326.10.8.12.1.2", "1.3.6.1.4.1.17326.10.8.12.2.2",
+ "1.3.6.1.4.1.17326.10.14.2.1.2",
+ "1.3.6.1.4.1.17326.10.14.2.2.2",
},
},
// AddTrust External CA Root
@@ -173,14 +155,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0xac, 0x95, 0xcd, 0x4b, 0x93, 0xdb, 0xf3, 0xf2, 0x6a, 0xeb}},
{"1.3.6.1.4.1.6334.1.100.1", ""},
},
- // Buypass Class 3 CA 1
- // https://valid.evident.ca13.ssl.buypass.no/
- {
- {{0xb7, 0xb1, 0x2b, 0x17, 0x1f, 0x82, 0x1d, 0xaa, 0x99, 0x0c, 0xd0,
- 0xfe, 0x50, 0x87, 0xb1, 0x28, 0x44, 0x8b, 0xa8, 0xe5, 0x18, 0x4f,
- 0x84, 0xc5, 0x1e, 0x02, 0xb5, 0xc8, 0xfb, 0x96, 0x2b, 0x24}},
- {"2.16.578.1.26.1.3.3", ""},
- },
// Buypass Class 3 Root CA
// https://valid.evident.ca23.ssl.buypass.no/
{
@@ -189,14 +163,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x29, 0xb4, 0xae, 0x1d, 0x5b, 0x93, 0x32, 0xe6, 0xb2, 0x4d}},
{"2.16.578.1.26.1.3.3", ""},
},
- // CertPlus Class 2 Primary CA (KEYNECTIS)
- // https://www.keynectis.com/
- {
- {{0x0f, 0x99, 0x3c, 0x8a, 0xef, 0x97, 0xba, 0xaf, 0x56, 0x87, 0x14,
- 0x0e, 0xd5, 0x9a, 0xd1, 0x82, 0x1b, 0xb4, 0xaf, 0xac, 0xf0, 0xaa,
- 0x9a, 0x58, 0xb5, 0xd5, 0x7a, 0x33, 0x8a, 0x3a, 0xfb, 0xcb}},
- {"1.3.6.1.4.1.22234.2.5.2.3.1", ""},
- },
// Certum Trusted Network CA
// https://juice.certum.pl/
{
@@ -213,15 +179,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x2e, 0xf8, 0x00, 0xf3, 0x55, 0xc4, 0xc5, 0xfd, 0x70, 0xfd}},
{"2.16.156.112554.3", ""},
},
- // China Internet Network Information Center EV Certificates Root
- // https://evdemo.cnnic.cn/
- {
- // Root
- {{0x1c, 0x01, 0xc6, 0xf4, 0xdb, 0xb2, 0xfe, 0xfc, 0x22, 0x55, 0x8b,
- 0x2b, 0xca, 0x32, 0x56, 0x3f, 0x49, 0x84, 0x4a, 0xcf, 0xc3, 0x2b,
- 0x7b, 0xe4, 0xb0, 0xff, 0x59, 0x9f, 0x9e, 0x8c, 0x7a, 0xf7}},
- {"1.3.6.1.4.1.29836.1.10", ""},
- },
// COMODO Certification Authority
// https://secure.comodo.com/
{
@@ -271,6 +228,22 @@ static const EVMetadata kEvRootCaMetadata[] = {
0xbc, 0xf1, 0xdf, 0x69, 0x56, 0x1e, 0x3d, 0xc6, 0x32, 0x5c}},
{"2.16.840.1.114412.2.1", ""},
},
+ // DigiCert Assured ID Root G2
+ // https://assured-id-root-g2.chain-demos.digicert.com/
+ {
+ {{0x7d, 0x05, 0xeb, 0xb6, 0x82, 0x33, 0x9f, 0x8c, 0x94, 0x51, 0xee,
+ 0x09, 0x4e, 0xeb, 0xfe, 0xfa, 0x79, 0x53, 0xa1, 0x14, 0xed, 0xb2,
+ 0xf4, 0x49, 0x49, 0x45, 0x2f, 0xab, 0x7d, 0x2f, 0xc1, 0x85}},
+ {"2.16.840.1.114412.2.1", ""},
+ },
+ // DigiCert Assured ID Root G3
+ // https://assured-id-root-g3.chain-demos.digicert.com/
+ {
+ {{0x7e, 0x37, 0xcb, 0x8b, 0x4c, 0x47, 0x09, 0x0c, 0xab, 0x36, 0x55,
+ 0x1b, 0xa6, 0xf4, 0x5d, 0xb8, 0x40, 0x68, 0x0f, 0xba, 0x16, 0x6a,
+ 0x95, 0x2d, 0xb1, 0x00, 0x71, 0x7f, 0x43, 0x05, 0x3f, 0xc2}},
+ {"2.16.840.1.114412.2.1", ""},
+ },
// DigiCert Global Root CA
// https://global-root-ca.chain-demos.digicert.com/
{
@@ -319,13 +292,13 @@ static const EVMetadata kEvRootCaMetadata[] = {
0xd4, 0x73, 0x0c, 0x84, 0xea, 0xf1, 0xf3, 0xd3, 0x48, 0x81}},
{"1.3.6.1.4.1.4788.2.202.1", ""},
},
- // Entrust.net Secure Server Certification Authority
- // https://www.entrust.net/
+ // emSign Root CA - G1
+ // https://testevg1.emsign.com/
{
- {{0x62, 0xf2, 0x40, 0x27, 0x8c, 0x56, 0x4c, 0x4d, 0xd8, 0xbf, 0x7d,
- 0x9d, 0x4f, 0x6f, 0x36, 0x6e, 0xa8, 0x94, 0xd2, 0x2f, 0x5f, 0x34,
- 0xd9, 0x89, 0xa9, 0x83, 0xac, 0xec, 0x2f, 0xff, 0xed, 0x50}},
- {"2.16.840.1.114028.10.1.2", ""},
+ {{0x40, 0xf6, 0xaf, 0x03, 0x46, 0xa9, 0x9a, 0xa1, 0xcd, 0x1d, 0x55,
+ 0x5a, 0x4e, 0x9c, 0xce, 0x62, 0xc7, 0xf9, 0x63, 0x46, 0x03, 0xee,
+ 0x40, 0x66, 0x15, 0x83, 0x3d, 0xc8, 0xc8, 0xd0, 0x03, 0x67}},
+ {"2.23.140.1.1", ""},
},
// Entrust Root Certification Authority
// https://www.entrust.net/
@@ -351,14 +324,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0xab, 0x1d, 0x3b, 0x8e, 0xb0, 0x70, 0xe5, 0x6e, 0xdf, 0xf5}},
{"2.16.840.1.114028.10.1.2", ""},
},
- // Equifax Secure Certificate Authority (GeoTrust)
- // https://www.geotrust.com/
- {
- {{0x08, 0x29, 0x7a, 0x40, 0x47, 0xdb, 0xa2, 0x36, 0x80, 0xc7, 0x31,
- 0xdb, 0x6e, 0x31, 0x76, 0x53, 0xca, 0x78, 0x48, 0xe1, 0xbe, 0xbd,
- 0x3a, 0x0b, 0x01, 0x79, 0xa7, 0x07, 0xf9, 0x2c, 0xf1, 0x78}},
- {"1.3.6.1.4.1.14370.1.6", ""},
- },
// E-Tugra Certification Authority
// https://sslev.e-tugra.com.tr
{
@@ -367,36 +332,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x65, 0xea, 0x89, 0x39, 0x11, 0xf5, 0x5e, 0x55, 0xf2, 0x3c}},
{"2.16.792.3.0.4.1.1.4", ""},
},
- // GeoTrust Primary Certification Authority
- // https://www.geotrust.com/
- {
- {{0x37, 0xd5, 0x10, 0x06, 0xc5, 0x12, 0xea, 0xab, 0x62, 0x64, 0x21,
- 0xf1, 0xec, 0x8c, 0x92, 0x01, 0x3f, 0xc5, 0xf8, 0x2a, 0xe9, 0x8e,
- 0xe5, 0x33, 0xeb, 0x46, 0x19, 0xb8, 0xde, 0xb4, 0xd0, 0x6c}},
- {"1.3.6.1.4.1.14370.1.6", ""},
- },
- // GeoTrust Primary Certification Authority - G2
- {
- {{0x5e, 0xdb, 0x7a, 0xc4, 0x3b, 0x82, 0xa0, 0x6a, 0x87, 0x61, 0xe8,
- 0xd7, 0xbe, 0x49, 0x79, 0xeb, 0xf2, 0x61, 0x1f, 0x7d, 0xd7, 0x9b,
- 0xf9, 0x1c, 0x1c, 0x6b, 0x56, 0x6a, 0x21, 0x9e, 0xd7, 0x66}},
- {"1.3.6.1.4.1.14370.1.6", ""},
- },
- // GeoTrust Primary Certification Authority - G3
- {
- {{0xb4, 0x78, 0xb8, 0x12, 0x25, 0x0d, 0xf8, 0x78, 0x63, 0x5c, 0x2a,
- 0xa7, 0xec, 0x7d, 0x15, 0x5e, 0xaa, 0x62, 0x5e, 0xe8, 0x29, 0x16,
- 0xe2, 0xcd, 0x29, 0x43, 0x61, 0x88, 0x6c, 0xd1, 0xfb, 0xd4}},
- {"1.3.6.1.4.1.14370.1.6", ""},
- },
- // GlobalSign Root CA - R2
- // https://www.globalsign.com/
- {
- {{0xca, 0x42, 0xdd, 0x41, 0x74, 0x5f, 0xd0, 0xb8, 0x1e, 0xb9, 0x02,
- 0x36, 0x2c, 0xf9, 0xd8, 0xbf, 0x71, 0x9d, 0xa1, 0xbd, 0x1b, 0x1e,
- 0xfc, 0x94, 0x6f, 0x5b, 0x4c, 0x99, 0xf4, 0x2c, 0x1b, 0x9e}},
- {"1.3.6.1.4.1.4146.1.1", ""},
- },
// GlobalSign Root CA
{
{{0xeb, 0xd4, 0x10, 0x40, 0xe4, 0xbb, 0x3e, 0xc7, 0x42, 0xc9, 0xe3,
@@ -412,14 +347,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x63, 0x5a, 0x7c, 0xf4, 0x72, 0x0d, 0xc9, 0x63, 0xc5, 0x3b}},
{"1.3.6.1.4.1.4146.1.1", ""},
},
- // GlobalSign ECC Root CA - R4
- // https://2038r4.globalsign.com
- {
- {{0xbe, 0xc9, 0x49, 0x11, 0xc2, 0x95, 0x56, 0x76, 0xdb, 0x6c, 0x0a,
- 0x55, 0x09, 0x86, 0xd7, 0x6e, 0x3b, 0xa0, 0x05, 0x66, 0x7c, 0x44,
- 0x2c, 0x97, 0x62, 0xb4, 0xfb, 0xb7, 0x73, 0xde, 0x22, 0x8c}},
- {"1.3.6.1.4.1.4146.1.1", ""},
- },
// GlobalSign ECC Root CA - R5
// https://2038r5.globalsign.com/
{
@@ -444,13 +371,13 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x63, 0xe2, 0x74, 0x9d, 0xd3, 0xac, 0xa9, 0x19, 0x8e, 0xda}},
{"2.16.840.1.114413.1.7.23.3", ""},
},
- // GTE CyberTrust Global Root
- // https://www.cybertrust.ne.jp/
+ // Hongkong Post Root CA 3
+ // https://valid-ev.ecert.gov.hk/
{
- {{0xa5, 0x31, 0x25, 0x18, 0x8d, 0x21, 0x10, 0xaa, 0x96, 0x4b, 0x02,
- 0xc7, 0xb7, 0xc6, 0xda, 0x32, 0x03, 0x17, 0x08, 0x94, 0xe5, 0xfb,
- 0x71, 0xff, 0xfb, 0x66, 0x67, 0xd5, 0xe6, 0x81, 0x0a, 0x36}},
- {"1.3.6.1.4.1.6334.1.100.1", ""},
+ {{0x5a, 0x2f, 0xc0, 0x3f, 0x0c, 0x83, 0xb0, 0x90, 0xbb, 0xfa, 0x40,
+ 0x60, 0x4b, 0x09, 0x88, 0x44, 0x6c, 0x76, 0x36, 0x18, 0x3d, 0xf9,
+ 0x84, 0x6e, 0x17, 0x10, 0x1a, 0x44, 0x7f, 0xb8, 0xef, 0xd6}},
+ {"2.23.140.1.1", ""},
},
// Izenpe.com - SHA256 root
// The first OID is for businesses and the second for government entities.
@@ -545,14 +472,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x82, 0x01, 0x78, 0x95, 0x97, 0x4a, 0x99, 0x02, 0x6b, 0x6c}},
{"1.2.392.200091.100.721.1", ""},
},
- // Security Communication EV RootCA1
- // https://www.secomtrust.net/contact/form.html
- {
- {{0xa2, 0x2d, 0xba, 0x68, 0x1e, 0x97, 0x37, 0x6e, 0x2d, 0x39, 0x7d,
- 0x72, 0x8a, 0xae, 0x3a, 0x9b, 0x62, 0x96, 0xb9, 0xfd, 0xba, 0x60,
- 0xbc, 0x2e, 0x11, 0xf6, 0x47, 0xf2, 0xc6, 0x75, 0xfb, 0x37}},
- {"1.2.392.200091.100.721.1", ""},
- },
// Security Communication EV RootCA2
// https://www.secomtrust.net/contact/form.html
{
@@ -561,6 +480,22 @@ static const EVMetadata kEvRootCaMetadata[] = {
0xd2, 0xb5, 0x21, 0x48, 0x4a, 0xa4, 0x7a, 0x0e, 0xbe, 0xf6}},
{"1.2.392.200091.100.721.1", ""},
},
+ // SSL.com EV Root Certification Authority ECC
+ // https://test-ev-ecc.ssl.com/
+ {
+ {{0x22, 0xa2, 0xc1, 0xf7, 0xbd, 0xed, 0x70, 0x4c, 0xc1, 0xe7, 0x01,
+ 0xb5, 0xf4, 0x08, 0xc3, 0x10, 0x88, 0x0f, 0xe9, 0x56, 0xb5, 0xde,
+ 0x2a, 0x4a, 0x44, 0xf9, 0x9c, 0x87, 0x3a, 0x25, 0xa7, 0xc8}},
+ {"2.23.140.1.1", ""},
+ },
+ // SSL.com EV Root Certification Authority RSA R2
+ // https://test-ev-rsa.ssl.com/
+ {
+ {{0x2e, 0x7b, 0xf1, 0x6c, 0xc2, 0x24, 0x85, 0xa7, 0xbb, 0xe2, 0xaa,
+ 0x86, 0x96, 0x75, 0x07, 0x61, 0xb0, 0xae, 0x39, 0xbe, 0x3b, 0x2f,
+ 0xe9, 0xd0, 0xcc, 0x6d, 0x4e, 0xf7, 0x34, 0x91, 0x42, 0x5c}},
+ {"2.23.140.1.1", ""},
+ },
// Staat der Nederlanden EV Root CA
// https://pkioevssl-v.quovadisglobal.com/
{
@@ -569,14 +504,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x9d, 0x8a, 0x90, 0x7a, 0xc4, 0xcb, 0x5d, 0xad, 0xc1, 0x5a}},
{"2.16.528.1.1003.1.2.7", ""},
},
- // StartCom Certification Authority
- // https://www.startssl.com/
- {
- {{0xc7, 0x66, 0xa9, 0xbe, 0xf2, 0xd4, 0x07, 0x1c, 0x86, 0x3a, 0x31,
- 0xaa, 0x49, 0x20, 0xe8, 0x13, 0xb2, 0xd1, 0x98, 0x60, 0x8c, 0xb7,
- 0xb7, 0xcf, 0xe2, 0x11, 0x43, 0xb8, 0x36, 0xdf, 0x09, 0xea}},
- {"1.3.6.1.4.1.23223.1.1.1", ""},
- },
// Starfield Class 2 Certification Authority
// https://www.starfieldtech.com/
{
@@ -609,44 +536,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x8f, 0x64, 0x7c, 0x68, 0x81, 0xf2, 0xc8, 0x35, 0x7b, 0x95}},
{"2.16.756.1.89.1.2.1.1", ""},
},
- // Swisscom Root EV CA 2
- // https://test-quarz-ev-ca-2.pre.swissdigicert.ch
- {
- {{0xd9, 0x5f, 0xea, 0x3c, 0xa4, 0xee, 0xdc, 0xe7, 0x4c, 0xd7, 0x6e,
- 0x75, 0xfc, 0x6d, 0x1f, 0xf6, 0x2c, 0x44, 0x1f, 0x0f, 0xa8, 0xbc,
- 0x77, 0xf0, 0x34, 0xb1, 0x9e, 0x5d, 0xb2, 0x58, 0x01, 0x5d}},
- {"2.16.756.1.83.21.0", ""},
- },
- // Thawte Premium Server CA
- // https://www.thawte.com/
- {
- {{0xab, 0x70, 0x36, 0x36, 0x5c, 0x71, 0x54, 0xaa, 0x29, 0xc2, 0xc2,
- 0x9f, 0x5d, 0x41, 0x91, 0x16, 0x3b, 0x16, 0x2a, 0x22, 0x25, 0x01,
- 0x13, 0x57, 0xd5, 0x6d, 0x07, 0xff, 0xa7, 0xbc, 0x1f, 0x72}},
- {"2.16.840.1.113733.1.7.48.1", ""},
- },
- // thawte Primary Root CA
- // https://www.thawte.com/
- {
- {{0x8d, 0x72, 0x2f, 0x81, 0xa9, 0xc1, 0x13, 0xc0, 0x79, 0x1d, 0xf1,
- 0x36, 0xa2, 0x96, 0x6d, 0xb2, 0x6c, 0x95, 0x0a, 0x97, 0x1d, 0xb4,
- 0x6b, 0x41, 0x99, 0xf4, 0xea, 0x54, 0xb7, 0x8b, 0xfb, 0x9f}},
- {"2.16.840.1.113733.1.7.48.1", ""},
- },
- // thawte Primary Root CA - G2
- {
- {{0xa4, 0x31, 0x0d, 0x50, 0xaf, 0x18, 0xa6, 0x44, 0x71, 0x90, 0x37,
- 0x2a, 0x86, 0xaf, 0xaf, 0x8b, 0x95, 0x1f, 0xfb, 0x43, 0x1d, 0x83,
- 0x7f, 0x1e, 0x56, 0x88, 0xb4, 0x59, 0x71, 0xed, 0x15, 0x57}},
- {"2.16.840.1.113733.1.7.48.1", ""},
- },
- // thawte Primary Root CA - G3
- {
- {{0x4b, 0x03, 0xf4, 0x58, 0x07, 0xad, 0x70, 0xf2, 0x1b, 0xfc, 0x2c,
- 0xae, 0x71, 0xc9, 0xfd, 0xe4, 0x60, 0x4c, 0x06, 0x4c, 0xf5, 0xff,
- 0xb6, 0x86, 0xba, 0xe5, 0xdb, 0xaa, 0xd7, 0xfd, 0xd3, 0x4c}},
- {"2.16.840.1.113733.1.7.48.1", ""},
- },
// TWCA Global Root CA
// https://evssldemo3.twca.com.tw/index.html
{
@@ -671,6 +560,14 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x7e, 0x31, 0x70, 0x7a, 0xf3, 0xe9, 0x6d, 0x52, 0x2b, 0xbd}},
{"1.3.6.1.4.1.7879.13.24.1", ""},
},
+ // UCA Extended Validation Root
+ // https://rsaevg1.good.sheca.com/
+ {
+ {{0xd4, 0x3a, 0xf9, 0xb3, 0x54, 0x73, 0x75, 0x5c, 0x96, 0x84, 0xfc,
+ 0x06, 0xd7, 0xd8, 0xcb, 0x70, 0xee, 0x5c, 0x28, 0xe7, 0x73, 0xfb,
+ 0x29, 0x4e, 0xb4, 0x1e, 0xe7, 0x17, 0x22, 0x92, 0x4d, 0x24}},
+ {"2.23.140.1.1", ""},
+ },
// USERTrust ECC Certification Authority
// https://usertrustecccertificationauthority-ev.comodoca.com/
{
@@ -687,63 +584,6 @@ static const EVMetadata kEvRootCaMetadata[] = {
0x89, 0x64, 0xb1, 0x74, 0x6d, 0x46, 0xc3, 0xd4, 0xcb, 0xd2}},
{"1.3.6.1.4.1.6449.1.2.1.5.1", ""},
},
- // UTN-USERFirst-Hardware
- {
- {{0x6e, 0xa5, 0x47, 0x41, 0xd0, 0x04, 0x66, 0x7e, 0xed, 0x1b, 0x48,
- 0x16, 0x63, 0x4a, 0xa3, 0xa7, 0x9e, 0x6e, 0x4b, 0x96, 0x95, 0x0f,
- 0x82, 0x79, 0xda, 0xfc, 0x8d, 0x9b, 0xd8, 0x81, 0x21, 0x37}},
- {
- "1.3.6.1.4.1.6449.1.2.1.5.1",
- // This is the Network Solutions EV OID. However, this root
- // cross-certifies NetSol and so we need it here too.
- "1.3.6.1.4.1.782.1.2.1.8.1",
- },
- },
- // ValiCert Class 2 Policy Validation Authority
- {
- {{0x58, 0xd0, 0x17, 0x27, 0x9c, 0xd4, 0xdc, 0x63, 0xab, 0xdd, 0xb1,
- 0x96, 0xa6, 0xc9, 0x90, 0x6c, 0x30, 0xc4, 0xe0, 0x87, 0x83, 0xea,
- 0xe8, 0xc1, 0x60, 0x99, 0x54, 0xd6, 0x93, 0x55, 0x59, 0x6b}},
- {"2.16.840.1.114413.1.7.23.3", "2.16.840.1.114414.1.7.23.3"},
- },
- // VeriSign Class 3 Public Primary Certification Authority
- // https://www.verisign.com/
- {
- {{0xe7, 0x68, 0x56, 0x34, 0xef, 0xac, 0xf6, 0x9a, 0xce, 0x93, 0x9a,
- 0x6b, 0x25, 0x5b, 0x7b, 0x4f, 0xab, 0xef, 0x42, 0x93, 0x5b, 0x50,
- 0xa2, 0x65, 0xac, 0xb5, 0xcb, 0x60, 0x27, 0xe4, 0x4e, 0x70}},
- {"2.16.840.1.113733.1.7.23.6", ""},
- },
- // VeriSign Class 3 Public Primary Certification Authority - G4
- {
- {{0x69, 0xdd, 0xd7, 0xea, 0x90, 0xbb, 0x57, 0xc9, 0x3e, 0x13, 0x5d,
- 0xc8, 0x5e, 0xa6, 0xfc, 0xd5, 0x48, 0x0b, 0x60, 0x32, 0x39, 0xbd,
- 0xc4, 0x54, 0xfc, 0x75, 0x8b, 0x2a, 0x26, 0xcf, 0x7f, 0x79}},
- {"2.16.840.1.113733.1.7.23.6", ""},
- },
- // VeriSign Class 3 Public Primary Certification Authority - G5
- // https://www.verisign.com/
- {
- {{0x9a, 0xcf, 0xab, 0x7e, 0x43, 0xc8, 0xd8, 0x80, 0xd0, 0x6b, 0x26,
- 0x2a, 0x94, 0xde, 0xee, 0xe4, 0xb4, 0x65, 0x99, 0x89, 0xc3, 0xd0,
- 0xca, 0xf1, 0x9b, 0xaf, 0x64, 0x05, 0xe4, 0x1a, 0xb7, 0xdf}},
- {"2.16.840.1.113733.1.7.23.6", ""},
- },
- // VeriSign Universal Root Certification Authority
- {
- {{0x23, 0x99, 0x56, 0x11, 0x27, 0xa5, 0x71, 0x25, 0xde, 0x8c, 0xef,
- 0xea, 0x61, 0x0d, 0xdf, 0x2f, 0xa0, 0x78, 0xb5, 0xc8, 0x06, 0x7f,
- 0x4e, 0x82, 0x82, 0x90, 0xbf, 0xb8, 0x60, 0xe8, 0x4b, 0x3c}},
- {"2.16.840.1.113733.1.7.23.6", ""},
- },
- // Wells Fargo WellsSecure Public Root Certificate Authority
- // https://nerys.wellsfargo.com/test.html
- {
- {{0xa7, 0x12, 0x72, 0xae, 0xaa, 0xa3, 0xcf, 0xe8, 0x72, 0x7f, 0x7f,
- 0xb3, 0x9f, 0x0f, 0xb3, 0xd1, 0xe5, 0x42, 0x6e, 0x90, 0x60, 0xb0,
- 0x6e, 0xe6, 0xf1, 0x3e, 0x9a, 0x3c, 0x58, 0x33, 0xcd, 0x43}},
- {"2.16.840.1.114171.500.9", ""},
- },
// XRamp Global Certification Authority
{
{{0xce, 0xcd, 0xdc, 0x90, 0x50, 0x99, 0xd8, 0xda, 0xdf, 0xc5, 0xb1,
@@ -763,113 +603,7 @@ EVRootCAMetadata* EVRootCAMetadata::GetInstance() {
return g_ev_root_ca_metadata.Pointer();
}
-#if defined(USE_NSS_CERTS)
-
-namespace {
-// Converts a DER-encoded OID (without leading tag and length) to a SECOidTag.
-//
-// Returns true if it was able to find an *existing* SECOidTag (it will not
-// register one if missing).
-//
-// Since all the EV OIDs are registered during EVRootCAMetadata's constructor,
-// doing a lookup only needs to consider existing OID tags.
-bool ConvertBytesToSecOidTag(const der::Input& oid, SECOidTag* out) {
- SECItem item;
- item.data = const_cast<uint8_t*>(oid.UnsafeData());
- item.len = oid.Length();
- *out = SECOID_FindOIDTag(&item);
- return *out != SEC_OID_UNKNOWN;
-}
-
-} // namespace
-
-bool EVRootCAMetadata::IsEVPolicyOID(PolicyOID policy_oid) const {
- return policy_oids_.find(policy_oid) != policy_oids_.end();
-}
-
-bool EVRootCAMetadata::IsEVPolicyOIDGivenBytes(
- const der::Input& policy_oid) const {
- SECOidTag oid_tag;
- return ConvertBytesToSecOidTag(policy_oid, &oid_tag) &&
- IsEVPolicyOID(oid_tag);
-}
-
-bool EVRootCAMetadata::HasEVPolicyOID(const SHA256HashValue& fingerprint,
- PolicyOID policy_oid) const {
- auto iter = ev_policy_.find(fingerprint);
- if (iter == ev_policy_.end())
- return false;
- return std::find(iter->second.begin(), iter->second.end(), policy_oid) !=
- iter->second.end();
-}
-
-bool EVRootCAMetadata::HasEVPolicyOIDGivenBytes(
- const SHA256HashValue& fingerprint,
- const der::Input& policy_oid) const {
- SECOidTag oid_tag;
- return ConvertBytesToSecOidTag(policy_oid, &oid_tag) &&
- HasEVPolicyOID(fingerprint, oid_tag);
-}
-
-// static
-bool EVRootCAMetadata::IsCaBrowserForumEvOid(PolicyOID policy_oid) {
- // OID: 2.23.140.1.1
- const uint8_t kCabEvOid[] = {0x67, 0x81, 0x0c, 0x01, 0x01};
- SECItem item;
- item.data = const_cast<uint8_t*>(&kCabEvOid[0]);
- item.len = sizeof(kCabEvOid);
- return policy_oid == SECOID_FindOIDTag(&item);
-}
-
-bool EVRootCAMetadata::AddEVCA(const SHA256HashValue& fingerprint,
- const char* policy) {
- if (ev_policy_.find(fingerprint) != ev_policy_.end())
- return false;
-
- PolicyOID oid;
- if (!RegisterOID(policy, &oid))
- return false;
-
- ev_policy_[fingerprint].push_back(oid);
- policy_oids_.insert(oid);
-
- return true;
-}
-
-bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
- auto it = ev_policy_.find(fingerprint);
- if (it == ev_policy_.end())
- return false;
- PolicyOID oid = it->second[0];
- ev_policy_.erase(it);
- policy_oids_.erase(oid);
- return true;
-}
-
-// static
-bool EVRootCAMetadata::RegisterOID(const char* policy,
- PolicyOID* out) {
- PRUint8 buf[64];
- SECItem oid_item;
- oid_item.data = buf;
- oid_item.len = sizeof(buf);
- SECStatus status = SEC_StringToOID(NULL, &oid_item, policy, 0);
- if (status != SECSuccess)
- return false;
-
- // Register the OID.
- SECOidData od;
- od.oid.len = oid_item.len;
- od.oid.data = oid_item.data;
- od.offset = SEC_OID_UNKNOWN;
- od.desc = policy;
- od.mechanism = CKM_INVALID_MECHANISM;
- od.supportedExtension = INVALID_CERT_EXTENSION;
- *out = SECOID_AddEntry(&od);
- return *out != SEC_OID_UNKNOWN;
-}
-
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
namespace {
@@ -1084,24 +818,7 @@ bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
EVRootCAMetadata::EVRootCAMetadata() {
// Constructs the object from the raw metadata in kEvRootCaMetadata.
-#if defined(USE_NSS_CERTS)
- crypto::EnsureNSSInit();
-
- for (const auto& ev_root : kEvRootCaMetadata) {
- for (const auto& policy : ev_root.policy_oids) {
- if (policy.empty())
- break;
- PolicyOID policy_oid;
- if (!RegisterOID(policy.data(), &policy_oid)) {
- LOG(ERROR) << "Failed to register OID: " << policy;
- continue;
- }
-
- ev_policy_[ev_root.fingerprint].push_back(policy_oid);
- policy_oids_.insert(policy_oid);
- }
- }
-#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA) && !defined(OS_WIN)
+#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA) && !defined(OS_WIN)
for (const auto& ev_root : kEvRootCaMetadata) {
for (const auto& policy : ev_root.policy_oids) {
if (policy.empty())
diff --git a/chromium/net/cert/ev_root_ca_metadata.h b/chromium/net/cert/ev_root_ca_metadata.h
index 42daddbd8bd..b79206e9141 100644
--- a/chromium/net/cert/ev_root_ca_metadata.h
+++ b/chromium/net/cert/ev_root_ca_metadata.h
@@ -7,10 +7,6 @@
#include "build/build_config.h"
-#if defined(USE_NSS_CERTS)
-#include <secoidt.h>
-#endif
-
#include <map>
#include <set>
#include <string>
@@ -42,9 +38,7 @@ class Input;
// extended-validation (EV) certificates.
class NET_EXPORT_PRIVATE EVRootCAMetadata {
public:
-#if defined(USE_NSS_CERTS)
- typedef SECOidTag PolicyOID;
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
typedef const char* PolicyOID;
#else
// DER-encoded OID value (no tag or length).
@@ -90,16 +84,7 @@ class NET_EXPORT_PRIVATE EVRootCAMetadata {
EVRootCAMetadata();
~EVRootCAMetadata();
-#if defined(USE_NSS_CERTS)
- using PolicyOIDMap = std::map<SHA256HashValue, std::vector<PolicyOID>>;
-
- // RegisterOID registers |policy|, a policy OID in dotted string form, and
- // writes the memoized form to |*out|. It returns true on success.
- static bool RegisterOID(const char* policy, PolicyOID* out);
-
- PolicyOIDMap ev_policy_;
- std::set<PolicyOID> policy_oids_;
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
using ExtraEVCAMap = std::map<SHA256HashValue, std::string>;
// extra_cas_ contains any EV CA metadata that was added at runtime.
diff --git a/chromium/net/cert/ev_root_ca_metadata_unittest.cc b/chromium/net/cert/ev_root_ca_metadata_unittest.cc
index bb69645df5e..56ffc5e643e 100644
--- a/chromium/net/cert/ev_root_ca_metadata_unittest.cc
+++ b/chromium/net/cert/ev_root_ca_metadata_unittest.cc
@@ -10,132 +10,74 @@
#include "net/test/cert_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS_CERTS)
-#include "crypto/nss_util.h"
-#include "crypto/scoped_nss_types.h"
-#endif
-
namespace net {
namespace {
-#if defined(USE_NSS_CERTS) || defined(OS_WIN)
-const char kVerisignPolicyStr[] = "2.16.840.1.113733.1.7.23.6";
-const char kThawtePolicyStr[] = "2.16.840.1.113733.1.7.48.1";
+#if defined(OS_WIN)
const char kFakePolicyStr[] = "2.16.840.1.42";
const char kCabEvPolicyStr[] = "2.23.140.1.1";
-#elif defined(OS_MACOSX)
+const char kStarfieldPolicyStr[] = "2.16.840.1.114414.1.7.23.3";
+#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
const char kFakePolicyStr[] = "2.16.840.1.42";
#endif
-#if defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
+#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
// DER OID values (no tag or length).
-const uint8_t kVerisignPolicyBytes[] = {0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
- 0x45, 0x01, 0x07, 0x17, 0x06};
-const uint8_t kThawtePolicyBytes[] = {0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
- 0x45, 0x01, 0x07, 0x30, 0x01};
const uint8_t kFakePolicyBytes[] = {0x60, 0x86, 0x48, 0x01, 0x2a};
const uint8_t kCabEvPolicyBytes[] = {0x67, 0x81, 0x0c, 0x01, 0x01};
+const uint8_t kStarfieldPolicyBytes[] = {0x60, 0x86, 0x48, 0x01, 0x86, 0xFD,
+ 0x6E, 0x01, 0x07, 0x17, 0x03};
-const SHA256HashValue kVerisignFingerprint = {
- {0xe7, 0x68, 0x56, 0x34, 0xef, 0xac, 0xf6, 0x9a, 0xce, 0x93, 0x9a,
- 0x6b, 0x25, 0x5b, 0x7b, 0x4f, 0xab, 0xef, 0x42, 0x93, 0x5b, 0x50,
- 0xa2, 0x65, 0xac, 0xb5, 0xcb, 0x60, 0x27, 0xe4, 0x4e, 0x70}};
const SHA256HashValue kFakeFingerprint = {
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}};
+const SHA256HashValue kStarfieldFingerprint = {
+ {0x14, 0x65, 0xfa, 0x20, 0x53, 0x97, 0xb8, 0x76, 0xfa, 0xa6, 0xf0,
+ 0xa9, 0x95, 0x8e, 0x55, 0x90, 0xe4, 0x0f, 0xcc, 0x7f, 0xaa, 0x4f,
+ 0xb7, 0xc2, 0xc8, 0x67, 0x75, 0x21, 0xfb, 0x5f, 0xb6, 0x58}};
class EVOidData {
public:
EVOidData();
bool Init();
- EVRootCAMetadata::PolicyOID verisign_policy;
- der::Input verisign_policy_bytes;
-
- EVRootCAMetadata::PolicyOID thawte_policy;
- der::Input thawte_policy_bytes;
-
EVRootCAMetadata::PolicyOID fake_policy;
der::Input fake_policy_bytes;
EVRootCAMetadata::PolicyOID cab_ev_policy;
der::Input cab_ev_policy_bytes;
-};
-
-#endif // defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
-
-#if defined(USE_NSS_CERTS)
-
-SECOidTag RegisterOID(PLArenaPool* arena, const char* oid_string) {
- SECOidData oid_data;
- memset(&oid_data, 0, sizeof(oid_data));
- oid_data.offset = SEC_OID_UNKNOWN;
- oid_data.desc = oid_string;
- oid_data.mechanism = CKM_INVALID_MECHANISM;
- oid_data.supportedExtension = INVALID_CERT_EXTENSION;
- SECStatus rv = SEC_StringToOID(arena, &oid_data.oid, oid_string, 0);
- if (rv != SECSuccess)
- return SEC_OID_UNKNOWN;
-
- return SECOID_AddEntry(&oid_data);
-}
-
-EVOidData::EVOidData()
- : verisign_policy(SEC_OID_UNKNOWN),
- verisign_policy_bytes(kVerisignPolicyBytes),
- thawte_policy(SEC_OID_UNKNOWN),
- thawte_policy_bytes(kThawtePolicyBytes),
- fake_policy(SEC_OID_UNKNOWN),
- fake_policy_bytes(kFakePolicyBytes),
- cab_ev_policy(SEC_OID_UNKNOWN),
- cab_ev_policy_bytes(kCabEvPolicyBytes) {}
+ EVRootCAMetadata::PolicyOID starfield_policy;
+ der::Input starfield_policy_bytes;
+};
-bool EVOidData::Init() {
- crypto::EnsureNSSInit();
- crypto::ScopedPLArenaPool pool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!pool.get())
- return false;
-
- verisign_policy = RegisterOID(pool.get(), kVerisignPolicyStr);
- thawte_policy = RegisterOID(pool.get(), kThawtePolicyStr);
- fake_policy = RegisterOID(pool.get(), kFakePolicyStr);
- cab_ev_policy = RegisterOID(pool.get(), kCabEvPolicyStr);
-
- return verisign_policy != SEC_OID_UNKNOWN &&
- thawte_policy != SEC_OID_UNKNOWN && fake_policy != SEC_OID_UNKNOWN &&
- cab_ev_policy != SEC_OID_UNKNOWN;
-}
+#endif // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
EVOidData::EVOidData()
- : verisign_policy(kVerisignPolicyStr),
- verisign_policy_bytes(kVerisignPolicyBytes),
- thawte_policy(kThawtePolicyStr),
- thawte_policy_bytes(kThawtePolicyBytes),
- fake_policy(kFakePolicyStr),
+ : fake_policy(kFakePolicyStr),
fake_policy_bytes(kFakePolicyBytes),
cab_ev_policy(kCabEvPolicyStr),
- cab_ev_policy_bytes(kCabEvPolicyBytes) {}
+ cab_ev_policy_bytes(kCabEvPolicyBytes),
+ starfield_policy(kStarfieldPolicyStr),
+ starfield_policy_bytes(kStarfieldPolicyBytes) {}
bool EVOidData::Init() {
return true;
}
-#elif defined(OS_MACOSX)
+#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
EVOidData::EVOidData()
- : verisign_policy(kVerisignPolicyBytes),
- verisign_policy_bytes(kVerisignPolicyBytes),
- thawte_policy(kThawtePolicyBytes),
- thawte_policy_bytes(kThawtePolicyBytes),
- fake_policy(kFakePolicyBytes),
+ : fake_policy(kFakePolicyBytes),
fake_policy_bytes(kFakePolicyBytes),
cab_ev_policy(kCabEvPolicyBytes),
- cab_ev_policy_bytes(kCabEvPolicyBytes) {}
+ cab_ev_policy_bytes(kCabEvPolicyBytes),
+ starfield_policy(kStarfieldPolicyBytes),
+ starfield_policy_bytes(kStarfieldPolicyBytes) {}
bool EVOidData::Init() {
return true;
@@ -143,7 +85,7 @@ bool EVOidData::Init() {
#endif
-#if defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
+#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
class EVRootCAMetadataTest : public testing::Test {
protected:
@@ -155,43 +97,51 @@ class EVRootCAMetadataTest : public testing::Test {
TEST_F(EVRootCAMetadataTest, Basic) {
EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance());
- EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.verisign_policy));
+ // Contains an expected policy.
+ EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.starfield_policy));
EXPECT_TRUE(
- ev_metadata->IsEVPolicyOIDGivenBytes(ev_oid_data.verisign_policy_bytes));
+ ev_metadata->IsEVPolicyOIDGivenBytes(ev_oid_data.starfield_policy_bytes));
+ // Does not contain an unregistered policy.
EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
EXPECT_FALSE(
ev_metadata->IsEVPolicyOIDGivenBytes(ev_oid_data.fake_policy_bytes));
- EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
- ev_oid_data.verisign_policy));
+ // The policy is correct for the right root.
+ EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kStarfieldFingerprint,
+ ev_oid_data.starfield_policy));
EXPECT_TRUE(ev_metadata->HasEVPolicyOIDGivenBytes(
- kVerisignFingerprint, ev_oid_data.verisign_policy_bytes));
+ kStarfieldFingerprint, ev_oid_data.starfield_policy_bytes));
+ // The policy does not match if the root does not match.
EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint,
- ev_oid_data.verisign_policy));
+ ev_oid_data.starfield_policy));
EXPECT_FALSE(ev_metadata->HasEVPolicyOIDGivenBytes(
- kFakeFingerprint, ev_oid_data.verisign_policy_bytes));
+ kFakeFingerprint, ev_oid_data.starfield_policy_bytes));
- EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
+ // The expected root only has the expected policies; it should fail to match
+ // the root against both unknown policies as well as policies associated
+ // with other roots.
+ EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kStarfieldFingerprint,
ev_oid_data.fake_policy));
EXPECT_FALSE(ev_metadata->HasEVPolicyOIDGivenBytes(
- kVerisignFingerprint, ev_oid_data.fake_policy_bytes));
+ kStarfieldFingerprint, ev_oid_data.fake_policy_bytes));
- EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
- ev_oid_data.thawte_policy));
+ EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kStarfieldFingerprint,
+ ev_oid_data.cab_ev_policy));
EXPECT_FALSE(ev_metadata->HasEVPolicyOIDGivenBytes(
- kVerisignFingerprint, ev_oid_data.thawte_policy_bytes));
+ kStarfieldFingerprint, ev_oid_data.cab_ev_policy_bytes));
// Test a completely bogus OID given bytes.
const uint8_t bad_oid[] = {0};
- EXPECT_FALSE(ev_metadata->HasEVPolicyOIDGivenBytes(kVerisignFingerprint,
+ EXPECT_FALSE(ev_metadata->HasEVPolicyOIDGivenBytes(kStarfieldFingerprint,
der::Input(bad_oid)));
}
TEST_F(EVRootCAMetadataTest, AddRemove) {
EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance());
+ // An unregistered/junk policy should not work.
EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
EXPECT_FALSE(
ev_metadata->IsEVPolicyOIDGivenBytes(ev_oid_data.fake_policy_bytes));
@@ -202,6 +152,8 @@ TEST_F(EVRootCAMetadataTest, AddRemove) {
kFakeFingerprint, ev_oid_data.fake_policy_bytes));
{
+ // However, this unregistered/junk policy can be temporarily registered
+ // and made to work.
ScopedTestEVPolicy test_ev_policy(ev_metadata, kFakeFingerprint,
kFakePolicyStr);
@@ -215,6 +167,7 @@ TEST_F(EVRootCAMetadataTest, AddRemove) {
kFakeFingerprint, ev_oid_data.fake_policy_bytes));
}
+ // It should go out of scope when the ScopedTestEVPolicy goes out of scope.
EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
EXPECT_FALSE(
ev_metadata->IsEVPolicyOIDGivenBytes(ev_oid_data.fake_policy_bytes));
@@ -232,10 +185,10 @@ TEST_F(EVRootCAMetadataTest, IsCaBrowserForumEvOid) {
EXPECT_FALSE(
EVRootCAMetadata::IsCaBrowserForumEvOid(ev_oid_data.fake_policy));
EXPECT_FALSE(
- EVRootCAMetadata::IsCaBrowserForumEvOid(ev_oid_data.verisign_policy));
+ EVRootCAMetadata::IsCaBrowserForumEvOid(ev_oid_data.starfield_policy));
}
-#endif // defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_MACOSX)
+#endif // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
} // namespace
diff --git a/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc b/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc
index cb1718673a1..3d3e00ed321 100644
--- a/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc
+++ b/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/macros.h"
#include "net/cert/internal/parse_certificate.h"
#include "net/der/input.h"
diff --git a/chromium/net/cert/internal/parsed_certificate.h b/chromium/net/cert/internal/parsed_certificate.h
index c83cebe57c5..a5ad843e001 100644
--- a/chromium/net/cert/internal/parsed_certificate.h
+++ b/chromium/net/cert/internal/parsed_certificate.h
@@ -9,7 +9,7 @@
#include <memory>
#include <vector>
-#include "base/logging.h"
+#include "base/check.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/internal/certificate_policies.h"
diff --git a/chromium/net/cert/internal/path_builder.cc b/chromium/net/cert/internal/path_builder.cc
index ccd89249ab4..568497b7b4a 100644
--- a/chromium/net/cert/internal/path_builder.cc
+++ b/chromium/net/cert/internal/path_builder.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
+#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/sha2.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/cert/internal/path_builder_pkits_unittest.cc b/chromium/net/cert/internal/path_builder_pkits_unittest.cc
index dca35a8cb0a..b6daaaf0a17 100644
--- a/chromium/net/cert/internal/path_builder_pkits_unittest.cc
+++ b/chromium/net/cert/internal/path_builder_pkits_unittest.cc
@@ -114,7 +114,9 @@ class PathBuilderPkitsTestDelegate {
public:
static void RunTest(std::vector<std::string> cert_ders,
std::vector<std::string> crl_ders,
- const PkitsTestInfo& info) {
+ const PkitsTestInfo& orig_info) {
+ PkitsTestInfo info = orig_info;
+
ASSERT_FALSE(cert_ders.empty());
ParsedCertificateList certs;
for (const std::string& der : cert_ders) {
@@ -139,28 +141,71 @@ class PathBuilderPkitsTestDelegate {
scoped_refptr<ParsedCertificate> target_cert(certs.back());
+ base::Time verify_time;
+ ASSERT_TRUE(der::GeneralizedTimeToTime(info.time, &verify_time));
+ CrlCheckingPathBuilderDelegate path_builder_delegate(
+ crl_ders, verify_time, /*max_age=*/base::TimeDelta::FromDays(365 * 2),
+ 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
+
base::StringPiece test_number = info.test_number;
- std::unique_ptr<CertPathBuilderDelegate> path_builder_delegate;
if (test_number == "4.4.19" || test_number == "4.5.3" ||
test_number == "4.5.4" || test_number == "4.5.6") {
- // TODO(https://crbug.com/749276): extend CRL support: These tests
- // require better CRL issuer cert discovery & path building and/or
- // issuingDistributionPoint extension handling. Disable CRL checking for
- // them for now. Maybe should just run these with CRL checking enabled
- // and expect them to fail?
- path_builder_delegate = std::make_unique<SimplePathBuilderDelegate>(
- 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
- } else {
- base::Time verify_time;
- ASSERT_TRUE(der::GeneralizedTimeToTime(info.time, &verify_time));
- path_builder_delegate = std::make_unique<CrlCheckingPathBuilderDelegate>(
- crl_ders, verify_time, /*max_age=*/base::TimeDelta::FromDays(365 * 2),
- 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
+ // 4.4.19 - fails since CRL is signed by a certificate that is not part
+ // of the verified chain, which is not supported.
+ // 4.5.3 - fails since non-URI distribution point names are not supported
+ // 4.5.4, 4.5.6 - fails since CRL is signed by a certificate that is not
+ // part of verified chain, and also non-URI distribution
+ // point names not supported
+ info.should_validate = false;
+ } else if (test_number == "4.14.1" || test_number == "4.14.4" ||
+ test_number == "4.14.5" || test_number == "4.14.7" ||
+ test_number == "4.14.18" || test_number == "4.14.19" ||
+ test_number == "4.14.22" || test_number == "4.14.24" ||
+ test_number == "4.14.25" || test_number == "4.14.28" ||
+ test_number == "4.14.29" || test_number == "4.14.30" ||
+ test_number == "4.14.33") {
+ // 4.14 tests:
+ // .1 - fails since non-URI distribution point names not supported
+ // .2, .3 - fails since non-URI distribution point names not supported
+ // (but test is expected to fail for other reason)
+ // .4, .5 - fails since non-URI distribution point names not supported,
+ // also uses nameRelativeToCRLIssuer which is not supported
+ // .6 - fails since non-URI distribution point names not supported, also
+ // uses nameRelativeToCRLIssuer which is not supported (but test is
+ // expected to fail for other reason)
+ // .7 - fails since relative distributionPointName not supported
+ // .8, .9 - fails since relative distributionPointName not supported (but
+ // test is expected to fail for other reason)
+ // .10, .11, .12, .13, .14, .27, .35 - PASS
+ // .15, .16, .17, .20, .21 - fails since onlySomeReasons is not supported
+ // (but test is expected to fail for other
+ // reason)
+ // .18, .19 - fails since onlySomeReasons is not supported
+ // .22, .24, .25, .28, .29, .30, .33 - fails since indirect CRLs are not
+ // supported
+ // .23, .26, .31, .32, .34 - fails since indirect CRLs are not supported
+ // (but test is expected to fail for other
+ // reason)
+ info.should_validate = false;
+ } else if (test_number == "4.15.1" || test_number == "4.15.5") {
+ // 4.15 tests:
+ // .1 - fails due to unhandled critical deltaCRLIndicator extension
+ // .2, .3, .6, .7, .8, .9, .10 - PASS since expected cert status is
+ // reflected in base CRL and delta CRL is
+ // ignored
+ // .5 - fails, cert status is "on hold" in base CRL but the delta CRL
+ // which removes the cert from CRL is ignored
+ info.should_validate = false;
+ } else if (test_number == "4.15.4") {
+ // 4.15.4 - Invalid delta-CRL Test4 has the target cert marked revoked in
+ // a delta-CRL. Since delta-CRLs are not supported, the chain validates
+ // successfully.
+ info.should_validate = true;
}
CertPathBuilder path_builder(
- std::move(target_cert), &trust_store, path_builder_delegate.get(),
- info.time, KeyPurpose::ANY_EKU, info.initial_explicit_policy,
+ std::move(target_cert), &trust_store, &path_builder_delegate, info.time,
+ KeyPurpose::ANY_EKU, info.initial_explicit_policy,
info.initial_policy_set, info.initial_policy_mapping_inhibit,
info.initial_inhibit_any_policy);
path_builder.AddCertIssuerSource(&cert_issuer_source);
@@ -228,12 +273,13 @@ INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
PkitsTest13NameConstraints,
PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
+ PkitsTest14DistributionPoints,
+ PathBuilderPkitsTestDelegate);
+INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
+ PkitsTest15DeltaCRLs,
+ PathBuilderPkitsTestDelegate);
+INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
PkitsTest16PrivateCertificateExtensions,
PathBuilderPkitsTestDelegate);
-// TODO(https://crbug.com/749276): extend CRL support?:
-// PkitsTest14DistributionPoints: indirect CRLs and reason codes are not
-// supported.
-// PkitsTest15DeltaCRLs: Delta CRLs are not supported.
-
} // namespace net
diff --git a/chromium/net/cert/internal/system_trust_store.cc b/chromium/net/cert/internal/system_trust_store.cc
index f3737ebd167..0f0d3332b5a 100644
--- a/chromium/net/cert/internal/system_trust_store.cc
+++ b/chromium/net/cert/internal/system_trust_store.cc
@@ -19,6 +19,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/logging.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
#include "net/cert/internal/cert_errors.h"
diff --git a/chromium/net/cert/internal/trust_store_mac_unittest.cc b/chromium/net/cert/internal/trust_store_mac_unittest.cc
index dd79ef376b5..7c5ff55227e 100644
--- a/chromium/net/cert/internal/trust_store_mac_unittest.cc
+++ b/chromium/net/cert/internal/trust_store_mac_unittest.cc
@@ -7,6 +7,7 @@
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/string_split.h"
diff --git a/chromium/net/cert/internal/trust_store_nss.cc b/chromium/net/cert/internal/trust_store_nss.cc
index e4cf9e3a94a..4b0ba6e5457 100644
--- a/chromium/net/cert/internal/trust_store_nss.cc
+++ b/chromium/net/cert/internal/trust_store_nss.cc
@@ -7,6 +7,7 @@
#include <cert.h>
#include <certdb.h>
+#include "base/logging.h"
#include "crypto/nss_util.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parsed_certificate.h"
diff --git a/chromium/net/cert/known_roots_mac.cc b/chromium/net/cert/known_roots_mac.cc
index 72ed07f027a..dfcaecd73d3 100644
--- a/chromium/net/cert/known_roots_mac.cc
+++ b/chromium/net/cert/known_roots_mac.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "crypto/mac_security_services_lock.h"
#include "net/cert/x509_util_mac.h"
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index 8b0ff51d732..f2546d9187d 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -22,6 +22,10 @@
#include "net/log/net_log_source_type.h"
#include "net/log/net_log_with_source.h"
+#if defined(USE_NSS_CERTS)
+#include "net/cert/x509_util_nss.h"
+#endif
+
namespace net {
// Allows DoVerifyOnWorkerThread to wait on a base::WaitableEvent.
@@ -232,6 +236,21 @@ void MultiThreadedCertVerifier::SetConfig(const CertVerifier::Config& config) {
<< "Attempted to set a CertVerifier::Config with additional trust "
"anchors, but |verify_proc_| does not support additional trust "
"anchors.";
+
+// TODO(https://crbug.com/978854): Pass these into the actual CertVerifyProc
+// rather than relying on global side-effects.
+#if !defined(USE_NSS_CERTS)
+ // Not yet implemented.
+ DCHECK(config.additional_untrusted_authorities.empty());
+#else
+ for (const auto& cert : config.additional_untrusted_authorities) {
+ ScopedCERTCertificate x509_cert =
+ x509_util::CreateCERTCertificateFromX509Certificate(cert.get());
+ DCHECK(x509_cert);
+ temp_certs_.push_back(std::move(x509_cert));
+ }
+#endif
+
config_ = config;
if (!config_.crl_set)
config_.crl_set = CRLSet::BuiltinCRLSet();
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index ef8225bc878..82b750a42f8 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -18,6 +18,10 @@
#include "net/base/net_export.h"
#include "net/cert/cert_verifier.h"
+#if defined(USE_NSS_CERTS)
+#include "net/cert/scoped_nss_types.h"
+#endif
+
namespace net {
class CertVerifyProc;
@@ -48,6 +52,14 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
base::LinkedList<InternalRequest> request_list_;
+#if defined(USE_NSS_CERTS)
+ // Holds NSS temporary certificates that will be exposed as untrusted
+ // authorities by SystemCertStoreNSS.
+ // TODO(https://crbug.com/978854): Pass these into the actual CertVerifyProc
+ // rather than relying on global side-effects.
+ net::ScopedCERTCertificateList temp_certs_;
+#endif
+
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier);
diff --git a/chromium/net/cert/test_keychain_search_list_mac.h b/chromium/net/cert/test_keychain_search_list_mac.h
index 4ae25729c93..48edf89d979 100644
--- a/chromium/net/cert/test_keychain_search_list_mac.h
+++ b/chromium/net/cert/test_keychain_search_list_mac.h
@@ -5,6 +5,8 @@
#ifndef NET_CERT_TEST_KEYCHAIN_SEARCH_LIST_MAC_H_
#define NET_CERT_TEST_KEYCHAIN_SEARCH_LIST_MAC_H_
+#include <memory>
+
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h
index c0be7b78328..756379fb9b7 100644
--- a/chromium/net/cert/test_root_certs.h
+++ b/chromium/net/cert/test_root_certs.h
@@ -12,11 +12,7 @@
#include "net/base/net_export.h"
#include "net/cert/internal/trust_store_in_memory.h"
-#if defined(USE_NSS_CERTS)
-#include <cert.h>
-#include <vector>
-#include "net/cert/scoped_nss_types.h"
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
#include <windows.h>
#include "base/win/wincrypt_shim.h"
#elif defined(OS_MACOSX)
@@ -62,10 +58,7 @@ class NET_EXPORT TestRootCerts {
// Returns true if there are no certificates that have been marked trusted.
bool IsEmpty() const;
-#if defined(USE_NSS_CERTS)
- bool Contains(CERTCertificate* cert) const;
- TrustStore* test_trust_store() { return &test_trust_store_; }
-#elif defined(OS_MACOSX)
+#if defined(OS_MACOSX)
CFArrayRef temporary_roots() const { return temporary_roots_; }
// Modifies the root certificates of |trust_ref| to include the
@@ -82,7 +75,7 @@ class NET_EXPORT TestRootCerts {
// engine is appropriate. The caller is responsible for freeing the
// returned HCERTCHAINENGINE.
HCERTCHAINENGINE GetChainEngine() const;
-#elif defined(OS_FUCHSIA)
+#elif defined(OS_FUCHSIA) || defined(OS_LINUX) || defined(OS_CHROMEOS)
TrustStore* test_trust_store() { return &test_trust_store_; }
#endif
@@ -95,46 +88,17 @@ class NET_EXPORT TestRootCerts {
// Performs platform-dependent initialization.
void Init();
-#if defined(USE_NSS_CERTS)
- // TrustEntry is used to store the original CERTCertificate and CERTCertTrust
- // for a certificate whose trust status has been changed by the
- // TestRootCerts.
- class TrustEntry {
- public:
- // Creates a new TrustEntry by incrementing the reference to |certificate|
- // and copying |trust|.
- TrustEntry(ScopedCERTCertificate certificate, const CERTCertTrust& trust);
- ~TrustEntry();
-
- CERTCertificate* certificate() const { return certificate_.get(); }
- const CERTCertTrust& trust() const { return trust_; }
-
- private:
- // The temporary root certificate.
- ScopedCERTCertificate certificate_;
-
- // The original trust settings, before |certificate_| was manipulated to
- // be a temporarily trusted root.
- CERTCertTrust trust_;
-
- DISALLOW_COPY_AND_ASSIGN(TrustEntry);
- };
-
- // It is necessary to maintain a cache of the original certificate trust
- // settings, in order to restore them when Clear() is called.
- std::vector<std::unique_ptr<TrustEntry>> trust_cache_;
-
- TrustStoreInMemory test_trust_store_;
-#elif defined(OS_WIN)
+#if defined(OS_WIN)
HCERTSTORE temporary_roots_;
#elif defined(OS_MACOSX)
base::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots_;
TrustStoreInMemory test_trust_store_;
-#elif defined(OS_FUCHSIA)
+#elif defined(OS_FUCHSIA) || defined(OS_LINUX) || defined(OS_CHROMEOS)
TrustStoreInMemory test_trust_store_;
#endif
-#if defined(OS_WIN) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+#if defined(OS_WIN) || defined(OS_ANDROID) || defined(OS_FUCHSIA) || \
+ defined(OS_LINUX) || defined(OS_CHROMEOS)
// True if there are no temporarily trusted root certificates.
bool empty_ = true;
#endif
diff --git a/chromium/net/cert/test_root_certs_fuchsia.cc b/chromium/net/cert/test_root_certs_builtin.cc
index 3bf05c8f34b..3bf05c8f34b 100644
--- a/chromium/net/cert/test_root_certs_fuchsia.cc
+++ b/chromium/net/cert/test_root_certs_builtin.cc
diff --git a/chromium/net/cert/test_root_certs_nss.cc b/chromium/net/cert/test_root_certs_nss.cc
deleted file mode 100644
index a04885edbb8..00000000000
--- a/chromium/net/cert/test_root_certs_nss.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2011 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/cert/test_root_certs.h"
-
-#include <cert.h>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "crypto/nss_util.h"
-#include "net/cert/internal/cert_errors.h"
-#include "net/cert/x509_certificate.h"
-#include "net/cert/x509_util.h"
-#include "net/cert/x509_util_nss.h"
-#include "third_party/boringssl/src/include/openssl/pool.h"
-
-namespace net {
-
-TestRootCerts::TrustEntry::TrustEntry(ScopedCERTCertificate certificate,
- const CERTCertTrust& trust)
- : certificate_(std::move(certificate)), trust_(trust) {}
-
-TestRootCerts::TrustEntry::~TrustEntry() = default;
-
-bool TestRootCerts::Add(X509Certificate* certificate) {
- ScopedCERTCertificate cert_handle =
- x509_util::CreateCERTCertificateFromX509Certificate(certificate);
- if (!cert_handle)
- return false;
- // Preserve the original trust bits so that they can be restored when
- // the certificate is removed.
- CERTCertTrust original_trust;
- SECStatus rv = CERT_GetCertTrust(cert_handle.get(), &original_trust);
- if (rv != SECSuccess) {
- // CERT_GetCertTrust will fail if the certificate does not have any
- // particular trust settings associated with it, and attempts to use
- // |original_trust| later to restore the original trust settings will not
- // cause the trust settings to be revoked. If the certificate has no
- // particular trust settings associated with it, mark the certificate as
- // a valid CA certificate with no specific trust.
- rv = CERT_DecodeTrustString(&original_trust, "c,c,c");
- }
-
- // Change the trust bits to unconditionally trust this certificate.
- CERTCertTrust new_trust;
- rv = CERT_DecodeTrustString(&new_trust, "TCPu,Cu,Tu");
- if (rv != SECSuccess) {
- LOG(ERROR) << "Cannot decode certificate trust string.";
- return false;
- }
-
- rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert_handle.get(),
- &new_trust);
- if (rv != SECSuccess) {
- LOG(ERROR) << "Cannot change certificate trust.";
- return false;
- }
-
- trust_cache_.push_back(
- std::make_unique<TrustEntry>(std::move(cert_handle), original_trust));
-
- // Add the certificate to the parallel |test_trust_store_|. TrustStoreNSS
- // ignores temporary certs, so it won't see the cert that was added above.
- // (See https://crbug.com/951166)
- // TODO(https://crbug.com/951479): remove this when the istemp check is
- // removed from TrustStoreNSS.
- CertErrors errors;
- scoped_refptr<ParsedCertificate> parsed = ParsedCertificate::Create(
- bssl::UpRef(certificate->cert_buffer()),
- x509_util::DefaultParseCertificateOptions(), &errors);
- if (!parsed)
- return false;
- test_trust_store_.AddTrustAnchor(parsed);
-
- return true;
-}
-
-void TestRootCerts::Clear() {
- // Restore the certificate trusts to what they were originally, before
- // Add() was called. Work from the rear first, since if a certificate was
- // added twice, the second entry's original trust status will be that of
- // the first entry, while the first entry contains the desired resultant
- // status.
- for (auto it = trust_cache_.rbegin(); it != trust_cache_.rend(); ++it) {
- CERTCertTrust original_trust = (*it)->trust();
- SECStatus rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
- (*it)->certificate(),
- &original_trust);
- // DCHECK(), rather than LOG(), as a failure to restore the original
- // trust can cause flake or hard-to-trace errors in any unit tests that
- // occur after Clear() has been called.
- DCHECK_EQ(SECSuccess, rv) << "Cannot restore certificate trust.";
- }
- trust_cache_.clear();
-
- test_trust_store_.Clear();
-}
-
-bool TestRootCerts::IsEmpty() const {
- return trust_cache_.empty();
-}
-
-bool TestRootCerts::Contains(CERTCertificate* cert) const {
- for (const auto& item : trust_cache_)
- if (x509_util::IsSameCertificate(cert, item->certificate()))
- return true;
-
- return false;
-}
-
-TestRootCerts::~TestRootCerts() {
- Clear();
-}
-
-void TestRootCerts::Init() {
- crypto::EnsureNSSInit();
-}
-
-} // namespace net
diff --git a/chromium/net/cert/test_root_certs_unittest.cc b/chromium/net/cert/test_root_certs_unittest.cc
index f65174ddf68..983c88c3b80 100644
--- a/chromium/net/cert/test_root_certs_unittest.cc
+++ b/chromium/net/cert/test_root_certs_unittest.cc
@@ -21,12 +21,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS_CERTS)
-#include <nss.h>
-
-#include "net/cert/x509_util_nss.h"
-#endif
-
using net::test::IsOk;
namespace net {
@@ -147,45 +141,6 @@ TEST(TestRootCertsTest, OverrideTrust) {
EXPECT_EQ(bad_verify_result.cert_status, restored_verify_result.cert_status);
}
-#if defined(USE_NSS_CERTS)
-TEST(TestRootCertsTest, Contains) {
- // Another test root certificate.
- const char kRootCertificateFile2[] = "2048-rsa-root.pem";
-
- TestRootCerts* test_roots = TestRootCerts::GetInstance();
- ASSERT_TRUE(test_roots);
-
- scoped_refptr<X509Certificate> root_cert_1 =
- ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile);
- ASSERT_TRUE(root_cert_1);
- ScopedCERTCertificate nss_root_cert_1 =
- x509_util::CreateCERTCertificateFromX509Certificate(root_cert_1.get());
- ASSERT_TRUE(nss_root_cert_1);
-
- scoped_refptr<X509Certificate> root_cert_2 =
- ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile2);
- ASSERT_TRUE(root_cert_2);
- ScopedCERTCertificate nss_root_cert_2 =
- x509_util::CreateCERTCertificateFromX509Certificate(root_cert_2.get());
- ASSERT_TRUE(nss_root_cert_2);
-
- EXPECT_FALSE(test_roots->Contains(nss_root_cert_1.get()));
- EXPECT_FALSE(test_roots->Contains(nss_root_cert_2.get()));
-
- EXPECT_TRUE(test_roots->Add(root_cert_1.get()));
- EXPECT_TRUE(test_roots->Contains(nss_root_cert_1.get()));
- EXPECT_FALSE(test_roots->Contains(nss_root_cert_2.get()));
-
- EXPECT_TRUE(test_roots->Add(root_cert_2.get()));
- EXPECT_TRUE(test_roots->Contains(nss_root_cert_1.get()));
- EXPECT_TRUE(test_roots->Contains(nss_root_cert_2.get()));
-
- test_roots->Clear();
- EXPECT_FALSE(test_roots->Contains(nss_root_cert_1.get()));
- EXPECT_FALSE(test_roots->Contains(nss_root_cert_2.get()));
-}
-#endif
-
// TODO(rsleevi): Add tests for revocation checking via CRLs, ensuring that
// TestRootCerts properly injects itself into the validation process. See
// http://crbug.com/63958
diff --git a/chromium/net/cert/x509_cert_types.h b/chromium/net/cert/x509_cert_types.h
index 3317d93adfe..b5c42777309 100644
--- a/chromium/net/cert/x509_cert_types.h
+++ b/chromium/net/cert/x509_cert_types.h
@@ -13,7 +13,6 @@
#include <string>
#include <vector>
-#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "net/base/hash_value.h"
diff --git a/chromium/net/cert/x509_util.cc b/chromium/net/cert/x509_util.cc
index 90b848da6ab..4ebef1754b0 100644
--- a/chromium/net/cert/x509_util.cc
+++ b/chromium/net/cert/x509_util.cc
@@ -10,6 +10,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
diff --git a/chromium/net/cert/x509_util_ios_and_mac.cc b/chromium/net/cert/x509_util_ios_and_mac.cc
index 8e41cd87cd0..4d503de1414 100644
--- a/chromium/net/cert/x509_util_ios_and_mac.cc
+++ b/chromium/net/cert/x509_util_ios_and_mac.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_util_ios_and_mac.h"
+#include "base/logging.h"
#include "net/cert/x509_certificate.h"
#if defined(OS_IOS)
#include "net/cert/x509_util_ios.h"
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index e87937435d9..68fa41779bb 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -105,16 +105,6 @@ void AppendCookieLineEntry(const CanonicalCookie& cookie,
*cookie_line += cookie.Value();
}
-uint32_t GetExclusionBitmask(
- CanonicalCookie::CookieInclusionStatus::ExclusionReason reason) {
- return 1u << static_cast<uint32_t>(reason);
-}
-
-uint32_t GetWarningBitmask(
- CanonicalCookie::CookieInclusionStatus::WarningReason reason) {
- return 1u << static_cast<uint32_t>(reason);
-}
-
// Captures Strict -> Lax context downgrade with Strict cookie
bool IsBreakingStrictToLaxDowngrade(
CookieOptions::SameSiteCookieContext::ContextType context,
@@ -198,13 +188,13 @@ void ApplySameSiteCookieWarningToStatus(
CookieEffectiveSameSite effective_samesite,
bool is_secure,
CookieOptions::SameSiteCookieContext same_site_context,
- CanonicalCookie::CookieInclusionStatus* status,
+ CookieInclusionStatus* status,
bool is_cookie_being_set) {
if (samesite == CookieSameSite::UNSPECIFIED &&
same_site_context.GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
}
if (effective_samesite == CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE &&
same_site_context.GetContextForCookieInclusion() ==
@@ -213,14 +203,13 @@ void ApplySameSiteCookieWarningToStatus(
// This warning is more specific so remove the previous, more general,
// warning.
status->RemoveWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
}
if (samesite == CookieSameSite::NO_RESTRICTION && !is_secure) {
status->AddWarningReason(
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
}
// Add a warning if the cookie would be accessible in
@@ -229,19 +218,19 @@ void ApplySameSiteCookieWarningToStatus(
if (IsBreakingStrictToLaxDowngrade(same_site_context.context(),
same_site_context.schemeful_context(),
effective_samesite, is_cookie_being_set)) {
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
} else if (IsBreakingStrictToCrossDowngrade(
same_site_context.context(),
same_site_context.schemeful_context(), effective_samesite)) {
// Which warning to apply depends on the SameSite value.
if (effective_samesite == CookieEffectiveSameSite::STRICT_MODE) {
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
} else {
// LAX_MODE or LAX_MODE_ALLOW_UNSAFE.
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
}
} else if (IsBreakingLaxToCrossDowngrade(
@@ -250,13 +239,13 @@ void ApplySameSiteCookieWarningToStatus(
is_cookie_being_set)) {
// Which warning to apply depends on the SameSite value.
if (effective_samesite == CookieEffectiveSameSite::STRICT_MODE) {
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
} else {
// LAX_MODE or LAX_MODE_ALLOW_UNSAFE.
// This warning applies to both set/send.
- status->AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
+ status->AddWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
}
}
@@ -581,11 +570,10 @@ bool CanonicalCookie::IsDomainMatch(const std::string& host) const {
return cookie_util::IsDomainMatch(domain_, host);
}
-CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
+CookieAccessResult CanonicalCookie::IncludeForRequestURL(
const GURL& url,
const CookieOptions& options,
CookieAccessSemantics access_semantics) const {
- base::TimeDelta cookie_age = base::Time::Now() - CreationDate();
CookieInclusionStatus status;
// Filter out HttpOnly cookies, per options.
if (options.exclude_httponly() && IsHttpOnly())
@@ -627,17 +615,6 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
case CookieEffectiveSameSite::LAX_MODE:
if (options.same_site_cookie_context().GetContextForCookieInclusion() <
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX) {
- // Log metrics for a cookie that would have been included under the
- // "Lax-allow-unsafe" intervention, had it been new enough.
- if (SameSite() == CookieSameSite::UNSPECIFIED &&
- options.same_site_cookie_context().GetContextForCookieInclusion() ==
- CookieOptions::SameSiteCookieContext::ContextType::
- SAME_SITE_LAX_METHOD_UNSAFE) {
- UMA_HISTOGRAM_CUSTOM_TIMES(
- "Cookie.SameSiteUnspecifiedTooOldToAllowUnsafe", cookie_age,
- base::TimeDelta::FromMinutes(1), base::TimeDelta::FromDays(5),
- 100);
- }
status.AddExclusionReason(
(SameSite() == CookieSameSite::UNSPECIFIED)
? CookieInclusionStatus::
@@ -654,15 +631,6 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
// TODO(chlily): Do we need a separate CookieInclusionStatus for this?
status.AddExclusionReason(
CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
- } else if (options.same_site_cookie_context()
- .GetContextForCookieInclusion() ==
- CookieOptions::SameSiteCookieContext::ContextType::
- SAME_SITE_LAX_METHOD_UNSAFE) {
- // Log metrics for cookies that activate the "Lax-allow-unsafe"
- // intervention. This histogram macro allows up to 3 minutes, which is
- // enough for the current threshold of 2 minutes.
- UMA_HISTOGRAM_MEDIUM_TIMES("Cookie.LaxAllowUnsafeCookieIncludedAge",
- cookie_age);
}
break;
default:
@@ -700,10 +668,10 @@ CanonicalCookie::CookieInclusionStatus CanonicalCookie::IncludeForRequestURL(
}
// TODO(chlily): Log metrics.
- return status;
+ return CookieAccessResult(effective_same_site, status);
}
-CanonicalCookie::CookieInclusionStatus CanonicalCookie::IsSetPermittedInContext(
+CookieInclusionStatus CanonicalCookie::IsSetPermittedInContext(
const CookieOptions& options,
CookieAccessSemantics access_semantics) const {
CookieInclusionStatus status;
@@ -730,7 +698,7 @@ void CanonicalCookie::IsSetPermittedInContext(
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() rejecting insecure cookie with SameSite=None.";
status->AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE);
+ CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE);
}
// Log whether a SameSite=None cookie is Secure or not.
if (SameSite() == CookieSameSite::NO_RESTRICTION) {
@@ -867,10 +835,10 @@ std::string CanonicalCookie::BuildCookieLine(const CookieList& cookies) {
// static
std::string CanonicalCookie::BuildCookieLine(
- const CookieStatusList& cookie_status_list) {
+ const CookieAccessResultList& cookie_access_result_list) {
std::string cookie_line;
- for (const auto& cookie_with_status : cookie_status_list) {
- const CanonicalCookie& cookie = cookie_with_status.cookie;
+ for (const auto& cookie_with_access_result : cookie_access_result_list) {
+ const CanonicalCookie& cookie = cookie_with_access_result.cookie;
AppendCookieLineEntry(cookie, &cookie_line);
}
return cookie_line;
@@ -973,289 +941,12 @@ bool CanonicalCookie::IsRecentlyCreated(base::TimeDelta age_threshold) const {
return (base::Time::Now() - creation_date_) <= age_threshold;
}
-CanonicalCookie::CookieInclusionStatus::CookieInclusionStatus()
- : exclusion_reasons_(0u), warning_reasons_(0u) {}
-
-CanonicalCookie::CookieInclusionStatus::CookieInclusionStatus(
- ExclusionReason reason)
- : exclusion_reasons_(GetExclusionBitmask(reason)) {}
-
-CanonicalCookie::CookieInclusionStatus::CookieInclusionStatus(
- ExclusionReason reason,
- WarningReason warning)
- : exclusion_reasons_(GetExclusionBitmask(reason)),
- warning_reasons_(GetWarningBitmask(warning)) {}
-
-bool CanonicalCookie::CookieInclusionStatus::operator==(
- const CookieInclusionStatus& other) const {
- return exclusion_reasons_ == other.exclusion_reasons_ &&
- warning_reasons_ == other.warning_reasons_;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::operator!=(
- const CookieInclusionStatus& other) const {
- return !operator==(other);
-}
-
-bool CanonicalCookie::CookieInclusionStatus::IsInclude() const {
- return exclusion_reasons_ == 0u;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::HasExclusionReason(
- ExclusionReason reason) const {
- return exclusion_reasons_ & GetExclusionBitmask(reason);
-}
-
-void CanonicalCookie::CookieInclusionStatus::AddExclusionReason(
- ExclusionReason reason) {
- exclusion_reasons_ |= GetExclusionBitmask(reason);
- // If the cookie would be excluded for reasons other than the new SameSite
- // rules, don't bother warning about it.
- MaybeClearSameSiteWarning();
-}
-
-void CanonicalCookie::CookieInclusionStatus::RemoveExclusionReason(
- ExclusionReason reason) {
- exclusion_reasons_ &= ~(GetExclusionBitmask(reason));
-}
-
-void CanonicalCookie::CookieInclusionStatus::MaybeClearSameSiteWarning() {
- uint32_t samesite_reasons_mask =
- GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX) |
- GetExclusionBitmask(EXCLUDE_SAMESITE_NONE_INSECURE);
- if (exclusion_reasons_ & ~samesite_reasons_mask) {
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- RemoveWarningReason(
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
- }
-
- uint32_t context_reasons_mask =
- GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
- GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
- GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
- if (exclusion_reasons_ & ~context_reasons_mask) {
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
- RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
- }
-}
-
-bool CanonicalCookie::CookieInclusionStatus::ShouldRecordDowngradeMetrics()
- const {
- uint32_t context_reasons_mask =
- GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
- GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
- GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
-
- return (exclusion_reasons_ & ~context_reasons_mask) == 0u;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::ShouldWarn() const {
- return warning_reasons_ != 0u;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::HasWarningReason(
- WarningReason reason) const {
- return warning_reasons_ & GetWarningBitmask(reason);
-}
-
-bool net::CanonicalCookie::CookieInclusionStatus::HasDowngradeWarning(
- CookieInclusionStatus::WarningReason* reason) const {
- if (!ShouldWarn())
- return false;
-
- const CookieInclusionStatus::WarningReason kDowngradeWarnings[] = {
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
- };
-
- for (auto warning : kDowngradeWarnings) {
- if (!HasWarningReason(warning))
- continue;
-
- if (reason)
- *reason = warning;
-
- return true;
- }
-
- return false;
-}
-
-void CanonicalCookie::CookieInclusionStatus::AddWarningReason(
- WarningReason reason) {
- warning_reasons_ |= GetWarningBitmask(reason);
-}
-
-void CanonicalCookie::CookieInclusionStatus::RemoveWarningReason(
- WarningReason reason) {
- warning_reasons_ &= ~(GetWarningBitmask(reason));
-}
-
-CanonicalCookie::CookieInclusionStatus::ContextDowngradeMetricValues
-CanonicalCookie::CookieInclusionStatus::GetBreakingDowngradeMetricsEnumValue(
- const GURL& url) const {
- bool url_is_secure = url.SchemeIsCryptographic();
-
- // Start the |reason| as something other than the downgrade warnings.
- WarningReason reason = WarningReason::NUM_WARNING_REASONS;
-
- // Don't bother checking the return value because the default switch case
- // will handle if no reason was found.
- HasDowngradeWarning(&reason);
-
- switch (reason) {
- case WarningReason::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE:
- return url_is_secure
- ? ContextDowngradeMetricValues::STRICT_LAX_STRICT_SECURE
- : ContextDowngradeMetricValues::STRICT_LAX_STRICT_INSECURE;
- case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE:
- return url_is_secure
- ? ContextDowngradeMetricValues::STRICT_CROSS_STRICT_SECURE
- : ContextDowngradeMetricValues::STRICT_CROSS_STRICT_INSECURE;
- case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE:
- return url_is_secure
- ? ContextDowngradeMetricValues::STRICT_CROSS_LAX_SECURE
- : ContextDowngradeMetricValues::STRICT_CROSS_LAX_INSECURE;
- case WarningReason::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE:
- return url_is_secure
- ? ContextDowngradeMetricValues::LAX_CROSS_STRICT_SECURE
- : ContextDowngradeMetricValues::LAX_CROSS_STRICT_INSECURE;
- case WarningReason::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE:
- return url_is_secure
- ? ContextDowngradeMetricValues::LAX_CROSS_LAX_SECURE
- : ContextDowngradeMetricValues::LAX_CROSS_LAX_INSECURE;
- default:
- return url_is_secure
- ? ContextDowngradeMetricValues::NO_DOWNGRADE_SECURE
- : ContextDowngradeMetricValues::NO_DOWNGRADE_INSECURE;
- }
-}
-
-std::string CanonicalCookie::CookieInclusionStatus::GetDebugString() const {
- std::string out;
-
- // Inclusion/exclusion
- if (IsInclude())
- base::StrAppend(&out, {"INCLUDE, "});
- if (HasExclusionReason(EXCLUDE_UNKNOWN_ERROR))
- base::StrAppend(&out, {"EXCLUDE_UNKNOWN_ERROR, "});
- if (HasExclusionReason(EXCLUDE_HTTP_ONLY))
- base::StrAppend(&out, {"EXCLUDE_HTTP_ONLY, "});
- if (HasExclusionReason(EXCLUDE_SECURE_ONLY))
- base::StrAppend(&out, {"EXCLUDE_SECURE_ONLY, "});
- if (HasExclusionReason(EXCLUDE_DOMAIN_MISMATCH))
- base::StrAppend(&out, {"EXCLUDE_DOMAIN_MISMATCH, "});
- if (HasExclusionReason(EXCLUDE_NOT_ON_PATH))
- base::StrAppend(&out, {"EXCLUDE_NOT_ON_PATH, "});
- if (HasExclusionReason(EXCLUDE_SAMESITE_STRICT))
- base::StrAppend(&out, {"EXCLUDE_SAMESITE_STRICT, "});
- if (HasExclusionReason(EXCLUDE_SAMESITE_LAX))
- base::StrAppend(&out, {"EXCLUDE_SAMESITE_LAX, "});
- if (HasExclusionReason(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX))
- base::StrAppend(&out, {"EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX, "});
- if (HasExclusionReason(EXCLUDE_SAMESITE_NONE_INSECURE))
- base::StrAppend(&out, {"EXCLUDE_SAMESITE_NONE_INSECURE, "});
- if (HasExclusionReason(EXCLUDE_USER_PREFERENCES))
- base::StrAppend(&out, {"EXCLUDE_USER_PREFERENCES, "});
- if (HasExclusionReason(EXCLUDE_FAILURE_TO_STORE))
- base::StrAppend(&out, {"EXCLUDE_FAILURE_TO_STORE, "});
- if (HasExclusionReason(EXCLUDE_NONCOOKIEABLE_SCHEME))
- base::StrAppend(&out, {"EXCLUDE_NONCOOKIEABLE_SCHEME, "});
- if (HasExclusionReason(EXCLUDE_OVERWRITE_SECURE))
- base::StrAppend(&out, {"EXCLUDE_OVERWRITE_SECURE, "});
- if (HasExclusionReason(EXCLUDE_OVERWRITE_HTTP_ONLY))
- base::StrAppend(&out, {"EXCLUDE_OVERWRITE_HTTP_ONLY, "});
- if (HasExclusionReason(EXCLUDE_INVALID_DOMAIN))
- base::StrAppend(&out, {"EXCLUDE_INVALID_DOMAIN, "});
- if (HasExclusionReason(EXCLUDE_INVALID_PREFIX))
- base::StrAppend(&out, {"EXCLUDE_INVALID_PREFIX, "});
-
- // Add warning
- if (!ShouldWarn()) {
- base::StrAppend(&out, {"DO_NOT_WARN"});
- return out;
- }
-
- if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT))
- base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT, "});
- if (HasWarningReason(WARN_SAMESITE_NONE_INSECURE))
- base::StrAppend(&out, {"WARN_SAMESITE_NONE_INSECURE, "});
- if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE))
- base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE, "});
- if (HasWarningReason(WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE))
- base::StrAppend(&out, {"WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE, "});
- if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE))
- base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
- if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE))
- base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE, "});
- if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE))
- base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
- if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE))
- base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE, "});
-
- // Strip trailing comma and space.
- out.erase(out.end() - 2, out.end());
-
- return out;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::IsValid() const {
- // Bit positions where there should not be any true bits.
- uint32_t exclusion_mask = ~0u << static_cast<int>(NUM_EXCLUSION_REASONS);
- uint32_t warning_mask = ~0u << static_cast<int>(NUM_WARNING_REASONS);
- return (exclusion_mask & exclusion_reasons_) == 0u &&
- (warning_mask & warning_reasons_) == 0u;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::
- HasExactlyExclusionReasonsForTesting(
- std::vector<CanonicalCookie::CookieInclusionStatus::ExclusionReason>
- reasons) const {
- CookieInclusionStatus expected = MakeFromReasonsForTesting(reasons);
- return expected.exclusion_reasons_ == exclusion_reasons_;
-}
-
-bool CanonicalCookie::CookieInclusionStatus::HasExactlyWarningReasonsForTesting(
- std::vector<WarningReason> reasons) const {
- CookieInclusionStatus expected = MakeFromReasonsForTesting({}, reasons);
- return expected.warning_reasons_ == warning_reasons_;
-}
-
-// static
-CanonicalCookie::CookieInclusionStatus
-CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<ExclusionReason> reasons,
- std::vector<WarningReason> warnings) {
- CookieInclusionStatus status;
- for (ExclusionReason reason : reasons) {
- status.AddExclusionReason(reason);
- }
- for (WarningReason warning : warnings) {
- status.AddWarningReason(warning);
- }
- return status;
-}
-
CookieAndLineWithStatus::CookieAndLineWithStatus() = default;
CookieAndLineWithStatus::CookieAndLineWithStatus(
base::Optional<CanonicalCookie> cookie,
std::string cookie_string,
- CanonicalCookie::CookieInclusionStatus status)
+ CookieInclusionStatus status)
: cookie(std::move(cookie)),
cookie_string(std::move(cookie_string)),
status(status) {}
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index 10b66c661b2..aa538085ac8 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -14,7 +14,9 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
+#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_constants.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_options.h"
class GURL;
@@ -25,15 +27,16 @@ class ParsedCookie;
class CanonicalCookie;
struct CookieWithStatus;
+struct CookieWithAccessResult;
struct CookieAndLineWithStatus;
using CookieList = std::vector<CanonicalCookie>;
using CookieStatusList = std::vector<CookieWithStatus>;
using CookieAndLineStatusList = std::vector<CookieAndLineWithStatus>;
+using CookieAccessResultList = std::vector<CookieWithAccessResult>;
class NET_EXPORT CanonicalCookie {
public:
- class CookieInclusionStatus;
using UniqueCookieKey = std::tuple<std::string, std::string, std::string>;
CanonicalCookie();
@@ -228,7 +231,7 @@ class NET_EXPORT CanonicalCookie {
// request |url| using the CookieInclusionStatus enum. HTTP only cookies can
// be filter by using appropriate cookie |options|. PLEASE NOTE that this
// method does not check whether a cookie is expired or not!
- CookieInclusionStatus IncludeForRequestURL(
+ CookieAccessResult IncludeForRequestURL(
const GURL& url,
const CookieOptions& options,
CookieAccessSemantics access_semantics =
@@ -294,8 +297,9 @@ class NET_EXPORT CanonicalCookie {
// by |cookies|. The string is built in the same order as the given list.
static std::string BuildCookieLine(const CookieList& cookies);
- // Same as above but takes a CookieStatusList (ignores the statuses).
- static std::string BuildCookieLine(const CookieStatusList& cookies);
+ // Same as above but takes a CookieAccessResultList
+ // (ignores the access result).
+ static std::string BuildCookieLine(const CookieAccessResultList& cookies);
private:
FRIEND_TEST_ALL_PREFIXES(CanonicalCookieTest, TestPrefixHistograms);
@@ -358,250 +362,11 @@ class NET_EXPORT CanonicalCookie {
CookieSourceScheme source_scheme_;
};
-// This class represents if a cookie was included or excluded in a cookie get or
-// set operation, and if excluded why. It holds a vector of reasons for
-// exclusion, where cookie inclusion is represented by the absence of any
-// exclusion reasons. Also marks whether a cookie should be warned about, e.g.
-// for deprecation or intervention reasons.
-// TODO(chlily): Rename/move this to just net::CookieInclusionStatus.
-class NET_EXPORT CanonicalCookie::CookieInclusionStatus {
- public:
- // Types of reasons why a cookie might be excluded.
- // If adding a ExclusionReason, please also update the GetDebugString()
- // method.
- enum ExclusionReason {
- EXCLUDE_UNKNOWN_ERROR = 0,
-
- EXCLUDE_HTTP_ONLY = 1,
- EXCLUDE_SECURE_ONLY = 2,
- EXCLUDE_DOMAIN_MISMATCH = 3,
- EXCLUDE_NOT_ON_PATH = 4,
- EXCLUDE_SAMESITE_STRICT = 5,
- EXCLUDE_SAMESITE_LAX = 6,
-
- // The following two are used for the SameSiteByDefaultCookies experiment,
- // where if the SameSite attribute is not specified, it will be treated as
- // SameSite=Lax by default.
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX = 7,
- // This is used if SameSite=None is specified, but the cookie is not
- // Secure.
- EXCLUDE_SAMESITE_NONE_INSECURE = 8,
- EXCLUDE_USER_PREFERENCES = 9,
-
- // Statuses specific to setting cookies
- EXCLUDE_FAILURE_TO_STORE = 10,
- EXCLUDE_NONCOOKIEABLE_SCHEME = 11,
- EXCLUDE_OVERWRITE_SECURE = 12,
- EXCLUDE_OVERWRITE_HTTP_ONLY = 13,
- EXCLUDE_INVALID_DOMAIN = 14,
- EXCLUDE_INVALID_PREFIX = 15,
-
- // This should be kept last.
- NUM_EXCLUSION_REASONS
- };
-
- // Reason to warn about a cookie. If you add one, please update
- // GetDebugString().
- enum WarningReason {
- // Of the following 3 SameSite warnings, there will be, at most, a single
- // active one.
-
- // Warn if a cookie with unspecified SameSite attribute is used in a
- // cross-site context.
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT = 0,
- // Warn if a cookie with SameSite=None is not Secure.
- WARN_SAMESITE_NONE_INSECURE = 1,
- // Warn if a cookie with unspecified SameSite attribute is defaulted into
- // Lax and is sent on a request with unsafe method, only because it is new
- // enough to activate the Lax-allow-unsafe intervention.
- WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE = 2,
-
- // The following warnings indicate that an included cookie with an effective
- // SameSite is experiencing a SameSiteCookieContext::|context| ->
- // SameSiteCookieContext::|schemeful_context| downgrade that will prevent
- // its access schemefully.
- // This situation means that a cookie is accessible when the
- // SchemefulSameSite feature is disabled but not when it's enabled,
- // indicating changed behavior and potential breakage.
- //
- // For example, a Strict to Lax downgrade for an effective SameSite=Strict
- // cookie:
- // This cookie would be accessible in the Strict context as its SameSite
- // value is Strict. However its context for schemeful same-site becomes Lax.
- // A strict cookie cannot be accessed in a Lax context and therefore the
- // behavior has changed.
- // As a counterexample, a Strict to Lax downgrade for an effective
- // SameSite=Lax cookie: A Lax cookie can be accessed in both Strict and Lax
- // contexts so there is no behavior change (and we don't warn about it).
- //
- // The warnings are in the following format:
- // WARN_{context}_{schemeful_context}_DOWNGRADE_{samesite_value}_SAMESITE
- //
- // Of the following 5 SameSite warnings, there will be, at most, a single
- // active one.
-
- // Strict to Lax downgrade for an effective SameSite=Strict cookie.
- // This warning is only applicable for cookies being sent because a Strict
- // cookie will be set in both Strict and Lax Contexts so the downgrade will
- // not affect it.
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE = 3,
- // Strict to Cross-site downgrade for an effective SameSite=Strict cookie.
- // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
- // behaving like Cross-site.
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE = 4,
- // Strict to Cross-site downgrade for an effective SameSite=Lax cookie.
- // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
- // behaving like Cross-site.
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE = 5,
- // Lax to Cross-site downgrade for an effective SameSite=Strict cookie.
- // This warning is only applicable for cookies being set because a Strict
- // cookie will not be sent in a Lax context so the downgrade would not
- // affect it.
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE = 6,
- // Lax to Cross-site downgrade for an effective SameSite=Lax cookie.
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE = 7,
-
- // This should be kept last.
- NUM_WARNING_REASONS
- };
-
- // These enums encode the context downgrade warnings + the secureness of the
- // url sending/setting the cookie. They're used for metrics only. The format
- // is {context}_{schemeful_context}_{samesite_value}_{securness}.
- // NO_DOWNGRADE_{securness} indicates that a cookie didn't have a breaking
- // context downgrade and was A) included B) excluded only due to insufficient
- // same-site context. I.e. the cookie wasn't excluded due to other reasons
- // such as third-party cookie blocking. Keep this in line with
- // SameSiteCookieContextBreakingDowngradeWithSecureness in enums.xml.
- enum ContextDowngradeMetricValues {
- NO_DOWNGRADE_INSECURE = 0,
- NO_DOWNGRADE_SECURE = 1,
-
- STRICT_LAX_STRICT_INSECURE = 2,
- STRICT_CROSS_STRICT_INSECURE = 3,
- STRICT_CROSS_LAX_INSECURE = 4,
- LAX_CROSS_STRICT_INSECURE = 5,
- LAX_CROSS_LAX_INSECURE = 6,
-
- STRICT_LAX_STRICT_SECURE = 7,
- STRICT_CROSS_STRICT_SECURE = 8,
- STRICT_CROSS_LAX_SECURE = 9,
- LAX_CROSS_STRICT_SECURE = 10,
- LAX_CROSS_LAX_SECURE = 11,
-
- // Keep last.
- kMaxValue = LAX_CROSS_LAX_SECURE
- };
- // Makes a status that says include and should not warn.
- CookieInclusionStatus();
-
- // Make a status that contains the given exclusion reason.
- explicit CookieInclusionStatus(ExclusionReason reason);
- // Makes a status that contains the given exclusion reason and warning.
- CookieInclusionStatus(ExclusionReason reason, WarningReason warning);
-
- bool operator==(const CookieInclusionStatus& other) const;
- bool operator!=(const CookieInclusionStatus& other) const;
-
- // Whether the status is to include the cookie, and has no other reasons for
- // exclusion.
- bool IsInclude() const;
-
- // Whether the given reason for exclusion is present.
- bool HasExclusionReason(ExclusionReason status_type) const;
-
- // Add an exclusion reason.
- void AddExclusionReason(ExclusionReason status_type);
-
- // Remove an exclusion reason.
- void RemoveExclusionReason(ExclusionReason reason);
-
- // If the cookie would have been excluded for reasons other than
- // SAMESITE_UNSPECIFIED_TREATED_AS_LAX or SAMESITE_NONE_INSECURE, don't bother
- // warning about it (clear the warning).
- void MaybeClearSameSiteWarning();
-
- // Whether to record the breaking downgrade metrics if the cookie is included
- // or if it's only excluded because of insufficient same-site context.
- bool ShouldRecordDowngradeMetrics() const;
-
- // Whether the cookie should be warned about.
- bool ShouldWarn() const;
-
- // Whether the given reason for warning is present.
- bool HasWarningReason(WarningReason reason) const;
-
- // Whether a schemeful downgrade warning is present.
- // A schemeful downgrade means that an included cookie with an effective
- // SameSite is experiencing a SameSiteCookieContext::|context| ->
- // SameSiteCookieContext::|schemeful_context| downgrade that will prevent its
- // access schemefully. If the function returns true and |reason| is valid then
- // |reason| will contain which warning was found.
- bool HasDowngradeWarning(
- CookieInclusionStatus::WarningReason* reason = nullptr) const;
-
- // Add an warning reason.
- void AddWarningReason(WarningReason reason);
-
- // Remove an warning reason.
- void RemoveWarningReason(WarningReason reason);
-
- // Used for serialization/deserialization.
- uint32_t exclusion_reasons() const { return exclusion_reasons_; }
- void set_exclusion_reasons(uint32_t exclusion_reasons) {
- exclusion_reasons_ = exclusion_reasons;
- }
-
- uint32_t warning_reasons() const { return warning_reasons_; }
- void set_warning_reasons(uint32_t warning_reasons) {
- warning_reasons_ = warning_reasons;
- }
-
- ContextDowngradeMetricValues GetBreakingDowngradeMetricsEnumValue(
- const GURL& url) const;
-
- // Get exclusion reason(s) and warning in string format.
- std::string GetDebugString() const;
-
- // Checks that the underlying bit vector representation doesn't contain any
- // extraneous bits that are not mapped to any enum values. Does not check
- // for reasons which semantically cannot coexist.
- bool IsValid() const;
-
- // Checks whether the exclusion reasons are exactly the set of exclusion
- // reasons in the vector. (Ignores warnings.)
- bool HasExactlyExclusionReasonsForTesting(
- std::vector<ExclusionReason> reasons) const;
-
- // Checks whether the warning reasons are exactly the set of warning
- // reasons in the vector. (Ignores exclusions.)
- bool HasExactlyWarningReasonsForTesting(
- std::vector<WarningReason> reasons) const;
-
- // Makes a status that contains the given exclusion reasons and warning.
- static CookieInclusionStatus MakeFromReasonsForTesting(
- std::vector<ExclusionReason> reasons,
- std::vector<WarningReason> warnings = std::vector<WarningReason>());
-
- private:
- // A bit vector of the applicable exclusion reasons.
- uint32_t exclusion_reasons_ = 0u;
-
- // A bit vector of the applicable warning reasons.
- uint32_t warning_reasons_ = 0u;
-};
-
-NET_EXPORT inline std::ostream& operator<<(
- std::ostream& os,
- const CanonicalCookie::CookieInclusionStatus status) {
- return os << status.GetDebugString();
-}
-
// These enable us to pass along a list of excluded cookie with the reason they
// were excluded
struct CookieWithStatus {
CanonicalCookie cookie;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
};
// Used to pass excluded cookie information when it's possible that the
@@ -610,7 +375,7 @@ struct NET_EXPORT CookieAndLineWithStatus {
CookieAndLineWithStatus();
CookieAndLineWithStatus(base::Optional<CanonicalCookie> cookie,
std::string cookie_string,
- CanonicalCookie::CookieInclusionStatus status);
+ CookieInclusionStatus status);
CookieAndLineWithStatus(
const CookieAndLineWithStatus& cookie_and_line_with_status);
@@ -624,7 +389,12 @@ struct NET_EXPORT CookieAndLineWithStatus {
base::Optional<CanonicalCookie> cookie;
std::string cookie_string;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
+};
+
+struct CookieWithAccessResult {
+ CanonicalCookie cookie;
+ CookieAccessResult access_result;
};
} // namespace net
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 68548deed97..77465c83b92 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -125,7 +125,7 @@ TEST(CanonicalCookieTest, Create) {
// Test creating secure cookies. Secure scheme is not checked upon creation,
// so a URL of any scheme can create a Secure cookie.
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
cookie = CanonicalCookie::Create(url, "A=2; Secure", creation_time,
server_time, &status);
EXPECT_TRUE(cookie->IsSecure());
@@ -218,7 +218,7 @@ TEST(CanonicalCookieTest, CreateHttpOnly) {
GURL url("http://www.example.com/test/foo.html");
base::Time now = base::Time::Now();
base::Optional<base::Time> server_time = base::nullopt;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// An HttpOnly cookie can be created.
std::unique_ptr<CanonicalCookie> cookie =
@@ -231,13 +231,13 @@ TEST(CanonicalCookieTest, CreateWithInvalidDomain) {
GURL url("http://www.example.com/test/foo.html");
base::Time now = base::Time::Now();
base::Optional<base::Time> server_time = base::nullopt;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
url, "A=2; Domain=wrongdomain.com", now, server_time, &status);
EXPECT_EQ(nullptr, cookie.get());
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
}
TEST(CanonicalCookieTest, EmptyExpiry) {
@@ -656,50 +656,47 @@ TEST(CanonicalCookieTest, IncludeForRequestURL) {
std::unique_ptr<CanonicalCookie> cookie(
CanonicalCookie::Create(url, "A=2", creation_time, server_time));
- EXPECT_TRUE(cookie->IncludeForRequestURL(url, options).IsInclude());
+ EXPECT_TRUE(cookie->IncludeForRequestURL(url, options).status.IsInclude());
EXPECT_TRUE(cookie
->IncludeForRequestURL(GURL("http://www.example.com/foo/bar"),
options)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(cookie
->IncludeForRequestURL(
GURL("https://www.example.com/foo/bar"), options)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(
cookie->IncludeForRequestURL(GURL("https://sub.example.com"), options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_DOMAIN_MISMATCH}));
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
EXPECT_TRUE(
cookie->IncludeForRequestURL(GURL("https://sub.www.example.com"), options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_DOMAIN_MISMATCH}));
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
// Test that cookie with a cookie path that does not match the url path are
// not included.
cookie = CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time,
server_time);
- EXPECT_TRUE(
- cookie->IncludeForRequestURL(url, options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
+ EXPECT_TRUE(cookie->IncludeForRequestURL(url, options)
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
EXPECT_TRUE(
cookie
->IncludeForRequestURL(
GURL("http://www.example.com/foo/bar/index.html"), options)
- .IsInclude());
+ .status.IsInclude());
// Test that a secure cookie is not included for a non secure URL.
GURL secure_url("https://www.example.com");
cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
server_time);
EXPECT_TRUE(cookie->IsSecure());
- EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options).IsInclude());
EXPECT_TRUE(
- cookie->IncludeForRequestURL(url, options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ cookie->IncludeForRequestURL(secure_url, options).status.IsInclude());
+ EXPECT_TRUE(cookie->IncludeForRequestURL(url, options)
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
// Test that http only cookies are only included if the include httponly flag
// is set on the cookie options.
@@ -707,12 +704,11 @@ TEST(CanonicalCookieTest, IncludeForRequestURL) {
cookie =
CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time);
EXPECT_TRUE(cookie->IsHttpOnly());
- EXPECT_TRUE(cookie->IncludeForRequestURL(url, options).IsInclude());
+ EXPECT_TRUE(cookie->IncludeForRequestURL(url, options).status.IsInclude());
options.set_exclude_httponly();
- EXPECT_TRUE(
- cookie->IncludeForRequestURL(url, options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
+ EXPECT_TRUE(cookie->IncludeForRequestURL(url, options)
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
}
struct IncludeForRequestURLTestCase {
@@ -720,7 +716,7 @@ struct IncludeForRequestURLTestCase {
CookieSameSite expected_samesite;
CookieEffectiveSameSite expected_effective_samesite;
CookieOptions::SameSiteCookieContext request_options_samesite_context;
- CanonicalCookie::CookieInclusionStatus expected_inclusion_status;
+ CookieInclusionStatus expected_inclusion_status;
base::TimeDelta creation_time_delta = base::TimeDelta();
};
@@ -742,16 +738,16 @@ void VerifyIncludeForRequestURLTestCases(
std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
url, test.cookie_line, creation_time, base::nullopt /* server_time */);
EXPECT_EQ(test.expected_samesite, cookie->SameSite());
- EXPECT_EQ(test.expected_effective_samesite,
- cookie->GetEffectiveSameSiteForTesting(access_semantics));
CookieOptions request_options;
request_options.set_same_site_cookie_context(
test.request_options_samesite_context);
+ net::CookieAccessResult access_result =
+ cookie->IncludeForRequestURL(url, request_options, access_semantics);
- EXPECT_EQ(
- test.expected_inclusion_status,
- cookie->IncludeForRequestURL(url, request_options, access_semantics));
+ EXPECT_EQ(test.expected_inclusion_status, access_result.status);
+ EXPECT_EQ(test.expected_effective_samesite,
+ access_result.effective_same_site);
}
}
@@ -770,131 +766,116 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
{"Common=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
{"Common=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
{"Common=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
{"Common=4;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
// Strict cookies with downgrade:
{"Common=5;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
{"Common=6;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
{"Common=7;SameSite=Strict", CookieSameSite::STRICT_MODE,
CookieEffectiveSameSite::STRICT_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
// Lax cookies:
{"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
{"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
+ CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
{"Common=10;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"Common=11;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
// Lax cookies with downgrade:
{"Common=12;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"Common=13;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
{"Common=14;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
{"Common=15;SameSite=Lax", CookieSameSite::LAX_MODE,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
// None and Secure cookies:
{"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"Common=19;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus()}};
+ CookieInclusionStatus()}};
// Test cases where the default is None (either access semantics is LEGACY, or
// semantics is UNKNOWN and feature is enabled):
@@ -903,29 +884,27 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
{"DefaultNone=1", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
{"DefaultNone=2", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
{"DefaultNone=3", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus()},
+ CookieInclusionStatus()},
{"DefaultNone=4", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::NO_RESTRICTION,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus()}};
+ CookieInclusionStatus()}};
// Test cases where the default is Lax (either access semantics is NONLEGACY,
// or access semantics is UNKNOWN and feature is enabled):
@@ -934,60 +913,52 @@ TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
{"DefaultLax=1", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
+ CookieInclusionStatus(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
kShortAge},
{"DefaultLax=2", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE}),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE}),
kShortAge},
{"DefaultLax=3", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus(), kShortAge},
+ CookieInclusionStatus(), kShortAge},
{"DefaultLax=4", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus(), kShortAge},
+ CookieInclusionStatus(), kShortAge},
// Unspecified not-recently-created cookies (with SameSite-by-default):
{"DefaultLax=5", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
+ CookieInclusionStatus(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
kLongAge},
{"DefaultLax=6", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
+ CookieInclusionStatus(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
kLongAge},
{"DefaultLax=7", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
- CanonicalCookie::CookieInclusionStatus(), kLongAge},
+ CookieInclusionStatus(), kLongAge},
{"DefaultLax=8", CookieSameSite::UNSPECIFIED,
CookieEffectiveSameSite::LAX_MODE,
SameSiteCookieContext(
SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
- CanonicalCookie::CookieInclusionStatus(), kLongAge},
+ CookieInclusionStatus(), kLongAge},
};
VerifyIncludeForRequestURLTestCases(true, CookieAccessSemantics::UNKNOWN,
@@ -1046,19 +1017,18 @@ TEST(CanonicalCookieTest, IncludeCookiesWithoutSameSiteMustBeSecure) {
EXPECT_TRUE(
cookie
->IncludeForRequestURL(url, options, CookieAccessSemantics::UNKNOWN)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_NONE_INSECURE}));
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
EXPECT_TRUE(
cookie
->IncludeForRequestURL(url, options, CookieAccessSemantics::LEGACY)
- .IsInclude());
- EXPECT_TRUE(cookie
- ->IncludeForRequestURL(url, options,
- CookieAccessSemantics::NONLEGACY)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_NONE_INSECURE}));
+ .status.IsInclude());
+ EXPECT_TRUE(
+ cookie
+ ->IncludeForRequestURL(url, options,
+ CookieAccessSemantics::NONLEGACY)
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
}
// Features off:
{
@@ -1072,17 +1042,17 @@ TEST(CanonicalCookieTest, IncludeCookiesWithoutSameSiteMustBeSecure) {
EXPECT_TRUE(
cookie
->IncludeForRequestURL(url, options, CookieAccessSemantics::UNKNOWN)
- .IsInclude());
+ .status.IsInclude());
EXPECT_TRUE(
cookie
->IncludeForRequestURL(url, options, CookieAccessSemantics::LEGACY)
- .IsInclude());
+ .status.IsInclude());
// If the semantics is Nonlegacy, only reject the cookie if the
// SameSite=None-must-be-Secure feature is enabled.
EXPECT_TRUE(cookie
->IncludeForRequestURL(url, options,
CookieAccessSemantics::NONLEGACY)
- .IsInclude());
+ .status.IsInclude());
}
}
@@ -1102,35 +1072,32 @@ TEST(CanonicalCookieTest, MultipleExclusionReasons) {
"name", "value", "other-domain.com", "/bar", creation_time, base::Time(),
base::Time(), true /* secure */, true /* httponly */,
CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
- EXPECT_TRUE(
- cookie1.IncludeForRequestURL(url, options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_STRICT}));
+ EXPECT_TRUE(cookie1.IncludeForRequestURL(url, options)
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
+ CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH,
+ CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
+ CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT}));
// Test Create()
- CanonicalCookie::CookieInclusionStatus create_status;
+ CookieInclusionStatus create_status;
auto cookie2 = CanonicalCookie::Create(
url, "__Secure-notactuallysecure=value;Domain=some-other-domain.com",
creation_time, server_time, &create_status);
ASSERT_FALSE(cookie2);
EXPECT_TRUE(create_status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX,
+ CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
// Test IsSetPermittedInContext()
auto cookie3 = CanonicalCookie::Create(
url, "name=value;HttpOnly;SameSite=Lax", creation_time, server_time);
ASSERT_TRUE(cookie3);
- EXPECT_TRUE(
- cookie3->IsSetPermittedInContext(options)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
+ EXPECT_TRUE(cookie3->IsSetPermittedInContext(options)
+ .HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
+ CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
}
TEST(CanonicalCookieTest, PartialCompare) {
@@ -1166,18 +1133,18 @@ TEST(CanonicalCookieTest, SecureCookiePrefix) {
GURL http_url("http://www.example.test");
base::Time creation_time = base::Time::Now();
base::Optional<base::Time> server_time = base::nullopt;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// A __Secure- cookie must be Secure.
EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Secure-A=B", creation_time,
server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Secure-A=B; httponly",
creation_time, server_time, &status));
// (EXCLUDE_HTTP_ONLY would be fine, too)
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
// A typoed prefix does not have to be Secure.
EXPECT_TRUE(CanonicalCookie::Create(https_url, "__secure-A=B; Secure",
@@ -1193,7 +1160,7 @@ TEST(CanonicalCookieTest, SecureCookiePrefix) {
EXPECT_FALSE(CanonicalCookie::Create(http_url, "__Secure-A=B; Secure",
creation_time, server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
}
TEST(CanonicalCookieTest, HostCookiePrefix) {
@@ -1202,18 +1169,18 @@ TEST(CanonicalCookieTest, HostCookiePrefix) {
base::Time creation_time = base::Time::Now();
base::Optional<base::Time> server_time = base::nullopt;
std::string domain = https_url.host();
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// A __Host- cookie must be Secure.
EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Host-A=B;", creation_time,
server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_FALSE(CanonicalCookie::Create(
https_url, "__Host-A=B; Domain=" + domain + "; Path=/;", creation_time,
server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Path=/; Secure;",
creation_time, server_time));
@@ -1222,7 +1189,7 @@ TEST(CanonicalCookieTest, HostCookiePrefix) {
http_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
creation_time, server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Path=/; Secure;",
creation_time, server_time));
@@ -1231,12 +1198,12 @@ TEST(CanonicalCookieTest, HostCookiePrefix) {
https_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
creation_time, server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_FALSE(CanonicalCookie::Create(
https_url, "__Host-A=B; Domain=" + domain + "; Secure;", creation_time,
server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
// A __Host- cookie may have a domain if it's an IP address that matches the
// URL.
@@ -1255,11 +1222,11 @@ TEST(CanonicalCookieTest, HostCookiePrefix) {
"__Host-A=B; Path=/foo; Secure;",
creation_time, server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Host-A=B; Secure;",
creation_time, server_time, &status));
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
+ {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Secure; Path=/;",
creation_time, server_time));
@@ -2030,10 +1997,9 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(
cookie_httponly.IsSetPermittedInContext(context_network).IsInclude());
- EXPECT_TRUE(
- cookie_httponly.IsSetPermittedInContext(context_script)
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
+ EXPECT_TRUE(cookie_httponly.IsSetPermittedInContext(context_script)
+ .HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
CookieOptions context_cross_site;
CookieOptions context_same_site_lax;
@@ -2079,17 +2045,17 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ CookieInclusionStatus status_strict_to_lax =
cookie_same_site_unrestricted.IsSetPermittedInContext(
context_same_site_strict_to_lax);
EXPECT_TRUE(status_strict_to_lax.IsInclude());
EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ CookieInclusionStatus status_strict_to_cross =
cookie_same_site_unrestricted.IsSetPermittedInContext(
context_same_site_strict_to_cross);
EXPECT_TRUE(status_strict_to_cross.IsInclude());
EXPECT_FALSE(status_strict_to_cross.HasDowngradeWarning());
- CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ CookieInclusionStatus status_lax_to_cross =
cookie_same_site_unrestricted.IsSetPermittedInContext(
context_same_site_lax_to_cross);
EXPECT_TRUE(status_lax_to_cross.IsInclude());
@@ -2104,8 +2070,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(cookie_same_site_lax.IsSetPermittedInContext(context_cross_site)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_LAX}));
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
EXPECT_TRUE(
cookie_same_site_lax.IsSetPermittedInContext(context_same_site_lax)
.IsInclude());
@@ -2113,25 +2078,23 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
cookie_same_site_lax.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ CookieInclusionStatus status_strict_to_lax =
cookie_same_site_lax.IsSetPermittedInContext(
context_same_site_strict_to_lax);
EXPECT_TRUE(status_strict_to_lax.IsInclude());
EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ CookieInclusionStatus status_strict_to_cross =
cookie_same_site_lax.IsSetPermittedInContext(
context_same_site_strict_to_cross);
EXPECT_TRUE(status_strict_to_cross.IsInclude());
EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
- CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE));
+ CookieInclusionStatus status_lax_to_cross =
cookie_same_site_lax.IsSetPermittedInContext(
context_same_site_lax_to_cross);
EXPECT_TRUE(status_lax_to_cross.IsInclude());
EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE));
}
{
@@ -2145,8 +2108,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
EXPECT_TRUE(
cookie_same_site_strict.IsSetPermittedInContext(context_cross_site)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_STRICT}));
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT}));
EXPECT_TRUE(
cookie_same_site_strict.IsSetPermittedInContext(context_same_site_lax)
.IsInclude());
@@ -2154,25 +2116,23 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_same_site_strict)
.IsInclude());
- CanonicalCookie::CookieInclusionStatus status_strict_to_lax =
+ CookieInclusionStatus status_strict_to_lax =
cookie_same_site_strict.IsSetPermittedInContext(
context_same_site_strict_to_lax);
EXPECT_TRUE(status_strict_to_lax.IsInclude());
EXPECT_FALSE(status_strict_to_lax.HasDowngradeWarning());
- CanonicalCookie::CookieInclusionStatus status_strict_to_cross =
+ CookieInclusionStatus status_strict_to_cross =
cookie_same_site_strict.IsSetPermittedInContext(
context_same_site_strict_to_cross);
EXPECT_TRUE(status_strict_to_cross.IsInclude());
EXPECT_TRUE(status_strict_to_cross.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
- CanonicalCookie::CookieInclusionStatus status_lax_to_cross =
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ CookieInclusionStatus status_lax_to_cross =
cookie_same_site_strict.IsSetPermittedInContext(
context_same_site_lax_to_cross);
EXPECT_TRUE(status_lax_to_cross.IsInclude());
EXPECT_TRUE(status_lax_to_cross.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE));
}
// Behavior of UNSPECIFIED depends on an experiment and CookieAccessSemantics.
@@ -2213,7 +2173,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ {CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
@@ -2233,7 +2193,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::UNKNOWN)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ {CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
@@ -2259,7 +2219,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
.IsSetPermittedInContext(context_cross_site,
CookieAccessSemantics::NONLEGACY)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ {CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(cookie_same_site_unspecified
.IsSetPermittedInContext(context_same_site_lax,
@@ -2272,213 +2232,4 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
}
}
-TEST(CookieInclusionStatusTest, IncludeStatus) {
- int num_exclusion_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS);
- int num_warning_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_WARNING_REASONS);
- // Zero-argument constructor
- CanonicalCookie::CookieInclusionStatus status;
- EXPECT_TRUE(status.IsValid());
- EXPECT_TRUE(status.IsInclude());
- for (int i = 0; i < num_exclusion_reasons; ++i) {
- EXPECT_FALSE(status.HasExclusionReason(
- static_cast<CanonicalCookie::CookieInclusionStatus::ExclusionReason>(
- i)));
- }
- for (int i = 0; i < num_warning_reasons; ++i) {
- EXPECT_FALSE(status.HasWarningReason(
- static_cast<CanonicalCookie::CookieInclusionStatus::WarningReason>(i)));
- }
- EXPECT_FALSE(status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
-}
-
-TEST(CookieInclusionStatusTest, ExcludeStatus) {
- int num_exclusion_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS);
- for (int i = 0; i < num_exclusion_reasons; ++i) {
- auto reason =
- static_cast<CanonicalCookie::CookieInclusionStatus::ExclusionReason>(i);
- CanonicalCookie::CookieInclusionStatus status(reason);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.IsInclude());
- EXPECT_TRUE(status.HasExclusionReason(reason));
- for (int j = 0; j < num_exclusion_reasons; ++j) {
- if (i == j)
- continue;
- EXPECT_FALSE(status.HasExclusionReason(
- static_cast<CanonicalCookie::CookieInclusionStatus::ExclusionReason>(
- j)));
- }
- }
-}
-
-TEST(CookieInclusionStatusTest, NotValid) {
- CanonicalCookie::CookieInclusionStatus status;
- int num_exclusion_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS);
- int num_warning_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_WARNING_REASONS);
- status.set_exclusion_reasons(1 << num_exclusion_reasons);
- EXPECT_FALSE(status.IsInclude());
- EXPECT_FALSE(status.IsValid());
-
- status.set_exclusion_reasons(~0u);
- EXPECT_FALSE(status.IsInclude());
- EXPECT_FALSE(status.IsValid());
-
- status.set_warning_reasons(1 << num_warning_reasons);
- EXPECT_FALSE(status.IsInclude());
- EXPECT_FALSE(status.IsValid());
-
- status.set_warning_reasons(~0u);
- EXPECT_FALSE(status.IsInclude());
- EXPECT_FALSE(status.IsValid());
-
- status.set_exclusion_reasons(1 << num_exclusion_reasons);
- status.set_warning_reasons(1 << num_warning_reasons);
- EXPECT_FALSE(status.IsInclude());
- EXPECT_FALSE(status.IsValid());
-}
-
-TEST(CookieInclusionStatusTest, AddExclusionReason) {
- CanonicalCookie::CookieInclusionStatus status;
- status.AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
- status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
- EXPECT_TRUE(status.IsValid());
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR}));
- // Adding an exclusion reason other than
- // EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX or
- // EXCLUDE_SAMESITE_NONE_INSECURE should clear any SameSite warning.
- EXPECT_FALSE(status.ShouldWarn());
-
- status = CanonicalCookie::CookieInclusionStatus();
- status.AddWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- status.AddExclusionReason(CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
- EXPECT_TRUE(status.IsValid());
- EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
- EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
-}
-
-TEST(CookieInclusionStatusTest, CheckEachWarningReason) {
- CanonicalCookie::CookieInclusionStatus status;
-
- int num_warning_reasons = static_cast<int>(
- CanonicalCookie::CookieInclusionStatus::NUM_WARNING_REASONS);
- EXPECT_FALSE(status.ShouldWarn());
- for (int i = 0; i < num_warning_reasons; ++i) {
- auto reason =
- static_cast<CanonicalCookie::CookieInclusionStatus::WarningReason>(i);
- status.AddWarningReason(reason);
- EXPECT_TRUE(status.IsValid());
- EXPECT_TRUE(status.IsInclude());
- EXPECT_TRUE(status.ShouldWarn());
- EXPECT_TRUE(status.HasWarningReason(reason));
- for (int j = 0; j < num_warning_reasons; ++j) {
- if (i == j)
- continue;
- EXPECT_FALSE(status.HasWarningReason(
- static_cast<CanonicalCookie::CookieInclusionStatus::WarningReason>(
- j)));
- }
- status.RemoveWarningReason(reason);
- EXPECT_FALSE(status.ShouldWarn());
- }
-}
-
-TEST(CookieInclusionStatusTest, RemoveExclusionReason) {
- CanonicalCookie::CookieInclusionStatus status(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
- EXPECT_TRUE(status.IsValid());
- ASSERT_TRUE(status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
-
- status.RemoveExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
-
- // Removing a nonexistent exclusion reason doesn't do anything.
- ASSERT_FALSE(status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS));
- status.RemoveExclusionReason(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::NUM_EXCLUSION_REASONS));
-}
-
-TEST(CookieInclusionStatusTest, RemoveWarningReason) {
- CanonicalCookie::CookieInclusionStatus status(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
- EXPECT_TRUE(status.IsValid());
- EXPECT_TRUE(status.ShouldWarn());
- ASSERT_TRUE(status.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
-
- status.RemoveWarningReason(
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.ShouldWarn());
- EXPECT_FALSE(status.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
-
- // Removing a nonexistent warning reason doesn't do anything.
- ASSERT_FALSE(status.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
- status.RemoveWarningReason(CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- EXPECT_TRUE(status.IsValid());
- EXPECT_FALSE(status.ShouldWarn());
- EXPECT_FALSE(status.HasWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
-}
-
-TEST(CookieInclusionStatusTest, HasDowngradeWarning) {
- std::vector<CanonicalCookie::CookieInclusionStatus::WarningReason>
- downgrade_warnings = {
- CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
- CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
- CanonicalCookie::CookieInclusionStatus::
- WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
- CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
- CanonicalCookie::CookieInclusionStatus::
- WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
- };
-
- CanonicalCookie::CookieInclusionStatus empty_status;
- EXPECT_FALSE(empty_status.HasDowngradeWarning());
-
- CanonicalCookie::CookieInclusionStatus not_downgrade;
- not_downgrade.AddWarningReason(
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
- EXPECT_FALSE(not_downgrade.HasDowngradeWarning());
-
- for (auto warning : downgrade_warnings) {
- CanonicalCookie::CookieInclusionStatus status;
- status.AddWarningReason(warning);
- CanonicalCookie::CookieInclusionStatus::WarningReason reason;
-
- EXPECT_TRUE(status.HasDowngradeWarning(&reason));
- EXPECT_EQ(warning, reason);
- }
-}
} // namespace net
diff --git a/chromium/net/cookies/cookie_access_result.cc b/chromium/net/cookies/cookie_access_result.cc
new file mode 100644
index 00000000000..182dc53f704
--- /dev/null
+++ b/chromium/net/cookies/cookie_access_result.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "net/cookies/cookie_access_result.h"
+
+namespace net {
+
+CookieAccessResult::CookieAccessResult() = default;
+
+CookieAccessResult::CookieAccessResult(
+ CookieEffectiveSameSite effective_same_site,
+ CookieInclusionStatus status)
+ : effective_same_site(effective_same_site), status(status) {}
+
+CookieAccessResult::CookieAccessResult(const CookieAccessResult&) = default;
+
+CookieAccessResult& CookieAccessResult::operator=(
+ const CookieAccessResult& cookie_access_result) = default;
+
+CookieAccessResult::CookieAccessResult(CookieAccessResult&&) = default;
+
+CookieAccessResult::~CookieAccessResult() = default;
+
+} // namespace net
diff --git a/chromium/net/cookies/cookie_access_result.h b/chromium/net/cookies/cookie_access_result.h
new file mode 100644
index 00000000000..a21305bfe11
--- /dev/null
+++ b/chromium/net/cookies/cookie_access_result.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef NET_COOKIES_COOKIE_ACCESS_RESULT_H_
+#define NET_COOKIES_COOKIE_ACCESS_RESULT_H_
+
+#include "net/base/net_export.h"
+#include "net/cookies/cookie_constants.h"
+#include "net/cookies/cookie_inclusion_status.h"
+
+namespace net {
+
+struct NET_EXPORT CookieAccessResult {
+ CookieAccessResult();
+ CookieAccessResult(CookieEffectiveSameSite effective_same_site,
+ CookieInclusionStatus status);
+
+ CookieAccessResult(const CookieAccessResult& cookie_access_result);
+
+ CookieAccessResult& operator=(const CookieAccessResult& cookie_access_result);
+
+ CookieAccessResult(CookieAccessResult&& cookie_access_result);
+
+ ~CookieAccessResult();
+
+ CookieEffectiveSameSite effective_same_site =
+ CookieEffectiveSameSite::LAX_MODE;
+ CookieInclusionStatus status;
+};
+
+} // namespace net
+
+#endif // NET_COOKIES_COOKIE_ACCESS_RESULT_H_
diff --git a/chromium/net/cookies/cookie_deletion_info.cc b/chromium/net/cookies/cookie_deletion_info.cc
index b451dc2350f..6429510e83f 100644
--- a/chromium/net/cookies/cookie_deletion_info.cc
+++ b/chromium/net/cookies/cookie_deletion_info.cc
@@ -116,7 +116,7 @@ bool CookieDeletionInfo::Matches(const CanonicalCookie& cookie,
!cookie
.IncludeForRequestURL(url.value(), CookieOptions::MakeAllInclusive(),
access_semantics)
- .IsInclude()) {
+ .status.IsInclude()) {
return false;
}
diff --git a/chromium/net/cookies/cookie_inclusion_status.cc b/chromium/net/cookies/cookie_inclusion_status.cc
new file mode 100644
index 00000000000..8e13916ba13
--- /dev/null
+++ b/chromium/net/cookies/cookie_inclusion_status.cc
@@ -0,0 +1,290 @@
+// 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.
+
+#include "net/cookies/cookie_inclusion_status.h"
+
+#include "base/strings/strcat.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+uint32_t GetExclusionBitmask(CookieInclusionStatus::ExclusionReason reason) {
+ return 1u << static_cast<uint32_t>(reason);
+}
+
+uint32_t GetWarningBitmask(CookieInclusionStatus::WarningReason reason) {
+ return 1u << static_cast<uint32_t>(reason);
+}
+
+} // namespace
+
+CookieInclusionStatus::CookieInclusionStatus()
+ : exclusion_reasons_(0u), warning_reasons_(0u) {}
+
+CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason)
+ : exclusion_reasons_(GetExclusionBitmask(reason)) {}
+
+CookieInclusionStatus::CookieInclusionStatus(ExclusionReason reason,
+ WarningReason warning)
+ : exclusion_reasons_(GetExclusionBitmask(reason)),
+ warning_reasons_(GetWarningBitmask(warning)) {}
+
+bool CookieInclusionStatus::operator==(
+ const CookieInclusionStatus& other) const {
+ return exclusion_reasons_ == other.exclusion_reasons_ &&
+ warning_reasons_ == other.warning_reasons_;
+}
+
+bool CookieInclusionStatus::operator!=(
+ const CookieInclusionStatus& other) const {
+ return !operator==(other);
+}
+
+bool CookieInclusionStatus::IsInclude() const {
+ return exclusion_reasons_ == 0u;
+}
+
+bool CookieInclusionStatus::HasExclusionReason(ExclusionReason reason) const {
+ return exclusion_reasons_ & GetExclusionBitmask(reason);
+}
+
+void CookieInclusionStatus::AddExclusionReason(ExclusionReason reason) {
+ exclusion_reasons_ |= GetExclusionBitmask(reason);
+ // If the cookie would be excluded for reasons other than the new SameSite
+ // rules, don't bother warning about it.
+ MaybeClearSameSiteWarning();
+}
+
+void CookieInclusionStatus::RemoveExclusionReason(ExclusionReason reason) {
+ exclusion_reasons_ &= ~(GetExclusionBitmask(reason));
+}
+
+void CookieInclusionStatus::MaybeClearSameSiteWarning() {
+ uint32_t samesite_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_NONE_INSECURE);
+ if (exclusion_reasons_ & ~samesite_reasons_mask) {
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ RemoveWarningReason(CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
+ }
+
+ uint32_t context_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+ if (exclusion_reasons_ & ~context_reasons_mask) {
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE);
+ RemoveWarningReason(
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE);
+ }
+}
+
+bool CookieInclusionStatus::ShouldRecordDowngradeMetrics() const {
+ uint32_t context_reasons_mask =
+ GetExclusionBitmask(EXCLUDE_SAMESITE_STRICT) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_LAX) |
+ GetExclusionBitmask(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+
+ return (exclusion_reasons_ & ~context_reasons_mask) == 0u;
+}
+
+bool CookieInclusionStatus::ShouldWarn() const {
+ return warning_reasons_ != 0u;
+}
+
+bool CookieInclusionStatus::HasWarningReason(WarningReason reason) const {
+ return warning_reasons_ & GetWarningBitmask(reason);
+}
+
+bool CookieInclusionStatus::HasDowngradeWarning(
+ CookieInclusionStatus::WarningReason* reason) const {
+ if (!ShouldWarn())
+ return false;
+
+ const CookieInclusionStatus::WarningReason kDowngradeWarnings[] = {
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
+ };
+
+ for (auto warning : kDowngradeWarnings) {
+ if (!HasWarningReason(warning))
+ continue;
+
+ if (reason)
+ *reason = warning;
+
+ return true;
+ }
+
+ return false;
+}
+
+void CookieInclusionStatus::AddWarningReason(WarningReason reason) {
+ warning_reasons_ |= GetWarningBitmask(reason);
+}
+
+void CookieInclusionStatus::RemoveWarningReason(WarningReason reason) {
+ warning_reasons_ &= ~(GetWarningBitmask(reason));
+}
+
+CookieInclusionStatus::ContextDowngradeMetricValues
+CookieInclusionStatus::GetBreakingDowngradeMetricsEnumValue(
+ const GURL& url) const {
+ bool url_is_secure = url.SchemeIsCryptographic();
+
+ // Start the |reason| as something other than the downgrade warnings.
+ WarningReason reason = WarningReason::NUM_WARNING_REASONS;
+
+ // Don't bother checking the return value because the default switch case
+ // will handle if no reason was found.
+ HasDowngradeWarning(&reason);
+
+ switch (reason) {
+ case WarningReason::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_LAX_STRICT_SECURE
+ : ContextDowngradeMetricValues::STRICT_LAX_STRICT_INSECURE;
+ case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_CROSS_STRICT_SECURE
+ : ContextDowngradeMetricValues::STRICT_CROSS_STRICT_INSECURE;
+ case WarningReason::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::STRICT_CROSS_LAX_SECURE
+ : ContextDowngradeMetricValues::STRICT_CROSS_LAX_INSECURE;
+ case WarningReason::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::LAX_CROSS_STRICT_SECURE
+ : ContextDowngradeMetricValues::LAX_CROSS_STRICT_INSECURE;
+ case WarningReason::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::LAX_CROSS_LAX_SECURE
+ : ContextDowngradeMetricValues::LAX_CROSS_LAX_INSECURE;
+ default:
+ return url_is_secure
+ ? ContextDowngradeMetricValues::NO_DOWNGRADE_SECURE
+ : ContextDowngradeMetricValues::NO_DOWNGRADE_INSECURE;
+ }
+}
+
+std::string CookieInclusionStatus::GetDebugString() const {
+ std::string out;
+
+ // Inclusion/exclusion
+ if (IsInclude())
+ base::StrAppend(&out, {"INCLUDE, "});
+ if (HasExclusionReason(EXCLUDE_UNKNOWN_ERROR))
+ base::StrAppend(&out, {"EXCLUDE_UNKNOWN_ERROR, "});
+ if (HasExclusionReason(EXCLUDE_HTTP_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_HTTP_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_SECURE_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_SECURE_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_DOMAIN_MISMATCH))
+ base::StrAppend(&out, {"EXCLUDE_DOMAIN_MISMATCH, "});
+ if (HasExclusionReason(EXCLUDE_NOT_ON_PATH))
+ base::StrAppend(&out, {"EXCLUDE_NOT_ON_PATH, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_STRICT))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_STRICT, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_LAX))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_LAX, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX, "});
+ if (HasExclusionReason(EXCLUDE_SAMESITE_NONE_INSECURE))
+ base::StrAppend(&out, {"EXCLUDE_SAMESITE_NONE_INSECURE, "});
+ if (HasExclusionReason(EXCLUDE_USER_PREFERENCES))
+ base::StrAppend(&out, {"EXCLUDE_USER_PREFERENCES, "});
+ if (HasExclusionReason(EXCLUDE_FAILURE_TO_STORE))
+ base::StrAppend(&out, {"EXCLUDE_FAILURE_TO_STORE, "});
+ if (HasExclusionReason(EXCLUDE_NONCOOKIEABLE_SCHEME))
+ base::StrAppend(&out, {"EXCLUDE_NONCOOKIEABLE_SCHEME, "});
+ if (HasExclusionReason(EXCLUDE_OVERWRITE_SECURE))
+ base::StrAppend(&out, {"EXCLUDE_OVERWRITE_SECURE, "});
+ if (HasExclusionReason(EXCLUDE_OVERWRITE_HTTP_ONLY))
+ base::StrAppend(&out, {"EXCLUDE_OVERWRITE_HTTP_ONLY, "});
+ if (HasExclusionReason(EXCLUDE_INVALID_DOMAIN))
+ base::StrAppend(&out, {"EXCLUDE_INVALID_DOMAIN, "});
+ if (HasExclusionReason(EXCLUDE_INVALID_PREFIX))
+ base::StrAppend(&out, {"EXCLUDE_INVALID_PREFIX, "});
+
+ // Add warning
+ if (!ShouldWarn()) {
+ base::StrAppend(&out, {"DO_NOT_WARN"});
+ return out;
+ }
+
+ if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT))
+ base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT, "});
+ if (HasWarningReason(WARN_SAMESITE_NONE_INSECURE))
+ base::StrAppend(&out, {"WARN_SAMESITE_NONE_INSECURE, "});
+ if (HasWarningReason(WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE))
+ base::StrAppend(&out, {"WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE, "});
+ if (HasWarningReason(WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE))
+ base::StrAppend(&out, {"WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE, "});
+ if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE))
+ base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE, "});
+ if (HasWarningReason(WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE))
+ base::StrAppend(&out, {"WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE, "});
+ if (HasWarningReason(WARN_SAMESITE_COMPAT_PAIR))
+ base::StrAppend(&out, {"WARN_SAMESITE_COMPAT_PAIR, "});
+
+ // Strip trailing comma and space.
+ out.erase(out.end() - 2, out.end());
+
+ return out;
+}
+
+bool CookieInclusionStatus::IsValid() const {
+ // Bit positions where there should not be any true bits.
+ uint32_t exclusion_mask = ~0u << static_cast<int>(NUM_EXCLUSION_REASONS);
+ uint32_t warning_mask = ~0u << static_cast<int>(NUM_WARNING_REASONS);
+ return (exclusion_mask & exclusion_reasons_) == 0u &&
+ (warning_mask & warning_reasons_) == 0u;
+}
+
+bool CookieInclusionStatus::HasExactlyExclusionReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason> reasons) const {
+ CookieInclusionStatus expected = MakeFromReasonsForTesting(reasons);
+ return expected.exclusion_reasons_ == exclusion_reasons_;
+}
+
+bool CookieInclusionStatus::HasExactlyWarningReasonsForTesting(
+ std::vector<WarningReason> reasons) const {
+ CookieInclusionStatus expected = MakeFromReasonsForTesting({}, reasons);
+ return expected.warning_reasons_ == warning_reasons_;
+}
+
+// static
+CookieInclusionStatus CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<ExclusionReason> reasons,
+ std::vector<WarningReason> warnings) {
+ CookieInclusionStatus status;
+ for (ExclusionReason reason : reasons) {
+ status.AddExclusionReason(reason);
+ }
+ for (WarningReason warning : warnings) {
+ status.AddWarningReason(warning);
+ }
+ return status;
+}
+
+} // namespace net
diff --git a/chromium/net/cookies/cookie_inclusion_status.h b/chromium/net/cookies/cookie_inclusion_status.h
new file mode 100644
index 00000000000..3f38eddb39b
--- /dev/null
+++ b/chromium/net/cookies/cookie_inclusion_status.h
@@ -0,0 +1,275 @@
+// 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.
+
+#ifndef NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
+#define NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace net {
+
+// This class represents if a cookie was included or excluded in a cookie get or
+// set operation, and if excluded why. It holds a vector of reasons for
+// exclusion, where cookie inclusion is represented by the absence of any
+// exclusion reasons. Also marks whether a cookie should be warned about, e.g.
+// for deprecation or intervention reasons.
+class NET_EXPORT CookieInclusionStatus {
+ public:
+ // Types of reasons why a cookie might be excluded.
+ // If adding a ExclusionReason, please also update the GetDebugString()
+ // method.
+ enum ExclusionReason {
+ EXCLUDE_UNKNOWN_ERROR = 0,
+
+ EXCLUDE_HTTP_ONLY = 1,
+ EXCLUDE_SECURE_ONLY = 2,
+ EXCLUDE_DOMAIN_MISMATCH = 3,
+ EXCLUDE_NOT_ON_PATH = 4,
+ EXCLUDE_SAMESITE_STRICT = 5,
+ EXCLUDE_SAMESITE_LAX = 6,
+
+ // The following two are used for the SameSiteByDefaultCookies experiment,
+ // where if the SameSite attribute is not specified, it will be treated as
+ // SameSite=Lax by default.
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX = 7,
+ // This is used if SameSite=None is specified, but the cookie is not
+ // Secure.
+ EXCLUDE_SAMESITE_NONE_INSECURE = 8,
+ EXCLUDE_USER_PREFERENCES = 9,
+
+ // Statuses specific to setting cookies
+ EXCLUDE_FAILURE_TO_STORE = 10,
+ EXCLUDE_NONCOOKIEABLE_SCHEME = 11,
+ EXCLUDE_OVERWRITE_SECURE = 12,
+ EXCLUDE_OVERWRITE_HTTP_ONLY = 13,
+ EXCLUDE_INVALID_DOMAIN = 14,
+ EXCLUDE_INVALID_PREFIX = 15,
+
+ // This should be kept last.
+ NUM_EXCLUSION_REASONS
+ };
+
+ // Reason to warn about a cookie. Any information contained in WarningReason
+ // of an included cookie may be passed to an untrusted renderer.
+ // If you add one, please update GetDebugString().
+ enum WarningReason {
+ // Of the following 3 SameSite warnings, there will be, at most, a single
+ // active one.
+
+ // Warn if a cookie with unspecified SameSite attribute is used in a
+ // cross-site context.
+ WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT = 0,
+ // Warn if a cookie with SameSite=None is not Secure.
+ WARN_SAMESITE_NONE_INSECURE = 1,
+ // Warn if a cookie with unspecified SameSite attribute is defaulted into
+ // Lax and is sent on a request with unsafe method, only because it is new
+ // enough to activate the Lax-allow-unsafe intervention.
+ WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE = 2,
+
+ // The following warnings indicate that an included cookie with an effective
+ // SameSite is experiencing a SameSiteCookieContext::|context| ->
+ // SameSiteCookieContext::|schemeful_context| downgrade that will prevent
+ // its access schemefully.
+ // This situation means that a cookie is accessible when the
+ // SchemefulSameSite feature is disabled but not when it's enabled,
+ // indicating changed behavior and potential breakage.
+ //
+ // For example, a Strict to Lax downgrade for an effective SameSite=Strict
+ // cookie:
+ // This cookie would be accessible in the Strict context as its SameSite
+ // value is Strict. However its context for schemeful same-site becomes Lax.
+ // A strict cookie cannot be accessed in a Lax context and therefore the
+ // behavior has changed.
+ // As a counterexample, a Strict to Lax downgrade for an effective
+ // SameSite=Lax cookie: A Lax cookie can be accessed in both Strict and Lax
+ // contexts so there is no behavior change (and we don't warn about it).
+ //
+ // The warnings are in the following format:
+ // WARN_{context}_{schemeful_context}_DOWNGRADE_{samesite_value}_SAMESITE
+ //
+ // Of the following 5 SameSite warnings, there will be, at most, a single
+ // active one.
+
+ // Strict to Lax downgrade for an effective SameSite=Strict cookie.
+ // This warning is only applicable for cookies being sent because a Strict
+ // cookie will be set in both Strict and Lax Contexts so the downgrade will
+ // not affect it.
+ WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE = 3,
+ // Strict to Cross-site downgrade for an effective SameSite=Strict cookie.
+ // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
+ // behaving like Cross-site.
+ WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE = 4,
+ // Strict to Cross-site downgrade for an effective SameSite=Lax cookie.
+ // This also applies to Strict to Lax Unsafe downgrades due to Lax Unsafe
+ // behaving like Cross-site.
+ WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE = 5,
+ // Lax to Cross-site downgrade for an effective SameSite=Strict cookie.
+ // This warning is only applicable for cookies being set because a Strict
+ // cookie will not be sent in a Lax context so the downgrade would not
+ // affect it.
+ WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE = 6,
+ // Lax to Cross-site downgrade for an effective SameSite=Lax cookie.
+ WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE = 7,
+
+ // This is applied to a cookie that may be part of a "double cookie" pair
+ // used for compatibility reasons. These pairs consist of one cookie that
+ // has "SameSite=None; Secure" and a duplicate cookie that leaves SameSite
+ // unspecified to maintain compatibility with browsers that do not support
+ // the "SameSite=None" attribute. This warning is applied to both
+ // members of the pair. See cookie_util::IsSameSiteCompatPair().
+ //
+ // If computing this for a cookie access attempt from a non-network context
+ // (i.e. script), this should not be applied if either member of the pair is
+ // HttpOnly, to avoid leaking information about the name and value of
+ // HttpOnly cookies to an untrusted renderer.
+ //
+ // This is only relevant if WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT is
+ // present on the same status or a status for a cookie accessed at the same
+ // time, so it may not be applied at other times (e.g. when the context is
+ // same-site).
+ WARN_SAMESITE_COMPAT_PAIR = 8,
+
+ // This should be kept last.
+ NUM_WARNING_REASONS
+ };
+
+ // These enums encode the context downgrade warnings + the secureness of the
+ // url sending/setting the cookie. They're used for metrics only. The format
+ // is {context}_{schemeful_context}_{samesite_value}_{securness}.
+ // NO_DOWNGRADE_{securness} indicates that a cookie didn't have a breaking
+ // context downgrade and was A) included B) excluded only due to insufficient
+ // same-site context. I.e. the cookie wasn't excluded due to other reasons
+ // such as third-party cookie blocking. Keep this in line with
+ // SameSiteCookieContextBreakingDowngradeWithSecureness in enums.xml.
+ enum ContextDowngradeMetricValues {
+ NO_DOWNGRADE_INSECURE = 0,
+ NO_DOWNGRADE_SECURE = 1,
+
+ STRICT_LAX_STRICT_INSECURE = 2,
+ STRICT_CROSS_STRICT_INSECURE = 3,
+ STRICT_CROSS_LAX_INSECURE = 4,
+ LAX_CROSS_STRICT_INSECURE = 5,
+ LAX_CROSS_LAX_INSECURE = 6,
+
+ STRICT_LAX_STRICT_SECURE = 7,
+ STRICT_CROSS_STRICT_SECURE = 8,
+ STRICT_CROSS_LAX_SECURE = 9,
+ LAX_CROSS_STRICT_SECURE = 10,
+ LAX_CROSS_LAX_SECURE = 11,
+
+ // Keep last.
+ kMaxValue = LAX_CROSS_LAX_SECURE
+ };
+ // Makes a status that says include and should not warn.
+ CookieInclusionStatus();
+
+ // Make a status that contains the given exclusion reason.
+ explicit CookieInclusionStatus(ExclusionReason reason);
+ // Makes a status that contains the given exclusion reason and warning.
+ CookieInclusionStatus(ExclusionReason reason, WarningReason warning);
+
+ bool operator==(const CookieInclusionStatus& other) const;
+ bool operator!=(const CookieInclusionStatus& other) const;
+
+ // Whether the status is to include the cookie, and has no other reasons for
+ // exclusion.
+ bool IsInclude() const;
+
+ // Whether the given reason for exclusion is present.
+ bool HasExclusionReason(ExclusionReason status_type) const;
+
+ // Add an exclusion reason.
+ void AddExclusionReason(ExclusionReason status_type);
+
+ // Remove an exclusion reason.
+ void RemoveExclusionReason(ExclusionReason reason);
+
+ // If the cookie would have been excluded for reasons other than
+ // SAMESITE_UNSPECIFIED_TREATED_AS_LAX or SAMESITE_NONE_INSECURE, don't bother
+ // warning about it (clear the warning).
+ void MaybeClearSameSiteWarning();
+
+ // Whether to record the breaking downgrade metrics if the cookie is included
+ // or if it's only excluded because of insufficient same-site context.
+ bool ShouldRecordDowngradeMetrics() const;
+
+ // Whether the cookie should be warned about.
+ bool ShouldWarn() const;
+
+ // Whether the given reason for warning is present.
+ bool HasWarningReason(WarningReason reason) const;
+
+ // Whether a schemeful downgrade warning is present.
+ // A schemeful downgrade means that an included cookie with an effective
+ // SameSite is experiencing a SameSiteCookieContext::|context| ->
+ // SameSiteCookieContext::|schemeful_context| downgrade that will prevent its
+ // access schemefully. If the function returns true and |reason| is valid then
+ // |reason| will contain which warning was found.
+ bool HasDowngradeWarning(
+ CookieInclusionStatus::WarningReason* reason = nullptr) const;
+
+ // Add an warning reason.
+ void AddWarningReason(WarningReason reason);
+
+ // Remove an warning reason.
+ void RemoveWarningReason(WarningReason reason);
+
+ // Used for serialization/deserialization.
+ uint32_t exclusion_reasons() const { return exclusion_reasons_; }
+ void set_exclusion_reasons(uint32_t exclusion_reasons) {
+ exclusion_reasons_ = exclusion_reasons;
+ }
+
+ uint32_t warning_reasons() const { return warning_reasons_; }
+ void set_warning_reasons(uint32_t warning_reasons) {
+ warning_reasons_ = warning_reasons;
+ }
+
+ ContextDowngradeMetricValues GetBreakingDowngradeMetricsEnumValue(
+ const GURL& url) const;
+
+ // Get exclusion reason(s) and warning in string format.
+ std::string GetDebugString() const;
+
+ // Checks that the underlying bit vector representation doesn't contain any
+ // extraneous bits that are not mapped to any enum values. Does not check
+ // for reasons which semantically cannot coexist.
+ bool IsValid() const;
+
+ // Checks whether the exclusion reasons are exactly the set of exclusion
+ // reasons in the vector. (Ignores warnings.)
+ bool HasExactlyExclusionReasonsForTesting(
+ std::vector<ExclusionReason> reasons) const;
+
+ // Checks whether the warning reasons are exactly the set of warning
+ // reasons in the vector. (Ignores exclusions.)
+ bool HasExactlyWarningReasonsForTesting(
+ std::vector<WarningReason> reasons) const;
+
+ // Makes a status that contains the given exclusion reasons and warning.
+ static CookieInclusionStatus MakeFromReasonsForTesting(
+ std::vector<ExclusionReason> reasons,
+ std::vector<WarningReason> warnings = std::vector<WarningReason>());
+
+ private:
+ // A bit vector of the applicable exclusion reasons.
+ uint32_t exclusion_reasons_ = 0u;
+
+ // A bit vector of the applicable warning reasons.
+ uint32_t warning_reasons_ = 0u;
+};
+
+NET_EXPORT inline std::ostream& operator<<(std::ostream& os,
+ const CookieInclusionStatus status) {
+ return os << status.GetDebugString();
+}
+
+} // namespace net
+
+#endif // NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
diff --git a/chromium/net/cookies/cookie_inclusion_status_unittest.cc b/chromium/net/cookies/cookie_inclusion_status_unittest.cc
new file mode 100644
index 00000000000..bc5c7edaa39
--- /dev/null
+++ b/chromium/net/cookies/cookie_inclusion_status_unittest.cc
@@ -0,0 +1,200 @@
+// 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.
+
+#include "net/cookies/cookie_inclusion_status.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+TEST(CookieInclusionStatusTest, IncludeStatus) {
+ int num_exclusion_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
+ int num_warning_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_WARNING_REASONS);
+ // Zero-argument constructor
+ CookieInclusionStatus status;
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_TRUE(status.IsInclude());
+ for (int i = 0; i < num_exclusion_reasons; ++i) {
+ EXPECT_FALSE(status.HasExclusionReason(
+ static_cast<CookieInclusionStatus::ExclusionReason>(i)));
+ }
+ for (int i = 0; i < num_warning_reasons; ++i) {
+ EXPECT_FALSE(status.HasWarningReason(
+ static_cast<CookieInclusionStatus::WarningReason>(i)));
+ }
+ EXPECT_FALSE(
+ status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
+}
+
+TEST(CookieInclusionStatusTest, ExcludeStatus) {
+ int num_exclusion_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
+ for (int i = 0; i < num_exclusion_reasons; ++i) {
+ auto reason = static_cast<CookieInclusionStatus::ExclusionReason>(i);
+ CookieInclusionStatus status(reason);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_TRUE(status.HasExclusionReason(reason));
+ for (int j = 0; j < num_exclusion_reasons; ++j) {
+ if (i == j)
+ continue;
+ EXPECT_FALSE(status.HasExclusionReason(
+ static_cast<CookieInclusionStatus::ExclusionReason>(j)));
+ }
+ }
+}
+
+TEST(CookieInclusionStatusTest, NotValid) {
+ CookieInclusionStatus status;
+ int num_exclusion_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
+ int num_warning_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_WARNING_REASONS);
+ status.set_exclusion_reasons(1 << num_exclusion_reasons);
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_FALSE(status.IsValid());
+
+ status.set_exclusion_reasons(~0u);
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_FALSE(status.IsValid());
+
+ status.set_warning_reasons(1 << num_warning_reasons);
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_FALSE(status.IsValid());
+
+ status.set_warning_reasons(~0u);
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_FALSE(status.IsValid());
+
+ status.set_exclusion_reasons(1 << num_exclusion_reasons);
+ status.set_warning_reasons(1 << num_warning_reasons);
+ EXPECT_FALSE(status.IsInclude());
+ EXPECT_FALSE(status.IsValid());
+}
+
+TEST(CookieInclusionStatusTest, AddExclusionReason) {
+ CookieInclusionStatus status;
+ status.AddWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
+ status.AddExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR}));
+ // Adding an exclusion reason other than
+ // EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX or
+ // EXCLUDE_SAMESITE_NONE_INSECURE should clear any SameSite warning.
+ EXPECT_FALSE(status.ShouldWarn());
+
+ status = CookieInclusionStatus();
+ status.AddWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ status.AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
+ EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
+ {CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
+}
+
+TEST(CookieInclusionStatusTest, CheckEachWarningReason) {
+ CookieInclusionStatus status;
+
+ int num_warning_reasons =
+ static_cast<int>(CookieInclusionStatus::NUM_WARNING_REASONS);
+ EXPECT_FALSE(status.ShouldWarn());
+ for (int i = 0; i < num_warning_reasons; ++i) {
+ auto reason = static_cast<CookieInclusionStatus::WarningReason>(i);
+ status.AddWarningReason(reason);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_TRUE(status.IsInclude());
+ EXPECT_TRUE(status.ShouldWarn());
+ EXPECT_TRUE(status.HasWarningReason(reason));
+ for (int j = 0; j < num_warning_reasons; ++j) {
+ if (i == j)
+ continue;
+ EXPECT_FALSE(status.HasWarningReason(
+ static_cast<CookieInclusionStatus::WarningReason>(j)));
+ }
+ status.RemoveWarningReason(reason);
+ EXPECT_FALSE(status.ShouldWarn());
+ }
+}
+
+TEST(CookieInclusionStatusTest, RemoveExclusionReason) {
+ CookieInclusionStatus status(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
+ EXPECT_TRUE(status.IsValid());
+ ASSERT_TRUE(
+ status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
+
+ status.RemoveExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_FALSE(
+ status.HasExclusionReason(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
+
+ // Removing a nonexistent exclusion reason doesn't do anything.
+ ASSERT_FALSE(
+ status.HasExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS));
+ status.RemoveExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_FALSE(
+ status.HasExclusionReason(CookieInclusionStatus::NUM_EXCLUSION_REASONS));
+}
+
+TEST(CookieInclusionStatusTest, RemoveWarningReason) {
+ CookieInclusionStatus status(
+ CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR,
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_TRUE(status.ShouldWarn());
+ ASSERT_TRUE(status.HasWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
+
+ status.RemoveWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_FALSE(status.ShouldWarn());
+ EXPECT_FALSE(status.HasWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE));
+
+ // Removing a nonexistent warning reason doesn't do anything.
+ ASSERT_FALSE(status.HasWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
+ status.RemoveWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ EXPECT_TRUE(status.IsValid());
+ EXPECT_FALSE(status.ShouldWarn());
+ EXPECT_FALSE(status.HasWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
+}
+
+TEST(CookieInclusionStatusTest, HasDowngradeWarning) {
+ std::vector<CookieInclusionStatus::WarningReason> downgrade_warnings = {
+ CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE,
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE,
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE,
+ CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE,
+ };
+
+ CookieInclusionStatus empty_status;
+ EXPECT_FALSE(empty_status.HasDowngradeWarning());
+
+ CookieInclusionStatus not_downgrade;
+ not_downgrade.AddWarningReason(
+ CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ EXPECT_FALSE(not_downgrade.HasDowngradeWarning());
+
+ for (auto warning : downgrade_warnings) {
+ CookieInclusionStatus status;
+ status.AddWarningReason(warning);
+ CookieInclusionStatus::WarningReason reason;
+
+ EXPECT_TRUE(status.HasDowngradeWarning(&reason));
+ EXPECT_EQ(warning, reason);
+ }
+}
+} // namespace net
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 533cc97ba71..477b47a7721 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -142,6 +142,8 @@ const size_t CookieMonster::kDomainPurgeCookies = 30;
const size_t CookieMonster::kMaxCookies = 3300;
const size_t CookieMonster::kPurgeCookies = 300;
+const size_t CookieMonster::kMaxDomainPurgedKeys = 100;
+
const size_t CookieMonster::kDomainCookiesQuotaLow = 30;
const size_t CookieMonster::kDomainCookiesQuotaMedium = 50;
const size_t CookieMonster::kDomainCookiesQuotaHigh =
@@ -319,7 +321,8 @@ CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
base::TimeDelta last_access_threshold,
NetLog* net_log)
- : initialized_(false),
+ : num_keys_(0u),
+ initialized_(false),
started_fetching_all_cookies_(false),
finished_fetching_all_cookies_(false),
seen_global_task_(false),
@@ -578,8 +581,8 @@ void CookieMonster::GetCookieListWithOptions(const GURL& url,
GetCookieListCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- CookieStatusList included_cookies;
- CookieStatusList excluded_cookies;
+ CookieAccessResultList included_cookies;
+ CookieAccessResultList excluded_cookies;
if (HasCookieableScheme(url)) {
std::vector<CanonicalCookie*> cookie_ptrs;
FindCookiesForRegistryControlledHost(url, &cookie_ptrs);
@@ -950,8 +953,8 @@ void CookieMonster::FilterCookiesWithOptions(
const GURL url,
const CookieOptions options,
std::vector<CanonicalCookie*>* cookie_ptrs,
- CookieStatusList* included_cookies,
- CookieStatusList* excluded_cookies) {
+ CookieAccessResultList* included_cookies,
+ CookieAccessResultList* excluded_cookies) {
DCHECK(thread_checker_.CalledOnValidThread());
// Probe to save statistics relatively frequently. We do it here rather
@@ -965,12 +968,12 @@ void CookieMonster::FilterCookiesWithOptions(
// Filter out cookies that should not be included for a request to the
// given |url|. HTTP only cookies are filtered depending on the passed
// cookie |options|.
- CanonicalCookie::CookieInclusionStatus status = (*it)->IncludeForRequestURL(
+ CookieAccessResult access_result = (*it)->IncludeForRequestURL(
url, options, GetAccessSemanticsForCookieGet(**it));
- if (!status.IsInclude()) {
+ if (!access_result.status.IsInclude()) {
if (options.return_excluded_cookies())
- excluded_cookies->push_back({**it, status});
+ excluded_cookies->push_back({**it, access_result});
continue;
}
@@ -979,7 +982,7 @@ void CookieMonster::FilterCookiesWithOptions(
MaybeRecordCookieAccessWithOptions(**it, options, false);
- included_cookies->push_back({**it, status});
+ included_cookies->push_back({**it, access_result});
}
}
@@ -990,12 +993,12 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
bool skip_httponly,
bool already_expired,
base::Time* creation_date_to_inherit,
- CanonicalCookie::CookieInclusionStatus* status) {
+ CookieInclusionStatus* status) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!status->HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE));
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE));
DCHECK(!status->HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY));
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY));
bool found_equivalent_cookie = false;
CookieMap::iterator deletion_candidate_it = cookies_.end();
@@ -1030,7 +1033,7 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
capture_mode);
});
status->AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE);
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE);
}
if (cookie_being_set.IsEquivalent(*cur_existing_cookie)) {
@@ -1050,8 +1053,8 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
return NetLogCookieMonsterCookieRejectedHttponly(
cur_existing_cookie, &cookie_being_set, capture_mode);
});
- status->AddExclusionReason(CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_HTTP_ONLY);
+ status->AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY);
} else {
deletion_candidate_it = cur_it;
}
@@ -1067,8 +1070,7 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
already_expired ? DELETE_COOKIE_EXPIRED_OVERWRITE
: DELETE_COOKIE_OVERWRITE);
} else if (status->HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE)) {
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE)) {
// Log that we preserved a cookie that would have been deleted due to
// Leave Secure Cookies Alone. This arbitrarily only logs the last
// |skipped_secure_cookie| that we were left with after the for loop, even
@@ -1145,6 +1147,15 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
CookieChangeCause::INSERTED),
true);
+ // If this is the first cookie in |cookies_| with this key, increment the
+ // |num_keys_| counter.
+ bool different_prev =
+ inserted == cookies_.begin() || std::prev(inserted)->first != key;
+ bool different_next =
+ inserted == cookies_.end() || std::next(inserted)->first != key;
+ if (different_prev && different_next)
+ ++num_keys_;
+
return inserted;
}
@@ -1154,19 +1165,18 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
SetCookiesCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
bool secure_source = source_url.SchemeIsCryptographic();
cc->SetSourceScheme(secure_source ? CookieSourceScheme::kSecure
: CookieSourceScheme::kNonSecure);
if ((cc->IsSecure() && !secure_source)) {
- status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY);
+ status.AddExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY);
}
if (!IsCookieableScheme(source_url.scheme())) {
status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME);
+ CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME);
}
const std::string key(GetKey(cc->Domain()));
@@ -1194,9 +1204,9 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
&creation_date_to_inherit, &status);
if (status.HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE) ||
- status.HasExclusionReason(CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_HTTP_ONLY)) {
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE) ||
+ status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY)) {
DVLOG(net::cookie_util::kVlogSetCookies)
<< "SetCookie() not clobbering httponly cookie or secure cookie for "
"insecure scheme";
@@ -1293,8 +1303,7 @@ void CookieMonster::SetAllCookies(CookieList list,
// shouldn't have a return value. But it should also be deleted (see
// https://codereview.chromium.org/2882063002/#msg64), which would
// solve the return value problem.
- MaybeRunCookieCallback(std::move(callback),
- CanonicalCookie::CookieInclusionStatus());
+ MaybeRunCookieCallback(std::move(callback), CookieInclusionStatus());
}
void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
@@ -1358,6 +1367,16 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
GetAccessSemanticsForCookie(*cc, false /* legacy_access_granted */),
mapping.cause),
mapping.notify);
+
+ // If this is the last cookie in |cookies_| with this key, decrement the
+ // |num_keys_| counter.
+ bool different_prev =
+ it == cookies_.begin() || std::prev(it)->first != it->first;
+ bool different_next =
+ it == cookies_.end() || std::next(it)->first != it->first;
+ if (different_prev && different_next)
+ --num_keys_;
+
cookies_.erase(it);
}
@@ -1385,6 +1404,10 @@ size_t CookieMonster::GarbageCollect(const Time& current,
if (cookie_its->size() > kDomainMaxCookies) {
DVLOG(net::cookie_util::kVlogGarbageCollection)
<< "Deep Garbage Collect domain.";
+
+ if (domain_purged_keys_.size() < kMaxDomainPurgedKeys)
+ domain_purged_keys_.insert(key);
+
size_t purge_goal =
cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies);
DCHECK(purge_goal > kDomainPurgeCookies);
@@ -1801,11 +1824,25 @@ void CookieMonster::RecordPeriodicStats(const base::Time& current_time) {
return;
}
+ if (DoRecordPeriodicStats())
+ last_statistic_record_time_ = current_time;
+}
+
+bool CookieMonster::DoRecordPeriodicStats() {
+ // These values are all bogus if we have only partially loaded the cookies.
+ if (started_fetching_all_cookies_ && !finished_fetching_all_cookies_)
+ return false;
+
// See InitializeHistograms() for details.
histogram_count_->Add(cookies_.size());
- // More detailed statistics on cookie counts at different granularities.
- last_statistic_record_time_ = current_time;
+ // Can be up to kMaxDomainPurgedKeys.
+ UMA_HISTOGRAM_COUNTS_100("Cookie.NumDomainPurgedKeys",
+ domain_purged_keys_.size());
+ // Can be up to kMaxCookies.
+ UMA_HISTOGRAM_COUNTS_10000("Cookie.NumKeys", num_keys_);
+
+ return true;
}
// Initialize all histogram counter variables used in this class.
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 46001bd4e4e..9908e6f8e7e 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -31,6 +31,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_delegate.h"
#include "net/cookies/cookie_constants.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_monster_change_dispatcher.h"
#include "net/cookies/cookie_store.h"
#include "net/log/net_log_with_source.h"
@@ -123,6 +124,9 @@ class NET_EXPORT CookieMonster : public CookieStore {
static const size_t kMaxCookies;
static const size_t kPurgeCookies;
+ // Max number of keys to store for domains that have been purged.
+ static const size_t kMaxDomainPurgedKeys;
+
// Quota for cookies with {low, medium, high} priorities within a domain.
static const size_t kDomainCookiesQuotaLow;
static const size_t kDomainCookiesQuotaMedium;
@@ -203,6 +207,10 @@ class NET_EXPORT CookieMonster : public CookieStore {
// before the CookieMap typedef.
static std::string GetKey(base::StringPiece domain);
+ // Triggers immediate recording of stats that are typically reported
+ // periodically.
+ bool DoRecordPeriodicStatsForTesting() { return DoRecordPeriodicStats(); }
+
private:
// For garbage collection constants.
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestHostGarbageCollection);
@@ -394,8 +402,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
void FilterCookiesWithOptions(const GURL url,
const CookieOptions options,
std::vector<CanonicalCookie*>* cookie_ptrs,
- CookieStatusList* included_cookies,
- CookieStatusList* excluded_cookies);
+ CookieAccessResultList* included_cookies,
+ CookieAccessResultList* excluded_cookies);
// Possibly delete an existing cookie equivalent to |cookie_being_set| (same
// path, domain, and name).
@@ -428,7 +436,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool skip_httponly,
bool already_expired,
base::Time* creation_date_to_inherit,
- CanonicalCookie::CookieInclusionStatus* status);
+ CookieInclusionStatus* status);
// This is only used if the RecentCreationTimeGrantsLegacyCookieSemantics
// feature is enabled. It finds an equivalent cookie (based on name, domain,
@@ -562,7 +570,11 @@ class NET_EXPORT CookieMonster : public CookieStore {
// statistics if a sufficient time period has passed.
void RecordPeriodicStats(const base::Time& current_time);
- // Initialize the above variables; should only be called from
+ // Records the aforementioned stats if we have already finished loading all
+ // cookies. Returns whether stats were recorded.
+ bool DoRecordPeriodicStats();
+
+ // Initialize the histogram_* variables below; should only be called from
// the constructor.
void InitializeHistograms();
@@ -588,6 +600,15 @@ class NET_EXPORT CookieMonster : public CookieStore {
base::HistogramBase* histogram_cookie_source_scheme_;
base::HistogramBase* histogram_time_blocked_on_load_;
+ // Set of keys (eTLD+1's) for which non-expired cookies have
+ // been evicted for hitting the per-domain max. The size of this set is
+ // histogrammed periodically. The size is limited to |kMaxDomainPurgedKeys|.
+ std::set<std::string> domain_purged_keys_;
+
+ // The number of distinct keys (eTLD+1's) currently present in the |cookies_|
+ // multimap. This is histogrammed periodically.
+ size_t num_keys_;
+
CookieMap cookies_;
CookieMonsterChangeDispatcher change_dispatcher_;
diff --git a/chromium/net/cookies/cookie_monster_change_dispatcher.cc b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
index 28cfe347c58..6bd731f47ca 100644
--- a/chromium/net/cookies/cookie_monster_change_dispatcher.cc
+++ b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
@@ -61,7 +61,7 @@ void CookieMonsterChangeDispatcher::Subscription::DispatchChange(
!cookie
.IncludeForRequestURL(url_, CookieOptions::MakeAllInclusive(),
change.access_semantics)
- .IsInclude()) {
+ .status.IsInclude()) {
return;
}
diff --git a/chromium/net/cookies/cookie_monster_perftest.cc b/chromium/net/cookies/cookie_monster_perftest.cc
index 6966a8a9e4b..96d16f545a6 100644
--- a/chromium/net/cookies/cookie_monster_perftest.cc
+++ b/chromium/net/cookies/cookie_monster_perftest.cc
@@ -105,7 +105,7 @@ class SetCookieCallback : public CookieTestCallback {
}
private:
- void Run(CanonicalCookie::CookieInclusionStatus status) {
+ void Run(CookieInclusionStatus status) {
EXPECT_TRUE(status.IsInclude());
CookieTestCallback::Run();
}
@@ -123,9 +123,9 @@ class GetCookieListCallback : public CookieTestCallback {
}
private:
- void Run(const CookieStatusList& cookie_list,
- const CookieStatusList& excluded_cookies) {
- cookie_list_ = cookie_util::StripStatuses(cookie_list);
+ void Run(const CookieAccessResultList& cookie_list,
+ const CookieAccessResultList& excluded_cookies) {
+ cookie_list_ = cookie_util::StripAccessResults(cookie_list);
CookieTestCallback::Run();
}
CookieList cookie_list_;
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index 82877bcb54b..fc83d6a6211 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -135,7 +135,7 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
return callback.cookies();
}
- CookieStatusList GetExcludedCookiesForURLWithOptions(
+ CookieAccessResultList GetExcludedCookiesForURLWithOptions(
CookieMonster* cm,
const GURL& url,
const CookieOptions& options) {
@@ -148,7 +148,7 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
bool SetAllCookies(CookieMonster* cm, const CookieList& list) {
DCHECK(cm);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm->SetAllCookiesAsync(list, callback.MakeCallback());
callback.WaitUntilDone();
return callback.result().IsInclude();
@@ -160,7 +160,7 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
base::Time creation_time) {
DCHECK(cm);
DCHECK(!creation_time.is_null());
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm->SetCanonicalCookieAsync(
CanonicalCookie::Create(url, cookie_line, creation_time,
base::nullopt /* server_time */),
@@ -310,10 +310,10 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
}
void TestHostGarbageCollectHelper() {
+ const char kHistogramName[] = "Cookie.NumDomainPurgedKeys";
int domain_max_cookies = CookieMonster::kDomainMaxCookies;
int domain_purge_cookies = CookieMonster::kDomainPurgeCookies;
- const int more_than_enough_cookies =
- (domain_max_cookies + domain_purge_cookies) * 2;
+ const int more_than_enough_cookies = domain_max_cookies + 10;
// Add a bunch of cookies on a single host, should purge them.
{
auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_);
@@ -326,6 +326,10 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
// Count the number of cookies.
EXPECT_LE(CountInString(cookies, '='), domain_max_cookies);
}
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 1 /* sample */,
+ 1 /* count */);
}
// Add a bunch of cookies on multiple hosts within a single eTLD.
@@ -359,6 +363,51 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
CountInString(cookies_specific, '='));
EXPECT_GE(total_cookies, domain_max_cookies - domain_purge_cookies);
EXPECT_LE(total_cookies, domain_max_cookies);
+
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 1 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test histogram for the number of registrable domains affected by domain
+ // purge.
+ {
+ auto cm = std::make_unique<CookieMonster>(nullptr, &net_log_);
+ GURL url;
+ for (int domain_num = 0; domain_num < 3; ++domain_num) {
+ url = GURL(base::StringPrintf("http://domain%d.test", domain_num));
+ for (int i = 0; i < more_than_enough_cookies; ++i) {
+ std::string cookie = base::StringPrintf("a%03d=b", i);
+ EXPECT_TRUE(SetCookie(cm.get(), url, cookie));
+ std::string cookies = this->GetCookies(cm.get(), url);
+ // Make sure we find it in the cookies.
+ EXPECT_NE(cookies.find(cookie), std::string::npos);
+ // Count the number of cookies.
+ EXPECT_LE(CountInString(cookies, '='), domain_max_cookies);
+ }
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(
+ kHistogramName, domain_num + 1 /* sample */, 1 /* count */);
+ }
+
+ // Triggering eviction again for a previously affected registrable domain
+ // does not increment the histogram.
+ for (int i = 0; i < domain_purge_cookies * 2; ++i) {
+ // Add some extra cookies (different names than before).
+ std::string cookie = base::StringPrintf("b%03d=b", i);
+ EXPECT_TRUE(SetCookie(cm.get(), url, cookie));
+ std::string cookies = this->GetCookies(cm.get(), url);
+ // Make sure we find it in the cookies.
+ EXPECT_NE(cookies.find(cookie), std::string::npos);
+ // Count the number of cookies.
+ EXPECT_LE(CountInString(cookies, '='), domain_max_cookies);
+ }
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
+ 1 /* count */);
}
}
@@ -932,7 +981,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
// Generate puts to store w/o needing a proper expiration.
cookie_monster_->SetPersistSessionCookies(true);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> call1;
+ ResultSavingCookieCallback<CookieInclusionStatus> call1;
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
base::nullopt /* server_time */),
@@ -946,7 +995,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
EXPECT_TRUE(call1.result().IsInclude());
EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ADD; ", TakeCommandSummary());
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> call2;
+ ResultSavingCookieCallback<CookieInclusionStatus> call2;
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "X=Y", base::Time::Now(),
base::nullopt /* server_time */),
@@ -971,7 +1020,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
false, true, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT));
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> call1;
+ ResultSavingCookieCallback<CookieInclusionStatus> call1;
cookie_monster_->SetAllCookiesAsync(list, call1.MakeCallback());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(call1.was_run());
@@ -982,7 +1031,7 @@ TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
EXPECT_EQ("LOAD; ADD; ADD; ", TakeCommandSummary());
// 2nd set doesn't need to read from store. It erases the old cookies, though.
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> call2;
+ ResultSavingCookieCallback<CookieInclusionStatus> call2;
cookie_monster_->SetAllCookiesAsync(list, call2.MakeCallback());
ASSERT_TRUE(call2.was_run());
EXPECT_TRUE(call2.result().IsInclude());
@@ -1183,30 +1232,30 @@ TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
bool get_cookie_list_callback_was_run = false;
GetCookieListCallback get_cookie_list_callback_deferred;
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookies_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookies_callback;
base::RunLoop run_loop;
cookie_monster_->GetCookieListWithOptionsAsync(
http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
- base::BindLambdaForTesting([&](const CookieStatusList& cookies,
- const CookieStatusList& excluded_list) {
- // This should complete before the set.
- get_cookie_list_callback_was_run = true;
- EXPECT_FALSE(set_cookies_callback.was_run());
- EXPECT_THAT(cookies, MatchesCookieLine("X=1"));
- // Can't use TakeCommandSummary here since ExecuteLoads is walking
- // through the data it takes.
- EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ",
- CommandSummary(persistent_store_->commands()));
-
- // Queue up a second get. It should see the result of the set queued
- // before it.
- cookie_monster_->GetCookieListWithOptionsAsync(
- http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
- get_cookie_list_callback_deferred.MakeCallback());
-
- run_loop.Quit();
- }));
+ base::BindLambdaForTesting(
+ [&](const CookieAccessResultList& cookies,
+ const CookieAccessResultList& excluded_list) {
+ // This should complete before the set.
+ get_cookie_list_callback_was_run = true;
+ EXPECT_FALSE(set_cookies_callback.was_run());
+ EXPECT_THAT(cookies, MatchesCookieLine("X=1"));
+ // Can't use TakeCommandSummary here since ExecuteLoads is walking
+ // through the data it takes.
+ EXPECT_EQ("LOAD; LOAD_FOR_KEY:foo.com; ",
+ CommandSummary(persistent_store_->commands()));
+
+ // Queue up a second get. It should see the result of the set queued
+ // before it.
+ cookie_monster_->GetCookieListWithOptionsAsync(
+ http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
+ get_cookie_list_callback_deferred.MakeCallback());
+
+ run_loop.Quit();
+ }));
cookie_monster_->SetCanonicalCookieAsync(
CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
@@ -1446,15 +1495,13 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), foo_url, "x=1")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NONCOOKIEABLE_SCHEME}));
+ {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm.get(),
CanonicalCookie::Create(foo_url, "y=1", now, server_time),
foo_url, false /*modify_httponly*/)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NONCOOKIEABLE_SCHEME}));
+ {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm_foo.get(), foo_url, "x=1").IsInclude());
@@ -1466,15 +1513,13 @@ TEST_F(CookieMonsterTest, SetCookieableSchemes) {
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm_foo.get(), http_url, "x=1")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NONCOOKIEABLE_SCHEME}));
+ {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
EXPECT_TRUE(SetCanonicalCookieReturnStatus(
cm_foo.get(),
CanonicalCookie::Create(http_url, "y=1", now, server_time),
http_url, false /*modify_httponly*/)
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NONCOOKIEABLE_SCHEME}));
+ {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
}
TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
@@ -1573,7 +1618,7 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) {
CookieOptions do_not_return_excluded;
do_not_return_excluded.unset_return_excluded_cookies();
- CookieStatusList excluded_cookies = GetExcludedCookiesForURLWithOptions(
+ CookieAccessResultList excluded_cookies = GetExcludedCookiesForURLWithOptions(
cm.get(), http_www_foo_.url(), do_not_return_excluded);
auto iter = excluded_cookies.begin();
@@ -1587,8 +1632,8 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) {
ASSERT_TRUE(iter != excluded_cookies.end());
EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain());
EXPECT_EQ("E", iter->cookie.Name());
- EXPECT_TRUE(iter->status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
ASSERT_TRUE(++iter == excluded_cookies.end());
@@ -1607,14 +1652,14 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) {
ASSERT_TRUE(iter != excluded_cookies.end());
EXPECT_EQ(http_www_foo_.host(), iter->cookie.Domain());
EXPECT_EQ("A", iter->cookie.Name());
- EXPECT_TRUE(iter->status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
+ EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
ASSERT_TRUE(++iter != excluded_cookies.end());
EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain());
EXPECT_EQ("E", iter->cookie.Name());
- EXPECT_TRUE(iter->status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ EXPECT_TRUE(iter->access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
ASSERT_TRUE(++iter == excluded_cookies.end());
@@ -1674,15 +1719,15 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURLPathMatching) {
EXPECT_TRUE(
CreateAndSetCookie(cm.get(), http_www_foo_.url(), "E=F;", options));
- CookieStatusList excluded_cookies =
+ CookieAccessResultList excluded_cookies =
GetExcludedCookiesForURL(cm.get(), www_foo_foo_.url());
auto it = excluded_cookies.begin();
ASSERT_TRUE(it != excluded_cookies.end());
EXPECT_EQ("C", it->cookie.Name());
EXPECT_EQ("/bar", it->cookie.Path());
- EXPECT_TRUE(it->status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
+ EXPECT_TRUE(it->access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
ASSERT_TRUE(++it == excluded_cookies.end());
@@ -1692,8 +1737,8 @@ TEST_F(CookieMonsterTest, GetExcludedCookiesForURLPathMatching) {
ASSERT_TRUE(it != excluded_cookies.end());
EXPECT_EQ("A", it->cookie.Name());
EXPECT_EQ("/foo", it->cookie.Path());
- EXPECT_TRUE(it->status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
+ EXPECT_TRUE(it->access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
ASSERT_TRUE(++it == excluded_cookies.end());
}
@@ -2189,8 +2234,7 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2278,8 +2322,7 @@ TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
CookieOptions::MakeAllInclusive(),
set_cookie_callback.MakeCallback());
@@ -2326,8 +2369,7 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
// Get all cookies task that queues a task to set a cookie when executed.
auto cookie = CanonicalCookie::Create(kUrl, "a=b", base::Time::Now(),
base::nullopt /* server_time */);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
cm->GetAllCookiesAsync(base::BindOnce(
&RunClosureOnAllCookiesReceived,
base::BindOnce(&CookieStore::SetCanonicalCookieAsync,
@@ -2720,6 +2762,95 @@ TEST_F(CookieMonsterTest, CookieSourceHistogram) {
CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1);
}
+// Test that inserting the first cookie for a key and deleting the last cookie
+// for a key correctly reflected in the Cookie.NumKeys histogram.
+TEST_F(CookieMonsterTest, NumKeysHistogram) {
+ const char kHistogramName[] = "Cookie.NumKeys";
+
+ // Test loading cookies from store.
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
+ initial_cookies.push_back(CanonicalCookie::Create(
+ GURL("http://domain1.test"), "A=1", base::Time::Now(), base::nullopt));
+ initial_cookies.push_back(CanonicalCookie::Create(
+ GURL("http://domain2.test"), "A=1", base::Time::Now(), base::nullopt));
+ initial_cookies.push_back(
+ CanonicalCookie::Create(GURL("http://sub.domain2.test"), "A=1",
+ base::Time::Now(), base::nullopt));
+ initial_cookies.push_back(CanonicalCookie::Create(
+ GURL("http://domain3.test"), "A=1", base::Time::Now(), base::nullopt));
+ initial_cookies.push_back(CanonicalCookie::Create(
+ GURL("http://domain3.test"), "B=1", base::Time::Now(), base::nullopt));
+ store->SetLoadExpectation(true /* return_value */,
+ std::move(initial_cookies));
+ auto cm = std::make_unique<CookieMonster>(store.get(), &net_log_);
+ {
+ base::HistogramTester histogram_tester;
+ // Access the cookies to trigger loading from the persistent store.
+ EXPECT_EQ(5u, this->GetAllCookies(cm.get()).size());
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ // There should be 3 keys: "domain1.test", "domain2.test", and
+ // "domain3.test".
+ histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test adding cookies for already existing key.
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain1.test"),
+ "B=1", CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("http://sub.domain1.test"),
+ "B=1", CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test adding a cookie for a new key.
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
+ "A=1", CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test overwriting the only cookie for a key. (Deletes and inserts, so the
+ // total doesn't change.)
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
+ "A=2", CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test deleting cookie for a key with more than one cookie.
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain2.test"),
+ "A=1; Max-Age=0",
+ CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 4 /* sample */,
+ 1 /* count */);
+ }
+
+ // Test deleting cookie for a key with only one cookie.
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(CreateAndSetCookie(cm.get(), GURL("https://domain4.test"),
+ "A=1; Max-Age=0",
+ CookieOptions::MakeAllInclusive()));
+ EXPECT_TRUE(cm->DoRecordPeriodicStatsForTesting());
+ histogram_tester.ExpectUniqueSample(kHistogramName, 3 /* sample */,
+ 1 /* count */);
+ }
+}
+
TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_));
@@ -2728,10 +2859,9 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
auto preexisting_cookie = CanonicalCookie::Create(
https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
base::nullopt /* server_time */);
- CanonicalCookie::CookieInclusionStatus status =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- https_www_foo_.url(),
- true /* can_modify_httponly */);
+ CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
+ true /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
// Set a new cookie with a different name. Should work because cookies with
@@ -2753,7 +2883,7 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
http_www_foo_.url(),
true /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
CookieOptions::MakeAllInclusive()),
@@ -2784,7 +2914,7 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
http_www_foo_.url(),
true /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// The preexisting cookie should still be there.
EXPECT_THAT(GetCookiesWithOptions(cm.get(), https_www_foo_.url(),
CookieOptions::MakeAllInclusive()),
@@ -2812,7 +2942,7 @@ TEST_F(CookieMonsterTest, MaybeDeleteEquivalentCookieAndUpdateStatus) {
https_www_foo_.url(),
false /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
entries = net_log_.GetEntries();
ExpectLogContainsSomewhere(
@@ -2832,10 +2962,9 @@ TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
auto preexisting_cookie = CanonicalCookie::Create(
https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
base::nullopt /* server_time */);
- CanonicalCookie::CookieInclusionStatus status =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- https_www_foo_.url(),
- true /* can_modify_httponly */);
+ CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
+ true /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
// Attempt to set a new cookie with the same name that is not Secure or
@@ -2847,8 +2976,8 @@ TEST_F(CookieMonsterTest, SkipDontOverwriteForMultipleReasons) {
http_www_foo_.url(),
false /* can_modify_httponly */);
EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE,
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE,
+ CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
auto entries = net_log_.GetEntries();
ExpectLogContainsSomewhere(
@@ -2868,21 +2997,19 @@ TEST_F(CookieMonsterTest, DontDeleteEquivalentCookieIfSetIsRejected) {
auto preexisting_cookie = CanonicalCookie::Create(
http_www_foo_.url(), "cookie=foo", base::Time::Now(),
base::nullopt /* server_time */);
- CanonicalCookie::CookieInclusionStatus status =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(preexisting_cookie),
- http_www_foo_.url(),
- false /* can_modify_httponly */);
+ CookieInclusionStatus status = SetCanonicalCookieReturnStatus(
+ cm.get(), std::move(preexisting_cookie), http_www_foo_.url(),
+ false /* can_modify_httponly */);
ASSERT_TRUE(status.IsInclude());
auto bad_cookie = CanonicalCookie::Create(
http_www_foo_.url(), "cookie=bar;secure", base::Time::Now(),
base::nullopt /* server_time */);
- CanonicalCookie::CookieInclusionStatus status2 =
- SetCanonicalCookieReturnStatus(cm.get(), std::move(bad_cookie),
- http_www_foo_.url(),
- false /* can_modify_httponly */);
+ CookieInclusionStatus status2 = SetCanonicalCookieReturnStatus(
+ cm.get(), std::move(bad_cookie), http_www_foo_.url(),
+ false /* can_modify_httponly */);
EXPECT_TRUE(status2.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
// Check that the original cookie is still there.
EXPECT_EQ("cookie=foo", GetCookies(cm.get(), https_www_foo_.url()));
@@ -2904,10 +3031,9 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B;").IsInclude());
// A secure cookie cannot be set from a URL with an insecure scheme.
- EXPECT_TRUE(
- CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=B; Secure")
- .HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=B; Secure")
+ .HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
// A secure cookie can be set from a URL with a secure scheme.
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "A=B; Secure")
@@ -2919,8 +3045,7 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C;")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// If a non-secure cookie is created from a URL with an secure scheme, and a
// secure cookie with the same name already exists, update the cookie.
@@ -2939,13 +3064,11 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
.IsInclude());
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; path=/")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; path=/my/path")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// But if the existing cookie has a path somewhere under the root, cookies
// with the same name may be set for paths which don't overlap the existing
@@ -2963,13 +3086,11 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
"WITH_PATH=C; path=/my/path")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
"WITH_PATH=C; path=/my/path/sub")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
DeleteAll(cm.get());
@@ -2994,12 +3115,10 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=D; path=/foo")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=D; path=/")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_THAT(GetCookies(cm.get(), https_foo_url), testing::HasSubstr("A=C"));
// ...but the original insecure cookie is still retained.
@@ -3022,13 +3141,11 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=C; domain=foo.com")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url,
"A=C; domain=www.foo.com")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// Since A=B was set above with no domain string, set a different cookie here
// so the insecure examples aren't trying to overwrite the one above.
@@ -3038,17 +3155,14 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=D; domain=foo.com")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=D")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
EXPECT_TRUE(
CreateAndSetCookieReturnStatus(cm.get(), http_superdomain_url, "B=D")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}));
// Verify that if an httponly version of the cookie exists, adding a Secure
// version of the cookie still does not overwrite it.
@@ -3059,8 +3173,7 @@ TEST_F(CookieMonsterTest, SetSecureCookies) {
// which in this case includes "exclude_httponly = true".
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), https_url, "C=E; Secure")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_HTTP_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_HTTP_ONLY}));
auto entries = net_log_.GetEntries();
ExpectLogContainsSomewhere(
@@ -3109,8 +3222,7 @@ TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) {
// cookie exists.
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "A=1")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}))
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
<< "Insecure host cookie from " << http_url
<< " should not be set if equivalent secure host cookie from "
<< preexisting_cookie_url << " exists.";
@@ -3118,15 +3230,13 @@ TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) {
cm.get(), http_url,
base::StrCat({"A=2; Domain=", new_cookie_host}))
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}))
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
<< "Insecure domain cookie from " << http_url
<< " should not be set if equivalent secure host cookie from "
<< preexisting_cookie_url << " exists.";
EXPECT_TRUE(CreateAndSetCookieReturnStatus(cm.get(), http_url, "B=1")
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}))
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
<< "Insecure host cookie from " << http_url
<< " should not be set if equivalent secure domain cookie from "
<< preexisting_cookie_url << " exists.";
@@ -3134,8 +3244,7 @@ TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_DomainMatch) {
cm.get(), http_url,
base::StrCat({"B=2; Domain=", new_cookie_host}))
.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE}))
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE}))
<< "Insecure domain cookie from " << http_url
<< " should not be set if equivalent secure domain cookie from "
<< preexisting_cookie_url << " exists.";
@@ -3282,14 +3391,11 @@ TEST_F(CookieMonsterTest, LeaveSecureCookiesAlone_PathMatch) {
// Don't set insecure cookie from an insecure URL if equivalent secure
// cookie exists.
- CanonicalCookie::CookieInclusionStatus set =
- CreateAndSetCookieReturnStatus(
- cm.get(), http_url,
- base::StrCat({"A=1; Path=", new_cookie_path}));
+ CookieInclusionStatus set = CreateAndSetCookieReturnStatus(
+ cm.get(), http_url, base::StrCat({"A=1; Path=", new_cookie_path}));
EXPECT_TRUE(should_path_match
? set.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_OVERWRITE_SECURE})
+ {CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE})
: set.IsInclude())
<< "Insecure cookie from " << http_url << " should "
<< (should_path_match ? "not " : "")
@@ -3507,8 +3613,7 @@ TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
CookieMonster cm(persistent_store.get(), nullptr);
// Start of a canonical cookie set.
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- callback_set;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback_set;
GURL cookie_url("http://a.com/");
cm.SetCanonicalCookieAsync(
CanonicalCookie::Create(cookie_url, "A=B", base::Time::Now(),
@@ -3594,16 +3699,14 @@ TEST_F(CookieMonsterTest, DeleteCookieWithInheritedTimestamps) {
// Write a cookie created at |t1|.
auto cookie = CanonicalCookie::Create(url, cookie_line, t1, server_time);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_callback_1;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_callback_1;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_1.MakeCallback());
set_callback_1.WaitUntilDone();
// Overwrite the cookie at |t2|.
cookie = CanonicalCookie::Create(url, cookie_line, t2, server_time);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_callback_2;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_callback_2;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options,
set_callback_2.MakeCallback());
set_callback_2.WaitUntilDone();
@@ -3627,7 +3730,7 @@ TEST_F(CookieMonsterTest, RejectCreatedSameSiteCookieOnSet) {
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// Cookie can be created successfully; SameSite is not checked on Creation.
auto cookie =
CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
@@ -3636,12 +3739,12 @@ TEST_F(CookieMonsterTest, RejectCreatedSameSiteCookieOnSet) {
ASSERT_TRUE(status.IsInclude());
// ... but the environment is checked on set, so this may be rejected then.
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), url, env_cross_site,
callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
+ {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}));
}
TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
@@ -3649,7 +3752,7 @@ TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
std::string cookie_line = "foo=bar; Secure";
CookieMonster cm(nullptr, nullptr);
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// Cookie can be created successfully from an any url. Secure is not checked
// on Create.
auto cookie =
@@ -3660,13 +3763,13 @@ TEST_F(CookieMonsterTest, RejectCreatedSecureCookieOnSet) {
ASSERT_TRUE(status.IsInclude());
// Cookie is rejected when attempting to set from a non-secure scheme.
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), http_url,
CookieOptions::MakeAllInclusive(),
callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
}
TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
@@ -3674,7 +3777,7 @@ TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
std::string cookie_line = "foo=bar; HttpOnly";
CookieMonster cm(nullptr, nullptr);
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
// Cookie can be created successfully; HttpOnly is not checked on Create.
auto cookie =
CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
@@ -3690,12 +3793,12 @@ TEST_F(CookieMonsterTest, RejectCreatedHttpOnlyCookieOnSet) {
CookieOptions::SameSiteCookieContext(
CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
options_no_httponly.set_exclude_httponly(); // Default, but make it explicit.
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm.SetCanonicalCookieAsync(std::move(cookie), url, options_no_httponly,
callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.result().HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
+ {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
}
// Test the CookiesWithoutSameSiteMustBeSecure experimental option (in
@@ -3708,7 +3811,7 @@ TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
bool is_cookies_without_samesite_must_be_secure_enabled;
bool is_url_secure;
std::string cookie_line;
- CanonicalCookie::CookieInclusionStatus expected_set_cookie_result;
+ CookieInclusionStatus expected_set_cookie_result;
// Only makes sense to check if result is INCLUDE:
CookieEffectiveSameSite expected_effective_samesite =
CookieEffectiveSameSite::NO_RESTRICTION;
@@ -3716,80 +3819,67 @@ TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
} test_cases[] = {
// Feature enabled:
// Cookie set from a secure URL with SameSite enabled is not rejected.
- {true, true, "A=B; SameSite=Lax",
- CanonicalCookie::CookieInclusionStatus(),
+ {true, true, "A=B; SameSite=Lax", CookieInclusionStatus(),
CookieEffectiveSameSite::LAX_MODE},
// Cookie set from a secure URL which is defaulted into Lax is not
// rejected.
{true, true, "A=B", // recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, kShortAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
+ kShortAge},
{true, true, "A=B", // not-recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE, kLongAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
// Cookie set from a secure URL with SameSite=None and Secure is set.
- {true, true, "A=B; SameSite=None; Secure",
- CanonicalCookie::CookieInclusionStatus(),
+ {true, true, "A=B; SameSite=None; Secure", CookieInclusionStatus(),
CookieEffectiveSameSite::NO_RESTRICTION},
// Cookie set from a secure URL with SameSite=None but not specifying
// Secure is rejected.
{true, true, "A=B; SameSite=None",
- CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_NONE_INSECURE,
- CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_NONE_INSECURE)},
+ CookieInclusionStatus(
+ CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE,
+ CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE)},
// Cookie set from an insecure URL which defaults into LAX_MODE is not
// rejected.
{true, false, "A=B", // recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, kShortAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
+ kShortAge},
{true, false, "A=B", // not-recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE, kLongAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
{true, false, "A=B; Max-Age=1000000", // recently-set persistent cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, kShortAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
+ kShortAge},
{true, false,
"A=B; Max-Age=1000000", // not-recently-set persistent cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE, kLongAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
// Feature not enabled (but SameSiteByDefaultCookies is still enabled):
// Cookie set from a secure URL with SameSite enabled is not rejected.
- {false, true, "A=B; SameSite=Lax",
- CanonicalCookie::CookieInclusionStatus(),
+ {false, true, "A=B; SameSite=Lax", CookieInclusionStatus(),
CookieEffectiveSameSite::LAX_MODE},
// Cookie set from a secure URL which is defaulted into Lax is not
// rejected.
{false, true, "A=B", // recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, kShortAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
+ kShortAge},
{false, true, "A=B", // not-recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE, kLongAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
// Cookie set from a secure URL with SameSite=None and Secure is set.
- {false, true, "A=B; SameSite=None; Secure",
- CanonicalCookie::CookieInclusionStatus(),
+ {false, true, "A=B; SameSite=None; Secure", CookieInclusionStatus(),
CookieEffectiveSameSite::NO_RESTRICTION},
// Cookie set from an insecure URL with SameSite=None (which can't ever be
// secure because it's an insecure URL) is NOT rejected, because
// CookiesWithoutSameSiteMustBeSecure is not enabled.
{false, false, "A=B; SameSite=None",
- CanonicalCookie::CookieInclusionStatus::MakeFromReasonsForTesting(
- std::vector<
- CanonicalCookie::CookieInclusionStatus::ExclusionReason>(),
- {CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_NONE_INSECURE}),
+ CookieInclusionStatus::MakeFromReasonsForTesting(
+ std::vector<CookieInclusionStatus::ExclusionReason>(),
+ {CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE}),
CookieEffectiveSameSite::NO_RESTRICTION},
// Cookie set from an insecure URL which is defaulted into Lax is not
// rejected.
{false, false, "A=B", // recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, kShortAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
+ kShortAge},
{false, false, "A=B", // not-recently-set session cookie.
- CanonicalCookie::CookieInclusionStatus(),
- CookieEffectiveSameSite::LAX_MODE, kLongAge},
+ CookieInclusionStatus(), CookieEffectiveSameSite::LAX_MODE, kLongAge},
};
auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
@@ -3820,10 +3910,9 @@ TEST_F(CookieMonsterTest, CookiesWithoutSameSiteMustBeSecure) {
base::nullopt /* server_time */);
// Make a copy so we can delete it after the test.
CanonicalCookie cookie_copy = *cookie;
- CanonicalCookie::CookieInclusionStatus result =
- SetCanonicalCookieReturnStatus(
- cm.get(), std::move(cookie), url,
- true /* can_modify_httponly (irrelevant) */);
+ CookieInclusionStatus result = SetCanonicalCookieReturnStatus(
+ cm.get(), std::move(cookie), url,
+ true /* can_modify_httponly (irrelevant) */);
EXPECT_EQ(test.expected_set_cookie_result, result)
<< "Test case " << i << " failed.";
if (result.IsInclude()) {
diff --git a/chromium/net/cookies/cookie_store.h b/chromium/net/cookies/cookie_store.h
index 4157f0ce83a..47f2942cd32 100644
--- a/chromium/net/cookies/cookie_store.h
+++ b/chromium/net/cookies/cookie_store.h
@@ -20,6 +20,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_delegate.h"
#include "net/cookies/cookie_deletion_info.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_options.h"
class GURL;
@@ -45,8 +46,8 @@ class NET_EXPORT CookieStore {
public:
// Callback definitions.
using GetCookieListCallback =
- base::OnceCallback<void(const CookieStatusList& included_cookies,
- const CookieStatusList& excluded_list)>;
+ base::OnceCallback<void(const CookieAccessResultList& included_cookies,
+ const CookieAccessResultList& excluded_list)>;
using GetAllCookiesCallback =
base::OnceCallback<void(const CookieList& cookies)>;
// |access_semantics_list| is guaranteed to the same length as |cookies|.
@@ -54,7 +55,7 @@ class NET_EXPORT CookieStore {
const CookieList& cookies,
const std::vector<CookieAccessSemantics>& access_semantics_list)>;
using SetCookiesCallback =
- base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus status)>;
+ base::OnceCallback<void(CookieInclusionStatus status)>;
using DeleteCallback = base::OnceCallback<void(uint32_t num_deleted)>;
using SetCookieableSchemesCallback = base::OnceCallback<void(bool success)>;
diff --git a/chromium/net/cookies/cookie_store_test_callbacks.cc b/chromium/net/cookies/cookie_store_test_callbacks.cc
index a582a6eb8d2..67461b50bf0 100644
--- a/chromium/net/cookies/cookie_store_test_callbacks.cc
+++ b/chromium/net/cookies/cookie_store_test_callbacks.cc
@@ -60,10 +60,11 @@ GetCookieListCallback::GetCookieListCallback(base::Thread* run_in_thread)
GetCookieListCallback::~GetCookieListCallback() = default;
-void GetCookieListCallback::Run(const CookieStatusList& cookies,
- const CookieStatusList& excluded_cookies) {
- cookies_with_statuses_ = cookies;
- cookies_ = cookie_util::StripStatuses(cookies);
+void GetCookieListCallback::Run(
+ const CookieAccessResultList& cookies,
+ const CookieAccessResultList& excluded_cookies) {
+ cookies_with_access_results_ = cookies;
+ cookies_ = cookie_util::StripAccessResults(cookies);
excluded_cookies_ = excluded_cookies;
CallbackEpilogue();
}
diff --git a/chromium/net/cookies/cookie_store_test_callbacks.h b/chromium/net/cookies/cookie_store_test_callbacks.h
index 54b00b565d7..b3195c20aca 100644
--- a/chromium/net/cookies/cookie_store_test_callbacks.h
+++ b/chromium/net/cookies/cookie_store_test_callbacks.h
@@ -109,26 +109,27 @@ class GetCookieListCallback : public CookieCallback {
~GetCookieListCallback();
- void Run(const CookieStatusList& cookies,
- const CookieStatusList& excluded_cookies);
+ void Run(const CookieAccessResultList& cookies,
+ const CookieAccessResultList& excluded_cookies);
// Makes a callback that will invoke Run. Assumes that |this| will be kept
// alive till the time the callback is used.
- base::OnceCallback<void(const CookieStatusList&, const CookieStatusList&)>
+ base::OnceCallback<void(const CookieAccessResultList&,
+ const CookieAccessResultList&)>
MakeCallback() {
return base::BindOnce(&GetCookieListCallback::Run, base::Unretained(this));
}
const CookieList& cookies() { return cookies_; }
- const CookieStatusList& cookies_with_statuses() {
- return cookies_with_statuses_;
+ const CookieAccessResultList& cookies_with_access_results() {
+ return cookies_with_access_results_;
}
- const CookieStatusList& excluded_cookies() { return excluded_cookies_; }
+ const CookieAccessResultList& excluded_cookies() { return excluded_cookies_; }
private:
CookieList cookies_;
- CookieStatusList cookies_with_statuses_;
- CookieStatusList excluded_cookies_;
+ CookieAccessResultList cookies_with_access_results_;
+ CookieAccessResultList excluded_cookies_;
};
class GetAllCookiesCallback : public CookieCallback {
diff --git a/chromium/net/cookies/cookie_store_test_helpers.cc b/chromium/net/cookies/cookie_store_test_helpers.cc
index a709c84f134..aae0c873540 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.cc
+++ b/chromium/net/cookies/cookie_store_test_helpers.cc
@@ -65,25 +65,24 @@ DelayedCookieMonsterChangeDispatcher::AddCallbackForAllChanges(
}
DelayedCookieMonster::DelayedCookieMonster()
- : cookie_monster_(new CookieMonster(nullptr /* store */,
- nullptr /* netlog */)),
+ : cookie_monster_(
+ new CookieMonster(nullptr /* store */, nullptr /* netlog */)),
did_run_(false),
- result_(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE) {}
+ result_(CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE) {}
DelayedCookieMonster::~DelayedCookieMonster() = default;
void DelayedCookieMonster::SetCookiesInternalCallback(
- CanonicalCookie::CookieInclusionStatus result) {
+ CookieInclusionStatus result) {
result_ = result;
did_run_ = true;
}
void DelayedCookieMonster::GetCookieListWithOptionsInternalCallback(
- const CookieStatusList& cookie_list,
- const CookieStatusList& excluded_cookies) {
- cookie_status_list_ = cookie_list;
- cookie_list_ = cookie_util::StripStatuses(cookie_status_list_);
+ const CookieAccessResultList& cookie_list,
+ const CookieAccessResultList& excluded_cookies) {
+ cookie_access_result_list_ = cookie_list;
+ cookie_list_ = cookie_util::StripAccessResults(cookie_access_result_list_);
did_run_ = true;
}
@@ -136,7 +135,8 @@ void DelayedCookieMonster::InvokeSetCookiesCallback(
void DelayedCookieMonster::InvokeGetCookieListCallback(
CookieMonster::GetCookieListCallback callback) {
if (!callback.is_null())
- std::move(callback).Run(cookie_status_list_, CookieStatusList());
+ std::move(callback).Run(cookie_access_result_list_,
+ CookieAccessResultList());
}
void DelayedCookieMonster::DeleteCanonicalCookieAsync(
diff --git a/chromium/net/cookies/cookie_store_test_helpers.h b/chromium/net/cookies/cookie_store_test_helpers.h
index ae6a152b7f2..5f9f03d15d4 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.h
+++ b/chromium/net/cookies/cookie_store_test_helpers.h
@@ -86,13 +86,12 @@ class DelayedCookieMonster : public CookieStore {
private:
// Be called immediately from CookieMonster.
- void SetCookiesInternalCallback(
- CanonicalCookie::CookieInclusionStatus result);
+ void SetCookiesInternalCallback(CookieInclusionStatus result);
void GetCookiesWithOptionsInternalCallback(const std::string& cookie);
void GetCookieListWithOptionsInternalCallback(
- const CookieStatusList& cookie,
- const CookieStatusList& excluded_cookies);
+ const CookieAccessResultList& cookie,
+ const CookieAccessResultList& excluded_cookies);
// Invoke the original callbacks.
@@ -107,10 +106,10 @@ class DelayedCookieMonster : public CookieStore {
DelayedCookieMonsterChangeDispatcher change_dispatcher_;
bool did_run_;
- CanonicalCookie::CookieInclusionStatus result_;
+ CookieInclusionStatus result_;
std::string cookie_;
std::string cookie_line_;
- CookieStatusList cookie_status_list_;
+ CookieAccessResultList cookie_access_result_list_;
CookieList cookie_list_;
DISALLOW_COPY_AND_ASSIGN(DelayedCookieMonster);
diff --git a/chromium/net/cookies/cookie_store_unittest.h b/chromium/net/cookies/cookie_store_unittest.h
index ee8e46f9b1d..026ed96ba11 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -171,7 +171,8 @@ class CookieStoreTest : public testing::Test {
}
// This does not update the access time on the cookies.
- CookieStatusList GetExcludedCookiesForURL(CookieStore* cs, const GURL& url) {
+ CookieAccessResultList GetExcludedCookiesForURL(CookieStore* cs,
+ const GURL& url) {
DCHECK(cs);
GetCookieListCallback callback;
CookieOptions options = CookieOptions::MakeAllInclusive();
@@ -200,7 +201,7 @@ class CookieStoreTest : public testing::Test {
if (!cookie)
return false;
DCHECK(cs);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
@@ -212,7 +213,7 @@ class CookieStoreTest : public testing::Test {
const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
CookieOptions options;
if (can_modify_httponly)
options.set_include_httponly();
@@ -248,11 +249,11 @@ class CookieStoreTest : public testing::Test {
return CreateAndSetCookie(cs, url, cookie_line, options);
}
- CanonicalCookie::CookieInclusionStatus CreateAndSetCookieReturnStatus(
+ CookieInclusionStatus CreateAndSetCookieReturnStatus(
CookieStore* cs,
const GURL& url,
const std::string& cookie_line) {
- CanonicalCookie::CookieInclusionStatus create_status;
+ CookieInclusionStatus create_status;
auto cookie = CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
base::nullopt /* server_time */,
&create_status);
@@ -267,20 +268,20 @@ class CookieStoreTest : public testing::Test {
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
DCHECK(cs);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cs->SetCanonicalCookieAsync(std::move(cookie), url, options,
callback.MakeCallback());
callback.WaitUntilDone();
return callback.result();
}
- CanonicalCookie::CookieInclusionStatus SetCanonicalCookieReturnStatus(
+ CookieInclusionStatus SetCanonicalCookieReturnStatus(
CookieStore* cs,
std::unique_ptr<CanonicalCookie> cookie,
const GURL& source_url,
bool can_modify_httponly) {
DCHECK(cs);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
CookieOptions options;
if (can_modify_httponly)
options.set_include_httponly();
@@ -568,12 +569,11 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), true)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
// A Secure cookie can be created from an insecure URL, but is rejected upon
// setting.
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
auto cookie = CanonicalCookie::Create(
this->http_www_foo_.url(), "foo=1; Secure", base::Time::Now(),
base::nullopt /* server_time */, &status);
@@ -582,8 +582,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
EXPECT_TRUE(
this->SetCanonicalCookieReturnStatus(cs, std::move(cookie),
this->http_www_foo_.url(), true)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
// A secure source is also required for overwriting secure cookies. Writing
// a secure cookie then overwriting it from a non-secure source should fail.
@@ -603,8 +602,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
base::Time(), true /* secure */, false /* httponly */,
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), true /* modify_http_only */)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
if (TypeParam::supports_http_only) {
// Permission to modify http only cookies is required to set an
@@ -618,12 +616,11 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
true /* httponly */, CookieSameSite::LAX_MODE,
COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), false /* modify_http_only */)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
// A HttpOnly cookie can be created, but is rejected
// upon setting if the options do not specify include_httponly.
- CanonicalCookie::CookieInclusionStatus create_status;
+ CookieInclusionStatus create_status;
auto c = CanonicalCookie::Create(
this->http_www_foo_.url(), "bar=1; HttpOnly", base::Time::Now(),
base::nullopt /* server_time */, &create_status);
@@ -633,8 +630,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
this->SetCanonicalCookieReturnStatus(cs, std::move(c),
this->http_www_foo_.url(),
false /* can_modify_httponly */)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
// Permission to modify httponly cookies is also required to overwrite
// an httponly cookie.
@@ -655,8 +651,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
true /* httponly */, CookieSameSite::LAX_MODE,
COOKIE_PRIORITY_DEFAULT),
this->http_www_foo_.url(), false /* modify_http_only */)
- .HasExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
+ .HasExclusionReason(CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
} else {
// Leave store in same state as if the above tests had been run.
EXPECT_TRUE(this->SetCanonicalCookie(
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index 7f3afe4e178..99859d89606 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/check.h"
#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
@@ -121,6 +122,10 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet(
} // namespace
+void FireStorageAccessHistogram(StorageAccessResult result) {
+ UMA_HISTOGRAM_ENUMERATION("API.StorageAccess.AllowedRequests", result);
+}
+
bool DomainIsHostOnly(const std::string& domain_string) {
return (domain_string.empty() || domain_string[0] != '.');
}
@@ -551,6 +556,48 @@ CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSubresource(
return CookieOptions::SameSiteCookieContext::MakeInclusive();
}
+bool IsSameSiteCompatPair(const CanonicalCookie& c1,
+ const CanonicalCookie& c2,
+ const CookieOptions& options) {
+ if (options.exclude_httponly() && (c1.IsHttpOnly() || c2.IsHttpOnly()))
+ return false;
+
+ if (c1.IsEquivalent(c2))
+ return false;
+
+ // One of them is SameSite=None and Secure; the other one has unspecified
+ // SameSite.
+ bool same_site_attributes_ok =
+ c1.SameSite() == CookieSameSite::NO_RESTRICTION && c1.IsSecure() &&
+ c2.SameSite() == CookieSameSite::UNSPECIFIED;
+ same_site_attributes_ok =
+ same_site_attributes_ok ||
+ (c2.SameSite() == CookieSameSite::NO_RESTRICTION && c2.IsSecure() &&
+ c1.SameSite() == CookieSameSite::UNSPECIFIED);
+ if (!same_site_attributes_ok)
+ return false;
+
+ if (c1.Domain() != c2.Domain() || c1.Path() != c2.Path() ||
+ c1.Value() != c2.Value()) {
+ return false;
+ }
+
+ DCHECK(c1.Name() != c2.Name());
+ std::string shorter, longer;
+ std::tie(shorter, longer) = (c1.Name().length() < c2.Name().length())
+ ? std::tie(c1.Name(), c2.Name())
+ : std::tie(c2.Name(), c1.Name());
+ // One of them has a name that is a prefix or suffix of the other and has
+ // length at least 3 characters.
+ if (shorter.length() < kMinCompatPairNameLength)
+ return false;
+ if (base::StartsWith(longer, shorter, base::CompareCase::SENSITIVE) ||
+ base::EndsWith(longer, shorter, base::CompareCase::SENSITIVE)) {
+ return true;
+ }
+ return false;
+}
+
bool IsSameSiteByDefaultCookiesEnabled() {
return base::FeatureList::IsEnabled(features::kSameSiteByDefaultCookies);
}
@@ -610,21 +657,23 @@ bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date) {
return (base::Time::Now() - creation_date) < recency_threshold;
}
-base::OnceCallback<void(net::CanonicalCookie::CookieInclusionStatus)>
+base::OnceCallback<void(CookieInclusionStatus)>
AdaptCookieInclusionStatusToBool(base::OnceCallback<void(bool)> callback) {
return base::BindOnce(
[](base::OnceCallback<void(bool)> inner_callback,
- const net::CanonicalCookie::CookieInclusionStatus status) {
+ const CookieInclusionStatus status) {
bool success = status.IsInclude();
std::move(inner_callback).Run(success);
},
std::move(callback));
}
-CookieList StripStatuses(const CookieStatusList& cookie_status_list) {
+CookieList StripAccessResults(
+ const CookieAccessResultList& cookie_access_results_list) {
CookieList cookies;
- for (const CookieWithStatus& cookie_with_status : cookie_status_list) {
- cookies.push_back(cookie_with_status.cookie);
+ for (const CookieWithAccessResult& cookie_with_access_result :
+ cookie_access_results_list) {
+ cookies.push_back(cookie_with_access_result.cookie);
}
return cookies;
}
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index 3634058c1b0..be3cd3f458d 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/site_for_cookies.h"
#include "url/origin.h"
@@ -27,6 +28,23 @@ const int kVlogPerCookieMonster = 1;
const int kVlogSetCookies = 7;
const int kVlogGarbageCollection = 5;
+// Minimum name length for SameSite compatibility pair heuristic (see
+// IsSameSiteCompatPair() below.)
+const int kMinCompatPairNameLength = 3;
+
+// This enum must match the numbering for StorageAccessResult in
+// histograms/enums.xml. Do not reorder or remove items, only add new items
+// at the end.
+enum class StorageAccessResult {
+ ACCESS_BLOCKED = 0,
+ ACCESS_ALLOWED = 1,
+ ACCESS_ALLOWED_STORAGE_ACCESS_GRANT = 2,
+ kMaxValue = ACCESS_ALLOWED_STORAGE_ACCESS_GRANT,
+};
+// Helper to fire telemetry indicating if a given request for storage was
+// allowed or not by the provided |result|.
+NET_EXPORT void FireStorageAccessHistogram(StorageAccessResult result);
+
// Returns the effective TLD+1 for a given host. This only makes sense for http
// and https schemes. For other schemes, the host will be returned unchanged
// (minus any leading period).
@@ -172,6 +190,26 @@ ComputeSameSiteContextForSubresource(const GURL& url,
const SiteForCookies& site_for_cookies,
bool force_ignore_site_for_cookies);
+// Evaluates a heuristic to determine whether |c1| and |c2| are likely to be a
+// "double cookie" pair used for SameSite=None compatibility reasons.
+//
+// This returns true if all of the following are true:
+// 1. The cookies are not equivalent (i.e. same name, domain, and path).
+// 2. One of them is SameSite=None and Secure; the other one has unspecified
+// SameSite.
+// 3. Their domains are equal.
+// 4. Their paths are equal.
+// 5. Their values are equal.
+// 6. One of them has a name that is a prefix or suffix of the other and has
+// length at least 3 characters.
+//
+// |options| is the CookieOptions object used to access (get/set) the cookies.
+// If the CookieOptions indicate that HttpOnly cookies are not allowed, this
+// will return false if either of |c1| or |c2| is HttpOnly.
+NET_EXPORT bool IsSameSiteCompatPair(const CanonicalCookie& c1,
+ const CanonicalCookie& c2,
+ const CookieOptions& options);
+
// Returns whether the respective SameSite feature is enabled.
NET_EXPORT bool IsSameSiteByDefaultCookiesEnabled();
NET_EXPORT bool IsCookiesWithoutSameSiteMustBeSecureEnabled();
@@ -198,12 +236,13 @@ bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date);
//
// Can be used with SetCanonicalCookie when you don't need to know why a cookie
// was blocked, only whether it was blocked.
-NET_EXPORT base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus)>
+NET_EXPORT base::OnceCallback<void(CookieInclusionStatus)>
AdaptCookieInclusionStatusToBool(base::OnceCallback<void(bool)> callback);
-// Turn a CookieStatusList into a CookieList by stripping out the statuses
-// (for callers who don't care about the statuses).
-NET_EXPORT CookieList StripStatuses(const CookieStatusList& cookie_status_list);
+// Turn a CookieAccessResultList into a CookieList by stripping out access
+// results (for callers who only care about cookies).
+NET_EXPORT CookieList
+StripAccessResults(const CookieAccessResultList& cookie_access_result_list);
} // namespace cookie_util
} // namespace net
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index b95e1d6da26..14f8edf50f7 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -1216,13 +1216,11 @@ TEST(CookieUtilTest, AdaptCookieInclusionStatusToBool) {
base::OnceCallback<void(bool)> callback = base::BindLambdaForTesting(
[&result_out](bool result) { result_out = result; });
- base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus)>
- adapted_callback =
- cookie_util::AdaptCookieInclusionStatusToBool(std::move(callback));
+ base::OnceCallback<void(CookieInclusionStatus)> adapted_callback =
+ cookie_util::AdaptCookieInclusionStatusToBool(std::move(callback));
std::move(adapted_callback)
- .Run(CanonicalCookie::CookieInclusionStatus(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
+ .Run(CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR));
EXPECT_FALSE(result_out);
@@ -1233,11 +1231,144 @@ TEST(CookieUtilTest, AdaptCookieInclusionStatusToBool) {
adapted_callback =
cookie_util::AdaptCookieInclusionStatusToBool(std::move(callback));
- std::move(adapted_callback).Run(CanonicalCookie::CookieInclusionStatus());
+ std::move(adapted_callback).Run(CookieInclusionStatus());
EXPECT_TRUE(result_out);
}
+TEST(CookieUtilTest, IsSameSiteCompatPair) {
+ ASSERT_EQ(3, cookie_util::kMinCompatPairNameLength)
+ << "This test assumes that SameSite compatibility pairs have cookie name "
+ "length at least 3.";
+ GURL url("https://www.site.example/path");
+
+ struct {
+ const char* cookie_line_1;
+ const char* cookie_line_2;
+ bool expected_is_same_site_compat_pair;
+ } kTestCases[] = {
+ // Matching cases
+ {"name=value; SameSite=None; Secure", "name_legacy=value", true},
+ {"uid=value; SameSite=None; Secure", "uid_old=value", true},
+ {"name=value; SameSite=None; Secure", "name2=value; Secure", true},
+ {"name_samesite=value; SameSite=None; Secure", "name=value", true},
+ {"__Secure-name=value; SameSite=None; Secure", "name=value", true},
+ {"__Secure-3Pname=value; SameSite=None; Secure", "name=value", true},
+ {"name=value; SameSite=None; Secure; HttpOnly", "name_legacy=value",
+ true},
+ {"name=value; SameSite=None; Secure; Domain=site.example",
+ "name_legacy=value; Secure; Domain=site.example", true},
+ // Fails because cookies are equivalent
+ {"name=value; SameSite=None; Secure", "name=value", false},
+ // Fails SameSite criterion
+ {"name=value", "name_legacy=value", false},
+ {"name=value; SameSite=None", "name_legacy=value", false},
+ {"name=value; SameSite=None; Secure", "name_legacy=value; SameSite=None",
+ false},
+ {"name=value; SameSite=None; Secure",
+ "name_legacy=value; SameSite=None; Secure", false},
+ // Fails Domain criterion
+ {"name=value; SameSite=None; Secure; Domain=site.example",
+ "name_legacy=value", false},
+ {"name=value; SameSite=None; Secure; Domain=www.site.example",
+ "name_legacy=value", false},
+ {"name=value; SameSite=None; Secure",
+ "name_legacy=value; Domain=site.example", false},
+ {"name=value; SameSite=None; Secure",
+ "name_legacy=value; Domain=www.site.example", false},
+ // Fails Path criterion
+ {"name=value; SameSite=None; Secure; Path=/path", "name_legacy=value",
+ false},
+ {"name=value; SameSite=None; Secure; Path=/path",
+ "name_legacy=value; Path=/", false},
+ {"name=value; SameSite=None; Secure; Path=/",
+ "name_legacy=value; Path=/path", false},
+ {"name=value; SameSite=None; Secure", "name_legacy=value; Path=/path",
+ false},
+ // Fails value criterion
+ {"name=value; SameSite=None; Secure", "name_legacy=foobar", false},
+ {"name=value; SameSite=None; Secure", "name_legacy=value2", false},
+ // Fails name length criterion
+ {"id=value; SameSite=None; Secure", "id_legacy=value", false},
+ {"id_samesite=value; SameSite=None; Secure", "id=value", false},
+ {"value; SameSite=None; Secure", "legacy=value", false},
+ // Fails suffix/prefix criterion
+ {"name_samesite=value; SameSite=None; Secure", "name_legacy=value",
+ false},
+ {"name1=value; SameSite=None; Secure", "name2=value", false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ auto cookie1 = CanonicalCookie::Create(url, test_case.cookie_line_1,
+ base::Time::Now(), base::nullopt);
+ auto cookie2 = CanonicalCookie::Create(url, test_case.cookie_line_2,
+ base::Time::Now(), base::nullopt);
+
+ ASSERT_TRUE(cookie1);
+ ASSERT_TRUE(cookie2);
+ EXPECT_EQ(test_case.expected_is_same_site_compat_pair,
+ cookie_util::IsSameSiteCompatPair(
+ *cookie1, *cookie2, CookieOptions::MakeAllInclusive()));
+ EXPECT_EQ(test_case.expected_is_same_site_compat_pair,
+ cookie_util::IsSameSiteCompatPair(
+ *cookie2, *cookie1, CookieOptions::MakeAllInclusive()));
+ }
+}
+
+TEST(CookieUtilTest, IsSameSiteCompatPair_HttpOnly) {
+ GURL url("https://www.site.example/path");
+ auto new_cookie =
+ CanonicalCookie::Create(url, "name=value; SameSite=None; Secure",
+ base::Time::Now(), base::nullopt);
+ auto legacy_cookie = CanonicalCookie::Create(
+ url, "name_legacy=value", base::Time::Now(), base::nullopt);
+ auto http_only_new_cookie = CanonicalCookie::Create(
+ url, "name=value; SameSite=None; Secure; HttpOnly", base::Time::Now(),
+ base::nullopt);
+ auto http_only_legacy_cookie = CanonicalCookie::Create(
+ url, "name_legacy=value; HttpOnly", base::Time::Now(), base::nullopt);
+ ASSERT_TRUE(new_cookie);
+ ASSERT_TRUE(legacy_cookie);
+ ASSERT_TRUE(http_only_new_cookie);
+ ASSERT_TRUE(http_only_legacy_cookie);
+
+ // Allows HttpOnly access.
+ CookieOptions inclusive_options = CookieOptions::MakeAllInclusive();
+ // Disallows HttpOnly access.
+ CookieOptions restrictive_options;
+ // Allows SameSite but not HttpOnly access. (SameSite shouldn't matter.)
+ CookieOptions same_site_options;
+ same_site_options.set_same_site_cookie_context(
+ CookieOptions::SameSiteCookieContext::MakeInclusive());
+
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(*new_cookie, *legacy_cookie,
+ inclusive_options));
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *legacy_cookie, inclusive_options));
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(
+ *new_cookie, *http_only_legacy_cookie, inclusive_options));
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *http_only_legacy_cookie, inclusive_options));
+
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(*new_cookie, *legacy_cookie,
+ restrictive_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *legacy_cookie, restrictive_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *new_cookie, *http_only_legacy_cookie, restrictive_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *http_only_legacy_cookie, restrictive_options));
+
+ EXPECT_TRUE(cookie_util::IsSameSiteCompatPair(*new_cookie, *legacy_cookie,
+ same_site_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *legacy_cookie, same_site_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *new_cookie, *http_only_legacy_cookie, same_site_options));
+ EXPECT_FALSE(cookie_util::IsSameSiteCompatPair(
+ *http_only_new_cookie, *http_only_legacy_cookie, same_site_options));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/data/ssl/certificates/398_days_1_second_after_2020_09_01.pem b/chromium/net/data/ssl/certificates/398_days_1_second_after_2020_09_01.pem
new file mode 100644
index 00000000000..de02b968499
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/398_days_1_second_after_2020_09_01.pem
@@ -0,0 +1,85 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ ef:2f:0a:6a:75:56:1e:b1:0b:03:50:df:7c:9a:63:bb
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Sep 2 00:00:00 2020 GMT
+ Not After : Oct 5 00:00:01 2021 GMT
+ Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:a0:5a:8e:f1:48:37:d4:3a:96:e6:c1:b5:20:88:
+ 16:f4:a5:80:cb:72:18:0c:db:c0:26:9f:75:8a:c1:
+ 58:3a:a9:9c:05:fe:f4:9c:92:7f:2e:59:ec:97:77:
+ ca:87:43:0a:05:4a:d3:a6:af:67:f7:c1:9a:f3:7e:
+ 92:86:ed:c9:3e:89:b4:fa:be:c8:a7:6c:b5:02:a0:
+ b5:02:f1:83:41:18:d6:86:29:c8:b1:be:16:e0:15:
+ 49:2e:bf:d0:a0:65:b9:05:4b:52:f0:be:88:a4:30:
+ b1:73:f3:aa:69:65:80:99:ad:14:62:13:bc:7b:52:
+ 93:fe:91:4f:8a:b1:4c:d3:52:ac:77:7c:92:02:fc:
+ 34:c7:15:10:a8:70:f1:77:ec:0d:c7:5b:53:df:49:
+ 1f:be:59:a0:93:45:4b:eb:71:c2:ba:8f:0c:43:73:
+ 96:5c:f4:96:bd:ed:cd:8c:18:79:db:18:ef:29:5e:
+ d9:78:80:c4:92:ec:6b:e1:19:19:83:c3:4e:bb:08:
+ 1c:5d:8e:a4:10:24:48:fe:69:f5:d2:01:ef:a5:59:
+ ce:de:2f:b4:20:f4:83:b3:ef:e0:e8:af:09:69:dc:
+ 09:70:79:9b:3b:60:f6:6f:32:71:93:7a:29:9a:f3:
+ e1:54:5f:9c:5a:41:33:2a:f9:29:ec:db:83:45:9d:
+ 4f:59
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 70:97:92:9D:2A:18:0D:AD:5F:DE:86:29:A0:44:DF:0B:3E:41:A4:D5
+ X509v3 Authority Key Identifier:
+ keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ IP Address:127.0.0.1
+ Signature Algorithm: sha256WithRSAEncryption
+ 80:fe:bc:f5:9a:97:cf:a2:26:63:e5:4a:4a:53:71:bc:40:e2:
+ a5:30:21:28:f8:0e:12:b1:00:bc:ab:c8:50:8b:a7:fc:15:ef:
+ 3c:57:ef:92:90:ff:89:42:42:34:6d:00:ff:d6:0a:a8:89:0b:
+ c9:cf:fb:15:6a:6c:ab:c0:18:05:68:e5:a1:ef:d4:20:55:0c:
+ 4f:84:da:f7:df:29:4a:69:c9:8f:1c:c8:a6:c9:ca:a0:86:bc:
+ c4:4d:96:0f:62:63:4b:ea:85:8d:fa:5a:2b:7e:4e:1f:4a:60:
+ ed:8a:cc:f4:0f:6d:56:2f:ce:18:56:54:c3:1f:09:39:d2:62:
+ 63:75:11:3f:70:6f:cc:af:cb:c4:52:c7:1f:19:5f:ce:24:5b:
+ f8:54:c8:25:78:a8:51:eb:f9:26:41:e1:f0:a1:29:ec:fc:8c:
+ aa:ed:2c:fd:49:28:ff:ad:2a:ea:87:83:cf:02:ac:1b:2d:a1:
+ e7:0e:51:59:8f:62:ab:95:f1:b4:f2:9f:62:a7:04:b2:13:a8:
+ ae:41:88:b5:1c:0c:cf:5a:f3:a7:41:d2:9c:88:4d:50:54:14:
+ c3:58:c1:10:93:49:33:21:ff:00:41:0c:71:7e:00:ab:44:35:
+ ea:c1:c4:1c:76:a1:3a:09:21:35:8b:45:13:ba:9a:58:a0:e6:
+ 8f:1e:55:94
+-----BEGIN CERTIFICATE-----
+MIIDzzCCAregAwIBAgIRAO8vCmp1Vh6xCwNQ33yaY7swDQYJKoZIhvcNAQELBQAw
+YzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
+dW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3QgQ0ExFTATBgNVBAMMDFRlc3QgUm9v
+dCBDQTAeFw0yMDA5MDIwMDAwMDBaFw0yMTEwMDUwMDAwMDFaMGAxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3
+MRAwDgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWo7xSDfUOpbmwbUgiBb0pYDLchgM28Am
+n3WKwVg6qZwF/vSckn8uWeyXd8qHQwoFStOmr2f3wZrzfpKG7ck+ibT6vsinbLUC
+oLUC8YNBGNaGKcixvhbgFUkuv9CgZbkFS1LwvoikMLFz86ppZYCZrRRiE7x7UpP+
+kU+KsUzTUqx3fJIC/DTHFRCocPF37A3HW1PfSR++WaCTRUvrccK6jwxDc5Zc9Ja9
+7c2MGHnbGO8pXtl4gMSS7GvhGRmDw067CBxdjqQQJEj+afXSAe+lWc7eL7Qg9IOz
+7+Dorwlp3AlweZs7YPZvMnGTeima8+FUX5xaQTMq+Sns24NFnU9ZAgMBAAGjgYAw
+fjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRwl5KdKhgNrV/ehimgRN8LPkGk1TAf
+BgNVHSMEGDAWgBSbJguKmKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEF
+BQcDAQYIKwYBBQUHAwIwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQsFAAOC
+AQEAgP689ZqXz6ImY+VKSlNxvEDipTAhKPgOErEAvKvIUIun/BXvPFfvkpD/iUJC
+NG0A/9YKqIkLyc/7FWpsq8AYBWjloe/UIFUMT4Ta998pSmnJjxzIpsnKoIa8xE2W
+D2JjS+qFjfpaK35OH0pg7YrM9A9tVi/OGFZUwx8JOdJiY3URP3BvzK/LxFLHHxlf
+ziRb+FTIJXioUev5JkHh8KEp7PyMqu0s/Uko/60q6oeDzwKsGy2h5w5RWY9iq5Xx
+tPKfYqcEshOorkGItRwMz1rzp0HSnIhNUFQUw1jBEJNJMyH/AEEMcX4Aq0Q16sHE
+HHahOgkhNYtFE7qaWKDmjx5VlA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/398_days_after_2020_09_01.pem b/chromium/net/data/ssl/certificates/398_days_after_2020_09_01.pem
new file mode 100644
index 00000000000..475fa9e71ea
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/398_days_after_2020_09_01.pem
@@ -0,0 +1,85 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ ef:2f:0a:6a:75:56:1e:b1:0b:03:50:df:7c:9a:63:ba
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Sep 2 00:00:00 2020 GMT
+ Not After : Oct 5 00:00:00 2021 GMT
+ Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:d3:41:3d:2b:88:60:a1:04:75:8f:26:22:b0:55:
+ 52:26:fd:78:db:f4:f8:c4:89:d7:f2:b2:77:85:02:
+ 25:4a:48:08:1d:e0:1c:df:90:29:9a:fa:94:ca:c5:
+ 51:ee:49:72:35:70:e0:40:f8:4f:7f:e3:97:68:9f:
+ 2d:1f:68:b6:1c:e6:29:02:cc:3d:ca:31:3f:e1:a5:
+ 70:30:40:f0:b0:4f:ed:21:5f:17:b8:49:30:bc:aa:
+ d4:0a:11:d5:85:b6:2d:91:f4:19:f5:1d:29:94:83:
+ 08:ec:fc:03:fc:b1:f1:24:87:35:14:ab:9c:57:ae:
+ f5:a2:f5:74:24:23:93:2d:aa:10:4d:8b:3d:7f:26:
+ 66:88:3a:a0:a3:7f:d6:e8:35:d5:6f:9c:46:5f:77:
+ d5:e2:6f:59:cf:d0:ac:d2:09:b1:11:5f:62:83:c7:
+ f7:57:22:37:20:68:eb:29:ec:da:d2:d9:2a:99:a9:
+ 56:c3:f7:62:89:f2:43:b4:e8:48:4b:ba:af:2e:81:
+ 29:5b:e0:1c:a4:b0:11:f9:8a:38:3e:8a:02:5d:6e:
+ 0a:01:c7:ee:da:db:25:b7:b2:49:ad:b3:63:42:7c:
+ a6:d3:0d:3c:bb:4b:86:ba:be:45:fc:03:18:2a:8d:
+ 57:81:57:0c:21:14:c3:cb:4c:db:8b:ee:d5:ce:7a:
+ 5c:a7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 13:0F:2C:60:16:93:D8:1D:23:A3:72:5F:53:88:02:23:C9:2A:6B:CF
+ X509v3 Authority Key Identifier:
+ keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ IP Address:127.0.0.1
+ Signature Algorithm: sha256WithRSAEncryption
+ bf:48:b6:5d:1e:6e:bb:ff:65:33:c3:39:ab:82:8e:54:b1:ff:
+ b5:58:41:fb:91:27:a5:61:d8:0c:cc:97:62:31:4f:f7:61:a2:
+ 91:ba:16:ed:73:08:7f:75:be:b5:6e:50:79:c3:a0:73:1b:4d:
+ a1:85:cc:48:54:5c:27:1e:03:96:a8:1e:65:2e:0f:7c:9d:78:
+ 30:84:db:46:ec:48:53:26:b8:8f:ee:89:9c:c9:f2:c1:92:ce:
+ f6:fc:0f:c8:bc:6f:e0:ce:83:a8:85:7d:19:c3:07:f1:31:c0:
+ 5f:f9:d0:4c:90:89:59:69:3e:54:69:eb:15:52:3d:9e:b9:71:
+ 14:d4:a6:20:e0:d6:de:2b:b7:04:43:85:54:a7:42:d6:ca:00:
+ b4:57:68:93:65:6c:36:90:3f:5c:23:23:e3:7a:62:36:92:8f:
+ e7:37:0e:65:0b:71:fe:72:ed:8c:d3:da:bd:98:66:01:e6:4d:
+ 91:11:ab:e5:f1:c8:79:66:8e:27:f9:e0:60:49:fc:86:ed:95:
+ 36:9a:15:ca:84:d4:d4:69:1c:c2:d5:c7:30:ac:7e:f1:97:49:
+ ec:8e:39:ab:3c:58:2e:2f:21:13:f8:ee:a5:00:49:ca:88:7a:
+ 8b:e7:b9:5d:37:92:5c:b8:8d:8e:27:84:01:1f:14:6c:33:11:
+ 4b:cd:9a:e0
+-----BEGIN CERTIFICATE-----
+MIIDzzCCAregAwIBAgIRAO8vCmp1Vh6xCwNQ33yaY7owDQYJKoZIhvcNAQELBQAw
+YzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
+dW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3QgQ0ExFTATBgNVBAMMDFRlc3QgUm9v
+dCBDQTAeFw0yMDA5MDIwMDAwMDBaFw0yMTEwMDUwMDAwMDBaMGAxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3
+MRAwDgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTQT0riGChBHWPJiKwVVIm/Xjb9PjEidfy
+sneFAiVKSAgd4BzfkCma+pTKxVHuSXI1cOBA+E9/45dony0faLYc5ikCzD3KMT/h
+pXAwQPCwT+0hXxe4STC8qtQKEdWFti2R9Bn1HSmUgwjs/AP8sfEkhzUUq5xXrvWi
+9XQkI5MtqhBNiz1/JmaIOqCjf9boNdVvnEZfd9Xib1nP0KzSCbERX2KDx/dXIjcg
+aOsp7NrS2SqZqVbD92KJ8kO06EhLuq8ugSlb4ByksBH5ijg+igJdbgoBx+7a2yW3
+skmts2NCfKbTDTy7S4a6vkX8AxgqjVeBVwwhFMPLTNuL7tXOelynAgMBAAGjgYAw
+fjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQTDyxgFpPYHSOjcl9TiAIjySprzzAf
+BgNVHSMEGDAWgBSbJguKmKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEF
+BQcDAQYIKwYBBQUHAwIwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQsFAAOC
+AQEAv0i2XR5uu/9lM8M5q4KOVLH/tVhB+5EnpWHYDMyXYjFP92GikboW7XMIf3W+
+tW5QecOgcxtNoYXMSFRcJx4DlqgeZS4PfJ14MITbRuxIUya4j+6JnMnywZLO9vwP
+yLxv4M6DqIV9GcMH8THAX/nQTJCJWWk+VGnrFVI9nrlxFNSmIODW3iu3BEOFVKdC
+1soAtFdok2VsNpA/XCMj43piNpKP5zcOZQtx/nLtjNPavZhmAeZNkRGr5fHIeWaO
+J/ngYEn8hu2VNpoVyoTU1GkcwtXHMKx+8ZdJ7I45qzxYLi8hE/jupQBJyoh6i+e5
+XTeSXLiNjieEAR8UbDMRS82a4A==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/399_days_after_2020_09_01.pem b/chromium/net/data/ssl/certificates/399_days_after_2020_09_01.pem
new file mode 100644
index 00000000000..6f101151d7b
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/399_days_after_2020_09_01.pem
@@ -0,0 +1,85 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ ef:2f:0a:6a:75:56:1e:b1:0b:03:50:df:7c:9a:63:b9
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Sep 2 00:00:00 2020 GMT
+ Not After : Oct 6 00:00:00 2021 GMT
+ Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:c5:26:15:5a:01:bc:a6:ca:fe:e3:aa:f1:02:b3:
+ 0d:f9:2f:0c:53:18:0b:b2:e1:8e:3b:e4:eb:bf:ff:
+ d3:90:40:7f:3c:f2:9c:c7:4d:c0:e5:7f:b2:8d:79:
+ e8:d9:c6:79:f4:2b:29:40:a7:5d:27:52:b7:d0:ed:
+ b6:aa:21:32:fd:57:27:6a:30:bb:bc:11:46:38:83:
+ 5c:f4:ec:db:6c:99:29:5d:38:e0:41:e3:ae:fe:81:
+ 5c:1e:53:51:95:55:e9:e6:e3:e6:20:52:40:c5:c7:
+ c7:18:96:08:96:66:fb:a6:3b:8a:8a:c1:b6:88:c9:
+ 90:1b:42:fd:b2:1d:68:10:8f:f9:4e:94:df:31:4c:
+ 36:b9:70:ff:82:7c:5a:84:9e:51:91:1e:8d:e7:23:
+ 3a:7a:a3:65:6d:f8:b7:0a:87:1e:a5:78:04:2c:a8:
+ 1c:f7:ed:a8:fd:f4:36:52:97:6c:f1:de:59:66:6e:
+ 97:52:30:c8:60:59:ed:1a:5a:51:23:bc:83:9e:72:
+ b1:50:35:cd:a6:66:bf:ef:07:d4:f0:f4:ef:38:e5:
+ 0d:5d:d4:74:51:ca:5c:96:2f:e4:24:59:61:f6:cd:
+ ac:f9:1b:bd:62:2b:f3:7d:3e:db:6d:04:49:a4:e1:
+ c1:72:59:3c:95:49:36:87:ba:57:ac:de:cd:f6:90:
+ 49:09
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 1A:11:83:6D:87:2A:09:79:38:65:B2:89:81:B1:F5:26:46:33:82:62
+ X509v3 Authority Key Identifier:
+ keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ IP Address:127.0.0.1
+ Signature Algorithm: sha256WithRSAEncryption
+ 15:c0:67:79:e4:03:8d:38:8b:ca:57:ff:1e:fd:d6:2b:1e:0e:
+ ed:9d:6a:c7:16:53:36:f7:ce:eb:8d:36:79:a1:b6:59:d8:d0:
+ bb:35:96:53:57:59:ad:91:39:f9:70:36:ac:37:9f:75:40:a3:
+ 3b:be:59:ed:32:4e:c4:a7:a9:3b:79:4d:8c:0c:3d:ba:6f:98:
+ 3e:3a:ff:28:19:fd:a2:d2:12:41:75:4a:1f:b0:22:0b:51:28:
+ 4d:9e:bd:e9:f3:67:b3:11:ef:9b:01:cb:c1:01:b1:6b:71:d2:
+ 68:a7:29:33:41:9a:3f:7b:ae:45:67:8f:a8:97:65:21:85:93:
+ b9:db:1b:46:bd:c9:46:23:71:27:1b:9a:aa:58:b7:7b:a1:2d:
+ 8c:27:65:75:9b:be:56:c5:bb:50:0c:62:ce:93:47:90:aa:db:
+ 47:c4:80:c5:43:f7:89:6b:b0:ea:a1:91:d5:2f:89:f8:d7:05:
+ 56:60:18:3c:c1:4a:bf:93:df:76:0a:ff:9f:b5:30:da:10:1a:
+ 15:94:f0:5a:82:11:ef:26:27:1c:50:1d:8b:c6:19:01:e4:01:
+ 48:22:c0:b9:97:12:58:4b:f1:61:7d:a9:69:d8:70:83:54:af:
+ 39:9e:fc:9b:17:f5:b1:69:cd:3e:b5:ba:13:df:e6:fd:71:9d:
+ d2:ef:95:1c
+-----BEGIN CERTIFICATE-----
+MIIDzzCCAregAwIBAgIRAO8vCmp1Vh6xCwNQ33yaY7kwDQYJKoZIhvcNAQELBQAw
+YzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1v
+dW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3QgQ0ExFTATBgNVBAMMDFRlc3QgUm9v
+dCBDQTAeFw0yMDA5MDIwMDAwMDBaFw0yMTEwMDYwMDAwMDBaMGAxCzAJBgNVBAYT
+AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3
+MRAwDgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFJhVaAbymyv7jqvECsw35LwxTGAuy4Y47
+5Ou//9OQQH888pzHTcDlf7KNeejZxnn0KylAp10nUrfQ7baqITL9VydqMLu8EUY4
+g1z07NtsmSldOOBB467+gVweU1GVVenm4+YgUkDFx8cYlgiWZvumO4qKwbaIyZAb
+Qv2yHWgQj/lOlN8xTDa5cP+CfFqEnlGRHo3nIzp6o2Vt+LcKhx6leAQsqBz37aj9
+9DZSl2zx3llmbpdSMMhgWe0aWlEjvIOecrFQNc2mZr/vB9Tw9O845Q1d1HRRylyW
+L+QkWWH2zaz5G71iK/N9PtttBEmk4cFyWTyVSTaHules3s32kEkJAgMBAAGjgYAw
+fjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQaEYNthyoJeThlsomBsfUmRjOCYjAf
+BgNVHSMEGDAWgBSbJguKmKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEF
+BQcDAQYIKwYBBQUHAwIwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQsFAAOC
+AQEAFcBneeQDjTiLylf/Hv3WKx4O7Z1qxxZTNvfO6402eaG2WdjQuzWWU1dZrZE5
++XA2rDefdUCjO75Z7TJOxKepO3lNjAw9um+YPjr/KBn9otISQXVKH7AiC1EoTZ69
+6fNnsxHvmwHLwQGxa3HSaKcpM0GaP3uuRWePqJdlIYWTudsbRr3JRiNxJxuaqli3
+e6EtjCdldZu+VsW7UAxizpNHkKrbR8SAxUP3iWuw6qGR1S+J+NcFVmAYPMFKv5Pf
+dgr/n7Uw2hAaFZTwWoIR7yYnHFAdi8YZAeQBSCLAuZcSWEvxYX2padhwg1SvOZ78
+mxf1sWnNPrW6E9/m/XGd0u+VHA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic-short-lived.pem b/chromium/net/data/ssl/certificates/quic-short-lived.pem
new file mode 100644
index 00000000000..36422406f9a
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic-short-lived.pem
@@ -0,0 +1,80 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 02:10:43:05:54:18:1c:69:17:b8:d7:dd:1c:87:89:d3:d3:f9:8d:c7
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = US, CN = Short-lived Certificate
+ Validity
+ Not Before: Jun 5 19:49:12 2020 GMT
+ Not After : Jun 19 19:49:12 2020 GMT
+ Subject: C = US, CN = Short-lived Certificate
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:b2:56:6f:7e:d4:b4:b6:4e:e3:15:8e:8a:e9:46:
+ 06:15:63:4c:6d:3a:32:67:c7:14:a4:17:fc:b7:04:
+ 98:fb:b5:11:ae:93:1c:20:73:15:cd:b3:bc:ee:61:
+ 82:8e:cb:b8:78:ca:6d:e6:57:73:f3:45:6e:1e:c3:
+ 27:5d:af:5e:52:6d:12:47:44:72:3d:7d:8a:c1:47:
+ 50:19:4a:21:a4:08:b4:cc:2e:9c:a2:2a:ce:1b:87:
+ 82:ae:3a:23:b0:dd:d2:3e:64:fe:ce:a6:35:34:93:
+ 07:f8:88:6e:c8:be:b2:0b:5f:9c:96:0e:79:1c:a3:
+ 2b:c9:23:5a:8a:1f:1e:17:e2:a9:d4:3c:49:22:29:
+ 43:fa:63:55:3c:72:62:4a:d1:72:5a:ae:75:a8:14:
+ 67:eb:58:88:ce:11:0c:bf:09:67:f2:bb:c8:80:3e:
+ 4a:f0:35:ad:d2:dc:43:a3:2f:da:c6:3b:1c:6e:76:
+ 70:31:73:cc:33:5b:4f:36:dc:f3:8f:9f:a6:07:6d:
+ 61:e0:66:6f:2c:76:bd:85:a3:8b:d0:8a:ce:c4:bc:
+ 97:e0:ed:e1:29:df:a1:62:b9:ad:d8:0f:1a:f8:ae:
+ 44:fe:a6:28:95:c4:cc:df:b5:f7:6d:46:ae:ef:9b:
+ af:73:50:1d:9f:f0:c7:a0:ef:37:4b:13:73:96:24:
+ 95:0f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9A:4F:94:3E:9D:8E:6D:5A:9B:9B:8B:88:97:B6:D4:FF:10:AE:47:76
+ X509v3 Authority Key Identifier:
+ keyid:9A:4F:94:3E:9D:8E:6D:5A:9B:9B:8B:88:97:B6:D4:FF:10:AE:47:76
+
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Alternative Name:
+ DNS:example.org
+ Signature Algorithm: sha256WithRSAEncryption
+ 7b:10:40:c9:9b:ad:b1:3d:03:c3:b6:f3:d7:3f:75:56:2b:80:
+ ff:c4:e5:88:3a:b4:0b:c2:4a:cd:ae:0a:b3:d4:1f:d3:ec:ec:
+ 81:85:0b:96:47:2d:78:d1:9c:45:c3:cd:7c:ba:a0:f8:b0:56:
+ 83:2f:e9:8a:06:05:fa:06:65:85:fd:60:99:6e:29:5c:b8:22:
+ 6f:1b:24:63:ce:95:f6:bc:a1:76:69:15:b7:33:b4:e1:c4:e4:
+ e1:8d:2b:71:5f:af:8d:0e:17:be:ea:b1:b7:75:66:29:8d:4d:
+ 92:bc:fe:7e:12:b3:46:ab:fb:7f:01:46:77:c1:6a:1b:9b:65:
+ 79:cb:aa:64:24:1a:ee:99:85:8e:b8:51:33:c7:8d:88:40:ae:
+ 0b:e2:cf:b1:57:f1:c9:a7:08:d7:8d:3d:da:9c:f4:79:28:a3:
+ 39:0e:e6:2f:16:71:89:4c:8b:cc:62:6c:13:b2:f0:38:1d:7b:
+ 04:4b:21:01:c9:52:09:6e:0f:7a:13:a7:62:07:08:7a:0e:90:
+ a8:fd:13:2b:2c:39:37:3b:0f:fa:36:f7:64:76:d3:b5:9b:7a:
+ ab:49:b3:52:0f:cf:d2:c6:02:c9:05:30:3f:60:c7:c5:f3:4b:
+ fa:c3:e6:fd:de:3f:2b:d6:a5:1a:ff:6c:8e:75:d0:c9:ff:f2:
+ 65:d8:07:d1
+-----BEGIN CERTIFICATE-----
+MIIDVzCCAj+gAwIBAgIUAhBDBVQYHGkXuNfdHIeJ09P5jccwDQYJKoZIhvcNAQEL
+BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF1Nob3J0LWxpdmVkIENlcnRpZmlj
+YXRlMB4XDTIwMDYwNTE5NDkxMloXDTIwMDYxOTE5NDkxMlowLzELMAkGA1UEBhMC
+VVMxIDAeBgNVBAMMF1Nob3J0LWxpdmVkIENlcnRpZmljYXRlMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAslZvftS0tk7jFY6K6UYGFWNMbToyZ8cUpBf8
+twSY+7URrpMcIHMVzbO87mGCjsu4eMpt5ldz80VuHsMnXa9eUm0SR0RyPX2KwUdQ
+GUohpAi0zC6coirOG4eCrjojsN3SPmT+zqY1NJMH+IhuyL6yC1+clg55HKMrySNa
+ih8eF+Kp1DxJIilD+mNVPHJiStFyWq51qBRn61iIzhEMvwln8rvIgD5K8DWt0txD
+oy/axjscbnZwMXPMM1tPNtzzj5+mB21h4GZvLHa9haOL0IrOxLyX4O3hKd+hYrmt
+2A8a+K5E/qYolcTM37X3bUau75uvc1Adn/DHoO83SxNzliSVDwIDAQABo2swaTAd
+BgNVHQ4EFgQUmk+UPp2ObVqbm4uIl7bU/xCuR3YwHwYDVR0jBBgwFoAUmk+UPp2O
+bVqbm4uIl7bU/xCuR3YwDwYDVR0TAQH/BAUwAwEB/zAWBgNVHREEDzANggtleGFt
+cGxlLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAexBAyZutsT0Dw7bz1z91ViuA/8Tl
+iDq0C8JKza4Ks9Qf0+zsgYULlkcteNGcRcPNfLqg+LBWgy/pigYF+gZlhf1gmW4p
+XLgibxskY86V9ryhdmkVtzO04cTk4Y0rcV+vjQ4Xvuqxt3VmKY1Nkrz+fhKzRqv7
+fwFGd8FqG5tlecuqZCQa7pmFjrhRM8eNiECuC+LPsVfxyacI14092pz0eSijOQ7m
+LxZxiUyLzGJsE7LwOB17BEshAclSCW4PehOnYgcIeg6QqP0TKyw5NzsP+jb3ZHbT
+tZt6q0mzUg/P0sYCyQUwP2DHxfNL+sPm/d4/K9alGv9sjnXQyf/yZdgH0Q==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178.pem b/chromium/net/data/ssl/ev_roots/08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178.pem
deleted file mode 100644
index 6cd05f10420..00000000000
--- a/chromium/net/data/ssl/ev_roots/08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178.pem
+++ /dev/null
@@ -1,71 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 903804111 (0x35def4cf)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Validity
- Not Before: Aug 22 16:41:51 1998 GMT
- Not After : Aug 22 16:41:51 2018 GMT
- Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:c1:5d:b1:58:67:08:62:ee:a0:9a:2d:1f:08:6d:
- 91:14:68:98:0a:1e:fe:da:04:6f:13:84:62:21:c3:
- d1:7c:ce:9f:05:e0:b8:01:f0:4e:34:ec:e2:8a:95:
- 04:64:ac:f1:6b:53:5f:05:b3:cb:67:80:bf:42:02:
- 8e:fe:dd:01:09:ec:e1:00:14:4f:fc:fb:f0:0c:dd:
- 43:ba:5b:2b:e1:1f:80:70:99:15:57:93:16:f1:0f:
- 97:6a:b7:c2:68:23:1c:cc:4d:59:30:ac:51:1e:3b:
- af:2b:d6:ee:63:45:7b:c5:d9:5f:50:d2:e3:50:0f:
- 3a:88:e7:bf:14:fd:e0:c7:b9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 CRL Distribution Points:
-
- Full Name:
- DirName: C = US, O = Equifax, OU = Equifax Secure Certificate Authority, CN = CRL1
-
- X509v3 Private Key Usage Period:
- Not After: Aug 22 16:41:51 2018 GMT
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
-
- X509v3 Subject Key Identifier:
- 48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4
- X509v3 Basic Constraints:
- CA:TRUE
- 1.2.840.113533.7.65.0:
- 0...V3.0c....
- Signature Algorithm: sha1WithRSAEncryption
- 58:ce:29:ea:fc:f7:de:b5:ce:02:b9:17:b5:85:d1:b9:e3:e0:
- 95:cc:25:31:0d:00:a6:92:6e:7f:b6:92:63:9e:50:95:d1:9a:
- 6f:e4:11:de:63:85:6e:98:ee:a8:ff:5a:c8:d3:55:b2:66:71:
- 57:de:c0:21:eb:3d:2a:a7:23:49:01:04:86:42:7b:fc:ee:7f:
- a2:16:52:b5:67:67:d3:40:db:3b:26:58:b2:28:77:3d:ae:14:
- 77:61:d6:fa:2a:66:27:a0:0d:fa:a7:73:5c:ea:70:f1:94:21:
- 65:44:5f:fa:fc:ef:29:68:a9:a2:87:79:ef:79:ef:4f:ac:07:
- 77:38
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
-UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
-dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
-MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
-dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
-BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
-cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
-AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
-MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
-aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
-ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
-MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
-A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
-1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/0f993c8aef97baaf5687140ed59ad1821bb4afacf0aa9a58b5d57a338a3afbcb.pem b/chromium/net/data/ssl/ev_roots/0f993c8aef97baaf5687140ed59ad1821bb4afacf0aa9a58b5d57a338a3afbcb.pem
deleted file mode 100644
index 58656022a93..00000000000
--- a/chromium/net/data/ssl/ev_roots/0f993c8aef97baaf5687140ed59ad1821bb4afacf0aa9a58b5d57a338a3afbcb.pem
+++ /dev/null
@@ -1,86 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 85:bd:4b:f3:d8:da:e3:69:f6:94:d7:5f:c3:a5:44:23
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=FR, O=Certplus, CN=Class 2 Primary CA
- Validity
- Not Before: Jul 7 17:05:00 1999 GMT
- Not After : Jul 6 23:59:59 2019 GMT
- Subject: C=FR, O=Certplus, CN=Class 2 Primary CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dc:50:96:d0:12:f8:35:d2:08:78:7a:b6:52:70:
- fd:6f:ee:cf:b9:11:cb:5d:77:e1:ec:e9:7e:04:8d:
- d6:cc:6f:73:43:57:60:ac:33:0a:44:ec:03:5f:1c:
- 80:24:91:e5:a8:91:56:12:82:f7:e0:2b:f4:db:ae:
- 61:2e:89:10:8d:6b:6c:ba:b3:02:bd:d5:36:c5:48:
- 37:23:e2:f0:5a:37:52:33:17:12:e2:d1:60:4d:be:
- 2f:41:11:e3:f6:17:25:0c:8b:91:c0:1b:99:7b:99:
- 56:0d:af:ee:d2:bc:47:57:e3:79:49:7b:34:89:27:
- 24:84:de:b1:ec:e9:58:4e:fe:4e:df:5a:be:41:ad:
- ac:08:c5:18:0e:ef:d2:53:ee:6c:d0:9d:12:01:13:
- 8d:dc:80:62:f7:95:a9:44:88:4a:71:4e:60:55:9e:
- db:23:19:79:56:07:0c:3f:63:0b:5c:b0:e2:be:7e:
- 15:fc:94:33:58:41:38:74:c4:e1:8f:8b:df:26:ac:
- 1f:b5:8b:3b:b7:43:59:6b:b0:24:a6:6d:90:8b:c4:
- 72:ea:5d:33:98:b7:cb:de:5e:7b:ef:94:f1:1b:3e:
- ca:c9:21:c1:c5:98:02:aa:a2:f6:5b:77:9b:f5:7e:
- 96:55:34:1c:67:69:c0:f1:42:e3:47:ac:fc:28:1c:
- 66:55
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:TRUE, pathlen:10
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- E3:73:2D:DF:CB:0E:28:0C:DE:DD:B3:A4:CA:79:B8:8E:BB:E8:30:89
- Netscape Cert Type:
- SSL CA, S/MIME CA
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://www.certplus.com/CRL/class2.crl
-
- Signature Algorithm: sha1WithRSAEncryption
- a7:54:cf:88:44:19:cb:df:d4:7f:00:df:56:33:62:b5:f7:51:
- 01:90:eb:c3:3f:d1:88:44:e9:24:5d:ef:e7:14:bd:20:b7:9a:
- 3c:00:fe:6d:9f:db:90:dc:d7:f4:62:d6:8b:70:5d:e7:e5:04:
- 48:a9:68:7c:c9:f1:42:f3:6c:7f:c5:7a:7c:1d:51:88:ba:d2:
- 0a:3e:27:5d:de:2d:51:4e:d3:13:64:69:e4:2e:e3:d3:e7:9b:
- 09:99:a6:e0:95:9b:ce:1a:d7:7f:be:3c:ce:52:b3:11:15:c1:
- 0f:17:cd:03:bb:9c:25:15:ba:a2:76:89:fc:06:f1:18:d0:93:
- 4b:0e:7c:82:b7:a5:f4:f6:5f:fe:ed:40:a6:9d:84:74:39:b9:
- dc:1e:85:16:da:29:1b:86:23:00:c9:bb:89:7e:6e:80:88:1e:
- 2f:14:b4:03:24:a8:32:6f:03:9a:47:2c:30:be:56:c6:a7:42:
- 02:70:1b:ea:40:d8:ba:05:03:70:07:a4:96:ff:fd:48:33:0a:
- e1:dc:a5:81:90:9b:4d:dd:7d:e7:e7:b2:cd:5c:c8:6a:95:f8:
- a5:f6:8d:c4:5d:78:08:be:7b:06:d6:49:cf:19:36:50:23:2e:
- 08:e6:9e:05:4d:47:18:d5:16:e9:b1:d6:b6:10:d5:bb:97:bf:
- a2:8e:b4:54
------BEGIN CERTIFICATE-----
-MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
-PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
-cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
-MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
-IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
-ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
-VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
-kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
-EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
-H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
-HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
-DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
-QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
-Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
-AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
-yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
-FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
-ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
-kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
-l7+ijrRU
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca.pem b/chromium/net/data/ssl/ev_roots/136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca.pem
deleted file mode 100644
index 7e4f933d417..00000000000
--- a/chromium/net/data/ssl/ev_roots/136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca.pem
+++ /dev/null
@@ -1,137 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 14541511773111788494 (0xc9cdd3e9d57d23ce)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=EU, L=Madrid (see current address at www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A., CN=Global Chambersign Root - 2008
- Validity
- Not Before: Aug 1 12:31:40 2008 GMT
- Not After : Jul 31 12:31:40 2038 GMT
- Subject: C=EU, L=Madrid (see current address at www.camerfirma.com/address)/serialNumber=A82743287, O=AC Camerfirma S.A., CN=Global Chambersign Root - 2008
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:c0:df:56:d3:e4:3a:9b:76:45:b4:13:db:ff:c1:
- b6:19:8b:37:41:18:95:52:47:eb:17:9d:29:88:8e:
- 35:6c:06:32:2e:47:62:f3:49:04:bf:7d:44:36:b1:
- 71:cc:bd:5a:09:73:d5:d9:85:44:ff:91:57:25:df:
- 5e:36:8e:70:d1:5c:71:43:1d:d9:da:ef:5c:d2:fb:
- 1b:bd:3a:b5:cb:ad:a3:cc:44:a7:0d:ae:21:15:3f:
- b9:7a:5b:92:75:d8:a4:12:38:89:19:8a:b7:80:d2:
- e2:32:6f:56:9c:91:d6:88:10:0b:b3:74:64:92:74:
- 60:f3:f6:cf:18:4f:60:b2:23:d0:c7:3b:ce:61:4b:
- 99:8f:c2:0c:d0:40:b2:98:dc:0d:a8:4e:a3:b9:0a:
- ae:60:a0:ad:45:52:63:ba:66:bd:68:e0:f9:be:1a:
- a8:81:bb:1e:41:78:75:d3:c1:fe:00:55:b0:87:54:
- e8:27:90:35:1d:4c:33:ad:97:fc:97:2e:98:84:bf:
- 2c:c9:a3:bf:d1:98:11:14:ed:63:f8:ca:98:88:58:
- 17:99:ed:45:03:97:7e:3c:86:1e:88:8c:be:f2:91:
- 84:8f:65:34:d8:00:4c:7d:b7:31:17:5a:29:7a:0a:
- 18:24:30:a3:37:b5:7a:a9:01:7d:26:d6:f9:0e:8e:
- 59:f1:fd:1b:33:b5:29:3b:17:3b:41:b6:21:dd:d4:
- c0:3d:a5:9f:9f:1f:43:50:c9:bb:bc:6c:7a:97:98:
- ee:cd:8c:1f:fb:9c:51:ae:8b:70:bd:27:9f:71:c0:
- 6b:ac:7d:90:66:e8:d7:5d:3a:0d:b0:d5:c2:8d:d5:
- c8:9d:9d:c1:6d:d0:d0:bf:51:e4:e3:f8:c3:38:36:
- ae:d6:a7:75:e6:af:84:43:5d:93:92:0c:6a:07:de:
- 3b:1d:98:22:d6:ac:c1:35:db:a3:a0:25:ff:72:b5:
- 76:1d:de:6d:e9:2c:66:2c:52:84:d0:45:92:ce:1c:
- e5:e5:33:1d:dc:07:53:54:a3:aa:82:3b:9a:37:2f:
- dc:dd:a0:64:e9:e6:dd:bd:ae:fc:64:85:1d:3c:a7:
- c9:06:de:84:ff:6b:e8:6b:1a:3c:c5:a2:b3:42:fb:
- 8b:09:3e:5f:08:52:c7:62:c4:d4:05:71:bf:c4:64:
- e4:f8:a1:83:e8:3e:12:9b:a8:1e:d4:36:4d:2f:71:
- f6:8d:28:f6:83:a9:13:d2:61:c1:91:bb:48:c0:34:
- 8f:41:8c:4b:4c:db:69:12:ff:50:94:9c:20:83:59:
- 73:ed:7c:a1:f2:f1:fd:dd:f7:49:d3:43:58:a0:56:
- 63:ca:3d:3d:e5:35:56:59:e9:0e:ca:20:cc:2b:4b:
- 93:29:0f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:12
- X509v3 Subject Key Identifier:
- B9:09:CA:9C:1E:DB:D3:6C:3A:6B:AE:ED:54:F1:5B:93:06:35:2E:5E
- X509v3 Authority Key Identifier:
- keyid:B9:09:CA:9C:1E:DB:D3:6C:3A:6B:AE:ED:54:F1:5B:93:06:35:2E:5E
- DirName:/C=EU/L=Madrid (see current address at www.camerfirma.com/address)/serialNumber=A82743287/O=AC Camerfirma S.A./CN=Global Chambersign Root - 2008
- serial:C9:CD:D3:E9:D5:7D:23:CE
-
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Certificate Policies:
- Policy: X509v3 Any Policy
- CPS: http://policy.camerfirma.com
-
- Signature Algorithm: sha1WithRSAEncryption
- 80:88:7f:70:de:92:28:d9:05:94:46:ff:90:57:a9:f1:2f:df:
- 1a:0d:6b:fa:7c:0e:1c:49:24:79:27:d8:46:aa:6f:29:59:52:
- 88:70:12:ea:dd:3d:f5:9b:53:54:6f:e1:60:a2:a8:09:b9:ec:
- eb:59:7c:c6:35:f1:dc:18:e9:f1:67:e5:af:ba:45:e0:09:de:
- ca:44:0f:c2:17:0e:77:91:45:7a:33:5f:5f:96:2c:68:8b:c1:
- 47:8f:98:9b:3d:c0:ec:cb:f5:d5:82:92:84:35:d1:be:36:38:
- 56:72:31:5b:47:2d:aa:17:a4:63:51:eb:0a:01:ad:7f:ec:75:
- 9e:cb:a1:1f:f1:7f:12:b1:b9:e4:64:7f:67:d6:23:2a:f4:b8:
- 39:5d:98:e8:21:a7:e1:bd:3d:42:1a:74:9a:70:af:68:6c:50:
- 5d:49:cf:ff:fb:0e:5d:e6:2c:47:d7:81:3a:59:00:b5:73:6b:
- 63:20:f6:31:45:08:39:0e:f4:70:7e:40:70:5a:3f:d0:6b:42:
- a9:74:3d:28:2f:02:6d:75:72:95:09:8d:48:63:c6:c6:23:57:
- 92:93:5e:35:c1:8d:f9:0a:f7:2c:9d:62:1c:f6:ad:7c:dd:a6:
- 31:1e:b6:b1:c7:7e:85:26:fa:a4:6a:b5:da:63:30:d1:ef:93:
- 37:b2:66:2f:7d:05:f7:e7:b7:4b:98:94:35:c0:d9:3a:29:c1:
- 9d:b2:50:33:1d:4a:a9:5a:a6:c9:03:ef:ed:f4:e7:a8:6e:8a:
- b4:57:84:eb:a4:3f:d0:ee:aa:aa:87:5b:63:e8:93:e2:6b:a8:
- d4:b8:72:78:6b:1b:ed:39:e4:5d:cb:9b:aa:87:d5:4f:4e:00:
- fe:d9:6a:9f:3c:31:0f:28:02:01:7d:98:e8:a7:b0:a2:64:9e:
- 79:f8:48:f2:15:a9:cc:e6:c8:44:eb:3f:78:99:f2:7b:71:3e:
- 3c:f1:98:a7:c5:18:12:3f:e6:bb:28:33:42:e9:45:0a:7c:6d:
- f2:86:79:2f:c5:82:19:7d:09:89:7c:b2:54:76:88:ae:de:c1:
- f3:cc:e1:6e:db:31:d6:93:ae:99:a0:ef:25:6a:73:98:89:5b:
- 3a:2e:13:88:1e:bf:c0:92:94:34:1b:e3:27:b7:8b:1e:6f:42:
- ff:e7:e9:37:9b:50:1d:2d:a2:f9:02:ee:cb:58:58:3a:71:bc:
- 68:e3:aa:c1:af:1c:28:1f:a2:dc:23:65:3f:81:ea:ae:99:d3:
- d8:30:cf:13:0d:4f:15:c9:84:bc:a7:48:2d:f8:30:23:77:d8:
- 46:4b:79:6d:f6:8c:ed:3a:7f:60:11:78:f4:e9:9b:ae:d5:54:
- c0:74:80:d1:0b:42:9f:c1
------BEGIN CERTIFICATE-----
-MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
-aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
-MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
-cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
-A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
-BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
-KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
-G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
-zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
-ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
-HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
-Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
-yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
-beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
-6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
-wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
-zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
-BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
-ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
-ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
-cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
-YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
-CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
-KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
-hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
-UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
-X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
-fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
-a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
-Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
-SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
-AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
-M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
-v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
-09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem b/chromium/net/data/ssl/ev_roots/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
deleted file mode 100644
index 03178d483e9..00000000000
--- a/chromium/net/data/ssl/ev_roots/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
+++ /dev/null
@@ -1,83 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1218379777 (0x489f0001)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=CN, O=China Internet Network Information Center, CN=China Internet Network Information Center EV Certificates Root
- Validity
- Not Before: Aug 31 07:11:25 2010 GMT
- Not After : Aug 31 07:11:25 2030 GMT
- Subject: C=CN, O=China Internet Network Information Center, CN=China Internet Network Information Center EV Certificates Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9b:7e:73:ee:bd:3b:78:aa:64:43:41:f5:50:df:
- 94:f2:2e:b2:8d:4a:8e:46:54:d2:21:12:c8:39:32:
- 42:06:e9:83:d5:9f:52:ed:e5:67:03:3b:54:c1:8c:
- 99:99:cc:e9:c0:0f:ff:0d:d9:84:11:b2:b8:d1:cb:
- 5b:dc:1e:f9:68:31:64:e1:9b:fa:74:eb:68:b9:20:
- 95:f7:c6:0f:8d:47:ac:5a:06:dd:61:ab:e2:ec:d8:
- 9f:17:2d:9c:ca:3c:35:97:55:71:cd:43:85:b1:47:
- 16:f5:2c:53:80:76:cf:d3:00:64:bd:40:99:dd:cc:
- d8:db:c4:9f:d6:13:5f:41:83:8b:f9:0d:87:92:56:
- 34:6c:1a:10:0b:17:d5:5a:1c:97:58:84:3c:84:1a:
- 2e:5c:91:34:6e:19:5f:7f:17:69:c5:65:ef:6b:21:
- c6:d5:50:3a:bf:61:b9:05:8d:ef:6f:34:3a:b2:6f:
- 14:63:bf:16:3b:9b:a9:2a:fd:b7:2b:38:66:06:c5:
- 2c:e2:aa:67:1e:45:a7:8d:04:66:42:f6:8f:2b:ef:
- 88:20:69:8f:32:8c:14:73:da:2b:86:91:63:22:9a:
- f2:a7:db:ce:89:8b:ab:5d:c7:14:c1:5b:30:6a:1f:
- b1:b7:9e:2e:81:01:02:ed:cf:96:5e:63:db:a8:e6:
- 38:b7
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Authority Key Identifier:
- keyid:7C:72:4B:39:C7:C0:DB:62:A5:4F:9B:AA:18:34:92:A2:CA:83:82:59
-
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7C:72:4B:39:C7:C0:DB:62:A5:4F:9B:AA:18:34:92:A2:CA:83:82:59
- Signature Algorithm: sha1WithRSAEncryption
- 2a:c3:c7:43:37:8f:dd:ad:a4:b2:0c:ee:dc:14:6d:8f:28:a4:
- 98:49:cb:0c:80:ea:f3:ed:23:66:75:7d:c5:d3:21:67:79:d1:
- 73:c5:b5:03:b7:58:ac:0c:54:2f:c6:56:13:0f:31:da:06:e7:
- 65:3b:1d:6f:36:db:c8:1d:f9:fd:80:06:ca:a3:3d:66:16:a8:
- 9d:4c:16:7d:c0:95:46:b5:51:e4:e2:1f:d7:ea:06:4d:63:8d:
- 96:8c:ef:e7:33:57:42:3a:eb:8c:c1:79:c8:4d:76:7d:de:f6:
- b1:b7:81:e0:a0:f9:a1:78:46:17:1a:56:98:f0:4e:3d:ab:1c:
- ed:ec:39:dc:07:48:f7:63:fe:06:ae:c2:a4:5c:6a:5b:32:88:
- c5:c7:33:85:ac:66:42:47:c2:58:24:99:e1:e5:3e:e5:75:2c:
- 8e:43:d6:5d:3c:78:1e:a8:95:82:29:50:d1:d1:16:ba:ef:c1:
- be:7a:d9:b4:d8:cc:1e:4c:46:e1:77:b1:31:ab:bd:2a:c8:ce:
- 8f:6e:a1:5d:7f:03:75:34:e4:ad:89:45:54:5e:be:ae:28:a5:
- bb:3f:78:79:eb:73:b3:0a:0d:fd:be:c9:f7:56:ac:f6:b7:ed:
- 2f:9b:21:29:c7:38:b6:95:c4:04:f2:c3:2d:fd:14:2a:90:99:
- b9:07:cc:9f
------BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
-Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
-Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
-aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
-Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
-SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
-aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
-ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
-7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
-DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
-zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
-hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
-4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
-gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
-NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
-j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
-52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
-echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
-ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
-zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
-wy39FCqQmbkHzJ8=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem b/chromium/net/data/ssl/ev_roots/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem
new file mode 100644
index 00000000000..17ec3a9d91f
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8.pem
@@ -0,0 +1,56 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3182246526754555285 (0x2c299c5b16ed0595)
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority ECC
+ Validity
+ Not Before: Feb 12 18:15:23 2016 GMT
+ Not After : Feb 12 18:15:23 2041 GMT
+ Subject: C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority ECC
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:aa:12:47:90:98:1b:fb:ef:c3:40:07:83:20:4e:
+ f1:30:82:a2:06:d1:f2:92:86:61:f2:f6:21:68:ca:
+ 00:c4:c7:ea:43:00:54:86:dc:fd:1f:df:00:b8:41:
+ 62:5c:dc:70:16:32:de:1f:99:d4:cc:c5:07:c8:08:
+ 1f:61:16:07:51:3d:7d:5c:07:53:e3:35:38:8c:df:
+ cd:9f:d9:2e:0d:4a:b6:19:2e:5a:70:5a:06:ed:be:
+ f0:a1:b0:ca:d0:09:29
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 5B:CA:5E:E5:DE:D2:81:AA:CD:A8:2D:64:51:B6:D9:72:9B:97:E6:4F
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ keyid:5B:CA:5E:E5:DE:D2:81:AA:CD:A8:2D:64:51:B6:D9:72:9B:97:E6:4F
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:65:02:31:00:8a:e6:40:89:37:eb:e9:d5:13:d9:ca:d4:6b:
+ 24:f3:b0:3d:87:46:58:1a:ec:b1:df:6f:fb:56:ba:70:6b:c7:
+ 38:cc:e8:b1:8c:4f:0f:f7:f1:67:76:0e:83:d0:1e:51:8f:02:
+ 30:3d:f6:23:28:26:4c:c6:60:87:93:26:9b:b2:35:1e:ba:d6:
+ f7:3c:d1:1c:ce:fa:25:3c:a6:1a:81:15:5b:f3:12:0f:6c:ee:
+ 65:8a:c9:87:a8:f9:07:e0:62:9a:8c:5c:4a
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c.pem b/chromium/net/data/ssl/ev_roots/2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c.pem
deleted file mode 100644
index 36b2c073f64..00000000000
--- a/chromium/net/data/ssl/ev_roots/2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c.pem
+++ /dev/null
@@ -1,87 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 40:1a:c4:64:21:b3:13:21:03:0e:bb:e4:12:1a:c5:1d
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority
- Validity
- Not Before: Apr 2 00:00:00 2008 GMT
- Not After : Dec 1 23:59:59 2037 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:c7:61:37:5e:b1:01:34:db:62:d7:15:9b:ff:58:
- 5a:8c:23:23:d6:60:8e:91:d7:90:98:83:7a:e6:58:
- 19:38:8c:c5:f6:e5:64:85:b4:a2:71:fb:ed:bd:b9:
- da:cd:4d:00:b4:c8:2d:73:a5:c7:69:71:95:1f:39:
- 3c:b2:44:07:9c:e8:0e:fa:4d:4a:c4:21:df:29:61:
- 8f:32:22:61:82:c5:87:1f:6e:8c:7c:5f:16:20:51:
- 44:d1:70:4f:57:ea:e3:1c:e3:cc:79:ee:58:d8:0e:
- c2:b3:45:93:c0:2c:e7:9a:17:2b:7b:00:37:7a:41:
- 33:78:e1:33:e2:f3:10:1a:7f:87:2c:be:f6:f5:f7:
- 42:e2:e5:bf:87:62:89:5f:00:4b:df:c5:dd:e4:75:
- 44:32:41:3a:1e:71:6e:69:cb:0b:75:46:08:d1:ca:
- d2:2b:95:d0:cf:fb:b9:40:6b:64:8c:57:4d:fc:13:
- 11:79:84:ed:5e:54:f6:34:9f:08:01:f3:10:25:06:
- 17:4a:da:f1:1d:7a:66:6b:98:60:66:a4:d9:ef:d2:
- 2e:82:f1:f0:ef:09:ea:44:c9:15:6a:e2:03:6e:33:
- d3:ac:9f:55:00:c7:f6:08:6a:94:b9:5f:dc:e0:33:
- f1:84:60:f9:5b:27:11:b4:fc:16:f2:bb:56:6a:80:
- 25:8d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Subject Key Identifier:
- B6:77:FA:69:48:47:9F:53:12:D5:C2:EA:07:32:76:07:D1:97:07:19
- Signature Algorithm: sha256WithRSAEncryption
- 4a:f8:f8:b0:03:e6:2c:67:7b:e4:94:77:63:cc:6e:4c:f9:7d:
- 0e:0d:dc:c8:b9:35:b9:70:4f:63:fa:24:fa:6c:83:8c:47:9d:
- 3b:63:f3:9a:f9:76:32:95:91:b1:77:bc:ac:9a:be:b1:e4:31:
- 21:c6:81:95:56:5a:0e:b1:c2:d4:b1:a6:59:ac:f1:63:cb:b8:
- 4c:1d:59:90:4a:ef:90:16:28:1f:5a:ae:10:fb:81:50:38:0c:
- 6c:cc:f1:3d:c3:f5:63:e3:b3:e3:21:c9:24:39:e9:fd:15:66:
- 46:f4:1b:11:d0:4d:73:a3:7d:46:f9:3d:ed:a8:5f:62:d4:f1:
- 3f:f8:e0:74:57:2b:18:9d:81:b4:c4:28:da:94:97:a5:70:eb:
- ac:1d:be:07:11:f0:d5:db:dd:e5:8c:f0:d5:32:b0:83:e6:57:
- e2:8f:bf:be:a1:aa:bf:3d:1d:b5:d4:38:ea:d7:b0:5c:3a:4f:
- 6a:3f:8f:c0:66:6c:63:aa:e9:d9:a4:16:f4:81:d1:95:14:0e:
- 7d:cd:95:34:d9:d2:8f:70:73:81:7b:9c:7e:bd:98:61:d8:45:
- 87:98:90:c5:eb:86:30:c6:35:bf:f0:ff:c3:55:88:83:4b:ef:
- 05:92:06:71:f2:b8:98:93:b7:ec:cd:82:61:f1:38:e6:4f:97:
- 98:2a:5a:8d
------BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
-vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
-ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
-IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
-IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
-bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
-9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
-H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
-LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
-/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
-rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
-WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
-exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
-sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
-seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
-4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
-BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
-lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
-7M2CYfE45k+XmCpajQ==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem b/chromium/net/data/ssl/ev_roots/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem
new file mode 100644
index 00000000000..fb4614a611d
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c.pem
@@ -0,0 +1,124 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 6248227494352943350 (0x56b629cd34bc78f6)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2
+ Validity
+ Not Before: May 31 18:14:37 2017 GMT
+ Not After : May 30 18:14:37 2042 GMT
+ Subject: C = US, ST = Texas, L = Houston, O = SSL Corporation, CN = SSL.com EV Root Certification Authority RSA R2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (4096 bit)
+ Modulus:
+ 00:8f:36:65:40:e1:d6:4d:c0:d7:b4:e9:46:da:6b:
+ ea:33:47:cd:4c:f9:7d:7d:be:bd:2d:3d:f0:db:78:
+ e1:86:a5:d9:ba:09:57:68:ed:57:3e:a0:d0:08:41:
+ 83:e7:28:41:24:1f:e3:72:15:d0:01:1a:fb:5e:70:
+ 23:b2:cb:9f:39:e3:cf:c5:4e:c6:92:6d:26:c6:7b:
+ bb:b3:da:27:9d:0a:86:e9:81:37:05:fe:f0:71:71:
+ ec:c3:1c:e9:63:a2:17:14:9d:ef:1b:67:d3:85:55:
+ 02:02:d6:49:c9:cc:5a:e1:b1:f7:6f:32:9f:c9:d4:
+ 3b:88:41:a8:9c:bd:cb:ab:db:6d:7b:09:1f:a2:4c:
+ 72:90:da:2b:08:fc:cf:3c:54:ce:67:0f:a8:cf:5d:
+ 96:19:0b:c4:e3:72:eb:ad:d1:7d:1d:27:ef:92:eb:
+ 10:bf:5b:eb:3b:af:cf:80:dd:c1:d2:96:04:5b:7a:
+ 7e:a4:a9:3c:38:76:a4:62:8e:a0:39:5e:ea:77:cf:
+ 5d:00:59:8f:66:2c:3e:07:a2:a3:05:26:11:69:97:
+ ea:85:b7:0f:96:0b:4b:c8:40:e1:50:ba:2e:8a:cb:
+ f7:0f:9a:22:e7:7f:9a:37:13:cd:f2:4d:13:6b:21:
+ d1:c0:cc:22:f2:a1:46:f6:44:69:9c:ca:61:35:07:
+ 00:6f:d6:61:08:11:ea:ba:b8:f6:e9:b3:60:e5:4d:
+ b9:ec:9f:14:66:c9:57:58:db:cd:87:69:f8:8a:86:
+ 12:03:47:bf:66:13:76:ac:77:7d:34:24:85:83:cd:
+ d7:aa:9c:90:1a:9f:21:2c:7f:78:b7:64:b8:d8:e8:
+ a6:f4:78:b3:55:cb:84:d2:32:c4:78:ae:a3:8f:61:
+ dd:ce:08:53:ad:ec:88:fc:15:e4:9a:0d:e6:9f:1a:
+ 77:ce:4c:8f:b8:14:15:3d:62:9c:86:38:06:00:66:
+ 12:e4:59:76:5a:53:c0:02:98:a2:10:2b:68:44:7b:
+ 8e:79:ce:33:4a:76:aa:5b:81:16:1b:b5:8a:d8:d0:
+ 00:7b:5e:62:b4:09:d6:86:63:0e:a6:05:95:49:ba:
+ 28:8b:88:93:b2:34:1c:d8:a4:55:6e:b7:1c:d0:de:
+ 99:55:3b:23:f4:22:e0:f9:29:66:26:ec:20:50:77:
+ db:4a:0b:8f:be:e5:02:60:70:41:5e:d4:ae:50:39:
+ 22:14:26:cb:b2:3b:73:74:55:47:07:79:81:39:a8:
+ 30:13:44:e5:04:8a:ae:96:13:25:42:0f:b9:53:c4:
+ 9b:fc:cd:e4:1c:de:3c:fa:ab:d6:06:4a:1f:67:a6:
+ 98:30:1c:dd:2c:db:dc:18:95:57:66:c6:ff:5c:8b:
+ 56:f5:77
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Authority Key Identifier:
+ keyid:F9:60:BB:D4:E3:D5:34:F6:B8:F5:06:80:25:A7:73:DB:46:69:A8:9E
+
+ X509v3 Subject Key Identifier:
+ F9:60:BB:D4:E3:D5:34:F6:B8:F5:06:80:25:A7:73:DB:46:69:A8:9E
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: sha256WithRSAEncryption
+ 56:b3:8e:cb:0a:9d:49:8e:bf:a4:c4:91:bb:66:17:05:51:98:
+ 75:fb:e5:50:2c:7a:9e:f1:14:fa:ab:d3:8a:3e:ff:91:29:8f:
+ 63:8b:d8:b4:a9:54:01:0d:be:93:86:2f:f9:4a:6d:c7:5e:f5:
+ 57:f9:ca:55:1c:12:be:47:0f:36:c5:df:6a:b7:db:75:c2:47:
+ 25:7f:b9:f1:63:f8:68:2d:55:04:d1:f2:8d:b0:a4:cf:bc:3c:
+ 5e:1f:78:e7:a5:a0:20:70:b0:04:c5:b7:f7:72:a7:de:22:0d:
+ bd:33:25:46:8c:64:92:26:e3:3e:2e:63:96:da:9b:8c:3d:f8:
+ 18:09:d7:03:cc:7d:86:82:e0:ca:04:07:51:50:d7:ff:92:d5:
+ 0c:ef:da:86:9f:99:d7:eb:b7:af:68:e2:39:26:94:ba:68:b7:
+ bf:83:d3:ea:7a:67:3d:62:67:ae:25:e5:72:e8:e2:e4:ec:ae:
+ 12:f6:4b:2b:3c:9f:e9:b0:40:f3:38:54:b3:fd:b7:68:c8:da:
+ c6:8f:51:3c:b2:fb:91:dc:1c:e7:9b:9d:e1:b7:0d:72:8f:e2:
+ a4:c4:a9:78:f9:eb:14:ac:c6:43:05:c2:65:39:28:18:02:c3:
+ 82:b2:9d:05:be:65:ed:96:5f:65:74:3c:fb:09:35:2e:7b:9c:
+ 13:fd:1b:0f:5d:c7:6d:81:3a:56:0f:cc:3b:e1:af:02:2f:22:
+ ac:46:ca:46:3c:a0:1c:4c:d6:44:b4:5e:2e:5c:15:66:09:e1:
+ 26:29:fe:c6:52:61:ba:b1:73:ff:c3:0c:9c:e5:6c:6a:94:3f:
+ 14:ca:40:16:95:84:f3:59:a9:ac:5f:4c:61:93:6d:d1:3b:cc:
+ a2:95:0c:22:a6:67:67:44:2e:b9:d9:d2:8a:41:b3:66:0b:5a:
+ fb:7d:23:a5:f2:1a:b0:ff:de:9b:83:94:2e:d1:3f:df:92:b7:
+ 91:af:05:3b:65:c7:a0:6c:b1:cd:62:12:c3:90:1b:e3:25:ce:
+ 34:bc:6f:77:76:b1:10:c3:f7:05:1a:c0:d6:af:74:62:48:17:
+ 77:92:69:90:61:1c:de:95:80:74:54:8f:18:1c:c3:f3:03:d0:
+ bf:a4:43:75:86:53:18:7a:0a:2e:09:1c:36:9f:91:fd:82:8a:
+ 22:4b:d1:0e:50:25:dd:cb:03:0c:17:c9:83:00:08:4e:35:4d:
+ 8a:8b:ed:f0:02:94:66:2c:44:7f:cb:95:27:96:17:ad:09:30:
+ ac:b6:71:17:6e:8b:17:f6:1c:09:d4:2d:3b:98:a5:71:d3:54:
+ 13:d9:60:f3:f5:4b:66:4f:fa:f1:ee:20:12:8d:b4:ac:57:b1:
+ 45:63:a1:ac:76:a9:c2:fb
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c.pem b/chromium/net/data/ssl/ev_roots/37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c.pem
deleted file mode 100644
index 6f784f046aa..00000000000
--- a/chromium/net/data/ssl/ev_roots/37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c.pem
+++ /dev/null
@@ -1,78 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 18:ac:b5:6a:fd:69:b6:15:3a:63:6c:af:da:fa:c4:a1
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Validity
- Not Before: Nov 27 00:00:00 2006 GMT
- Not After : Jul 16 23:59:59 2036 GMT
- Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8:
- 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44:
- 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02:
- bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e:
- 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed:
- 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0:
- 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75:
- e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30:
- 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a:
- 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8:
- 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68:
- 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df:
- be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42:
- 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af:
- 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f:
- fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef:
- 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70:
- 71:35
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
- Signature Algorithm: sha1WithRSAEncryption
- 5a:70:7f:2c:dd:b7:34:4f:f5:86:51:a9:26:be:4b:b8:aa:f1:
- 71:0d:dc:61:c7:a0:ea:34:1e:7a:77:0f:04:35:e8:27:8f:6c:
- 90:bf:91:16:24:46:3e:4a:4e:ce:2b:16:d5:0b:52:1d:fc:1f:
- 67:a2:02:45:31:4f:ce:f3:fa:03:a7:79:9d:53:6a:d9:da:63:
- 3a:f8:80:d7:d3:99:e1:a5:e1:be:d4:55:71:98:35:3a:be:93:
- ea:ae:ad:42:b2:90:6f:e0:fc:21:4d:35:63:33:89:49:d6:9b:
- 4e:ca:c7:e7:4e:09:00:f7:da:c7:ef:99:62:99:77:b6:95:22:
- 5e:8a:a0:ab:f4:b8:78:98:ca:38:19:99:c9:72:9e:78:cd:4b:
- ac:af:19:a0:73:12:2d:fc:c2:41:ba:81:91:da:16:5a:31:b7:
- f9:b4:71:80:12:48:99:72:73:5a:59:53:c1:63:52:33:ed:a7:
- c9:d2:39:02:70:fa:e0:b1:42:66:29:aa:9b:51:ed:30:54:22:
- 14:5f:d9:ab:1d:c1:e4:94:f0:f8:f5:2b:f7:ea:ca:78:46:d6:
- b8:91:fd:a6:0d:2b:1a:14:01:3e:80:f0:42:a0:95:07:5e:6d:
- cd:cc:4b:a4:45:8d:ab:12:e8:b3:de:5a:e5:a0:7c:e8:0f:22:
- 1d:5a:e9:59
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
-MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
-AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
-ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
-7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
-kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
-mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
-KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
-6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
-4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
-oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
-UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
-AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem b/chromium/net/data/ssl/ev_roots/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem
new file mode 100644
index 00000000000..cf78be92339
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367.pem
@@ -0,0 +1,79 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 31:f5:e4:62:0c:6c:58:ed:d6:d8
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = IN, OU = emSign PKI, O = eMudhra Technologies Limited, CN = emSign Root CA - G1
+ Validity
+ Not Before: Feb 18 18:30:00 2018 GMT
+ Not After : Feb 18 18:30:00 2043 GMT
+ Subject: C = IN, OU = emSign PKI, O = eMudhra Technologies Limited, CN = emSign Root CA - G1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:93:4b:bb:e9:66:8a:ee:9d:5b:d5:34:93:d0:1b:
+ 1e:c3:e7:9e:b8:64:33:7f:63:78:68:b4:cd:2e:71:
+ 75:d7:9b:20:c6:4d:29:bc:b6:68:60:8a:f7:21:9a:
+ 56:35:5a:f3:76:bd:d8:cd:9a:ff:93:56:4b:a5:59:
+ 06:a1:93:34:29:dd:16:34:75:4e:f2:81:b4:c7:96:
+ 4e:ad:19:15:52:4a:fe:3c:70:75:70:cd:af:2b:ab:
+ 15:9a:33:3c:aa:b3:8b:aa:cd:43:fd:f5:ea:70:ff:
+ ed:cf:11:3b:94:ce:4e:32:16:d3:23:40:2a:77:b3:
+ af:3c:01:2c:6c:ed:99:2c:8b:d9:4e:69:98:b2:f7:
+ 8f:41:b0:32:78:61:d6:0d:5f:c3:fa:a2:40:92:1d:
+ 5c:17:e6:70:3e:35:e7:a2:b7:c2:62:e2:ab:a4:38:
+ 4c:b5:39:35:6f:ea:03:69:fa:3a:54:68:85:6d:d6:
+ f2:2f:43:55:1e:91:0d:0e:d8:d5:6a:a4:96:d1:13:
+ 3c:2c:78:50:e8:3a:92:d2:17:56:e5:35:1a:40:1c:
+ 3e:8d:2c:ed:39:df:42:e0:83:41:74:df:a3:cd:c2:
+ 86:60:48:68:e3:69:0b:54:00:8b:e4:76:69:21:0d:
+ 79:4e:34:08:5e:14:c2:cc:b1:b7:ad:d7:7c:70:8a:
+ c7:85
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ FB:EF:0D:86:9E:B0:E3:DD:A9:B9:F1:21:17:7F:3E:FC:F0:77:2B:1A
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 59:ff:f2:8c:f5:87:7d:71:3d:a3:9f:1b:5b:d1:da:f8:d3:9c:
+ 6b:36:bd:9b:a9:61:eb:de:16:2c:74:3d:9e:e6:75:da:d7:ba:
+ a7:bc:42:17:e7:3d:91:eb:e5:7d:dd:3e:9c:f1:cf:92:ac:6c:
+ 48:cc:c2:22:3f:69:3b:c5:b6:15:2f:a3:35:c6:68:2a:1c:57:
+ af:39:ef:8d:d0:35:c3:18:0c:7b:00:56:1c:cd:8b:19:74:de:
+ be:0f:12:e0:d0:aa:a1:3f:02:34:b1:70:ce:9d:18:d6:08:03:
+ 09:46:ee:60:e0:7e:b6:c4:49:04:51:7d:70:60:bc:aa:b2:ff:
+ 79:72:7a:a6:1d:3d:5f:2a:f8:ca:e2:fd:39:b7:47:b9:eb:7e:
+ df:04:23:af:fa:9c:06:07:e9:fb:63:93:80:40:b5:c6:6c:0a:
+ 31:28:ce:0c:9f:cf:b3:23:35:80:41:8d:6c:c4:37:7b:81:2f:
+ 80:a1:40:42:85:e9:d9:38:8d:e8:a1:53:cd:01:bf:69:e8:5a:
+ 06:f2:45:0b:90:fa:ae:e1:bf:9d:f2:ae:57:3c:a5:ae:b2:56:
+ f4:8b:65:40:e9:fd:31:81:2c:f4:39:09:d8:ee:6b:a7:b4:a6:
+ 1d:15:a5:98:f7:01:81:d8:85:7d:f3:51:5c:71:88:de:ba:cc:
+ 1f:80:7e:4a
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
+VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
+ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
+MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
+MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
+Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
+f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
+8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
+d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
+tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
+Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
+o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
+PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
+wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
+GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
+6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
+RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
+iN66zB+Afko=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/4b03f45807ad70f21bfc2cae71c9fde4604c064cf5ffb686bae5dbaad7fdd34c.pem b/chromium/net/data/ssl/ev_roots/4b03f45807ad70f21bfc2cae71c9fde4604c064cf5ffb686bae5dbaad7fdd34c.pem
deleted file mode 100644
index 901e6ae1a5b..00000000000
--- a/chromium/net/data/ssl/ev_roots/4b03f45807ad70f21bfc2cae71c9fde4604c064cf5ffb686bae5dbaad7fdd34c.pem
+++ /dev/null
@@ -1,82 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 60:01:97:b7:46:a7:ea:b4:b4:9a:d6:4b:2f:f7:90:fb
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
- Validity
- Not Before: Apr 2 00:00:00 2008 GMT
- Not After : Dec 1 23:59:59 2037 GMT
- Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b2:bf:27:2c:fb:db:d8:5b:dd:78:7b:1b:9e:77:
- 66:81:cb:3e:bc:7c:ae:f3:a6:27:9a:34:a3:68:31:
- 71:38:33:62:e4:f3:71:66:79:b1:a9:65:a3:a5:8b:
- d5:8f:60:2d:3f:42:cc:aa:6b:32:c0:23:cb:2c:41:
- dd:e4:df:fc:61:9c:e2:73:b2:22:95:11:43:18:5f:
- c4:b6:1f:57:6c:0a:05:58:22:c8:36:4c:3a:7c:a5:
- d1:cf:86:af:88:a7:44:02:13:74:71:73:0a:42:59:
- 02:f8:1b:14:6b:42:df:6f:5f:ba:6b:82:a2:9d:5b:
- e7:4a:bd:1e:01:72:db:4b:74:e8:3b:7f:7f:7d:1f:
- 04:b4:26:9b:e0:b4:5a:ac:47:3d:55:b8:d7:b0:26:
- 52:28:01:31:40:66:d8:d9:24:bd:f6:2a:d8:ec:21:
- 49:5c:9b:f6:7a:e9:7f:55:35:7e:96:6b:8d:93:93:
- 27:cb:92:bb:ea:ac:40:c0:9f:c2:f8:80:cf:5d:f4:
- 5a:dc:ce:74:86:a6:3e:6c:0b:53:ca:bd:92:ce:19:
- 06:72:e6:0c:5c:38:69:c7:04:d6:bc:6c:ce:5b:f6:
- f7:68:9c:dc:25:15:48:88:a1:e9:a9:f8:98:9c:e0:
- f3:d5:31:28:61:11:6c:67:96:8d:39:99:cb:c2:45:
- 24:39
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
- Signature Algorithm: sha256WithRSAEncryption
- 1a:40:d8:95:65:ac:09:92:89:c6:39:f4:10:e5:a9:0e:66:53:
- 5d:78:de:fa:24:91:bb:e7:44:51:df:c6:16:34:0a:ef:6a:44:
- 51:ea:2b:07:8a:03:7a:c3:eb:3f:0a:2c:52:16:a0:2b:43:b9:
- 25:90:3f:70:a9:33:25:6d:45:1a:28:3b:27:cf:aa:c3:29:42:
- 1b:df:3b:4c:c0:33:34:5b:41:88:bf:6b:2b:65:af:28:ef:b2:
- f5:c3:aa:66:ce:7b:56:ee:b7:c8:cb:67:c1:c9:9c:1a:18:b8:
- c4:c3:49:03:f1:60:0e:50:cd:46:c5:f3:77:79:f7:b6:15:e0:
- 38:db:c7:2f:28:a0:0c:3f:77:26:74:d9:25:12:da:31:da:1a:
- 1e:dc:29:41:91:22:3c:69:a7:bb:02:f2:b6:5c:27:03:89:f4:
- 06:ea:9b:e4:72:82:e3:a1:09:c1:e9:00:19:d3:3e:d4:70:6b:
- ba:71:a6:aa:58:ae:f4:bb:e9:6c:b6:ef:87:cc:9b:bb:ff:39:
- e6:56:61:d3:0a:a7:c4:5c:4c:60:7b:05:77:26:7a:bf:d8:07:
- 52:2c:62:f7:70:63:d9:39:bc:6f:1c:c2:79:dc:76:29:af:ce:
- c5:2c:64:04:5e:88:36:6e:31:d4:40:1a:62:34:36:3f:35:01:
- ae:ac:63:a0
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
-Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
-LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
-MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
-gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
-YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
-b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
-9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
-zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
-OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
-2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
-oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
-KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
-m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
-MdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/58d017279cd4dc63abddb196a6c9906c30c4e08783eae8c1609954d69355596b.pem b/chromium/net/data/ssl/ev_roots/58d017279cd4dc63abddb196a6c9906c30c4e08783eae8c1609954d69355596b.pem
deleted file mode 100644
index 0900e0140aa..00000000000
--- a/chromium/net/data/ssl/ev_roots/58d017279cd4dc63abddb196a6c9906c30c4e08783eae8c1609954d69355596b.pem
+++ /dev/null
@@ -1,51 +0,0 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Validity
- Not Before: Jun 26 00:19:54 1999 GMT
- Not After : Jun 26 00:19:54 2019 GMT
- Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:ce:3a:71:ca:e5:ab:c8:59:92:55:d7:ab:d8:74:
- 0e:f9:ee:d9:f6:55:47:59:65:47:0e:05:55:dc:eb:
- 98:36:3c:5c:53:5d:d3:30:cf:38:ec:bd:41:89:ed:
- 25:42:09:24:6b:0a:5e:b3:7c:dd:52:2d:4c:e6:d4:
- d6:7d:5a:59:a9:65:d4:49:13:2d:24:4d:1c:50:6f:
- b5:c1:85:54:3b:fe:71:e4:d3:5c:42:f9:80:e0:91:
- 1a:0a:5b:39:36:67:f3:3f:55:7c:1b:3f:b4:5f:64:
- 73:34:e3:b4:12:bf:87:64:f8:da:12:ff:37:27:c1:
- b3:43:bb:ef:7b:6e:2e:69:f7
- Exponent: 65537 (0x10001)
- Signature Algorithm: sha1WithRSAEncryption
- 3b:7f:50:6f:6f:50:94:99:49:62:38:38:1f:4b:f8:a5:c8:3e:
- a7:82:81:f6:2b:c7:e8:c5:ce:e8:3a:10:82:cb:18:00:8e:4d:
- bd:a8:58:7f:a1:79:00:b5:bb:e9:8d:af:41:d9:0f:34:ee:21:
- 81:19:a0:32:49:28:f4:c4:8e:56:d5:52:33:fd:50:d5:7e:99:
- 6c:03:e4:c9:4c:fc:cb:6c:ab:66:b3:4a:21:8c:e5:b5:0c:32:
- 3e:10:b2:cc:6c:a1:dc:9a:98:4c:02:5b:f3:ce:b9:9e:a5:72:
- 0e:4a:b7:3f:3c:e6:16:68:f8:be:ed:74:4c:bc:5b:d5:62:1f:
- 43:dd
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
-NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
-dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
-WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
-v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
-UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
-IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
-W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem b/chromium/net/data/ssl/ev_roots/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem
new file mode 100644
index 00000000000..43021ef5202
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6.pem
@@ -0,0 +1,125 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 08:16:5f:8a:4c:a5:ec:00:c9:93:40:df:c4:c6:ae:23:b8:1c:5a:a4
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = HK, ST = Hong Kong, L = Hong Kong, O = Hongkong Post, CN = Hongkong Post Root CA 3
+ Validity
+ Not Before: Jun 3 02:29:46 2017 GMT
+ Not After : Jun 3 02:29:46 2042 GMT
+ Subject: C = HK, ST = Hong Kong, L = Hong Kong, O = Hongkong Post, CN = Hongkong Post Root CA 3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (4096 bit)
+ Modulus:
+ 00:b3:88:d7:ea:ce:0f:20:4e:be:e6:d6:03:6d:ee:
+ 59:fc:c2:57:df:29:68:a1:83:0e:3e:68:c7:68:58:
+ 9c:1c:60:4b:89:43:0c:b9:d4:15:b2:ee:c1:4e:75:
+ e9:b5:a7:ef:e5:e9:35:99:e4:cc:1c:e7:4b:5f:8d:
+ 33:30:20:33:53:d9:a6:bb:d5:3e:13:8e:e9:1f:87:
+ 49:ad:50:2d:50:ca:18:be:01:58:a2:13:70:96:bb:
+ 89:88:56:80:5c:f8:bd:2c:3c:e1:4c:57:88:bb:d3:
+ b9:95:ef:cb:c7:f6:da:31:74:28:a6:e6:54:89:f5:
+ 41:31:ca:e5:26:1a:cd:82:e0:70:da:3b:29:bb:d5:
+ 03:f5:99:ba:55:f5:64:d1:60:0e:b3:89:49:b8:8a:
+ 2f:05:d2:84:45:28:7c:8f:68:50:12:78:fc:0b:b5:
+ 53:cb:c2:98:1c:84:a3:9e:b0:be:23:a4:da:dc:c8:
+ 2b:1e:da:6e:45:1e:89:98:da:f9:00:2e:06:e9:0c:
+ 3b:70:d5:50:25:88:99:cb:cd:73:60:f7:d5:ff:35:
+ 67:c5:a1:bc:5e:ab:cd:4a:b8:45:eb:c8:68:1e:0d:
+ 0d:14:46:12:e3:d2:64:62:8a:42:98:bc:b4:c6:08:
+ 08:f8:fd:a8:4c:64:9c:76:01:bd:2f:a9:6c:33:0f:
+ d8:3f:28:b8:3c:69:01:42:86:7e:69:c1:c9:06:ca:
+ e5:7a:46:65:e9:c2:d6:50:41:2e:3f:b7:e4:ed:6c:
+ d7:bf:26:01:11:a2:16:29:4a:6b:34:06:90:ec:13:
+ d2:b6:fb:6a:76:d2:3c:ed:f0:d6:2d:dd:e1:15:ec:
+ a3:9b:2f:2c:c9:3e:2b:e4:69:3b:ff:72:25:b1:36:
+ 86:5b:c7:7f:6b:8b:55:1b:4a:c5:20:61:3d:ae:cb:
+ 50:e1:08:3a:be:b0:8f:63:41:53:30:08:59:3c:98:
+ 1d:77:ba:63:91:7a:ca:10:50:60:bf:f0:d7:bc:95:
+ 87:8f:97:c5:fe:97:6a:01:94:a3:7c:5b:85:1d:2a:
+ 39:3a:d0:54:a1:d1:39:71:9d:fd:21:f9:b5:7b:f0:
+ e2:e0:02:8f:6e:96:24:25:2c:a0:1e:2c:a8:c4:89:
+ a7:ef:ed:99:06:2f:b6:0a:4c:4f:db:a2:cc:37:1a:
+ af:47:85:2d:8a:5f:c4:34:34:4c:00:fd:18:93:67:
+ 13:d1:37:e6:48:b4:8b:06:c5:57:7b:19:86:0a:79:
+ cb:00:c9:52:af:42:ff:37:8f:e1:a3:1e:7a:3d:50:
+ ab:63:06:e7:15:b5:3f:b6:45:37:94:37:b1:7e:f2:
+ 48:c3:7f:c5:75:fe:97:8d:45:8f:1a:a7:1a:72:28:
+ 1a:40:0f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Authority Key Identifier:
+ keyid:17:9D:CD:1E:8B:D6:39:2B:70:D3:5C:D4:A0:B8:1F:B0:00:FC:C5:61
+
+ X509v3 Subject Key Identifier:
+ 17:9D:CD:1E:8B:D6:39:2B:70:D3:5C:D4:A0:B8:1F:B0:00:FC:C5:61
+ Signature Algorithm: sha256WithRSAEncryption
+ 56:d5:7b:6e:e6:22:01:d2:42:9b:18:d5:0e:d7:66:23:5c:e3:
+ fe:a0:c7:92:d2:e9:94:ad:4b:a2:c6:ec:12:7c:74:d5:48:d2:
+ 59:14:99:c0:eb:b9:d1:eb:f4:48:30:5b:ad:a7:57:73:99:a9:
+ d3:e5:b7:d1:2e:59:24:58:dc:68:2e:2e:62:d8:6a:e4:70:0b:
+ 2d:20:50:20:a4:32:95:d1:00:98:bb:d3:fd:f7:32:f2:49:ae:
+ c6:7a:e0:47:be:6e:ce:cb:a3:72:3a:2d:69:5d:cb:c8:e8:45:
+ 39:d4:fa:42:c1:11:4c:77:5d:92:fb:6a:ff:58:44:e5:eb:81:
+ 9e:af:a0:99:ad:be:a9:01:66:cb:38:1d:3c:df:43:1f:f4:4d:
+ 6e:b4:ba:17:46:fc:7d:fd:87:81:79:6a:0d:33:0f:fa:2f:f8:
+ 14:b9:80:b3:5d:4d:aa:97:e1:f9:e4:18:c5:f8:d5:38:8c:26:
+ 3c:fd:f2:28:e2:ee:5a:49:88:2c:df:79:3d:8e:9e:90:3c:bd:
+ 41:4a:3a:dd:5b:f6:9a:b4:ce:3f:25:30:7f:32:7d:a2:03:94:
+ d0:dc:7a:a1:52:de:6e:93:8d:18:26:fd:55:ac:bd:8f:9b:d2:
+ cf:af:e7:86:2c:cb:1f:09:6f:a3:6f:a9:84:d4:73:bf:4d:a1:
+ 74:1b:4e:23:60:f2:cc:0e:aa:7f:a4:9c:4c:25:a8:b2:66:3b:
+ 38:ff:d9:94:30:f6:72:84:be:68:55:10:0f:c6:73:2c:16:69:
+ 93:07:fe:b1:45:ed:bb:a2:55:6a:b0:da:b5:4a:02:25:27:85:
+ d7:b7:b7:86:44:16:89:6c:80:2b:3e:97:a9:9c:d5:7e:55:4c:
+ c6:de:45:10:1c:ea:e9:3b:9f:03:53:ee:ee:7a:01:02:16:78:
+ d4:e8:c2:be:46:76:88:13:3f:22:bb:48:12:1d:52:00:b4:02:
+ 7e:21:1a:1e:9c:25:f4:f3:3d:5e:1e:d2:1c:f9:b3:2d:b6:f7:
+ 37:5c:c6:cb:21:4e:b0:f7:99:47:18:85:c1:2b:ba:55:ae:06:
+ ea:d0:07:b2:dc:ab:d0:82:96:75:ce:d2:50:fe:99:e7:cf:2f:
+ 9f:e7:76:d1:61:2a:fb:21:bb:31:d0:aa:9f:47:a4:b2:22:ca:
+ 16:3a:50:57:c4:5b:43:67:c5:65:62:03:49:01:eb:43:d9:d8:
+ f8:9e:ad:cf:b1:63:0e:45:f4:a0:5a:2c:9b:2d:c5:a6:c0:ad:
+ a8:47:f4:27:4c:38:0d:2e:1b:49:3b:52:f4:e8:88:83:2b:54:
+ 28:d4:f2:35:52:b4:32:83:62:69:64:0c:91:9c:9f:97:ea:74:
+ 16:fd:1f:11:06:9a:9b:f4
+-----BEGIN CERTIFICATE-----
+MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL
+BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ
+SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n
+a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5
+NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT
+CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u
+Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO
+dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI
+VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV
+9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY
+2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY
+vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt
+bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb
+x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+
+l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK
+TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj
+Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e
+i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw
+DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG
+7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk
+MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr
+gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk
+GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS
+3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm
+Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+
+l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c
+JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP
+L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
+LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
+mpv0
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766.pem b/chromium/net/data/ssl/ev_roots/5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766.pem
deleted file mode 100644
index ad1ace9c9da..00000000000
--- a/chromium/net/data/ssl/ev_roots/5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766.pem
+++ /dev/null
@@ -1,54 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 3c:b2:f4:48:0a:00:e2:fe:eb:24:3b:5e:60:3e:c3:6b
- Signature Algorithm: ecdsa-with-SHA384
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2
- Validity
- Not Before: Nov 5 00:00:00 2007 GMT
- Not After : Jan 18 23:59:59 2038 GMT
- Subject: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:15:b1:e8:fd:03:15:43:e5:ac:eb:87:37:11:62:
- ef:d2:83:36:52:7d:45:57:0b:4a:8d:7b:54:3b:3a:
- 6e:5f:15:02:c0:50:a6:cf:25:2f:7d:ca:48:b8:c7:
- 50:63:1c:2a:21:08:7c:9a:36:d8:0b:fe:d1:26:c5:
- 58:31:30:28:25:f3:5d:5d:a3:b8:b6:a5:b4:92:ed:
- 6c:2c:9f:eb:dd:43:89:a2:3c:4b:48:91:1d:50:ec:
- 26:df:d6:60:2e:bd:21
- ASN1 OID: secp384r1
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 15:5F:35:57:51:55:FB:25:B2:AD:03:69:FC:01:A3:FA:BE:11:55:D5
- Signature Algorithm: ecdsa-with-SHA384
- 30:64:02:30:64:96:59:a6:e8:09:de:8b:ba:fa:5a:88:88:f0:
- 1f:91:d3:46:a8:f2:4a:4c:02:63:fb:6c:5f:38:db:2e:41:93:
- a9:0e:e6:9d:dc:31:1c:b2:a0:a7:18:1c:79:e1:c7:36:02:30:
- 3a:56:af:9a:74:6c:f6:fb:83:e0:33:d3:08:5f:a1:9c:c2:5b:
- 9f:46:d6:b6:cb:91:06:63:a2:06:e7:33:ac:3e:a8:81:12:d0:
- cb:ba:d0:92:0b:b6:9e:96:aa:04:0f:8a
------BEGIN CERTIFICATE-----
-MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
-MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
-KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
-MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
-BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
-NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
-BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
-MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
-So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
-tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
-CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
-qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
-rD6ogRLQy7rQkgu2npaqBA+K
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50.pem b/chromium/net/data/ssl/ev_roots/62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50.pem
deleted file mode 100644
index d989575f69f..00000000000
--- a/chromium/net/data/ssl/ev_roots/62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50.pem
+++ /dev/null
@@ -1,86 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 927650371 (0x374ad243)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
- Validity
- Not Before: May 25 16:09:40 1999 GMT
- Not After : May 25 16:39:40 2019 GMT
- Subject: C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:cd:28:83:34:54:1b:89:f3:0f:af:37:91:31:ff:
- af:31:60:c9:a8:e8:b2:10:68:ed:9f:e7:93:36:f1:
- 0a:64:bb:47:f5:04:17:3f:23:47:4d:c5:27:19:81:
- 26:0c:54:72:0d:88:2d:d9:1f:9a:12:9f:bc:b3:71:
- d3:80:19:3f:47:66:7b:8c:35:28:d2:b9:0a:df:24:
- da:9c:d6:50:79:81:7a:5a:d3:37:f7:c2:4a:d8:29:
- 92:26:64:d1:e4:98:6c:3a:00:8a:f5:34:9b:65:f8:
- ed:e3:10:ff:fd:b8:49:58:dc:a0:de:82:39:6b:81:
- b1:16:19:61:b9:54:b6:e6:43
- Exponent: 3 (0x3)
- X509v3 extensions:
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- X509v3 CRL Distribution Points:
-
- Full Name:
- DirName: C = US, O = Entrust.net, OU = www.entrust.net/CPS incorp. by ref. (limits liab.), OU = (c) 1999 Entrust.net Limited, CN = Entrust.net Secure Server Certification Authority, CN = CRL1
-
- Full Name:
- URI:http://www.entrust.net/CRL/net1.crl
-
- X509v3 Private Key Usage Period:
- Not Before: May 25 16:09:40 1999 GMT, Not After: May 25 16:09:40 2019 GMT
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Authority Key Identifier:
- keyid:F0:17:62:13:55:3D:B3:FF:0A:00:6B:FB:50:84:97:F3:ED:62:D0:1A
-
- X509v3 Subject Key Identifier:
- F0:17:62:13:55:3D:B3:FF:0A:00:6B:FB:50:84:97:F3:ED:62:D0:1A
- X509v3 Basic Constraints:
- CA:TRUE
- 1.2.840.113533.7.65.0:
- 0
-..V4.0....
- Signature Algorithm: sha1WithRSAEncryption
- 90:dc:30:02:fa:64:74:c2:a7:0a:a5:7c:21:8d:34:17:a8:fb:
- 47:0e:ff:25:7c:8d:13:0a:fb:e4:98:b5:ef:8c:f8:c5:10:0d:
- f7:92:be:f1:c3:d5:d5:95:6a:04:bb:2c:ce:26:36:65:c8:31:
- c6:e7:ee:3f:e3:57:75:84:7a:11:ef:46:4f:18:f4:d3:98:bb:
- a8:87:32:ba:72:f6:3c:e2:3d:9f:d7:1d:d9:c3:60:43:8c:58:
- 0e:22:96:2f:62:a3:2c:1f:ba:ad:05:ef:ab:32:78:87:a0:54:
- 73:19:b5:5c:05:f9:52:3e:6d:2d:45:0b:f7:0a:93:ea:ed:06:
- f9:b2
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
-VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
-ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
-KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
-ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
-MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
-b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
-bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
-U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
-A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
-I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
-wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
-AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
-oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
-BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
-dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
-MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
-b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
-dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
-MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
-E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
-MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
-hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
-95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
-2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79.pem b/chromium/net/data/ssl/ev_roots/69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79.pem
deleted file mode 100644
index ef1dd9e5d18..00000000000
--- a/chromium/net/data/ssl/ev_roots/69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79.pem
+++ /dev/null
@@ -1,60 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 2f:80:fe:23:8c:0e:22:0f:48:67:12:28:91:87:ac:b3
- Signature Algorithm: ecdsa-with-SHA384
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2007 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G4
- Validity
- Not Before: Nov 5 00:00:00 2007 GMT
- Not After : Jan 18 23:59:59 2038 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2007 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G4
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:a7:56:7a:7c:52:da:64:9b:0e:2d:5c:d8:5e:ac:
- 92:3d:fe:01:e6:19:4a:3d:14:03:4b:fa:60:27:20:
- d9:83:89:69:fa:54:c6:9a:18:5e:55:2a:64:de:06:
- f6:8d:4a:3b:ad:10:3c:65:3d:90:88:04:89:e0:30:
- 61:b3:ae:5d:01:a7:7b:de:7c:b2:be:ca:65:61:00:
- 86:ae:da:8f:7b:d0:89:ad:4d:1d:59:9a:41:b1:bc:
- 47:80:dc:9e:62:c3:f9
- ASN1 OID: secp384r1
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Subject Key Identifier:
- B3:16:91:FD:EE:A6:6E:E4:B5:2E:49:8F:87:78:81:80:EC:E5:B1:B5
- Signature Algorithm: ecdsa-with-SHA384
- 30:65:02:30:66:21:0c:18:26:60:5a:38:7b:56:42:e0:a7:fc:
- 36:84:51:91:20:2c:76:4d:43:3d:c4:1d:84:23:d0:ac:d6:7c:
- 35:06:ce:cd:69:bd:90:0d:db:6c:48:42:1d:0e:aa:42:02:31:
- 00:9c:3d:48:39:23:39:58:1a:15:12:59:6a:9e:ef:d5:59:b2:
- 1d:52:2c:99:71:cd:c7:29:df:1b:2a:61:7b:71:d1:de:f3:c0:
- e5:0d:3a:4a:aa:2d:a7:d8:86:2a:dd:2e:10
------BEGIN CERTIFICATE-----
-MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
-U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
-SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
-biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
-GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
-fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
-aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
-aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
-kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
-4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
-FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/6ea54741d004667eed1b4816634aa3a79e6e4b96950f8279dafc8d9bd8812137.pem b/chromium/net/data/ssl/ev_roots/6ea54741d004667eed1b4816634aa3a79e6e4b96950f8279dafc8d9bd8812137.pem
deleted file mode 100644
index 129e75163af..00000000000
--- a/chromium/net/data/ssl/ev_roots/6ea54741d004667eed1b4816634aa3a79e6e4b96950f8279dafc8d9bd8812137.pem
+++ /dev/null
@@ -1,90 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 44:be:0c:8b:50:00:24:b4:11:d3:36:2a:fe:65:0a:fd
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware
- Validity
- Not Before: Jul 9 18:10:42 1999 GMT
- Not After : Jul 9 18:19:22 2019 GMT
- Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b1:f7:c3:38:3f:b4:a8:7f:cf:39:82:51:67:d0:
- 6d:9f:d2:ff:58:f3:e7:9f:2b:ec:0d:89:54:99:b9:
- 38:99:16:f7:e0:21:79:48:c2:bb:61:74:12:96:1d:
- 3c:6a:72:d5:3c:10:67:3a:39:ed:2b:13:cd:66:eb:
- 95:09:33:a4:6c:97:b1:e8:c6:ec:c1:75:79:9c:46:
- 5e:8d:ab:d0:6a:fd:b9:2a:55:17:10:54:b3:19:f0:
- 9a:f6:f1:b1:5d:b6:a7:6d:fb:e0:71:17:6b:a2:88:
- fb:00:df:fe:1a:31:77:0c:9a:01:7a:b1:32:e3:2b:
- 01:07:38:6e:c3:a5:5e:23:bc:45:9b:7b:50:c1:c9:
- 30:8f:db:e5:2b:7a:d3:5b:fb:33:40:1e:a0:d5:98:
- 17:bc:8b:87:c3:89:d3:5d:a0:8e:b2:aa:aa:f6:8e:
- 69:88:06:c5:fa:89:21:f3:08:9d:69:2e:09:33:9b:
- 29:0d:46:0f:8c:cc:49:34:b0:69:51:bd:f9:06:cd:
- 68:ad:66:4c:bc:3e:ac:61:bd:0a:88:0e:c8:df:3d:
- ee:7c:04:4c:9d:0a:5e:6b:91:d6:ee:c7:ed:28:8d:
- ab:4d:87:89:73:d0:6e:a4:d0:1e:16:8b:14:e1:76:
- 44:03:7f:63:ac:e4:cd:49:9c:c5:92:f4:ab:32:a1:
- 48:5b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage:
- Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.usertrust.com/UTN-USERFirst-Hardware.crl
-
- X509v3 Extended Key Usage:
- TLS Web Server Authentication, IPSec End System, IPSec Tunnel, IPSec User
- Signature Algorithm: sha1WithRSAEncryption
- 47:19:0f:de:74:c6:99:97:af:fc:ad:28:5e:75:8e:eb:2d:67:
- ee:4e:7b:2b:d7:0c:ff:f6:de:cb:55:a2:0a:e1:4c:54:65:93:
- 60:6b:9f:12:9c:ad:5e:83:2c:eb:5a:ae:c0:e4:2d:f4:00:63:
- 1d:b8:c0:6c:f2:cf:49:bb:4d:93:6f:06:a6:0a:22:b2:49:62:
- 08:4e:ff:c8:c8:14:b2:88:16:5d:e7:01:e4:12:95:e5:45:34:
- b3:8b:69:bd:cf:b4:85:8f:75:51:9e:7d:3a:38:3a:14:48:12:
- c6:fb:a7:3b:1a:8d:0d:82:40:07:e8:04:08:90:a1:89:cb:19:
- 50:df:ca:1c:01:bc:1d:04:19:7b:10:76:97:3b:ee:90:90:ca:
- c4:0e:1f:16:6e:75:ef:33:f8:d3:6f:5b:1e:96:e3:e0:74:77:
- 74:7b:8a:a2:6e:2d:dd:76:d6:39:30:82:f0:ab:9c:52:f2:2a:
- c7:af:49:5e:7e:c7:68:e5:82:81:c8:6a:27:f9:27:88:2a:d5:
- 58:50:95:1f:f0:3b:1c:57:bb:7d:14:39:62:2b:9a:c9:94:92:
- 2a:a3:22:0c:ff:89:26:7d:5f:23:2b:47:d7:15:1d:a9:6a:9e:
- 51:0d:2a:51:9e:81:f9:d4:3b:5e:70:12:7f:10:32:9c:1e:bb:
- 9d:f8:66:a8
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
-lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
-SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
-A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
-MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
-d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
-cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
-0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
-M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
-MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
-oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
-DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
-oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
-dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
-bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
-BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
-//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
-CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
-CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
-3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
-KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem b/chromium/net/data/ssl/ev_roots/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem
new file mode 100644
index 00000000000..41bdf8673d6
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185.pem
@@ -0,0 +1,79 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0b:93:1c:3a:d6:39:67:ea:67:23:bf:c3:af:9a:f4:4b
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G2
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:d9:e7:28:2f:52:3f:36:72:49:88:93:34:f3:f8:
+ 6a:1e:31:54:80:9f:ad:54:41:b5:47:df:96:a8:d4:
+ af:80:2d:b9:0a:cf:75:fd:89:a5:7d:24:fa:e3:22:
+ 0c:2b:bc:95:17:0b:33:bf:19:4d:41:06:90:00:bd:
+ 0c:4d:10:fe:07:b5:e7:1c:6e:22:55:31:65:97:bd:
+ d3:17:d2:1e:62:f3:db:ea:6c:50:8c:3f:84:0c:96:
+ cf:b7:cb:03:e0:ca:6d:a1:14:4c:1b:89:dd:ed:00:
+ b0:52:7c:af:91:6c:b1:38:13:d1:e9:12:08:c0:00:
+ b0:1c:2b:11:da:77:70:36:9b:ae:ce:79:87:dc:82:
+ 70:e6:09:74:70:55:69:af:a3:68:9f:bf:dd:b6:79:
+ b3:f2:9d:70:29:55:f4:ab:ff:95:61:f3:c9:40:6f:
+ 1d:d1:be:93:bb:d3:88:2a:bb:9d:bf:72:5a:56:71:
+ 3b:3f:d4:f3:d1:0a:fe:28:ef:a3:ee:d9:99:af:03:
+ d3:8f:60:b7:f2:92:a1:b1:bd:89:89:1f:30:cd:c3:
+ a6:2e:62:33:ae:16:02:77:44:5a:e7:81:0a:3c:a7:
+ 44:2e:79:b8:3f:04:bc:5c:a0:87:e1:1b:af:51:8e:
+ cd:ec:2c:fa:f8:fe:6d:f0:3a:7c:aa:8b:e4:67:95:
+ 31:8d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ CE:C3:4A:B9:99:55:F2:B8:DB:60:BF:A9:7E:BD:56:B5:97:36:A7:D6
+ Signature Algorithm: sha256WithRSAEncryption
+ ca:a5:55:8c:e3:c8:41:6e:69:27:a7:75:11:ef:3c:86:36:6f:
+ d2:9d:c6:78:38:1d:69:96:a2:92:69:2e:38:6c:9b:7d:04:d4:
+ 89:a5:b1:31:37:8a:c9:21:cc:ab:6c:cd:8b:1c:9a:d6:bf:48:
+ d2:32:66:c1:8a:c0:f3:2f:3a:ef:c0:e3:d4:91:86:d1:50:e3:
+ 03:db:73:77:6f:4a:39:53:ed:de:26:c7:b5:7d:af:2b:42:d1:
+ 75:62:e3:4a:2b:02:c7:50:4b:e0:69:e2:96:6c:0e:44:66:10:
+ 44:8f:ad:05:eb:f8:79:ac:a6:1b:e8:37:34:9d:53:c9:61:aa:
+ a2:52:af:4a:70:16:86:c2:3a:c8:b1:13:70:36:d8:cf:ee:f4:
+ 0a:34:d5:5b:4c:fd:07:9c:a2:ba:d9:01:72:5c:f3:4d:c1:dd:
+ 0e:b1:1c:0d:c4:63:be:ad:f4:14:fb:89:ec:a2:41:0e:4c:cc:
+ c8:57:40:d0:6e:03:aa:cd:0c:8e:89:99:99:6c:f0:3c:30:af:
+ 38:df:6f:bc:a3:be:29:20:27:ab:74:ff:13:22:78:de:97:52:
+ 55:1e:83:b5:54:20:03:ee:ae:c0:4f:56:de:37:cc:c3:7f:aa:
+ 04:27:bb:d3:77:b8:62:db:17:7c:9c:28:22:13:73:6c:cf:26:
+ f5:8a:29:e7
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem b/chromium/net/data/ssl/ev_roots/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem
new file mode 100644
index 00000000000..5a8515c9f5c
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2.pem
@@ -0,0 +1,53 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 0b:a1:5a:fa:1d:df:a0:b5:49:44:af:cd:24:a0:6c:ec
+ Signature Algorithm: ecdsa-with-SHA384
+ Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G3
+ Validity
+ Not Before: Aug 1 12:00:00 2013 GMT
+ Not After : Jan 15 12:00:00 2038 GMT
+ Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Assured ID Root G3
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:19:e7:bc:ac:44:65:ed:cd:b8:3f:58:fb:8d:b1:
+ 57:a9:44:2d:05:15:f2:ef:0b:ff:10:74:9f:b5:62:
+ 52:5f:66:7e:1f:e5:dc:1b:45:79:0b:cc:c6:53:0a:
+ 9d:8d:5d:02:d9:a9:59:de:02:5a:f6:95:2a:0e:8d:
+ 38:4a:8a:49:c6:bc:c6:03:38:07:5f:55:da:7e:09:
+ 6e:e2:7f:5e:d0:45:20:0f:59:76:10:d6:a0:24:f0:
+ 2d:de:36:f2:6c:29:39
+ ASN1 OID: secp384r1
+ NIST CURVE: P-384
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ CB:D0:BD:A9:E1:98:05:51:A1:4D:37:A2:83:79:CE:8D:1D:2A:E4:84
+ Signature Algorithm: ecdsa-with-SHA384
+ 30:64:02:30:25:a4:81:45:02:6b:12:4b:75:74:4f:c8:23:e3:
+ 70:f2:75:72:de:7c:89:f0:cf:91:72:61:9e:5e:10:92:59:56:
+ b9:83:c7:10:e7:38:e9:58:26:36:7d:d5:e4:34:86:39:02:30:
+ 7c:36:53:f0:30:e5:62:63:3a:99:e2:b6:a3:3b:9b:34:fa:1e:
+ da:10:92:71:5e:91:13:a7:dd:a4:6e:92:cc:32:d6:f5:21:66:
+ c7:2f:ea:96:63:6a:65:45:92:95:01:b4
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/8d722f81a9c113c0791df136a2966db26c950a971db46b4199f4ea54b78bfb9f.pem b/chromium/net/data/ssl/ev_roots/8d722f81a9c113c0791df136a2966db26c950a971db46b4199f4ea54b78bfb9f.pem
deleted file mode 100644
index ff13d5593b6..00000000000
--- a/chromium/net/data/ssl/ev_roots/8d722f81a9c113c0791df136a2966db26c950a971db46b4199f4ea54b78bfb9f.pem
+++ /dev/null
@@ -1,82 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 34:4e:d5:57:20:d5:ed:ec:49:f4:2f:ce:37:db:2b:6d
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Validity
- Not Before: Nov 17 00:00:00 2006 GMT
- Not After : Jul 16 23:59:59 2036 GMT
- Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:
- 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:
- 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:
- e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:
- 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:
- 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:
- 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:
- fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:
- 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:
- 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:
- 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:
- dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:
- d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:
- 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:
- 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:
- 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:
- 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:
- d5:9d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
- Signature Algorithm: sha1WithRSAEncryption
- 79:11:c0:4b:b3:91:b6:fc:f0:e9:67:d4:0d:6e:45:be:55:e8:
- 93:d2:ce:03:3f:ed:da:25:b0:1d:57:cb:1e:3a:76:a0:4c:ec:
- 50:76:e8:64:72:0c:a4:a9:f1:b8:8b:d6:d6:87:84:bb:32:e5:
- 41:11:c0:77:d9:b3:60:9d:eb:1b:d5:d1:6e:44:44:a9:a6:01:
- ec:55:62:1d:77:b8:5c:8e:48:49:7c:9c:3b:57:11:ac:ad:73:
- 37:8e:2f:78:5c:90:68:47:d9:60:60:e6:fc:07:3d:22:20:17:
- c4:f7:16:e9:c4:d8:72:f9:c8:73:7c:df:16:2f:15:a9:3e:fd:
- 6a:27:b6:a1:eb:5a:ba:98:1f:d5:e3:4d:64:0a:9d:13:c8:61:
- ba:f5:39:1c:87:ba:b8:bd:7b:22:7f:f6:fe:ac:40:79:e5:ac:
- 10:6f:3d:8f:1b:79:76:8b:c4:37:b3:21:18:84:e5:36:00:eb:
- 63:20:99:b9:e9:fe:33:04:bb:41:c8:c1:02:f9:44:63:20:9e:
- 81:ce:42:d3:d6:3f:2c:76:d3:63:9c:59:dd:8f:a6:e1:0e:a0:
- 2e:41:f7:2e:95:47:cf:bc:fd:33:f3:f6:0b:61:7e:7e:91:2b:
- 81:47:c2:27:30:ee:a7:10:5d:37:8f:5c:39:2b:e4:04:f0:7b:
- 8d:56:8c:68
------BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
-NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
-LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
-A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
-W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
-3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
-6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
-Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
-NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
-r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
-DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
-YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
-/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
-LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
-jVaMaA==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/9acfab7e43c8d880d06b262a94deeee4b4659989c3d0caf19baf6405e41ab7df.pem b/chromium/net/data/ssl/ev_roots/9acfab7e43c8d880d06b262a94deeee4b4659989c3d0caf19baf6405e41ab7df.pem
deleted file mode 100644
index 4589be06f87..00000000000
--- a/chromium/net/data/ssl/ev_roots/9acfab7e43c8d880d06b262a94deeee4b4659989c3d0caf19baf6405e41ab7df.pem
+++ /dev/null
@@ -1,87 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 18:da:d1:9e:26:7d:e8:bb:4a:21:58:cd:cc:6b:3b:4a
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Validity
- Not Before: Nov 8 00:00:00 2006 GMT
- Not After : Jul 16 23:59:59 2036 GMT
- Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
- 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
- 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
- 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
- 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
- a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
- 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
- d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
- 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
- bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
- f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
- ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
- f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
- 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
- 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
- ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
- 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
- 25:15
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- 1.3.6.1.5.5.7.1.12:
- 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
- X509v3 Subject Key Identifier:
- 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
- Signature Algorithm: sha1WithRSAEncryption
- 93:24:4a:30:5f:62:cf:d8:1a:98:2f:3d:ea:dc:99:2d:bd:77:
- f6:a5:79:22:38:ec:c4:a7:a0:78:12:ad:62:0e:45:70:64:c5:
- e7:97:66:2d:98:09:7e:5f:af:d6:cc:28:65:f2:01:aa:08:1a:
- 47:de:f9:f9:7c:92:5a:08:69:20:0d:d9:3e:6d:6e:3c:0d:6e:
- d8:e6:06:91:40:18:b9:f8:c1:ed:df:db:41:aa:e0:96:20:c9:
- cd:64:15:38:81:c9:94:ee:a2:84:29:0b:13:6f:8e:db:0c:dd:
- 25:02:db:a4:8b:19:44:d2:41:7a:05:69:4a:58:4f:60:ca:7e:
- 82:6a:0b:02:aa:25:17:39:b5:db:7f:e7:84:65:2a:95:8a:bd:
- 86:de:5e:81:16:83:2d:10:cc:de:fd:a8:82:2a:6d:28:1f:0d:
- 0b:c4:e5:e7:1a:26:19:e1:f4:11:6f:10:b5:95:fc:e7:42:05:
- 32:db:ce:9d:51:5e:28:b6:9e:85:d3:5b:ef:a5:7d:45:40:72:
- 8e:b7:0e:6b:0e:06:fb:33:35:48:71:b8:9d:27:8b:c4:65:5f:
- 0d:86:76:9c:44:7a:f6:95:5c:f6:5d:32:08:33:a4:54:b6:18:
- 3f:68:5c:f2:42:4a:85:38:54:83:5f:d1:e8:2c:f2:ac:11:d6:
- a8:ed:63:6a
------BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
-nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
-t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
-SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
-BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
-rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
-NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
-BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
-MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
-p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
-5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
-WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
-4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
-hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37.pem b/chromium/net/data/ssl/ev_roots/a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37.pem
deleted file mode 100644
index e034a8a2b3c..00000000000
--- a/chromium/net/data/ssl/ev_roots/a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37.pem
+++ /dev/null
@@ -1,77 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication EV RootCA1
- Validity
- Not Before: Jun 6 02:12:32 2007 GMT
- Not After : Jun 6 02:12:32 2037 GMT
- Subject: C=JP, O=SECOM Trust Systems CO.,LTD., OU=Security Communication EV RootCA1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:bc:7f:ec:57:9b:24:e0:fe:9c:ba:42:79:a9:88:
- 8a:fa:80:e0:f5:07:29:43:ea:8e:0a:34:36:8d:1c:
- fa:a7:b5:39:78:ff:97:75:f7:2f:e4:aa:6b:04:84:
- 44:ca:a6:e2:68:8e:fd:55:50:62:0f:a4:71:0e:ce:
- 07:38:2d:42:85:50:ad:3c:96:6f:8b:d5:a2:0e:cf:
- de:49:89:3d:d6:64:2e:38:e5:1e:6c:b5:57:8a:9e:
- ef:48:0e:cd:7a:69:16:87:44:b5:90:e4:06:9d:ae:
- a1:04:97:58:79:ef:20:4a:82:6b:8c:22:bf:ec:1f:
- 0f:e9:84:71:ed:f1:0e:e4:b8:18:13:cc:56:36:5d:
- d1:9a:1e:51:6b:39:6e:60:76:88:34:0b:f3:b3:d1:
- b0:9d:ca:61:e2:64:1d:c1:46:07:b8:63:dd:1e:33:
- 65:b3:8e:09:55:52:3d:b5:bd:ff:07:eb:ad:61:55:
- 18:2c:a9:69:98:4a:aa:40:c5:33:14:65:74:00:f9:
- 91:de:af:03:48:c5:40:54:dc:0f:84:90:68:20:c5:
- 92:96:dc:2e:e5:02:45:aa:c0:5f:54:f8:6d:ea:49:
- cf:5d:6c:4b:af:ef:9a:c2:56:5c:c6:35:56:42:6a:
- 30:5f:c2:ab:f6:e2:3d:3f:b3:c9:11:8f:31:4c:d7:
- 9f:49
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 35:4A:F5:4D:AF:3F:D7:82:38:AC:AB:71:65:17:75:8C:9D:55:93:E6
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- a8:87:e9:ec:f8:40:67:5d:c3:c1:66:c7:40:4b:97:fc:87:13:
- 90:5a:c4:ef:a0:ca:5f:8b:b7:a7:b7:f1:d6:b5:64:b7:8a:b3:
- b8:1b:cc:da:fb:ac:66:88:41:ce:e8:fc:e4:db:1e:88:a6:ed:
- 27:50:1b:02:30:24:46:79:fe:04:87:70:97:40:73:d1:c0:c1:
- 57:19:9a:69:a5:27:99:ab:9d:62:84:f6:51:c1:2c:c9:23:15:
- d8:28:b7:ab:25:13:b5:46:e1:86:02:ff:26:8c:c4:88:92:1d:
- 56:fe:19:67:f2:55:e4:80:a3:6b:9c:ab:77:e1:51:71:0d:20:
- db:10:9a:db:bd:76:79:07:77:99:28:ad:9a:5e:da:b1:4f:44:
- 2c:35:8e:a5:96:c7:fd:83:f0:58:c6:79:d6:98:7c:a8:8d:fe:
- 86:3e:07:16:92:e1:7b:e7:1d:ec:33:76:7e:42:2e:4a:85:f9:
- 91:89:68:84:03:81:a5:9b:9a:be:e3:37:c5:54:ab:56:3b:18:
- 2d:41:a4:0c:f8:42:db:99:a0:e0:72:6f:bb:5d:e1:16:4f:53:
- 0a:64:f9:4e:f4:bf:4e:54:bd:78:6c:88:ea:bf:9c:13:24:c2:
- 70:69:a2:7f:0f:c8:3c:ad:08:c9:b0:98:40:a3:2a:e7:88:83:
- ed:77:8f:74
------BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
-MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
-IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
-bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
-RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
-zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
-bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
-MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
-VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
-OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
-tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
-q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
-EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
-Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
-VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557.pem b/chromium/net/data/ssl/ev_roots/a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557.pem
deleted file mode 100644
index 764184e9c66..00000000000
--- a/chromium/net/data/ssl/ev_roots/a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557.pem
+++ /dev/null
@@ -1,53 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 35:fc:26:5c:d9:84:4f:c9:3d:26:3d:57:9b:ae:d7:56
- Signature Algorithm: ecdsa-with-SHA384
- Issuer: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2
- Validity
- Not Before: Nov 5 00:00:00 2007 GMT
- Not After : Jan 18 23:59:59 2038 GMT
- Subject: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (384 bit)
- pub:
- 04:a2:d5:9c:82:7b:95:9d:f1:52:78:87:fe:8a:16:
- bf:05:e6:df:a3:02:4f:0d:07:c6:00:51:ba:0c:02:
- 52:2d:22:a4:42:39:c4:fe:8f:ea:c9:c1:be:d4:4d:
- ff:9f:7a:9e:e2:b1:7c:9a:ad:a7:86:09:73:87:d1:
- e7:9a:e3:7a:a5:aa:6e:fb:ba:b3:70:c0:67:88:a2:
- 35:d4:a3:9a:b1:fd:ad:c2:ef:31:fa:a8:b9:f3:fb:
- 08:c6:91:d1:fb:29:95
- ASN1 OID: secp384r1
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 9A:D8:00:30:00:E7:6B:7F:85:18:EE:8B:B6:CE:8A:0C:F8:11:E1:BB
- Signature Algorithm: ecdsa-with-SHA384
- 30:66:02:31:00:dd:f8:e0:57:47:5b:a7:e6:0a:c3:bd:f5:80:
- 8a:97:35:0d:1b:89:3c:54:86:77:28:ca:a1:f4:79:de:b5:e6:
- 38:b0:f0:65:70:8c:7f:02:54:c2:bf:ff:d8:a1:3e:d9:cf:02:
- 31:00:c4:8d:94:fc:dc:53:d2:dc:9d:78:16:1f:15:33:23:53:
- 52:e3:5a:31:5d:9d:ca:ae:bd:13:29:44:0d:27:5b:a8:e7:68:
- 9c:12:f7:58:3f:2e:72:02:57:a3:8f:a1:14:2e
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
-IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
-BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
-MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
-YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
-dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
-BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
-papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
-DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
-KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
-XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/a53125188d2110aa964b02c7b7c6da3203170894e5fb71fffb6667d5e6810a36.pem b/chromium/net/data/ssl/ev_roots/a53125188d2110aa964b02c7b7c6da3203170894e5fb71fffb6667d5e6810a36.pem
deleted file mode 100644
index 3139d848e56..00000000000
--- a/chromium/net/data/ssl/ev_roots/a53125188d2110aa964b02c7b7c6da3203170894e5fb71fffb6667d5e6810a36.pem
+++ /dev/null
@@ -1,48 +0,0 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 421 (0x1a5)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
- Validity
- Not Before: Aug 13 00:29:00 1998 GMT
- Not After : Aug 13 23:59:00 2018 GMT
- Subject: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:95:0f:a0:b6:f0:50:9c:e8:7a:c7:88:cd:dd:17:
- 0e:2e:b0:94:d0:1b:3d:0e:f6:94:c0:8a:94:c7:06:
- c8:90:97:c8:b8:64:1a:7a:7e:6c:3c:53:e1:37:28:
- 73:60:7f:b2:97:53:07:9f:53:f9:6d:58:94:d2:af:
- 8d:6d:88:67:80:e6:ed:b2:95:cf:72:31:ca:a5:1c:
- 72:ba:5c:02:e7:64:42:e7:f9:a9:2c:d6:3a:0d:ac:
- 8d:42:aa:24:01:39:e6:9c:3f:01:85:57:0d:58:87:
- 45:f8:d3:85:aa:93:69:26:85:70:48:80:3f:12:15:
- c7:79:b4:1f:05:2f:3b:62:99
- Exponent: 65537 (0x10001)
- Signature Algorithm: md5WithRSAEncryption
- 6d:eb:1b:09:e9:5e:d9:51:db:67:22:61:a4:2a:3c:48:77:e3:
- a0:7c:a6:de:73:a2:14:03:85:3d:fb:ab:0e:30:c5:83:16:33:
- 81:13:08:9e:7b:34:4e:df:40:c8:74:d7:b9:7d:dc:f4:76:55:
- 7d:9b:63:54:18:e9:f0:ea:f3:5c:b1:d9:8b:42:1e:b9:c0:95:
- 4e:ba:fa:d5:e2:7c:f5:68:61:bf:8e:ec:05:97:5f:5b:b0:d7:
- a3:85:34:c4:24:a7:0d:0f:95:93:ef:cb:94:d8:9e:1f:9d:5c:
- 85:6d:c7:aa:ae:4f:1f:22:b5:cd:95:ad:ba:a7:cc:f9:ab:0b:
- 7a:7f
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
-VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
-bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
-b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
-iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
-r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
-04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
-GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
-3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
-lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/a71272aeaaa3cfe8727f7fb39f0fb3d1e5426e9060b06ee6f13e9a3c5833cd43.pem b/chromium/net/data/ssl/ev_roots/a71272aeaaa3cfe8727f7fb39f0fb3d1e5426e9060b06ee6f13e9a3c5833cd43.pem
deleted file mode 100644
index 9e5c0f8833e..00000000000
--- a/chromium/net/data/ssl/ev_roots/a71272aeaaa3cfe8727f7fb39f0fb3d1e5426e9060b06ee6f13e9a3c5833cd43.pem
+++ /dev/null
@@ -1,94 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure Public Root Certificate Authority
- Validity
- Not Before: Dec 13 17:07:54 2007 GMT
- Not After : Dec 14 00:07:54 2022 GMT
- Subject: C=US, O=Wells Fargo WellsSecure, OU=Wells Fargo Bank NA, CN=WellsSecure Public Root Certificate Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:ee:6f:b4:bd:79:e2:8f:08:21:9e:38:04:41:25:
- ef:ab:5b:1c:53:92:ac:6d:9e:dd:c2:c4:2e:45:94:
- 03:35:88:67:74:57:e3:df:8c:b8:a7:76:8f:3b:f7:
- a8:c4:db:29:63:0e:91:68:36:8a:97:8e:8a:71:68:
- 09:07:e4:e8:d4:0e:4f:f8:d6:2b:4c:a4:16:f9:ef:
- 43:98:8f:b3:9e:52:df:6d:91:39:8f:38:bd:77:8b:
- 43:63:eb:b7:93:fc:30:4c:1c:01:93:b6:13:fb:f7:
- a1:1f:bf:25:e1:74:37:2c:1e:a4:5e:3c:68:f8:4b:
- bf:0d:b9:1e:2e:36:e8:a9:e4:a7:f8:0f:cb:82:75:
- 7c:35:2d:22:d6:c2:bf:0b:f3:b4:fc:6c:95:61:1e:
- 57:d7:04:81:32:83:52:79:e6:83:63:cf:b7:cb:63:
- 8b:11:e2:bd:5e:eb:f6:8d:ed:95:72:28:b4:ac:12:
- 62:e9:4a:33:e6:83:32:ae:05:75:95:bd:84:95:db:
- 2a:5c:9b:8e:2e:0c:b8:81:2b:41:e6:38:56:9f:49:
- 9b:6c:76:fa:8a:5d:f7:01:79:81:7c:c1:83:40:05:
- fe:71:fd:0c:3f:cc:4e:60:09:0e:65:47:10:2f:01:
- c0:05:3f:8f:f8:b3:41:ef:5a:42:7e:59:ef:d2:97:
- 0c:65
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.pki.wellsfargo.com/wsprca.crl
-
- X509v3 Key Usage: critical
- Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 26:95:19:10:D9:E8:A1:97:91:FF:DC:19:D9:B5:04:3E:D2:73:0A:6A
- X509v3 Authority Key Identifier:
- keyid:26:95:19:10:D9:E8:A1:97:91:FF:DC:19:D9:B5:04:3E:D2:73:0A:6A
- DirName:/C=US/O=Wells Fargo WellsSecure/OU=Wells Fargo Bank NA/CN=WellsSecure Public Root Certificate Authority
- serial:01
-
- Signature Algorithm: sha1WithRSAEncryption
- b9:15:b1:44:91:cc:23:c8:2b:4d:77:e3:f8:9a:7b:27:0d:cd:
- 72:bb:99:00:ca:7c:66:19:50:c6:d5:98:ed:ab:bf:03:5a:e5:
- 4d:e5:1e:c8:4f:71:97:86:d5:e3:1d:fd:90:c9:3c:75:77:57:
- 7a:7d:f8:de:f4:d4:d5:f7:95:e6:74:6e:1d:3c:ae:7c:9d:db:
- 02:03:05:2c:71:4b:25:3e:07:e3:5e:9a:f5:66:17:29:88:1a:
- 38:9f:cf:aa:41:03:84:97:6b:93:38:7a:ca:30:44:1b:24:44:
- 33:d0:e4:d1:dc:28:38:f4:13:43:35:35:29:63:a8:7c:a2:b5:
- ad:38:a4:ed:ad:fd:c6:9a:1f:ff:97:73:fe:fb:b3:35:a7:93:
- 86:c6:76:91:00:e6:ac:51:16:c4:27:32:5c:db:73:da:a5:93:
- 57:8e:3e:6d:35:26:08:59:d5:e7:44:d7:76:20:63:e7:ac:13:
- 67:c3:6d:b1:70:46:7c:d5:96:11:3d:89:6f:5d:a8:a1:eb:8d:
- 0a:da:c3:1d:33:6c:a3:ea:67:19:9a:99:7f:4b:3d:83:51:2a:
- 1d:ca:2f:86:0c:a2:7e:10:2d:2b:d4:16:95:0b:07:aa:2e:14:
- 92:49:b7:29:6f:d8:6d:31:7d:f5:fc:a1:10:07:87:ce:2f:59:
- dc:3e:58:db
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
-IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
-cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
-MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
-bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
-DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
-WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
-Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
-HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
-z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
-SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
-AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
-KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
-AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
-BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
-VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
-ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
-ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
-/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
-A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
-k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
-iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
-2G0xffX8oRAHh84vWdw+WNs=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72.pem b/chromium/net/data/ssl/ev_roots/ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72.pem
deleted file mode 100644
index ed8a8611be9..00000000000
--- a/chromium/net/data/ssl/ev_roots/ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72.pem
+++ /dev/null
@@ -1,55 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
- Validity
- Not Before: Aug 1 00:00:00 1996 GMT
- Not After : Dec 31 23:59:59 2020 GMT
- Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:d2:36:36:6a:8b:d7:c2:5b:9e:da:81:41:62:8f:
- 38:ee:49:04:55:d6:d0:ef:1c:1b:95:16:47:ef:18:
- 48:35:3a:52:f4:2b:6a:06:8f:3b:2f:ea:56:e3:af:
- 86:8d:9e:17:f7:9e:b4:65:75:02:4d:ef:cb:09:a2:
- 21:51:d8:9b:d0:67:d0:ba:0d:92:06:14:73:d4:93:
- cb:97:2a:00:9c:5c:4e:0c:bc:fa:15:52:fc:f2:44:
- 6e:da:11:4a:6e:08:9f:2f:2d:e3:f9:aa:3a:86:73:
- b6:46:53:58:c8:89:05:bd:83:11:b8:73:3f:aa:07:
- 8d:f4:42:4d:e7:40:9d:1c:37
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: md5WithRSAEncryption
- 26:48:2c:16:c2:58:fa:e8:16:74:0c:aa:aa:5f:54:3f:f2:d7:
- c9:78:60:5e:5e:6e:37:63:22:77:36:7e:b2:17:c4:34:b9:f5:
- 08:85:fc:c9:01:38:ff:4d:be:f2:16:42:43:e7:bb:5a:46:fb:
- c1:c6:11:1f:f1:4a:b0:28:46:c9:c3:c4:42:7d:bc:fa:ab:59:
- 6e:d5:b7:51:88:11:e3:a4:85:19:6b:82:4c:a4:0c:12:ad:e9:
- a4:ae:3f:f1:c3:49:65:9a:8c:c5:c8:3e:25:b7:94:99:bb:92:
- 32:71:07:f0:86:5e:ed:50:27:a6:0d:a6:23:f9:bb:cb:a6:07:
- 14:42
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
-FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
-VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
-dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
-MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
-MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
-A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
-b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
-cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
-VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
-ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
-uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
-hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
-pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4.pem b/chromium/net/data/ssl/ev_roots/b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4.pem
deleted file mode 100644
index 9d11047e2ce..00000000000
--- a/chromium/net/data/ssl/ev_roots/b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4.pem
+++ /dev/null
@@ -1,81 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 15:ac:6e:94:19:b2:79:4b:41:f6:27:a9:c3:18:0f:1f
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Validity
- Not Before: Apr 2 00:00:00 2008 GMT
- Not After : Dec 1 23:59:59 2037 GMT
- Subject: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:dc:e2:5e:62:58:1d:33:57:39:32:33:fa:eb:cb:
- 87:8c:a7:d4:4a:dd:06:88:ea:64:8e:31:98:a5:38:
- 90:1e:98:cf:2e:63:2b:f0:46:bc:44:b2:89:a1:c0:
- 28:0c:49:70:21:95:9f:64:c0:a6:93:12:02:65:26:
- 86:c6:a5:89:f0:fa:d7:84:a0:70:af:4f:1a:97:3f:
- 06:44:d5:c9:eb:72:10:7d:e4:31:28:fb:1c:61:e6:
- 28:07:44:73:92:22:69:a7:03:88:6c:9d:63:c8:52:
- da:98:27:e7:08:4c:70:3e:b4:c9:12:c1:c5:67:83:
- 5d:33:f3:03:11:ec:6a:d0:53:e2:d1:ba:36:60:94:
- 80:bb:61:63:6c:5b:17:7e:df:40:94:1e:ab:0d:c2:
- 21:28:70:88:ff:d6:26:6c:6c:60:04:25:4e:55:7e:
- 7d:ef:bf:94:48:de:b7:1d:dd:70:8d:05:5f:88:a5:
- 9b:f2:c2:ee:ea:d1:40:41:6d:62:38:1d:56:06:c5:
- 03:47:51:20:19:fc:7b:10:0b:0e:62:ae:76:55:bf:
- 5f:77:be:3e:49:01:53:3d:98:25:03:76:24:5a:1d:
- b4:db:89:ea:79:e5:b6:b3:3b:3f:ba:4c:28:41:7f:
- 06:ac:6a:8e:c1:d0:f6:05:1d:7d:e6:42:86:e3:a5:
- d5:47
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
- Signature Algorithm: sha256WithRSAEncryption
- 2d:c5:13:cf:56:80:7b:7a:78:bd:9f:ae:2c:99:e7:ef:da:df:
- 94:5e:09:69:a7:e7:6e:68:8c:bd:72:be:47:a9:0e:97:12:b8:
- 4a:f1:64:d3:39:df:25:34:d4:c1:cd:4e:81:f0:0f:04:c4:24:
- b3:34:96:c6:a6:aa:30:df:68:61:73:d7:f9:8e:85:89:ef:0e:
- 5e:95:28:4a:2a:27:8f:10:8e:2e:7c:86:c4:02:9e:da:0c:77:
- 65:0e:44:0d:92:fd:fd:b3:16:36:fa:11:0d:1d:8c:0e:07:89:
- 6a:29:56:f7:72:f4:dd:15:9c:77:35:66:57:ab:13:53:d8:8e:
- c1:40:c5:d7:13:16:5a:72:c7:b7:69:01:c4:7a:b1:83:01:68:
- 7d:8d:41:a1:94:18:c1:25:5c:fc:f0:fe:83:02:87:7c:0d:0d:
- cf:2e:08:5c:4a:40:0d:3e:ec:81:61:e6:24:db:ca:e0:0e:2d:
- 07:b2:3e:56:dc:8d:f5:41:85:07:48:9b:0c:0b:cb:49:3f:7d:
- ec:b7:fd:cb:8d:67:89:1a:ab:ed:bb:1e:a3:00:08:08:17:2a:
- 82:5c:31:5d:46:8a:2d:0f:86:9b:74:d9:45:fb:d4:40:b1:7a:
- aa:68:2d:86:b2:99:22:e1:c1:2b:c7:9c:f8:f3:5f:a8:82:12:
- eb:19:11:2d
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
-BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
-BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
-+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
-hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
-5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
-JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
-DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
-huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
-AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
-zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
-kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
-SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
-spki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/b7b12b171f821daa990cd0fe5087b128448ba8e5184f84c51e02b5c8fb962b24.pem b/chromium/net/data/ssl/ev_roots/b7b12b171f821daa990cd0fe5087b128448ba8e5184f84c51e02b5c8fb962b24.pem
deleted file mode 100644
index 8f25bab4c27..00000000000
--- a/chromium/net/data/ssl/ev_roots/b7b12b171f821daa990cd0fe5087b128448ba8e5184f84c51e02b5c8fb962b24.pem
+++ /dev/null
@@ -1,76 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1
- Validity
- Not Before: May 9 14:13:03 2005 GMT
- Not After : May 9 14:13:03 2015 GMT
- Subject: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 CA 1
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a4:8e:d7:74:d9:29:64:de:5f:1f:87:80:91:ea:
- 4e:39:e6:19:c6:44:0b:80:d5:0b:af:53:07:8b:12:
- bd:e6:67:f0:02:b1:89:f6:60:8a:c4:5b:b0:42:d1:
- c0:21:a8:cb:e1:9b:ef:64:51:b6:a7:cf:15:f5:74:
- 80:68:04:90:a0:58:a2:e6:74:a6:53:53:55:48:63:
- 3f:92:56:dd:24:4e:8e:f8:ba:2b:ff:f3:34:8a:9e:
- 28:d7:34:9f:ac:2f:d6:0f:f1:a4:2f:bd:52:b2:49:
- 85:6d:39:35:f0:44:30:93:46:24:f3:b6:e7:53:fb:
- bc:61:af:a9:a3:14:fb:c2:17:17:84:6c:e0:7c:88:
- f8:c9:1c:57:2c:f0:3d:7e:94:bc:25:93:84:e8:9a:
- 00:9a:45:05:42:57:80:f4:4e:ce:d9:ae:39:f6:c8:
- 53:10:0c:65:3a:47:7b:60:c2:d6:fa:91:c9:c6:71:
- 6c:bd:91:87:3c:91:86:49:ab:f3:0f:a0:6c:26:76:
- 5e:1c:ac:9b:71:e5:8d:bc:9b:21:1e:9c:d6:38:7e:
- 24:80:15:31:82:96:b1:49:d3:62:37:5b:88:0c:0a:
- 62:34:fe:a7:48:7e:99:b1:30:8b:90:37:95:1c:a8:
- 1f:a5:2c:8d:f4:55:c8:db:dd:59:0a:c2:ad:78:a0:
- f4:8b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 38:14:E6:C8:F0:A9:A4:03:F4:4E:3E:22:A3:5B:F2:D6:E0:AD:40:74
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Signature Algorithm: sha1WithRSAEncryption
- 01:67:a3:8c:c9:25:3d:13:63:5d:16:6f:ec:a1:3e:09:5c:91:
- 15:2a:2a:d9:80:21:4f:05:dc:bb:a5:89:ab:13:33:2a:9e:38:
- b7:8c:6f:02:72:63:c7:73:77:1e:09:06:ba:3b:28:7b:a4:47:
- c9:61:6b:08:08:20:fc:8a:05:8a:1f:bc:ba:c6:c2:fe:cf:6e:
- ec:13:33:71:67:2e:69:fa:a9:2c:3f:66:c0:12:59:4d:0b:54:
- 02:92:84:bb:db:12:ef:83:70:70:78:c8:53:fa:df:c6:c6:ff:
- dc:88:2f:07:c0:49:9d:32:57:60:d3:f2:f6:99:29:5f:e7:aa:
- 01:cc:ac:33:a8:1c:0a:bb:91:c4:03:a0:6f:b6:34:f9:86:d3:
- b3:76:54:98:f4:4a:81:b3:53:9d:4d:40:ec:e5:77:13:45:af:
- 5b:aa:1f:d8:2f:4c:82:7b:fe:2a:c4:58:bb:4f:fc:9e:fd:03:
- 65:1a:2a:0e:c3:a5:20:16:94:6b:79:a6:a2:12:b4:bb:1a:a4:
- 23:7a:5f:f0:ae:84:24:e4:f3:2b:fb:8a:24:a3:27:98:65:da:
- 30:75:76:fc:19:91:e8:db:eb:9b:3f:32:bf:40:97:07:26:ba:
- cc:f3:94:85:4a:7a:27:93:cf:90:42:d4:b8:5b:16:a6:e7:cb:
- 40:03:dd:79
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
-isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
-NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
-+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
-hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
-mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
-Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
-EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
-mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
-e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
-dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem b/chromium/net/data/ssl/ev_roots/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem
deleted file mode 100644
index 511423f7373..00000000000
--- a/chromium/net/data/ssl/ev_roots/bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c.pem
+++ /dev/null
@@ -1,46 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 2a:38:a4:1c:96:0a:04:de:42:b2:28:a5:0b:e8:34:98:02
- Signature Algorithm: ecdsa-with-SHA256
- Issuer: OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
- Validity
- Not Before: Nov 13 00:00:00 2012 GMT
- Not After : Jan 19 03:14:07 2038 GMT
- Subject: OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (256 bit)
- pub:
- 04:b8:c6:79:d3:8f:6c:25:0e:9f:2e:39:19:1c:03:
- a4:ae:9a:e5:39:07:09:16:ca:63:b1:b9:86:f8:8a:
- 57:c1:57:ce:42:fa:73:a1:f7:65:42:ff:1e:c1:00:
- b2:6e:73:0e:ff:c7:21:e5:18:a4:aa:d9:71:3f:a8:
- d4:b9:ce:8c:1d
- ASN1 OID: prime256v1
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 54:B0:7B:AD:45:B8:E2:40:7F:FB:0A:6E:FB:BE:33:C9:3C:A3:84:D5
- Signature Algorithm: ecdsa-with-SHA256
- 30:45:02:21:00:dc:92:a1:a0:13:a6:cf:03:b0:e6:c4:21:97:
- 90:fa:14:57:2d:03:ec:ee:3c:d3:6e:ca:a8:6c:76:bc:a2:de:
- bb:02:20:27:a8:85:27:35:9b:56:c6:a3:f2:47:d2:b7:6e:1b:
- 02:00:17:aa:67:a6:15:91:de:fa:94:ec:7b:0b:f8:9f:84
------BEGIN CERTIFICATE-----
-MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
-FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
-uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
-kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
-ewv4n4Q=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea.pem b/chromium/net/data/ssl/ev_roots/c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea.pem
deleted file mode 100644
index bf37b6ab59a..00000000000
--- a/chromium/net/data/ssl/ev_roots/c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea.pem
+++ /dev/null
@@ -1,152 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Validity
- Not Before: Sep 17 19:46:36 2006 GMT
- Not After : Sep 17 19:46:36 2036 GMT
- Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:c1:88:db:09:bc:6c:46:7c:78:9f:95:7b:b5:33:
- 90:f2:72:62:d6:c1:36:20:22:24:5e:ce:e9:77:f2:
- 43:0a:a2:06:64:a4:cc:8e:36:f8:38:e6:23:f0:6e:
- 6d:b1:3c:dd:72:a3:85:1c:a1:d3:3d:b4:33:2b:d3:
- 2f:af:fe:ea:b0:41:59:67:b6:c4:06:7d:0a:9e:74:
- 85:d6:79:4c:80:37:7a:df:39:05:52:59:f7:f4:1b:
- 46:43:a4:d2:85:85:d2:c3:71:f3:75:62:34:ba:2c:
- 8a:7f:1e:8f:ee:ed:34:d0:11:c7:96:cd:52:3d:ba:
- 33:d6:dd:4d:de:0b:3b:4a:4b:9f:c2:26:2f:fa:b5:
- 16:1c:72:35:77:ca:3c:5d:e6:ca:e1:26:8b:1a:36:
- 76:5c:01:db:74:14:25:fe:ed:b5:a0:88:0f:dd:78:
- ca:2d:1f:07:97:30:01:2d:72:79:fa:46:d6:13:2a:
- a8:b9:a6:ab:83:49:1d:e5:f2:ef:dd:e4:01:8e:18:
- 0a:8f:63:53:16:85:62:a9:0e:19:3a:cc:b5:66:a6:
- c2:6b:74:07:e4:2b:e1:76:3e:b4:6d:d8:f6:44:e1:
- 73:62:1f:3b:c4:be:a0:53:56:25:6c:51:09:f7:aa:
- ab:ca:bf:76:fd:6d:9b:f3:9d:db:bf:3d:66:bc:0c:
- 56:aa:af:98:48:95:3a:4b:df:a7:58:50:d9:38:75:
- a9:5b:ea:43:0c:02:ff:99:eb:e8:6c:4d:70:5b:29:
- 65:9c:dd:aa:5d:cc:af:01:31:ec:0c:eb:d2:8d:e8:
- ea:9c:7b:e6:6e:f7:27:66:0c:1a:48:d7:6e:42:e3:
- 3f:de:21:3e:7b:e1:0d:70:fb:63:aa:a8:6c:1a:54:
- b4:5c:25:7a:c9:a2:c9:8b:16:a6:bb:2c:7e:17:5e:
- 05:4d:58:6e:12:1d:01:ee:12:10:0d:c6:32:7f:18:
- ff:fc:f4:fa:cd:6e:91:e8:36:49:be:1a:48:69:8b:
- c2:96:4d:1a:12:b2:69:17:c1:0a:90:d6:fa:79:22:
- 48:bf:ba:7b:69:f8:70:c7:fa:7a:37:d8:d8:0d:d2:
- 76:4f:57:ff:90:b7:e3:91:d2:dd:ef:c2:60:b7:67:
- 3a:dd:fe:aa:9c:f0:d4:8b:7f:72:22:ce:c6:9f:97:
- b6:f8:af:8a:a0:10:a8:d9:fb:18:c6:b6:b5:5c:52:
- 3c:89:b6:19:2a:73:01:0a:0f:03:b3:12:60:f2:7a:
- 2f:81:db:a3:6e:ff:26:30:97:f5:8b:dd:89:57:b6:
- ad:3d:b3:af:2b:c5:b7:76:02:f0:a5:d6:2b:9a:86:
- 14:2a:72:f6:e3:33:8c:5d:09:4b:13:df:bb:8c:74:
- 13:52:4b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:TRUE
- X509v3 Key Usage:
- Digital Signature, Key Encipherment, Key Agreement, Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- 4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://cert.startcom.org/sfsca-crl.crl
-
- Full Name:
- URI:http://crl.startcom.org/sfsca-crl.crl
-
- X509v3 Certificate Policies:
- Policy: 1.3.6.1.4.1.23223.1.1.1
- CPS: http://cert.startcom.org/policy.pdf
- CPS: http://cert.startcom.org/intermediate.pdf
- User Notice:
- Organization: Start Commercial (StartCom) Ltd.
- Number: 1
- Explicit Text: Limited Liability, read the section *Legal Limitations* of the StartCom Certification Authority Policy available at http://cert.startcom.org/policy.pdf
-
- Netscape Cert Type:
- SSL CA, S/MIME CA, Object Signing CA
- Netscape Comment:
- StartCom Free SSL Certification Authority
- Signature Algorithm: sha1WithRSAEncryption
- 16:6c:99:f4:66:0c:34:f5:d0:85:5e:7d:0a:ec:da:10:4e:38:
- 1c:5e:df:a6:25:05:4b:91:32:c1:e8:3b:f1:3d:dd:44:09:5b:
- 07:49:8a:29:cb:66:02:b7:b1:9a:f7:25:98:09:3c:8e:1b:e1:
- dd:36:87:2b:4b:bb:68:d3:39:66:3d:a0:26:c7:f2:39:91:1d:
- 51:ab:82:7b:7e:d5:ce:5a:e4:e2:03:57:70:69:97:08:f9:5e:
- 58:a6:0a:df:8c:06:9a:45:16:16:38:0a:5e:57:f6:62:c7:7a:
- 02:05:e6:bc:1e:b5:f2:9e:f4:a9:29:83:f8:b2:14:e3:6e:28:
- 87:44:c3:90:1a:de:38:a9:3c:ac:43:4d:64:45:ce:dd:28:a9:
- 5c:f2:73:7b:04:f8:17:e8:ab:b1:f3:2e:5c:64:6e:73:31:3a:
- 12:b8:bc:b3:11:e4:7d:8f:81:51:9a:3b:8d:89:f4:4d:93:66:
- 7b:3c:03:ed:d3:9a:1d:9a:f3:65:50:f5:a0:d0:75:9f:2f:af:
- f0:ea:82:43:98:f8:69:9c:89:79:c4:43:8e:46:72:e3:64:36:
- 12:af:f7:25:1e:38:89:90:77:7e:c3:6b:6a:b9:c3:cb:44:4b:
- ac:78:90:8b:e7:c7:2c:1e:4b:11:44:c8:34:52:27:cd:0a:5d:
- 9f:85:c1:89:d5:1a:78:f2:95:10:53:32:dd:80:84:66:75:d9:
- b5:68:28:fb:61:2e:be:84:a8:38:c0:99:12:86:a5:1e:67:64:
- ad:06:2e:2f:a9:70:85:c7:96:0f:7c:89:65:f5:8e:43:54:0e:
- ab:dd:a5:80:39:94:60:c0:34:c9:96:70:2c:a3:12:f5:1f:48:
- 7b:bd:1c:7e:6b:b7:9d:90:f4:22:3b:ae:f8:fc:2a:ca:fa:82:
- 52:a0:ef:af:4b:55:93:eb:c1:b5:f0:22:8b:ac:34:4e:26:22:
- 04:a1:87:2c:75:4a:b7:e5:7d:13:d7:b8:0c:64:c0:36:d2:c9:
- 2f:86:12:8c:23:09:c1:1b:82:3b:73:49:a3:6a:57:87:94:e5:
- d6:78:c5:99:43:63:e3:4d:e0:77:2d:e1:65:99:72:69:04:1a:
- 47:09:e6:0f:01:56:24:fb:1f:bf:0e:79:a9:58:2e:b9:c4:09:
- 01:7e:95:ba:6d:00:06:3e:b2:ea:4a:10:39:d8:d0:2b:f5:bf:
- ec:75:bf:97:02:c5:09:1b:08:dc:55:37:e2:81:fb:37:84:43:
- 62:20:ca:e7:56:4b:65:ea:fe:6c:c1:24:93:24:a1:34:eb:05:
- ff:9a:22:ae:9b:7d:3f:f1:65:51:0a:a6:30:6a:b3:f4:88:1c:
- 80:0d:fc:72:8a:e8:83:5e
------BEGIN CERTIFICATE-----
-MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
-FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
-ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
-LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
-BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
-Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
-dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
-cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
-YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
-dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
-bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
-YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
-TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
-9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
-jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
-FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
-ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
-ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
-EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
-L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
-yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
-O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
-um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
-NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem b/chromium/net/data/ssl/ev_roots/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem
deleted file mode 100644
index 4f852e635af..00000000000
--- a/chromium/net/data/ssl/ev_roots/ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e.pem
+++ /dev/null
@@ -1,87 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 04:00:00:00:00:01:0f:86:26:e6:0d
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
- Validity
- Not Before: Dec 15 08:00:00 2006 GMT
- Not After : Dec 15 08:00:00 2021 GMT
- Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a6:cf:24:0e:be:2e:6f:28:99:45:42:c4:ab:3e:
- 21:54:9b:0b:d3:7f:84:70:fa:12:b3:cb:bf:87:5f:
- c6:7f:86:d3:b2:30:5c:d6:fd:ad:f1:7b:dc:e5:f8:
- 60:96:09:92:10:f5:d0:53:de:fb:7b:7e:73:88:ac:
- 52:88:7b:4a:a6:ca:49:a6:5e:a8:a7:8c:5a:11:bc:
- 7a:82:eb:be:8c:e9:b3:ac:96:25:07:97:4a:99:2a:
- 07:2f:b4:1e:77:bf:8a:0f:b5:02:7c:1b:96:b8:c5:
- b9:3a:2c:bc:d6:12:b9:eb:59:7d:e2:d0:06:86:5f:
- 5e:49:6a:b5:39:5e:88:34:ec:bc:78:0c:08:98:84:
- 6c:a8:cd:4b:b4:a0:7d:0c:79:4d:f0:b8:2d:cb:21:
- ca:d5:6c:5b:7d:e1:a0:29:84:a1:f9:d3:94:49:cb:
- 24:62:91:20:bc:dd:0b:d5:d9:cc:f9:ea:27:0a:2b:
- 73:91:c6:9d:1b:ac:c8:cb:e8:e0:a0:f4:2f:90:8b:
- 4d:fb:b0:36:1b:f6:19:7a:85:e0:6d:f2:61:13:88:
- 5c:9f:e0:93:0a:51:97:8a:5a:ce:af:ab:d5:f7:aa:
- 09:aa:60:bd:dc:d9:5f:df:72:a9:60:13:5e:00:01:
- c9:4a:fa:3f:a4:ea:07:03:21:02:8e:82:ca:03:c2:
- 9b:8f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Subject Key Identifier:
- 9B:E2:07:57:67:1C:1E:C0:6A:06:DE:59:B4:9A:2D:DF:DC:19:86:2E
- X509v3 CRL Distribution Points:
-
- Full Name:
- URI:http://crl.globalsign.net/root-r2.crl
-
- X509v3 Authority Key Identifier:
- keyid:9B:E2:07:57:67:1C:1E:C0:6A:06:DE:59:B4:9A:2D:DF:DC:19:86:2E
-
- Signature Algorithm: sha1WithRSAEncryption
- 99:81:53:87:1c:68:97:86:91:ec:e0:4a:b8:44:0b:ab:81:ac:
- 27:4f:d6:c1:b8:1c:43:78:b3:0c:9a:fc:ea:2c:3c:6e:61:1b:
- 4d:4b:29:f5:9f:05:1d:26:c1:b8:e9:83:00:62:45:b6:a9:08:
- 93:b9:a9:33:4b:18:9a:c2:f8:87:88:4e:db:dd:71:34:1a:c1:
- 54:da:46:3f:e0:d3:2a:ab:6d:54:22:f5:3a:62:cd:20:6f:ba:
- 29:89:d7:dd:91:ee:d3:5c:a2:3e:a1:5b:41:f5:df:e5:64:43:
- 2d:e9:d5:39:ab:d2:a2:df:b7:8b:d0:c0:80:19:1c:45:c0:2d:
- 8c:e8:f8:2d:a4:74:56:49:c5:05:b5:4f:15:de:6e:44:78:39:
- 87:a8:7e:bb:f3:79:18:91:bb:f4:6f:9d:c1:f0:8c:35:8c:5d:
- 01:fb:c3:6d:b9:ef:44:6d:79:46:31:7e:0a:fe:a9:82:c1:ff:
- ef:ab:6e:20:c4:50:c9:5f:9d:4d:9b:17:8c:0c:e5:01:c9:a0:
- 41:6a:73:53:fa:a5:50:b4:6e:25:0f:fb:4c:18:f4:fd:52:d9:
- 8e:69:b1:e8:11:0f:de:88:d8:fb:1d:49:f7:aa:de:95:cf:20:
- 78:c2:60:12:db:25:40:8c:6a:fc:7e:42:38:40:64:12:f7:9e:
- 81:e1:93:2e
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem b/chromium/net/data/ssl/ev_roots/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem
new file mode 100644
index 00000000000..90752467d03
--- /dev/null
+++ b/chromium/net/data/ssl/ev_roots/d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24.pem
@@ -0,0 +1,119 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 4f:d2:2b:8f:f5:64:c8:33:9e:4f:34:58:66:23:70:60
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = CN, O = UniTrust, CN = UCA Extended Validation Root
+ Validity
+ Not Before: Mar 13 00:00:00 2015 GMT
+ Not After : Dec 31 00:00:00 2038 GMT
+ Subject: C = CN, O = UniTrust, CN = UCA Extended Validation Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (4096 bit)
+ Modulus:
+ 00:a9:09:07:28:13:02:b0:99:e0:64:aa:1e:43:16:
+ 7a:73:b1:91:a0:75:3e:a8:fa:e3:38:00:7a:ec:89:
+ 6a:20:0f:8b:c5:b0:9b:33:03:5a:86:c6:58:86:d5:
+ c1:85:bb:4f:c6:9c:40:4d:ca:be:ee:69:96:b8:ad:
+ 81:30:9a:7c:92:05:eb:05:2b:9a:48:d0:b8:76:3e:
+ 96:c8:20:bb:d2:b0:f1:8f:d8:ac:45:46:ff:aa:67:
+ 60:b4:77:7e:6a:1f:3c:1a:52:7a:04:3d:07:3c:85:
+ 0d:84:d0:1f:76:0a:f7:6a:14:df:72:e3:34:7c:57:
+ 4e:56:01:3e:79:f1:aa:29:3b:6c:fa:f8:8f:6d:4d:
+ c8:35:df:ae:eb:dc:24:ee:79:45:a7:85:b6:05:88:
+ de:88:5d:25:7c:97:64:67:09:d9:bf:5a:15:05:86:
+ f3:09:1e:ec:58:32:33:11:f3:77:64:b0:76:1f:e4:
+ 10:35:17:1b:f2:0e:b1:6c:a4:2a:a3:73:fc:09:1f:
+ 1e:32:19:53:11:e7:d9:b3:2c:2e:76:2e:a1:a3:de:
+ 7e:6a:88:09:e8:f2:07:8a:f8:b2:cd:10:e7:e2:73:
+ 40:93:bb:08:d1:3f:e1:fc:0b:94:b3:25:ef:7c:a6:
+ d7:d1:af:9f:ff:96:9a:f5:91:7b:98:0b:77:d4:7e:
+ e8:07:d2:62:b5:95:39:e3:f3:f1:6d:0f:0e:65:84:
+ 8a:63:54:c5:80:b6:e0:9e:4b:7d:47:26:a7:01:08:
+ 5d:d1:88:9e:d7:c3:32:44:fa:82:4a:0a:68:54:7f:
+ 38:53:03:cc:a4:00:33:64:51:59:0b:a3:82:91:7a:
+ 5e:ec:16:c2:f3:2a:e6:62:da:2a:db:59:62:10:25:
+ 4a:2a:81:0b:47:07:43:06:70:87:d2:fa:93:11:29:
+ 7a:48:4d:eb:94:c7:70:4d:af:67:d5:51:b1:80:20:
+ 01:01:b4:7a:08:a6:90:7f:4e:e0:ef:07:41:87:af:
+ 6a:a5:5e:8b:fb:cf:50:b2:9a:54:af:c3:89:ba:58:
+ 2d:f5:30:98:b1:36:72:39:7e:49:04:fd:29:a7:4c:
+ 79:e4:05:57:db:94:b9:16:53:8d:46:b3:1d:95:61:
+ 57:56:7f:af:f0:16:5b:61:58:6f:36:50:11:0b:d8:
+ ac:2b:95:16:1a:0e:1f:08:cd:36:34:65:10:62:66:
+ d5:80:5f:14:20:5f:2d:0c:a0:78:0a:68:d6:2c:d7:
+ e9:6f:2b:d2:4a:05:93:fc:9e:6f:6b:67:ff:88:f1:
+ 4e:a5:69:4a:52:37:05:ea:c6:16:8d:d2:c4:99:d1:
+ 82:2b:3b:ba:35:75:f7:51:51:58:f3:c8:07:dd:e4:
+ b4:03:7f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ D9:74:3A:E4:30:3D:0D:F7:12:DC:7E:5A:05:9F:1E:34:9A:F7:E1:14
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Signature Algorithm: sha256WithRSAEncryption
+ 36:8d:97:cc:42:15:64:29:37:9b:26:2c:d6:fb:ae:15:69:2c:
+ 6b:1a:1a:f7:5f:b6:f9:07:4c:59:ea:f3:c9:c8:b9:ae:cc:ba:
+ 2e:7a:dc:c0:f5:b0:2d:c0:3b:af:9f:70:05:11:6a:9f:25:4f:
+ 01:29:70:e3:e5:0c:e1:ea:5a:7c:dc:49:bb:c1:1e:2a:81:f5:
+ 16:4b:72:91:c8:a2:31:b9:aa:da:fc:9d:1f:f3:5d:40:02:13:
+ fc:4e:1c:06:ca:b3:14:90:54:17:19:12:1a:f1:1f:d7:0c:69:
+ 5a:f6:71:78:f4:94:7d:91:0b:8e:ec:90:54:8e:bc:6f:a1:4c:
+ ab:fc:74:64:fd:71:9a:f8:41:07:a1:cd:91:e4:3c:9a:e0:9b:
+ 32:39:73:ab:2a:d5:69:c8:78:91:26:31:7d:e2:c7:30:f1:fc:
+ 14:78:77:12:0e:13:f4:dd:16:94:bf:4b:67:7b:70:53:85:ca:
+ b0:bb:f3:38:4d:2c:90:39:c0:0d:c2:5d:6b:e9:e2:e5:d5:88:
+ 8d:d6:2c:bf:ab:1b:be:b5:28:87:12:17:74:6e:fc:7d:fc:8f:
+ d0:87:26:b0:1b:fb:b9:6c:ab:e2:9e:3d:15:c1:3b:2e:67:02:
+ 58:91:9f:ef:f8:42:1f:2c:b7:68:f5:75:ad:cf:b5:f6:ff:11:
+ 7d:c2:f0:24:a5:ad:d3:fa:a0:3c:a9:fa:5d:dc:a5:a0:ef:44:
+ a4:be:d6:e8:e5:e4:13:96:17:7b:06:3e:32:ed:c7:b7:42:bc:
+ 76:a3:d8:65:38:2b:38:35:51:21:0e:0e:6f:2e:34:13:40:e1:
+ 2b:67:0c:6d:4a:41:30:18:23:5a:32:55:99:c9:17:e0:3c:de:
+ f6:ec:79:ad:2b:58:19:a2:ad:2c:22:1a:95:8e:be:96:90:5d:
+ 42:57:c4:f9:14:03:35:2b:1c:2d:51:57:08:a7:3a:de:3f:e4:
+ c8:b4:03:73:c2:c1:26:80:bb:0b:42:1f:ad:0d:af:26:72:da:
+ cc:be:b3:a3:83:58:0d:82:c5:1f:46:51:e3:9c:18:cc:8d:9b:
+ 8d:ec:49:eb:75:50:d5:8c:28:59:ca:74:34:da:8c:0b:21:ab:
+ 1e:ea:1b:e5:c7:fd:15:3e:c0:17:aa:fb:23:6e:26:46:cb:fa:
+ f9:b1:72:6b:69:cf:22:84:0b:62:0f:ac:d9:19:00:94:a2:76:
+ 3c:d4:2d:9a:ed:04:9e:2d:06:62:10:37:52:1c:85:72:1b:27:
+ e5:cc:c6:31:ec:37:ec:63:59:9b:0b:1d:76:cc:7e:32:9a:88:
+ 95:08:36:52:bb:de:76:5f:76:49:49:ad:7f:bd:65:20:b2:c9:
+ c1:2b:76:18:76:9f:56:b1
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
+MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
+eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
+MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
+BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
+D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
+sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
+O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
+sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
+c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
+VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
+KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
+TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
+sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
+1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
+fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
+AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
+l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
+ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
+VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
+c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
+4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
+t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
+2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
+vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
+xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
+cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
+fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d.pem b/chromium/net/data/ssl/ev_roots/d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d.pem
deleted file mode 100644
index e3ded339c9c..00000000000
--- a/chromium/net/data/ssl/ev_roots/d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d.pem
+++ /dev/null
@@ -1,127 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- f2:fa:64:e2:74:63:d3:8d:fd:10:1d:04:1f:76:ca:58
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root EV CA 2
- Validity
- Not Before: Jun 24 09:45:08 2011 GMT
- Not After : Jun 25 08:45:08 2031 GMT
- Subject: C=ch, O=Swisscom, OU=Digital Certificate Services, CN=Swisscom Root EV CA 2
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (4096 bit)
- Modulus:
- 00:c4:f7:1d:2f:57:ea:57:6c:f7:70:5d:63:b0:71:
- 52:09:60:44:28:33:a3:7a:4e:0a:fa:d8:ea:6c:8b:
- 51:16:1a:55:ae:54:26:c4:cc:45:07:41:4f:10:79:
- 7f:71:d2:7a:4e:3f:38:4e:b3:00:c6:95:ca:5b:cd:
- c1:2a:83:d7:27:1f:31:0e:23:16:b7:25:cb:1c:b4:
- b9:80:32:5e:1a:9d:93:f1:e8:3c:60:2c:a7:5e:57:
- 19:58:51:5e:bc:2c:56:0b:b8:d8:ef:8b:82:b4:3c:
- b8:c2:24:a8:13:c7:a0:21:36:1b:7a:57:29:28:a7:
- 2e:bf:71:25:90:f3:44:83:69:50:a4:e4:e1:1b:62:
- 19:94:09:a3:f3:c3:bc:ef:f4:bd:ec:db:13:9d:cf:
- 9d:48:09:52:67:c0:37:29:11:1e:fb:d2:11:a7:85:
- 18:74:79:e4:4f:85:14:eb:52:37:e2:b1:45:d8:cc:
- 0d:43:7f:ae:13:d2:6b:2b:3f:a7:c2:e2:a8:6d:76:
- 5b:43:9f:be:b4:9d:b3:26:86:3b:1f:7f:e5:f2:e8:
- 66:28:16:25:d0:4b:97:38:a7:e4:cf:09:d1:36:c3:
- 0b:be:da:3b:44:58:8d:be:f1:9e:09:6b:3e:f3:32:
- c7:2b:87:c6:ec:5e:9c:f6:87:65:ad:33:29:c4:2f:
- 89:d9:b9:cb:c9:03:9d:fb:6c:94:51:97:10:1b:86:
- 0b:1a:1b:3f:f6:02:7e:7b:d4:c5:51:64:28:9d:f5:
- d3:ac:83:81:88:d3:74:b4:59:9d:c1:eb:61:33:5a:
- 45:d1:cb:39:d0:06:6a:53:60:1d:af:f6:fb:69:bc:
- 6a:dc:01:cf:bd:f9:8f:d9:bd:5b:c1:3a:5f:8e:da:
- 0f:4b:a9:9b:9d:2a:28:6b:1a:0a:7c:3c:ab:22:0b:
- e5:77:2d:71:f6:82:35:81:ae:f8:7b:81:e6:ea:fe:
- ac:f4:1a:9b:74:5c:e8:8f:24:f6:5d:9d:46:c4:2c:
- d2:1e:2b:21:6a:83:27:67:55:4a:a4:e3:c8:32:97:
- 66:90:72:da:e3:d4:64:2e:5f:e3:a1:6a:f6:60:d4:
- e7:35:cd:ca:c4:68:8d:d7:71:c8:d3:24:33:73:b1:
- 6c:f9:6a:e1:28:db:5f:c6:3d:e8:be:55:e6:37:1b:
- ed:24:d9:0f:19:8f:5f:63:18:58:50:81:51:65:6f:
- f2:9f:7e:6a:04:e7:34:24:71:ba:76:4b:58:1e:19:
- bd:15:60:45:aa:0c:12:40:01:9d:10:e2:c7:38:07:
- 72:0a:65:c0:b6:bb:25:29:da:16:9e:8b:35:8b:61:
- ed:e5:71:57:83:b5:3c:71:9f:e3:4f:bf:7e:1e:81:
- 9f:41:97
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Certificate Sign, CRL Sign
- X509v3 Policy Mappings:
- 2.16.756.1.83.2.2:2.16.756.1.83.2.2
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:3
- X509v3 Subject Key Identifier:
- 45:D9:A5:81:6E:3D:88:4D:8D:71:D2:46:C1:6E:45:1E:F3:C4:80:9D
- X509v3 Authority Key Identifier:
- keyid:45:D9:A5:81:6E:3D:88:4D:8D:71:D2:46:C1:6E:45:1E:F3:C4:80:9D
-
- Signature Algorithm: sha256WithRSAEncryption
- 94:3a:73:06:9f:52:4b:30:5c:d4:fe:b1:5c:25:f9:d7:8e:6f:
- f5:87:64:9f:ed:14:8e:b8:04:8e:28:4b:8f:aa:7b:8e:39:b4:
- d9:58:f6:7b:a1:35:0a:a1:9d:8a:f7:63:e5:eb:bd:39:82:d4:
- e3:7a:2d:6f:df:13:3c:ba:fe:7e:56:98:0b:f3:54:9f:cd:44:
- 4e:6e:3c:e1:3e:15:bf:06:26:9d:e4:f0:90:b6:d4:c2:9e:30:
- 2e:1f:ef:c7:7a:c4:50:c7:ea:7b:da:50:cb:7a:26:cb:00:b4:
- 5a:ab:b5:93:1f:80:89:84:04:95:8d:8d:7f:09:93:bf:d4:a8:
- a8:e4:63:6d:d9:64:e4:b8:29:5a:08:bf:50:e1:84:0f:55:7b:
- 5f:08:22:1b:f5:bd:99:1e:14:f6:ce:f4:58:10:82:b3:0a:3d:
- 19:c1:bf:5b:ab:aa:99:d8:f2:31:bd:e5:38:66:dc:58:05:c7:
- ed:63:1a:2e:0a:97:7c:87:93:2b:b2:8a:e3:f1:ec:18:e5:75:
- b6:29:87:e7:dc:8b:1a:7e:b4:d8:c9:d3:8a:17:6c:7d:29:44:
- be:8a:aa:f5:7e:3a:2e:68:31:93:b9:6a:da:9a:e0:db:e9:2e:
- a5:84:cd:1c:0a:b8:4a:08:f9:9c:f1:61:26:98:93:b7:7b:66:
- ec:91:5e:dd:51:3f:db:73:0f:ad:04:58:09:dd:04:02:95:0a:
- 3e:d3:76:df:a6:10:1e:80:3d:e8:cd:a4:64:d1:33:c7:92:c7:
- e2:4e:44:e3:09:c9:4e:c2:5d:87:0e:12:9e:bf:0f:c9:05:10:
- de:7a:a3:b1:3c:f2:3f:a5:aa:27:79:ad:31:7d:1f:fd:fc:19:
- 69:c5:dd:b9:3f:7c:cd:c6:b4:c2:30:1e:7e:6e:92:d7:7f:61:
- 76:5a:8f:eb:95:4d:bc:11:6e:21:7c:59:37:99:d0:06:bc:f9:
- 06:6d:32:16:a5:d9:69:a8:e1:dc:3c:80:1e:60:51:dc:d7:54:
- 21:1e:ca:62:77:4f:fa:d8:8f:b3:2b:3a:0d:78:72:c9:68:41:
- 5a:47:4a:c2:a3:eb:1a:d7:0a:ab:3c:32:55:c8:0a:11:9c:df:
- 74:d6:f0:40:15:1d:c8:b9:8f:b5:36:c5:af:f8:22:b8:ca:1d:
- f3:d6:b6:19:0f:9f:61:65:6a:ea:74:c8:7c:8f:c3:4f:5d:65:
- 82:1f:d9:0d:89:da:75:72:fb:ef:f1:47:67:13:b3:c8:d1:19:
- 88:27:26:9a:99:79:7f:1e:e4:2c:3f:7b:ee:f1:de:4d:8b:96:
- 97:c3:d5:3f:7c:1b:23:ed:a4:b3:1d:16:72:43:4b:20:e1:59:
- 7e:c2:e8:ad:26:bf:a2:f7
------BEGIN CERTIFICATE-----
-MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
-ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
-dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
-IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
-VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
-dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
-MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
-UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
-1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
-oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
-HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
-5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
-idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
-OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
-NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
-46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
-UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
-7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
-A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
-MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
-bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
-XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
-PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
-Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
-WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
-Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
-7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
-nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
-vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
-WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
-fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
-I+2ksx0WckNLIOFZfsLorSa/ovc=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/ev_roots/e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70.pem b/chromium/net/data/ssl/ev_roots/e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70.pem
deleted file mode 100644
index c35c26eb4ed..00000000000
--- a/chromium/net/data/ssl/ev_roots/e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70.pem
+++ /dev/null
@@ -1,48 +0,0 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number:
- 70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf
- Signature Algorithm: md2WithRSAEncryption
- Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Validity
- Not Before: Jan 29 00:00:00 1996 GMT
- Not After : Aug 1 23:59:59 2028 GMT
- Subject: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (1024 bit)
- Modulus:
- 00:c9:5c:59:9e:f2:1b:8a:01:14:b4:10:df:04:40:
- db:e3:57:af:6a:45:40:8f:84:0c:0b:d1:33:d9:d9:
- 11:cf:ee:02:58:1f:25:f7:2a:a8:44:05:aa:ec:03:
- 1f:78:7f:9e:93:b9:9a:00:aa:23:7d:d6:ac:85:a2:
- 63:45:c7:72:27:cc:f4:4c:c6:75:71:d2:39:ef:4f:
- 42:f0:75:df:0a:90:c6:8e:20:6f:98:0f:f8:ac:23:
- 5f:70:29:36:a4:c9:86:e7:b1:9a:20:cb:53:a5:85:
- e7:3d:be:7d:9a:fe:24:45:33:dc:76:15:ed:0f:a2:
- 71:64:4c:65:2e:81:68:45:a7
- Exponent: 65537 (0x10001)
- Signature Algorithm: md2WithRSAEncryption
- bb:4c:12:2b:cf:2c:26:00:4f:14:13:dd:a6:fb:fc:0a:11:84:
- 8c:f3:28:1c:67:92:2f:7c:b6:c5:fa:df:f0:e8:95:bc:1d:8f:
- 6c:2c:a8:51:cc:73:d8:a4:c0:53:f0:4e:d6:26:c0:76:01:57:
- 81:92:5e:21:f1:d1:b1:ff:e7:d0:21:58:cd:69:17:e3:44:1c:
- 9c:19:44:39:89:5c:dc:9c:00:0f:56:8d:02:99:ed:a2:90:45:
- 4c:e4:bb:10:a4:3d:f0:32:03:0e:f1:ce:f8:e8:c9:51:8c:e6:
- 62:9f:e6:9f:c0:7d:b7:72:9c:c9:36:3a:6b:9f:4e:a8:ff:64:
- 0d:64
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
-lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
-AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/scripts/generate-test-certs.sh b/chromium/net/data/ssl/scripts/generate-test-certs.sh
index 6a195fac246..e3f539b35fe 100755
--- a/chromium/net/data/ssl/scripts/generate-test-certs.sh
+++ b/chromium/net/data/ssl/scripts/generate-test-certs.sh
@@ -16,7 +16,7 @@ set -e -x
# The current built-in verifier max lifetime is 39 months
# The current OS verifier max lifetime is 825 days, which comes from
# iOS 13/macOS 10.15 - https://support.apple.com/en-us/HT210176
-# 731 is used here as just a short-hand for 2 years
+# 730 is used here as just a short-hand for 2 years
CERT_LIFETIME=730
rm -rf out
@@ -461,6 +461,44 @@ CA_NAME="req_ca_dn" \
-out ../certificates/pre_june_2016.pem \
-config ca.cnf
+# Issued after 2020-09-01, lifetime == 399 days (bad)
+openssl req -config ../scripts/ee.cnf \
+ -newkey rsa:2048 -text -out out/399_days_after_2020_09_01.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 200902000000Z \
+ -enddate 211006000000Z \
+ -in out/399_days_after_2020_09_01.req \
+ -out ../certificates/399_days_after_2020_09_01.pem \
+ -config ca.cnf
+# Issued after 2020-09-01, lifetime == 398 days (good)
+openssl req -config ../scripts/ee.cnf \
+ -newkey rsa:2048 -text -out out/398_days_after_2020_09_01.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 200902000000Z \
+ -enddate 211005000000Z \
+ -in out/398_days_after_2020_09_01.req \
+ -out ../certificates/398_days_after_2020_09_01.pem \
+ -config ca.cnf
+# Issued after 2020-09-01, lifetime == 825 days and one second (bad)
+openssl req -config ../scripts/ee.cnf \
+ -newkey rsa:2048 -text -out out/398_days_1_second_after_2020_09_01.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 200902000000Z \
+ -enddate 211005000001Z \
+ -in out/398_days_1_second_after_2020_09_01.req \
+ -out ../certificates/398_days_1_second_after_2020_09_01.pem \
+ -config ca.cnf
+
+
# Issued after 1 June 2016 (Symantec CT Enforcement Date)
openssl req -config ../scripts/ee.cnf \
-newkey rsa:2048 -text -out out/post_june_2016.req
diff --git a/chromium/net/data/websocket/close_observer.html b/chromium/net/data/websocket/close_observer.html
index e0bf4df290e..759f81b44b2 100644
--- a/chromium/net/data/websocket/close_observer.html
+++ b/chromium/net/data/websocket/close_observer.html
@@ -9,20 +9,22 @@ let url = protocol + '//' + location.host + '/close-observer?role=observer';
// Do connection test.
let ws = new WebSocket(url);
+const id = setTimeout(() => {
+ console.log('close_observer.html had timeout');
+ document.title = 'FAIL';
+}, 3000);
+
ws.onmessage = e => {
+ clearTimeout(id);
console.log('close_observer.html got message: ' + e.data);
document.title = (e.data === 'OK' ? 'PASS' : 'FAIL');
ws.onclose = null;
}
ws.onclose = () => {
+ clearTimeout(id);
console.log('close_observer.html saw close with no message');
document.title = 'FAIL';
}
-setTimeout(() => {
- console.log('close_observer.html had timeout');
- document.title = 'FAIL';
-}, 1000);
-
</script>
diff --git a/chromium/net/der/tag.h b/chromium/net/der/tag.h
index 82d3b257e78..c7dda941f98 100644
--- a/chromium/net/der/tag.h
+++ b/chromium/net/der/tag.h
@@ -60,7 +60,7 @@ const unsigned kTagNumberMask = CBS_ASN1_TAG_NUMBER_MASK;
const unsigned kTagConstructionMask = CBS_ASN1_CONSTRUCTED;
const unsigned kTagClassMask = CBS_ASN1_CLASS_MASK;
-// Creates the value for the outter tag of an explicitly tagged type.
+// Creates the value for the outer tag of an explicitly tagged type.
//
// The ASN.1 keyword for this is:
// [tag_number] EXPLICIT
diff --git a/chromium/net/disk_cache/backend_unittest.cc b/chromium/net/disk_cache/backend_unittest.cc
index 8f88d07a799..e64900765eb 100644
--- a/chromium/net/disk_cache/backend_unittest.cc
+++ b/chromium/net/disk_cache/backend_unittest.cc
@@ -5279,3 +5279,38 @@ TEST_F(DiskCacheBackendTest, SimpleDontLeakPostDoomCreate) {
// Should not have leaked files here.
}
+
+TEST_F(DiskCacheBackendTest, BlockFileDelayedWriteFailureRecovery) {
+ // Test that blockfile recovers appropriately when some entries are
+ // in a screwed up state due to an error in delayed writeback.
+ //
+ // https://crbug.com/1086727
+ InitCache();
+
+ const char kKey[] = "Key2";
+ disk_cache::Entry* entry = nullptr;
+ ASSERT_THAT(CreateEntry(kKey, &entry), IsOk());
+
+ const int kBufSize = 24320;
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kBufSize);
+ CacheTestFillBuffer(buffer->data(), kBufSize, true);
+
+ ASSERT_EQ(kBufSize, WriteSparseData(entry, 0, buffer.get(), kBufSize));
+
+ // Setting the size limit artificially low injects a failure on writing back
+ // data buffered above.
+ SetMaxSize(4096);
+
+ // This causes SparseControl to close the child entry corresponding to
+ // low portion of offset space, triggering the writeback --- which fails
+ // due to the space cap, and in particular fails to allocate data for
+ // a stream, so it gets address 0.
+ ASSERT_EQ(net::ERR_FAILED, WriteSparseData(entry, 16773118, buffer.get(), 4));
+
+ // Now try reading the broken child. This should report an error, not
+ // DCHECK.
+ ASSERT_EQ(net::ERR_FAILED, ReadSparseData(entry, 4, buffer.get(), 4));
+
+ entry->Close();
+}
diff --git a/chromium/net/disk_cache/blockfile/addr.h b/chromium/net/disk_cache/blockfile/addr.h
index 32e035eac99..c7a9a2ae614 100644
--- a/chromium/net/disk_cache/blockfile/addr.h
+++ b/chromium/net/disk_cache/blockfile/addr.h
@@ -11,7 +11,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "base/logging.h"
+#include "base/notreached.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/disk_format_base.h"
diff --git a/chromium/net/disk_cache/blockfile/entry_impl.cc b/chromium/net/disk_cache/blockfile/entry_impl.cc
index 668101caf45..e83e5475851 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl.cc
+++ b/chromium/net/disk_cache/blockfile/entry_impl.cc
@@ -1064,7 +1064,6 @@ int EntryImpl::InternalReadData(int index,
}
address.set_value(entry_.Data()->data_addr[index]);
- DCHECK(address.is_initialized());
if (!address.is_initialized()) {
DoomImpl();
return net::ERR_FAILED;
diff --git a/chromium/net/disk_cache/blockfile/in_flight_io.h b/chromium/net/disk_cache/blockfile/in_flight_io.h
index 6857d370946..9ab21762baf 100644
--- a/chromium/net/disk_cache/blockfile/in_flight_io.h
+++ b/chromium/net/disk_cache/blockfile/in_flight_io.h
@@ -7,7 +7,7 @@
#include <set>
-#include "base/logging.h"
+#include "base/check.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
diff --git a/chromium/net/disk_cache/blockfile/mapped_file_posix.cc b/chromium/net/disk_cache/blockfile/mapped_file_posix.cc
index 99cf49c1890..7921ffdf40f 100644
--- a/chromium/net/disk_cache/blockfile/mapped_file_posix.cc
+++ b/chromium/net/disk_cache/blockfile/mapped_file_posix.cc
@@ -16,24 +16,24 @@ namespace disk_cache {
void* MappedFile::Init(const base::FilePath& name, size_t size) {
DCHECK(!init_);
if (init_ || !File::Init(name))
- return NULL;
+ return nullptr;
size_t temp_len = size ? size : 4096;
if (!size)
size = GetLength();
- buffer_ = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ buffer_ = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,
platform_file(), 0);
init_ = true;
view_size_ = size;
DPLOG_IF(FATAL, buffer_ == MAP_FAILED) << "Failed to mmap " << name.value();
if (buffer_ == MAP_FAILED)
- buffer_ = 0;
+ buffer_ = nullptr;
// Make sure we detect hardware failures reading the headers.
std::unique_ptr<char[]> temp(new char[temp_len]);
if (!Read(temp.get(), temp_len, 0))
- return NULL;
+ return nullptr;
return buffer_;
}
diff --git a/chromium/net/disk_cache/blockfile/stress_support.h b/chromium/net/disk_cache/blockfile/stress_support.h
index 2f07de83e0c..b4d3a6be0c6 100644
--- a/chromium/net/disk_cache/blockfile/stress_support.h
+++ b/chromium/net/disk_cache/blockfile/stress_support.h
@@ -5,7 +5,8 @@
#ifndef NET_DISK_CACHE_BLOCKFILE_STRESS_SUPPORT_H_
#define NET_DISK_CACHE_BLOCKFILE_STRESS_SUPPORT_H_
-#include "base/logging.h"
+#include "base/check.h"
+#include "base/notreached.h"
namespace disk_cache {
diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc
index 1e3226a2642..68b8319898c 100644
--- a/chromium/net/disk_cache/entry_unittest.cc
+++ b/chromium/net/disk_cache/entry_unittest.cc
@@ -2974,7 +2974,6 @@ bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key,
}
TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) {
- base::HistogramTester histogram_tester;
SetSimpleCacheMode();
InitCache();
@@ -2994,14 +2993,10 @@ TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) {
base::MakeRefCounted<net::IOBuffer>(kLargeSize);
EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
ReadData(entry, 1, 0, read_buffer.get(), kLargeSize));
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadResult",
- disk_cache::READ_RESULT_SYNC_CHECKSUM_FAILURE, 1);
}
// Tests that an entry that has had an IO error occur can still be Doomed().
TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
- base::HistogramTester histogram_tester;
SetSimpleCacheMode();
InitCache();
@@ -3020,9 +3015,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
base::MakeRefCounted<net::IOBuffer>(kLargeSize);
EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH,
ReadData(entry, 1, 0, read_buffer.get(), kLargeSize));
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadResult",
- disk_cache::READ_RESULT_SYNC_CHECKSUM_FAILURE, 1);
entry->Doom(); // Should not crash.
}
@@ -5540,22 +5532,17 @@ class DiskCacheSimplePrefetchTest : public DiskCacheEntryTest {
}
void SetupFullAndTrailerPrefetch(int full_size,
- bool trailer_hint,
int trailer_speculative_size) {
std::map<std::string, std::string> params;
params[disk_cache::kSimpleCacheFullPrefetchBytesParam] =
base::NumberToString(full_size);
- params[disk_cache::kSimpleCacheTrailerPrefetchHintParam] =
- trailer_hint ? "true" : "false";
params[disk_cache::kSimpleCacheTrailerPrefetchSpeculativeBytesParam] =
base::NumberToString(trailer_speculative_size);
scoped_feature_list_.InitAndEnableFeatureWithParameters(
disk_cache::kSimpleCachePrefetchExperiment, params);
}
- void SetupFullPrefetch(int size) {
- SetupFullAndTrailerPrefetch(size, false, 0);
- }
+ void SetupFullPrefetch(int size) { SetupFullAndTrailerPrefetch(size, 0); }
void InitCacheAndCreateEntry(const std::string& key) {
SetSimpleCacheMode();
@@ -5597,12 +5584,21 @@ class DiskCacheSimplePrefetchTest : public DiskCacheEntryTest {
entry->Close();
}
- void TryRead(const std::string& key) {
+ void TryRead(const std::string& key, bool expect_preread_stream1) {
disk_cache::Entry* entry = nullptr;
ASSERT_THAT(OpenEntry(key, &entry), IsOk());
scoped_refptr<net::IOBuffer> read_buf =
base::MakeRefCounted<net::IOBuffer>(kEntrySize);
- EXPECT_EQ(kEntrySize, ReadData(entry, 1, 0, read_buf.get(), kEntrySize));
+ net::TestCompletionCallback cb;
+ int rv = entry->ReadData(1, 0, read_buf.get(), kEntrySize, cb.callback());
+
+ // if preload happened, sync reply is expected.
+ if (expect_preread_stream1)
+ EXPECT_EQ(kEntrySize, rv);
+ else
+ EXPECT_EQ(net::ERR_IO_PENDING, rv);
+ rv = cb.GetResult(rv);
+ EXPECT_EQ(kEntrySize, rv);
EXPECT_EQ(0, memcmp(read_buf->data(), payload_->data(), kEntrySize));
entry->Close();
}
@@ -5618,12 +5614,10 @@ TEST_F(DiskCacheSimplePrefetchTest, NoPrefetch) {
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_NONE, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
}
TEST_F(DiskCacheSimplePrefetchTest, YesPrefetch) {
@@ -5632,12 +5626,10 @@ TEST_F(DiskCacheSimplePrefetchTest, YesPrefetch) {
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
}
TEST_F(DiskCacheSimplePrefetchTest, YesPrefetchNoRead) {
@@ -5653,12 +5645,6 @@ TEST_F(DiskCacheSimplePrefetchTest, YesPrefetchNoRead) {
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
- // Have to use GetHistogramSamplesSinceCreation here since it's the only
- // API that handles the cases where the histogram hasn't even been created.
- std::unique_ptr<base::HistogramSamples> samples(
- histogram_tester.GetHistogramSamplesSinceCreation(
- "SimpleCache.Http.ReadStream1FromPrefetched"));
- EXPECT_EQ(0, samples->TotalCount());
}
// This makes sure we detect checksum error on entry that's small enough to be
@@ -5685,11 +5671,8 @@ TEST_F(DiskCacheSimplePrefetchTest, ChecksumNoPrefetch) {
SetupFullPrefetch(0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
- // Expect 2 CRCs --- stream 0 and stream 1.
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFHasCrc",
- true, 2);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
}
@@ -5700,14 +5683,8 @@ TEST_F(DiskCacheSimplePrefetchTest, NoChecksumNoPrefetch) {
SetupFullPrefetch(0);
const char kKey[] = "a key";
InitCacheAndCreateEntryWithNoCrc(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
- // Stream 0 has CRC, stream 1 doesn't.
- histogram_tester.ExpectBucketCount("SimpleCache.Http.SyncCheckEOFHasCrc",
- true, 1);
- histogram_tester.ExpectBucketCount("SimpleCache.Http.SyncCheckEOFHasCrc",
- false, 1);
- // EOF check is recorded even if there is no CRC there.
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
}
@@ -5718,11 +5695,8 @@ TEST_F(DiskCacheSimplePrefetchTest, ChecksumPrefetch) {
SetupFullPrefetch(2 * kEntrySize);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
- // Expect 2 CRCs --- stream 0 and stream 1.
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFHasCrc",
- true, 2);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
}
@@ -5733,13 +5707,8 @@ TEST_F(DiskCacheSimplePrefetchTest, NoChecksumPrefetch) {
SetupFullPrefetch(2 * kEntrySize);
const char kKey[] = "a key";
InitCacheAndCreateEntryWithNoCrc(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
- // Stream 0 has CRC, stream 1 doesn't.
- histogram_tester.ExpectBucketCount("SimpleCache.Http.SyncCheckEOFHasCrc",
- true, 1);
- histogram_tester.ExpectBucketCount("SimpleCache.Http.SyncCheckEOFHasCrc",
- false, 1);
// EOF check is recorded even if there is no CRC there.
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncCheckEOFResult",
disk_cache::CHECK_EOF_RESULT_SUCCESS, 2);
@@ -5765,240 +5734,119 @@ TEST_F(DiskCacheSimplePrefetchTest, PrefetchReadsSync) {
entry->Close();
}
-TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, false, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_NONE, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount(
- "SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintNoSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, NoFullNoSpeculative) {
base::HistogramTester histogram_tester;
- // Trailer prefetch hint should do nothing outside of APP_CACHE mode.
- SetupFullAndTrailerPrefetch(0, true, 0);
+ SetupFullAndTrailerPrefetch(0, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_NONE, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintSmallSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, NoFullSmallSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, false, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(0, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, NoFullNoHintLargeSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, NoFullLargeSpeculative) {
base::HistogramTester histogram_tester;
// A large speculative trailer prefetch that exceeds the entry file
// size should effectively trigger full prefetch behavior.
- SetupFullAndTrailerPrefetch(0, false, kEntrySize * 2);
+ SetupFullAndTrailerPrefetch(0, kEntrySize * 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintSmallSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoSpeculative) {
base::HistogramTester histogram_tester;
- // Trailer prefetch hint should do nothing outside of APP_CACHE mode.
- SetupFullAndTrailerPrefetch(0, true, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(kEntrySize / 2, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_TRAILER, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
- 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount(
- "SimpleCache.Http.EntryTrailerPrefetchDelta", 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimplePrefetchTest, NoFullYesHintLargeSpeculative) {
- base::HistogramTester histogram_tester;
- // Trailer prefetch hint should do nothing outside of APP_CACHE mode.
- SetupFullAndTrailerPrefetch(0, true, kEntrySize * 2);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_FULL, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount(
- "SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
-}
-
-TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize / 2, false, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_NONE, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoHintNoSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize * 2, false, 0);
+ SetupFullAndTrailerPrefetch(kEntrySize * 2, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, SmallFullYesHintNoSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, SmallFullSmallSpeculative) {
base::HistogramTester histogram_tester;
- // Trailer prefetch hint should do nothing outside of APP_CACHE mode.
- SetupFullAndTrailerPrefetch(kEntrySize / 2, true, 0);
+ SetupFullAndTrailerPrefetch(kEntrySize / 2, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_NONE, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount(
- "SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimplePrefetchTest, LargeFullYesHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- // Trailer prefetch hint should do nothing outside of APP_CACHE mode.
- SetupFullAndTrailerPrefetch(kEntrySize * 2, true, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_FULL, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount(
- "SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
-}
-
-TEST_F(DiskCacheSimplePrefetchTest, SmallFullNoHintSmallSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize / 2, false, kEntrySize / 2);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimplePrefetchTest, LargeFullNoHintSmallSpeculative) {
+TEST_F(DiskCacheSimplePrefetchTest, LargeFullSmallSpeculative) {
base::HistogramTester histogram_tester;
// Full prefetch takes precedence over a trailer speculative prefetch.
- SetupFullAndTrailerPrefetch(kEntrySize * 2, false, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(kEntrySize * 2, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.Http.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.Http.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount(
"SimpleCache.Http.EntryTrailerPrefetchDelta", 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.Http.ReadStream1FromPrefetched", true, 1);
}
class DiskCacheSimpleAppCachePrefetchTest : public DiskCacheSimplePrefetchTest {
@@ -6007,237 +5855,119 @@ class DiskCacheSimpleAppCachePrefetchTest : public DiskCacheSimplePrefetchTest {
net::CacheType SimpleCacheType() const override { return net::APP_CACHE; }
};
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintNoSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, false, 0);
+ SetupFullAndTrailerPrefetch(0, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_NONE, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
- 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, true, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectUniqueSample(
"SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintSmallSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, false, kEntrySize / 2);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_TRAILER, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
- 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
- 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullNoHintLargeSpeculative) {
- base::HistogramTester histogram_tester;
- // A large speculative trailer prefetch that exceeds the entry file
- // size should effectively trigger full prefetch behavior.
- SetupFullAndTrailerPrefetch(0, false, kEntrySize * 2);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_FULL, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
- 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", true, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintSmallSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullSmallSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(0, true, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(0, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectUniqueSample(
"SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullYesHintLargeSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, NoFullLargeSpeculative) {
base::HistogramTester histogram_tester;
// Even though the speculative trailer prefetch size is larger than the
// file size, the hint should take precedence and still perform a limited
// trailer prefetch.
- SetupFullAndTrailerPrefetch(0, true, kEntrySize * 2);
+ SetupFullAndTrailerPrefetch(0, kEntrySize * 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectUniqueSample(
"SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoHintNoSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize / 2, false, 0);
+ SetupFullAndTrailerPrefetch(kEntrySize / 2, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_NONE, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
- 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
-}
-
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize * 2, false, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
-
- histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
- disk_cache::OPEN_PREFETCH_FULL, 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
- 0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
- 0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", true, 1);
-}
-
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullYesHintNoSpeculative) {
- base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize / 2, true, 0);
-
- const char kKey[] = "a key";
- InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectUniqueSample(
"SimpleCache.App.EntryTrailerPrefetchDelta", 0, 1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullYesHintNoSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoSpeculative) {
base::HistogramTester histogram_tester;
// Full prefetch takes precedence over a trailer hint prefetch.
- SetupFullAndTrailerPrefetch(kEntrySize * 2, true, 0);
+ SetupFullAndTrailerPrefetch(kEntrySize * 2, 0);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", true, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullNoHintSmallSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, SmallFullSmallSpeculative) {
base::HistogramTester histogram_tester;
- SetupFullAndTrailerPrefetch(kEntrySize / 2, false, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(kEntrySize / 2, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ false);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_TRAILER, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
1);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
1);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", false, 1);
}
-TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullNoHintSmallSpeculative) {
+TEST_F(DiskCacheSimpleAppCachePrefetchTest, LargeFullSmallSpeculative) {
base::HistogramTester histogram_tester;
// Full prefetch takes precedence over a trailer speculative prefetch.
- SetupFullAndTrailerPrefetch(kEntrySize * 2, false, kEntrySize / 2);
+ SetupFullAndTrailerPrefetch(kEntrySize * 2, kEntrySize / 2);
const char kKey[] = "a key";
InitCacheAndCreateEntry(kKey);
- TryRead(kKey);
+ TryRead(kKey, /* expect_preread_stream1 */ true);
histogram_tester.ExpectUniqueSample("SimpleCache.App.SyncOpenPrefetchMode",
disk_cache::OPEN_PREFETCH_FULL, 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchSize",
0);
- histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerSize", 1);
histogram_tester.ExpectTotalCount("SimpleCache.App.EntryTrailerPrefetchDelta",
0);
- histogram_tester.ExpectUniqueSample(
- "SimpleCache.App.ReadStream1FromPrefetched", true, 1);
}
diff --git a/chromium/net/disk_cache/memory/mem_backend_impl.cc b/chromium/net/disk_cache/memory/mem_backend_impl.cc
index 51a46a0ee29..ea9789f7d49 100644
--- a/chromium/net/disk_cache/memory/mem_backend_impl.cc
+++ b/chromium/net/disk_cache/memory/mem_backend_impl.cc
@@ -62,6 +62,7 @@ MemBackendImpl::MemBackendImpl(net::NetLog* net_log)
current_size_(0),
net_log_(net_log),
memory_pressure_listener_(
+ FROM_HERE,
base::BindRepeating(&MemBackendImpl::OnMemoryPressure,
base::Unretained(this))) {}
diff --git a/chromium/net/disk_cache/simple/post_doom_waiter.cc b/chromium/net/disk_cache/simple/post_doom_waiter.cc
index 0f355c33462..8814efbfb0e 100644
--- a/chromium/net/disk_cache/simple/post_doom_waiter.cc
+++ b/chromium/net/disk_cache/simple/post_doom_waiter.cc
@@ -14,8 +14,7 @@ namespace disk_cache {
SimplePostDoomWaiter::SimplePostDoomWaiter() {}
SimplePostDoomWaiter::SimplePostDoomWaiter(base::OnceClosure to_run_post_doom)
- : time_queued(base::TimeTicks::Now()),
- run_post_doom(std::move(to_run_post_doom)) {}
+ : run_post_doom(std::move(to_run_post_doom)) {}
SimplePostDoomWaiter::SimplePostDoomWaiter(SimplePostDoomWaiter&& other) =
default;
@@ -40,12 +39,7 @@ void SimplePostDoomWaiterTable::OnDoomComplete(uint64_t entry_hash) {
to_handle_waiters.swap(it->second);
entries_pending_doom_.erase(it);
- SIMPLE_CACHE_UMA(COUNTS_1000, "NumOpsBlockedByPendingDoom", cache_type_,
- to_handle_waiters.size());
-
for (SimplePostDoomWaiter& post_doom : to_handle_waiters) {
- SIMPLE_CACHE_UMA(TIMES, "QueueLatency.PendingDoom", cache_type_,
- (base::TimeTicks::Now() - post_doom.time_queued));
std::move(post_doom.run_post_doom).Run();
}
}
diff --git a/chromium/net/disk_cache/simple/post_doom_waiter.h b/chromium/net/disk_cache/simple/post_doom_waiter.h
index a7b42682ff2..1dff54bde84 100644
--- a/chromium/net/disk_cache/simple/post_doom_waiter.h
+++ b/chromium/net/disk_cache/simple/post_doom_waiter.h
@@ -19,13 +19,11 @@ namespace disk_cache {
struct SimplePostDoomWaiter {
SimplePostDoomWaiter();
- // Also initializes |time_queued|.
explicit SimplePostDoomWaiter(base::OnceClosure to_run_post_doom);
explicit SimplePostDoomWaiter(SimplePostDoomWaiter&& other);
~SimplePostDoomWaiter();
SimplePostDoomWaiter& operator=(SimplePostDoomWaiter&& other);
- base::TimeTicks time_queued;
base::OnceClosure run_post_doom;
};
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc
index 2e3eadcb2d5..5dfa78c1b07 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc
@@ -45,17 +45,6 @@ namespace {
// the cache.
const int64_t kMaxSparseDataSizeDivisor = 10;
-// Used in histograms, please only add entries at the end.
-enum SimpleEntryWriteResult {
- SIMPLE_ENTRY_WRITE_RESULT_SUCCESS = 0,
- SIMPLE_ENTRY_WRITE_RESULT_INVALID_ARGUMENT = 1,
- SIMPLE_ENTRY_WRITE_RESULT_OVER_MAX_SIZE = 2,
- SIMPLE_ENTRY_WRITE_RESULT_BAD_STATE = 3,
- SIMPLE_ENTRY_WRITE_RESULT_SYNC_WRITE_FAILURE = 4,
- SIMPLE_ENTRY_WRITE_RESULT_FAST_EMPTY_RETURN = 5,
- SIMPLE_ENTRY_WRITE_RESULT_MAX = 6,
-};
-
OpenEntryIndexEnum ComputeIndexState(SimpleBackendImpl* backend,
uint64_t entry_hash) {
if (!backend->index()->initialized())
@@ -71,17 +60,6 @@ void RecordOpenEntryIndexState(net::CacheType cache_type,
INDEX_MAX);
}
-void RecordReadResult(net::CacheType cache_type, SimpleReadResult result) {
- SIMPLE_CACHE_UMA(ENUMERATION,
- "ReadResult", cache_type, result, READ_RESULT_MAX);
-}
-
-void RecordWriteResult(net::CacheType cache_type,
- SimpleEntryWriteResult result) {
- SIMPLE_CACHE_UMA(ENUMERATION, "WriteResult2", cache_type, result,
- SIMPLE_ENTRY_WRITE_RESULT_MAX);
-}
-
void RecordHeaderSize(net::CacheType cache_type, int size) {
SIMPLE_CACHE_UMA(COUNTS_10000, "HeaderSize", cache_type, size);
}
@@ -426,7 +404,6 @@ int SimpleEntryImpl::ReadData(int stream_index,
net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
}
- RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT);
return net::ERR_INVALID_ARGUMENT;
}
@@ -469,7 +446,6 @@ int SimpleEntryImpl::WriteData(int stream_index,
net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT);
}
- RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_INVALID_ARGUMENT);
return net::ERR_INVALID_ARGUMENT;
}
int end_offset;
@@ -480,7 +456,6 @@ int SimpleEntryImpl::WriteData(int stream_index,
net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
net::NetLogEventPhase::NONE, net::ERR_FAILED);
}
- RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_OVER_MAX_SIZE);
return net::ERR_FAILED;
}
ScopedOperationRunner operation_runner(this);
@@ -853,7 +828,7 @@ void SimpleEntryImpl::OpenEntryInternal(
base::OnceClosure task = base::BindOnce(
&SimpleSynchronousEntry::OpenEntry, cache_type_, path_, key_, entry_hash_,
- start_time, file_tracker_, trailer_prefetch_size, results.get());
+ file_tracker_, trailer_prefetch_size, results.get());
base::OnceClosure reply = base::BindOnce(
&SimpleEntryImpl::CreationOperationComplete, this, result_state,
@@ -897,9 +872,9 @@ void SimpleEntryImpl::CreateEntryInternal(
new SimpleEntryCreationResults(SimpleEntryStat(
last_used_, last_modified_, data_size_, sparse_data_size_)));
- OnceClosure task = base::BindOnce(&SimpleSynchronousEntry::CreateEntry,
- cache_type_, path_, key_, entry_hash_,
- start_time, file_tracker_, results.get());
+ OnceClosure task =
+ base::BindOnce(&SimpleSynchronousEntry::CreateEntry, cache_type_, path_,
+ key_, entry_hash_, file_tracker_, results.get());
OnceClosure reply = base::BindOnce(
&SimpleEntryImpl::CreationOperationComplete, this, result_state,
std::move(callback), start_time, base::Time(), std::move(results),
@@ -958,10 +933,10 @@ void SimpleEntryImpl::OpenOrCreateEntryInternal(
}
}
- base::OnceClosure task = base::BindOnce(
- &SimpleSynchronousEntry::OpenOrCreateEntry, cache_type_, path_, key_,
- entry_hash_, index_state, optimistic_create, start_time, file_tracker_,
- trailer_prefetch_size, results.get());
+ base::OnceClosure task =
+ base::BindOnce(&SimpleSynchronousEntry::OpenOrCreateEntry, cache_type_,
+ path_, key_, entry_hash_, index_state, optimistic_create,
+ file_tracker_, trailer_prefetch_size, results.get());
base::OnceClosure reply = base::BindOnce(
&SimpleEntryImpl::CreationOperationComplete, this, result_state,
@@ -1047,7 +1022,6 @@ int SimpleEntryImpl::ReadDataInternal(bool sync_possible,
}
if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
- RecordReadResult(cache_type_, READ_RESULT_BAD_STATE);
if (net_log_.IsCapturing()) {
NetLogReadWriteComplete(net_log_,
net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
@@ -1061,9 +1035,6 @@ int SimpleEntryImpl::ReadDataInternal(bool sync_possible,
}
DCHECK_EQ(STATE_READY, state_);
if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) {
- RecordReadResult(cache_type_, sync_possible
- ? READ_RESULT_NONBLOCK_EMPTY_RETURN
- : READ_RESULT_FAST_EMPTY_RETURN);
// If there is nothing to read, we bail out before setting state_ to
// STATE_IO_PENDING (so ScopedOperationRunner might start us on next op
// here).
@@ -1081,12 +1052,6 @@ int SimpleEntryImpl::ReadDataInternal(bool sync_possible,
// Sometimes we can read in-ram prefetched stream 1 data immediately, too.
if (stream_index == 1) {
- if (is_initial_stream1_read_) {
- SIMPLE_CACHE_UMA(BOOLEAN, "ReadStream1FromPrefetched", cache_type_,
- stream_1_prefetch_data_ != nullptr);
- }
- is_initial_stream1_read_ = false;
-
if (stream_1_prefetch_data_) {
int rv =
ReadFromBuffer(stream_1_prefetch_data_.get(), offset, buf_len, buf);
@@ -1143,7 +1108,6 @@ void SimpleEntryImpl::WriteDataInternal(int stream_index,
}
if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
- RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_BAD_STATE);
if (net_log_.IsCapturing()) {
NetLogReadWriteComplete(
net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
@@ -1173,8 +1137,6 @@ void SimpleEntryImpl::WriteDataInternal(int stream_index,
if (buf_len == 0) {
int32_t data_size = data_size_[stream_index];
if (truncate ? (offset == data_size) : (offset <= data_size)) {
- RecordWriteResult(cache_type_,
- SIMPLE_ENTRY_WRITE_RESULT_FAST_EMPTY_RETURN);
if (!callback.is_null()) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), 0));
@@ -1595,7 +1557,7 @@ void SimpleEntryImpl::ReadOperationComplete(
crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE;
}
}
- RecordReadResultConsideringChecksum(read_result);
+
if (net_log_.IsCapturing()) {
NetLogReadWriteComplete(net_log_,
net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
@@ -1612,11 +1574,6 @@ void SimpleEntryImpl::WriteOperationComplete(
std::unique_ptr<SimpleSynchronousEntry::WriteResult> write_result,
net::IOBuffer* buf) {
int result = write_result->result;
- if (result >= 0)
- RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_SUCCESS);
- else
- RecordWriteResult(cache_type_,
- SIMPLE_ENTRY_WRITE_RESULT_SYNC_WRITE_FAILURE);
if (net_log_.IsCapturing()) {
NetLogReadWriteComplete(net_log_,
net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END,
@@ -1697,24 +1654,6 @@ void SimpleEntryImpl::DoomOperationComplete(
}
}
-void SimpleEntryImpl::RecordReadResultConsideringChecksum(
- const std::unique_ptr<SimpleSynchronousEntry::ReadResult>& read_result)
- const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(synchronous_entry_);
- DCHECK_EQ(STATE_IO_PENDING, state_);
-
- if (read_result->result >= 0) {
- RecordReadResult(cache_type_, READ_RESULT_SUCCESS);
- } else {
- if (read_result->crc_updated && read_result->crc_performed_verify &&
- !read_result->crc_verify_ok)
- RecordReadResult(cache_type_, READ_RESULT_SYNC_CHECKSUM_FAILURE);
- else
- RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE);
- }
-}
-
void SimpleEntryImpl::CloseOperationComplete(
std::unique_ptr<SimpleEntryCloseResults> in_results) {
DCHECK(!synchronous_entry_);
@@ -1771,7 +1710,6 @@ int SimpleEntryImpl::ReadFromBuffer(net::GrowableIOBuffer* in_buf,
memcpy(out_buf->data(), in_buf->data() + offset, buf_len);
UpdateDataFromEntryStat(SimpleEntryStat(base::Time::Now(), last_modified_,
data_size_, sparse_data_size_));
- RecordReadResult(cache_type_, READ_RESULT_SUCCESS);
return buf_len;
}
@@ -1813,7 +1751,6 @@ int SimpleEntryImpl::SetStream0Data(net::IOBuffer* buf,
UpdateDataFromEntryStat(
SimpleEntryStat(modification_time, modification_time, data_size_,
sparse_data_size_));
- RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_SUCCESS);
return buf_len;
}
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.h b/chromium/net/disk_cache/simple/simple_entry_impl.h
index ad2d267da97..2d66478bddd 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.h
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.h
@@ -336,10 +336,6 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
State state_to_restore,
int result);
- void RecordReadResultConsideringChecksum(
- const std::unique_ptr<SimpleSynchronousEntry::ReadResult>& read_result)
- const;
-
// Called after completion of an operation, to either incoproprate file info
// received from I/O done on the worker pool, or to simply bump the
// timestamps. Updates the metadata both in |this| and in the index.
@@ -381,7 +377,6 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
const base::FilePath path_;
const uint64_t entry_hash_;
const bool use_optimistic_operations_;
- bool is_initial_stream1_read_ = true; // used for metrics only.
std::string key_;
// |last_used_|, |last_modified_| and |data_size_| are copied from the
diff --git a/chromium/net/disk_cache/simple/simple_histogram_enums.h b/chromium/net/disk_cache/simple/simple_histogram_enums.h
index 0fd28b757b7..01cd170e064 100644
--- a/chromium/net/disk_cache/simple/simple_histogram_enums.h
+++ b/chromium/net/disk_cache/simple/simple_histogram_enums.h
@@ -8,18 +8,6 @@
namespace disk_cache {
// Used in histograms, please only add entries at the end.
-enum SimpleReadResult {
- READ_RESULT_SUCCESS = 0,
- READ_RESULT_INVALID_ARGUMENT = 1,
- READ_RESULT_NONBLOCK_EMPTY_RETURN = 2,
- READ_RESULT_BAD_STATE = 3,
- READ_RESULT_FAST_EMPTY_RETURN = 4,
- READ_RESULT_SYNC_READ_FAILURE = 5,
- READ_RESULT_SYNC_CHECKSUM_FAILURE = 6,
- READ_RESULT_MAX = 7,
-};
-
-// Used in histograms, please only add entries at the end.
enum OpenEntryResult {
OPEN_ENTRY_SUCCESS = 0,
OPEN_ENTRY_PLATFORM_FILE_ERROR = 1,
@@ -72,14 +60,6 @@ enum CloseResult {
};
// Used in histograms, please only add entries at the end.
-enum class KeySHA256Result {
- NOT_PRESENT = 0,
- MATCHED = 1,
- NO_MATCH = 2,
- MAX = 3
-};
-
-// Used in histograms, please only add entries at the end.
enum FileDescriptorLimiterOp {
FD_LIMIT_CLOSE_FILE = 0,
FD_LIMIT_REOPEN_FILE = 1,
diff --git a/chromium/net/disk_cache/simple/simple_index.cc b/chromium/net/disk_cache/simple/simple_index.cc
index 0775f57ff5a..7e65f1aad68 100644
--- a/chromium/net/disk_cache/simple/simple_index.cc
+++ b/chromium/net/disk_cache/simple/simple_index.cc
@@ -58,11 +58,6 @@ static const int kEstimatedEntryOverhead = 512;
namespace disk_cache {
-const base::Feature
- SimpleIndex::kSimpleCacheDisableEvictionSizeHeuristicForCodeCache{
- "SimpleCacheDisableEvictionSizeHeuristicForCodeCache",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
EntryMetadata::EntryMetadata()
: last_used_time_seconds_since_epoch_(0),
entry_size_256b_chunks_(0),
@@ -422,11 +417,7 @@ void SimpleIndex::StartEvictionIfNeeded() {
MEMORY_KB, "Eviction.MaxCacheSizeOnStart2", cache_type_,
static_cast<base::HistogramBase::Sample>(max_size_ / kBytesInKb));
- bool use_size_heuristic = true;
- if (cache_type_ == net::GENERATED_BYTE_CODE_CACHE) {
- use_size_heuristic = !base::FeatureList::IsEnabled(
- kSimpleCacheDisableEvictionSizeHeuristicForCodeCache);
- }
+ bool use_size_heuristic = (cache_type_ != net::GENERATED_BYTE_CODE_CACHE);
// Flatten for sorting.
std::vector<std::pair<uint64_t, const EntrySet::value_type*>> entries;
@@ -603,9 +594,6 @@ void SimpleIndex::MergeInitializingSet(
if (load_result->flush_required)
WriteToDisk(INDEX_WRITE_REASON_STARTUP_MERGE);
- SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
- "IndexInitializationWaiters", cache_type_,
- to_run_when_initialized_.size(), 0, 100, 20);
SIMPLE_CACHE_UMA(CUSTOM_COUNTS, "IndexNumEntriesOnInit", cache_type_,
entries_set_.size(), 0, 100000, 50);
SIMPLE_CACHE_UMA(
@@ -656,19 +644,6 @@ void SimpleIndex::WriteToDisk(IndexWriteToDiskReason reason) {
SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
"IndexNumEntriesOnWrite", cache_type_,
entries_set_.size(), 0, 100000, 50);
- const base::TimeTicks start = base::TimeTicks::Now();
- if (!last_write_to_disk_.is_null()) {
- if (app_on_background_) {
- SIMPLE_CACHE_UMA(MEDIUM_TIMES,
- "IndexWriteInterval.Background", cache_type_,
- start - last_write_to_disk_);
- } else {
- SIMPLE_CACHE_UMA(MEDIUM_TIMES,
- "IndexWriteInterval.Foreground", cache_type_,
- start - last_write_to_disk_);
- }
- }
- last_write_to_disk_ = start;
base::OnceClosure after_write;
if (cleanup_tracker_) {
@@ -680,7 +655,7 @@ void SimpleIndex::WriteToDisk(IndexWriteToDiskReason reason) {
}
index_file_->WriteToDisk(cache_type_, reason, entries_set_, cache_size_,
- start, app_on_background_, std::move(after_write));
+ std::move(after_write));
}
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_index.h b/chromium/net/disk_cache/simple/simple_index.h
index f8cdd3c102d..8a62fb1d16e 100644
--- a/chromium/net/disk_cache/simple/simple_index.h
+++ b/chromium/net/disk_cache/simple/simple_index.h
@@ -14,7 +14,6 @@
#include <vector>
#include "base/callback.h"
-#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
@@ -297,11 +296,6 @@ class NET_EXPORT_PRIVATE SimpleIndex
// enforces this.
SEQUENCE_CHECKER(sequence_checker_);
- // Timestamp of the last time we wrote the index to disk.
- // PostponeWritingToDisk() may give up postponing and allow the write if it
- // has been a while since last time we wrote.
- base::TimeTicks last_write_to_disk_;
-
base::OneShotTimer write_to_disk_timer_;
base::RepeatingClosure write_to_disk_cb_;
@@ -312,9 +306,6 @@ class NET_EXPORT_PRIVATE SimpleIndex
// background we can write the index much more frequently, to insure fresh
// index on next startup.
bool app_on_background_ = false;
-
- static const base::Feature
- kSimpleCacheDisableEvictionSizeHeuristicForCodeCache;
};
} // namespace disk_cache
diff --git a/chromium/net/disk_cache/simple/simple_index_file.cc b/chromium/net/disk_cache/simple/simple_index_file.cc
index 9d53a5e90c5..06a0fff535b 100644
--- a/chromium/net/disk_cache/simple/simple_index_file.cc
+++ b/chromium/net/disk_cache/simple/simple_index_file.cc
@@ -296,9 +296,7 @@ void SimpleIndexFile::SyncWriteToDisk(net::CacheType cache_type,
const base::FilePath& cache_directory,
const base::FilePath& index_filename,
const base::FilePath& temp_index_filename,
- std::unique_ptr<base::Pickle> pickle,
- const base::TimeTicks& start_time,
- bool app_on_background) {
+ std::unique_ptr<base::Pickle> pickle) {
DCHECK_EQ(index_filename.DirName().value(),
temp_index_filename.DirName().value());
base::FilePath index_file_directory = temp_index_filename.DirName();
@@ -327,16 +325,6 @@ void SimpleIndexFile::SyncWriteToDisk(net::CacheType cache_type,
// Atomically rename the temporary index file to become the real one.
if (!base::ReplaceFile(temp_index_filename, index_filename, nullptr))
return;
-
- if (app_on_background) {
- SIMPLE_CACHE_UMA(TIMES,
- "IndexWriteToDiskTime.Background", cache_type,
- (base::TimeTicks::Now() - start_time));
- } else {
- SIMPLE_CACHE_UMA(TIMES,
- "IndexWriteToDiskTime.Foreground", cache_type,
- (base::TimeTicks::Now() - start_time));
- }
}
bool SimpleIndexFile::IndexMetadata::CheckIndexMetadata() {
@@ -383,17 +371,14 @@ void SimpleIndexFile::WriteToDisk(net::CacheType cache_type,
SimpleIndex::IndexWriteToDiskReason reason,
const SimpleIndex::EntrySet& entry_set,
uint64_t cache_size,
- const base::TimeTicks& start,
- bool app_on_background,
base::OnceClosure callback) {
UmaRecordIndexWriteReason(reason, cache_type_);
IndexMetadata index_metadata(reason, entry_set.size(), cache_size);
std::unique_ptr<base::Pickle> pickle =
Serialize(cache_type, index_metadata, entry_set);
- base::OnceClosure task =
- base::BindOnce(&SimpleIndexFile::SyncWriteToDisk, cache_type_,
- cache_directory_, index_file_, temp_index_file_,
- std::move(pickle), start, app_on_background);
+ base::OnceClosure task = base::BindOnce(
+ &SimpleIndexFile::SyncWriteToDisk, cache_type_, cache_directory_,
+ index_file_, temp_index_file_, std::move(pickle));
if (callback.is_null())
cache_runner_->PostTask(FROM_HERE, std::move(task));
else
@@ -447,8 +432,6 @@ void SimpleIndexFile::SyncLoadIndexEntries(
SyncRestoreFromDisk(cache_type, cache_directory, index_file_path, out_result);
SIMPLE_CACHE_UMA(MEDIUM_TIMES, "IndexRestoreTime", cache_type,
base::TimeTicks::Now() - start);
- SIMPLE_CACHE_UMA(COUNTS_1M, "IndexEntriesRestored", cache_type,
- out_result->entries.size());
if (index_file_existed) {
out_result->init_method = SimpleIndex::INITIALIZE_METHOD_RECOVERED;
diff --git a/chromium/net/disk_cache/simple/simple_index_file.h b/chromium/net/disk_cache/simple/simple_index_file.h
index ae9345659e6..0e768f98656 100644
--- a/chromium/net/disk_cache/simple/simple_index_file.h
+++ b/chromium/net/disk_cache/simple/simple_index_file.h
@@ -13,7 +13,6 @@
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/pickle.h"
#include "net/base/cache_type.h"
@@ -107,8 +106,6 @@ class NET_EXPORT_PRIVATE SimpleIndexFile {
SimpleIndex::IndexWriteToDiskReason reason,
const SimpleIndex::EntrySet& entry_set,
uint64_t cache_size,
- const base::TimeTicks& start,
- bool app_on_background,
base::OnceClosure callback);
private:
@@ -178,9 +175,7 @@ class NET_EXPORT_PRIVATE SimpleIndexFile {
const base::FilePath& cache_directory,
const base::FilePath& index_filename,
const base::FilePath& temp_index_filename,
- std::unique_ptr<base::Pickle> pickle,
- const base::TimeTicks& start_time,
- bool app_on_background);
+ std::unique_ptr<base::Pickle> pickle);
// Scan the index directory for entries, returning an EntrySet of all entries
// found.
diff --git a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
index c193f72fd47..a162ca7e564 100644
--- a/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_index_file_unittest.cc
@@ -462,9 +462,9 @@ TEST_F(SimpleIndexFileTest, WriteThenLoadIndex) {
net::TestClosure closure;
{
WrappedSimpleIndexFile simple_index_file(cache_dir.GetPath());
- simple_index_file.WriteToDisk(
- net::DISK_CACHE, SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, entries,
- kCacheSize, base::TimeTicks(), false, closure.closure());
+ simple_index_file.WriteToDisk(net::DISK_CACHE,
+ SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN,
+ entries, kCacheSize, closure.closure());
closure.WaitForResult();
EXPECT_TRUE(base::PathExists(simple_index_file.GetIndexFilePath()));
}
@@ -637,9 +637,9 @@ TEST_F(SimpleIndexFileTest, OverwritesStaleTempFile) {
SimpleIndex::EntrySet entries;
SimpleIndex::InsertInEntrySet(11, EntryMetadata(Time(), 11u), &entries);
net::TestClosure closure;
- simple_index_file.WriteToDisk(
- net::DISK_CACHE, SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN, entries, 120U,
- base::TimeTicks(), false, closure.closure());
+ simple_index_file.WriteToDisk(net::DISK_CACHE,
+ SimpleIndex::INDEX_WRITE_REASON_SHUTDOWN,
+ entries, 120U, closure.closure());
closure.WaitForResult();
// Check that the temporary file was deleted and the index file was created.
diff --git a/chromium/net/disk_cache/simple/simple_index_unittest.cc b/chromium/net/disk_cache/simple/simple_index_unittest.cc
index e6e8e932d64..2f70905c705 100644
--- a/chromium/net/disk_cache/simple/simple_index_unittest.cc
+++ b/chromium/net/disk_cache/simple/simple_index_unittest.cc
@@ -78,8 +78,6 @@ class MockSimpleIndexFile : public SimpleIndexFile,
SimpleIndex::IndexWriteToDiskReason reason,
const SimpleIndex::EntrySet& entry_set,
uint64_t cache_size,
- const base::TimeTicks& start,
- bool app_on_background,
base::OnceClosure callback) override {
disk_writes_++;
disk_write_entry_set_ = entry_set;
@@ -642,10 +640,6 @@ TEST_F(SimpleIndexTest, EvictBySize) {
}
TEST_F(SimpleIndexCodeCacheTest, DisableEvictBySize) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {SimpleIndex::kSimpleCacheDisableEvictionSizeHeuristicForCodeCache}, {});
-
base::Time now(base::Time::Now());
index()->SetMaxSize(50000);
InsertIntoIndexFileReturn(hashes_.at<1>(), now - base::TimeDelta::FromDays(2),
@@ -675,40 +669,6 @@ TEST_F(SimpleIndexCodeCacheTest, DisableEvictBySize) {
ASSERT_EQ(2u, last_doom_entry_hashes().size());
}
-TEST_F(SimpleIndexCodeCacheTest, EnableEvictBySize) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {}, {SimpleIndex::kSimpleCacheDisableEvictionSizeHeuristicForCodeCache});
-
- base::Time now(base::Time::Now());
- index()->SetMaxSize(50000);
- InsertIntoIndexFileReturn(hashes_.at<1>(), now - base::TimeDelta::FromDays(2),
- 475u);
- InsertIntoIndexFileReturn(hashes_.at<2>(), now - base::TimeDelta::FromDays(1),
- 40000u);
- ReturnIndexFile();
- WaitForTimeChange();
-
- index()->Insert(hashes_.at<3>());
- // Confirm index is as expected: No eviction, everything there.
- EXPECT_EQ(3, index()->GetEntryCount());
- EXPECT_EQ(0, doom_entries_calls());
- EXPECT_TRUE(index()->Has(hashes_.at<1>()));
- EXPECT_TRUE(index()->Has(hashes_.at<2>()));
- EXPECT_TRUE(index()->Has(hashes_.at<3>()));
-
- // Trigger an eviction, and make sure the right things are tossed.
- // This has size-weighting enabled, so it end sup kickicking out entry
- // 2, which is biggest, and is enough, even though <1> is older.
- index()->UpdateEntrySize(hashes_.at<3>(), 40000u);
- EXPECT_EQ(1, doom_entries_calls());
- EXPECT_EQ(2, index()->GetEntryCount());
- EXPECT_TRUE(index()->Has(hashes_.at<1>()));
- EXPECT_FALSE(index()->Has(hashes_.at<2>()));
- EXPECT_TRUE(index()->Has(hashes_.at<3>()));
- ASSERT_EQ(1u, last_doom_entry_hashes().size());
-}
-
// Same as test above, but using much older entries to make sure that small
// things eventually get evictied.
TEST_F(SimpleIndexTest, EvictBySize2) {
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
index 6effe85bb22..140067a5864 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -60,12 +60,6 @@ void RecordCloseResult(net::CacheType cache_type, CloseResult result) {
"SyncCloseResult", cache_type, result, CLOSE_RESULT_MAX);
}
-void RecordKeySHA256Result(net::CacheType cache_type, KeySHA256Result result) {
- SIMPLE_CACHE_UMA(ENUMERATION, "SyncKeySHA256Result", cache_type,
- static_cast<int>(result),
- static_cast<int>(KeySHA256Result::MAX));
-}
-
void RecordOpenPrefetchMode(net::CacheType cache_type, OpenPrefetchMode mode) {
SIMPLE_CACHE_UMA(ENUMERATION, "SyncOpenPrefetchMode", cache_type, mode,
OPEN_PREFETCH_MAX);
@@ -208,11 +202,6 @@ const char kSimpleCacheFullPrefetchBytesParam[] = "FullPrefetchBytes";
constexpr base::FeatureParam<int> kSimpleCacheFullPrefetchSize{
&kSimpleCachePrefetchExperiment, kSimpleCacheFullPrefetchBytesParam, 0};
-const char kSimpleCacheTrailerPrefetchHintParam[] = "TrailerPrefetchHint";
-constexpr base::FeatureParam<bool> kSimpleCacheTrailerPrefetchHint{
- &kSimpleCachePrefetchExperiment, kSimpleCacheTrailerPrefetchHintParam,
- true};
-
const char kSimpleCacheTrailerPrefetchSpeculativeBytesParam[] =
"TrailerPrefetchSpeculativeBytes";
constexpr base::FeatureParam<int> kSimpleCacheTrailerPrefetchSpeculativeBytes{
@@ -224,7 +213,7 @@ int GetSimpleCacheFullPrefetchSize() {
}
int GetSimpleCacheTrailerPrefetchSize(int hint_size) {
- if (kSimpleCacheTrailerPrefetchHint.Get() && hint_size > 0)
+ if (hint_size > 0)
return hint_size;
return kSimpleCacheTrailerPrefetchSpeculativeBytes.Get();
}
@@ -338,13 +327,10 @@ void SimpleSynchronousEntry::OpenEntry(
const FilePath& path,
const std::string& key,
const uint64_t entry_hash,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results) {
base::TimeTicks start_sync_open_entry = base::TimeTicks::Now();
- SIMPLE_CACHE_UMA(TIMES, "QueueLatency.OpenEntry", cache_type,
- (start_sync_open_entry - time_enqueued));
SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry(
cache_type, path, key, entry_hash, file_tracker, trailer_prefetch_size);
@@ -371,13 +357,10 @@ void SimpleSynchronousEntry::CreateEntry(
const FilePath& path,
const std::string& key,
const uint64_t entry_hash,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
SimpleEntryCreationResults* out_results) {
DCHECK_EQ(entry_hash, GetEntryHashKey(key));
base::TimeTicks start_sync_create_entry = base::TimeTicks::Now();
- SIMPLE_CACHE_UMA(TIMES, "QueueLatency.CreateEntry", cache_type,
- (start_sync_create_entry - time_enqueued));
SimpleSynchronousEntry* sync_entry = new SimpleSynchronousEntry(
cache_type, path, key, entry_hash, file_tracker, -1);
@@ -404,13 +387,10 @@ void SimpleSynchronousEntry::OpenOrCreateEntry(
const uint64_t entry_hash,
OpenEntryIndexEnum index_state,
bool optimistic_create,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results) {
base::TimeTicks start = base::TimeTicks::Now();
- SIMPLE_CACHE_UMA(TIMES, "QueueLatency.OpenOrCreateEntry", cache_type,
- (start - time_enqueued));
if (index_state == INDEX_MISS) {
// Try to just create.
auto sync_entry = base::WrapUnique(
@@ -431,8 +411,8 @@ void SimpleSynchronousEntry::OpenOrCreateEntry(
// In this case, ::OpenOrCreateEntry already returned claiming it made
// a new entry. Try extra-hard to make that the actual case.
sync_entry->Doom();
- CreateEntry(cache_type, path, key, entry_hash, time_enqueued,
- file_tracker, out_results);
+ CreateEntry(cache_type, path, key, entry_hash, file_tracker,
+ out_results);
return;
}
// Otherwise can just try opening.
@@ -445,12 +425,11 @@ void SimpleSynchronousEntry::OpenOrCreateEntry(
}
// Try open, then if that fails create.
- OpenEntry(cache_type, path, key, entry_hash, time_enqueued, file_tracker,
+ OpenEntry(cache_type, path, key, entry_hash, file_tracker,
trailer_prefetch_size, out_results);
if (out_results->sync_entry)
return;
- CreateEntry(cache_type, path, key, entry_hash, time_enqueued, file_tracker,
- out_results);
+ CreateEntry(cache_type, path, key, entry_hash, file_tracker, out_results);
}
// static
@@ -628,8 +607,7 @@ void SimpleSynchronousEntry::WriteData(const WriteRequest& in_entry_op,
out_write_result->result = net::ERR_CACHE_WRITE_FAILURE;
return;
}
- CreateEntryResult result;
- if (!InitializeCreatedFile(file_index, &result)) {
+ if (!InitializeCreatedFile(file_index)) {
RecordWriteResult(cache_type_, SYNC_WRITE_RESULT_LAZY_INITIALIZE_FAILURE);
Doom();
out_write_result->result = net::ERR_CACHE_WRITE_FAILURE;
@@ -1203,7 +1181,6 @@ bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) {
have_open_files_ = true;
base::Time after_open_files = base::Time::Now();
- base::TimeDelta entry_age = after_open_files - base::Time::UnixEpoch();
for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) {
if (empty_file_omitted_[i]) {
out_entry_stat->set_data_size(i + 1, 0);
@@ -1221,11 +1198,6 @@ bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) {
out_entry_stat->set_last_used(file_info.last_accessed);
out_entry_stat->set_last_modified(file_info.last_modified);
- base::TimeDelta stream_age =
- base::Time::Now() - out_entry_stat->last_modified();
- if (stream_age < entry_age)
- entry_age = stream_age;
-
// Two things prevent from knowing the right values for |data_size|:
// 1) The key might not be known, hence its length might be unknown.
// 2) Stream 0 and stream 1 are in the same file, and the exact size for
@@ -1263,9 +1235,6 @@ bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) {
}
}
}
- SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
- "SyncOpenEntryAge", cache_type_,
- entry_age.InHours(), 1, 1000, 50);
return true;
}
@@ -1274,7 +1243,6 @@ bool SimpleSynchronousEntry::CreateFiles(SimpleEntryStat* out_entry_stat) {
for (int i = 0; i < kSimpleEntryNormalFileCount; ++i) {
base::File::Error error;
if (!MaybeCreateFile(i, FILE_NOT_REQUIRED, &error)) {
- RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR);
SIMPLE_CACHE_UMA(ENUMERATION,
"SyncCreatePlatformFileError", cache_type_,
-error, -base::File::FILE_ERROR_MAX);
@@ -1468,15 +1436,11 @@ int SimpleSynchronousEntry::InitializeForOpen(
return net::OK;
}
-bool SimpleSynchronousEntry::InitializeCreatedFile(
- int file_index,
- CreateEntryResult* out_result) {
+bool SimpleSynchronousEntry::InitializeCreatedFile(int file_index) {
SimpleFileTracker::FileHandle file =
file_tracker_->Acquire(this, SubFileForFileIndex(file_index));
- if (!file.IsOK()) {
- *out_result = CREATE_ENTRY_CANT_WRITE_HEADER;
+ if (!file.IsOK())
return false;
- }
SimpleFileHeader header;
header.initial_magic_number = kSimpleInitialMagicNumber;
@@ -1487,16 +1451,12 @@ bool SimpleSynchronousEntry::InitializeCreatedFile(
int bytes_written =
file->Write(0, reinterpret_cast<char*>(&header), sizeof(header));
- if (bytes_written != sizeof(header)) {
- *out_result = CREATE_ENTRY_CANT_WRITE_HEADER;
+ if (bytes_written != sizeof(header))
return false;
- }
bytes_written = file->Write(sizeof(header), key_.data(), key_.size());
- if (bytes_written != base::checked_cast<int>(key_.size())) {
- *out_result = CREATE_ENTRY_CANT_WRITE_KEY;
+ if (bytes_written != base::checked_cast<int>(key_.size()))
return false;
- }
return true;
}
@@ -1512,13 +1472,9 @@ int SimpleSynchronousEntry::InitializeForCreate(
if (empty_file_omitted_[i])
continue;
- CreateEntryResult result;
- if (!InitializeCreatedFile(i, &result)) {
- RecordSyncCreateResult(result);
+ if (!InitializeCreatedFile(i))
return net::ERR_FAILED;
- }
}
- RecordSyncCreateResult(CREATE_ENTRY_SUCCESS);
initialized_ = true;
return net::OK;
}
@@ -1617,12 +1573,9 @@ int SimpleSynchronousEntry::ReadAndValidateStream0AndMaybe1(
// Note the exact range needed in order to read the EOF record and stream 0.
// In APP_CACHE mode this will be stored directly in the index so we can
- // know exactly how much to read next time. Its also reported in a histogram
- // so we can tune the speculative trailer prefetching experiment.
+ // know exactly how much to read next time.
computed_trailer_prefetch_size_ =
prefetch_data.GetDesiredTrailerPrefetchSize();
- SIMPLE_CACHE_UMA(COUNTS_100000, "EntryTrailerSize", cache_type_,
- computed_trailer_prefetch_size_);
// If we performed a trailer prefetch, record how accurate the prefetch was
// compared to the ideal value.
@@ -1663,15 +1616,11 @@ int SimpleSynchronousEntry::ReadAndValidateStream0AndMaybe1(
std::memcmp(&hash_value,
stream_prefetch_data[0].data->data() + stream_0_size,
sizeof(hash_value)) == 0;
- if (!matched) {
- RecordKeySHA256Result(cache_type_, KeySHA256Result::NO_MATCH);
+ if (!matched)
return net::ERR_FAILED;
- }
+
// Elide header check if we verified sha256(key) via footer.
header_and_key_check_needed_[0] = false;
- RecordKeySHA256Result(cache_type_, KeySHA256Result::MATCHED);
- } else {
- RecordKeySHA256Result(cache_type_, KeySHA256Result::NOT_PRESENT);
}
// Ensure the key is validated before completion.
@@ -1733,9 +1682,6 @@ int SimpleSynchronousEntry::GetEOFRecordData(base::File* file,
if (!base::IsValueInRangeForNumericType<int32_t>(eof_record->stream_size))
return net::ERR_FAILED;
- SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_,
- (eof_record->flags & SimpleFileEOF::FLAG_HAS_CRC32) ==
- SimpleFileEOF::FLAG_HAS_CRC32);
return net::OK;
}
@@ -1781,12 +1727,6 @@ bool SimpleSynchronousEntry::TruncateFilesForEntryHash(
return result;
}
-void SimpleSynchronousEntry::RecordSyncCreateResult(CreateEntryResult result) {
- DCHECK_LT(result, CREATE_ENTRY_MAX);
- SIMPLE_CACHE_UMA(ENUMERATION,
- "SyncCreateResult", cache_type_, result, CREATE_ENTRY_MAX);
-}
-
FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(
int file_index) const {
return path_.AppendASCII(
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.h b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
index 958a052ec39..9e1536b1b42 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.h
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
@@ -38,7 +38,6 @@ namespace disk_cache {
NET_EXPORT_PRIVATE extern const base::Feature kSimpleCachePrefetchExperiment;
NET_EXPORT_PRIVATE extern const char kSimpleCacheFullPrefetchBytesParam[];
-NET_EXPORT_PRIVATE extern const char kSimpleCacheTrailerPrefetchHintParam[];
NET_EXPORT_PRIVATE extern const char
kSimpleCacheTrailerPrefetchSpeculativeBytesParam[];
@@ -191,13 +190,10 @@ class SimpleSynchronousEntry {
// Opens a disk cache entry on disk. The |key| parameter is optional, if empty
// the operation may be slower. The |entry_hash| parameter is required.
- // |time_enqueued| is when this operation was added to the I/O thread pool,
- // and is provided only for histograms.
static void OpenEntry(net::CacheType cache_type,
const base::FilePath& path,
const std::string& key,
uint64_t entry_hash,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results);
@@ -206,7 +202,6 @@ class SimpleSynchronousEntry {
const base::FilePath& path,
const std::string& key,
uint64_t entry_hash,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
SimpleEntryCreationResults* out_results);
@@ -216,7 +211,6 @@ class SimpleSynchronousEntry {
uint64_t entry_hash,
OpenEntryIndexEnum index_state,
bool optimistic_create,
- const base::TimeTicks& time_enqueued,
SimpleFileTracker* file_tracker,
int32_t trailer_prefetch_size,
SimpleEntryCreationResults* out_results);
@@ -304,14 +298,6 @@ class SimpleSynchronousEntry {
friend class SimpleFileTrackerTest;
class PrefetchData;
- enum CreateEntryResult {
- CREATE_ENTRY_SUCCESS = 0,
- CREATE_ENTRY_PLATFORM_FILE_ERROR = 1,
- CREATE_ENTRY_CANT_WRITE_HEADER = 2,
- CREATE_ENTRY_CANT_WRITE_KEY = 3,
- CREATE_ENTRY_MAX = 4,
- };
-
enum FileRequired {
FILE_NOT_REQUIRED,
FILE_REQUIRED
@@ -368,9 +354,8 @@ class SimpleSynchronousEntry {
SimpleStreamPrefetchData stream_prefetch_data[2]);
// Writes the header and key to a newly-created stream file. |index| is the
- // index of the stream. Returns true on success; returns false and sets
- // |*out_result| on failure.
- bool InitializeCreatedFile(int index, CreateEntryResult* out_result);
+ // index of the stream. Returns true on success; returns false and failure.
+ bool InitializeCreatedFile(int index);
// Returns a net error, including net::OK on success and net::FILE_EXISTS
// when the entry already exists.
@@ -469,8 +454,6 @@ class SimpleSynchronousEntry {
static bool TruncateFilesForEntryHash(const base::FilePath& path,
uint64_t entry_hash);
- void RecordSyncCreateResult(CreateEntryResult result);
-
base::FilePath GetFilenameFromFileIndex(int file_index) const;
bool sparse_file_open() const { return sparse_file_open_; }
diff --git a/chromium/net/dns/BUILD.gn b/chromium/net/dns/BUILD.gn
index 74680eccfea..3e24edd0b48 100644
--- a/chromium/net/dns/BUILD.gn
+++ b/chromium/net/dns/BUILD.gn
@@ -5,6 +5,10 @@
import("//net/features.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
+if (is_android) {
+ import("//build/config/android/rules.gni")
+}
+
enable_built_in_dns = !is_ios
source_set("dns") {
@@ -62,7 +66,6 @@ source_set("dns") {
"dns_transaction.cc",
"dns_udp_tracker.cc",
"dns_udp_tracker.h",
- "esni_content.cc",
"host_cache.cc",
"host_resolver.cc",
"host_resolver_manager.cc",
@@ -72,6 +75,8 @@ source_set("dns") {
"host_resolver_mdns_task.h",
"host_resolver_proc.cc",
"host_resolver_proc.h",
+ "httpssvc_metrics.cc",
+ "httpssvc_metrics.h",
"mapped_host_resolver.cc",
"notify_watcher_mac.cc",
"notify_watcher_mac.h",
@@ -198,7 +203,6 @@ source_set("host_resolver") {
sources += [
"dns_config.h",
"dns_config_overrides.h",
- "esni_content.h",
"host_cache.h",
"host_resolver.h",
"host_resolver_source.h",
@@ -371,6 +375,12 @@ source_set("mdns_client") {
public_deps = [ "//net:net_public_deps" ]
}
+if (is_android) {
+ java_cpp_enum("secure_dns_mode_generated_enum") {
+ sources = [ "dns_config.h" ]
+ }
+}
+
source_set("tests") {
testonly = true
sources = [
@@ -386,9 +396,9 @@ source_set("tests") {
"dns_transaction_unittest.cc",
"dns_udp_tracker_unittest.cc",
"dns_util_unittest.cc",
- "esni_content_unittest.cc",
"host_cache_unittest.cc",
"host_resolver_manager_unittest.cc",
+ "httpssvc_metrics_unittest.cc",
"mapped_host_resolver_unittest.cc",
"record_parsed_unittest.cc",
"record_rdata_unittest.cc",
diff --git a/chromium/net/dns/address_info.cc b/chromium/net/dns/address_info.cc
index ec8016a33f3..67a357a112e 100644
--- a/chromium/net/dns/address_info.cc
+++ b/chromium/net/dns/address_info.cc
@@ -5,6 +5,7 @@
#include "net/dns/address_info.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/sys_byteorder.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
diff --git a/chromium/net/dns/context_host_resolver.cc b/chromium/net/dns/context_host_resolver.cc
index 0ae8cc862f7..32a7a0ddf27 100644
--- a/chromium/net/dns/context_host_resolver.cc
+++ b/chromium/net/dns/context_host_resolver.cc
@@ -150,16 +150,6 @@ class ContextHostResolver::WrappedResolveHostRequest
return inner_request_->GetHostnameResults();
}
- const base::Optional<EsniContent>& GetEsniResults() const override {
- if (!inner_request_) {
- static const base::NoDestructor<base::Optional<EsniContent>>
- nullopt_result;
- return *nullopt_result;
- }
-
- return inner_request_->GetEsniResults();
- }
-
net::ResolveErrorInfo GetResolveErrorInfo() const override {
if (!inner_request_) {
return resolve_error_info_;
diff --git a/chromium/net/dns/dns_config.h b/chromium/net/dns/dns_config.h
index 9e1e3e917d0..d65a31eb45d 100644
--- a/chromium/net/dns/dns_config.h
+++ b/chromium/net/dns/dns_config.h
@@ -51,6 +51,7 @@ struct NET_EXPORT DnsConfig {
return !nameservers.empty() || !dns_over_https_servers.empty();
}
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
// The SecureDnsMode specifies what types of lookups (secure/insecure) should
// be performed and in what order when resolving a specific query. The int
// values should not be changed as they are logged.
diff --git a/chromium/net/dns/dns_hosts.cc b/chromium/net/dns/dns_hosts.cc
index 13ee84b7d0b..04b1596e613 100644
--- a/chromium/net/dns/dns_hosts.cc
+++ b/chromium/net/dns/dns_hosts.cc
@@ -7,7 +7,6 @@
#include "base/check.h"
#include "base/files/file_util.h"
#include "base/macros.h"
-#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "net/dns/dns_util.h"
@@ -199,9 +198,6 @@ bool ParseHostsFile(const base::FilePath& path, DnsHosts* dns_hosts) {
if (!base::GetFileSize(path, &size))
return false;
- UMA_HISTOGRAM_COUNTS_1M("AsyncDNS.HostsSize",
- static_cast<base::HistogramBase::Sample>(size));
-
// Reject HOSTS files larger than |kMaxHostsSize| bytes.
const int64_t kMaxHostsSize = 1 << 25; // 32MB
if (size > kMaxHostsSize)
diff --git a/chromium/net/dns/dns_response.cc b/chromium/net/dns/dns_response.cc
index 523ccc2725b..860eebbc5e7 100644
--- a/chromium/net/dns/dns_response.cc
+++ b/chromium/net/dns/dns_response.cc
@@ -93,8 +93,10 @@ DnsResourceRecord& DnsResourceRecord::operator=(DnsResourceRecord&& other) {
}
void DnsResourceRecord::SetOwnedRdata(std::string value) {
+ DCHECK(!value.empty());
owned_rdata = std::move(value);
rdata = owned_rdata;
+ DCHECK_EQ(owned_rdata.data(), rdata.data());
}
size_t DnsResourceRecord::CalculateRecordSize() const {
@@ -570,8 +572,7 @@ bool DnsResponse::WriteQuestion(base::BigEndianWriter* writer,
bool DnsResponse::WriteRecord(base::BigEndianWriter* writer,
const DnsResourceRecord& record) {
- if (record.rdata.data() != record.owned_rdata.data() ||
- record.rdata.size() != record.owned_rdata.size()) {
+ if (record.rdata != base::StringPiece(record.owned_rdata)) {
VLOG(1) << "record.rdata should point to record.owned_rdata.";
return false;
}
diff --git a/chromium/net/dns/dns_response.h b/chromium/net/dns/dns_response.h
index 75d69707345..b7fa79aadc5 100644
--- a/chromium/net/dns/dns_response.h
+++ b/chromium/net/dns/dns_response.h
@@ -44,8 +44,8 @@ struct NET_EXPORT_PRIVATE DnsResourceRecord {
DnsResourceRecord& operator=(const DnsResourceRecord& other);
DnsResourceRecord& operator=(DnsResourceRecord&& other);
- // A helper to set |owned_rdata| that also sets |rdata| to point to it.
- // See the definition of |owned_rdata| below.
+ // A helper to set |owned_rdata| that also sets |rdata| to point to it. The
+ // |value| must be non-empty. See the definition of |owned_rdata| below.
void SetOwnedRdata(std::string value);
// NAME (variable length) + TYPE (2 bytes) + CLASS (2 bytes) + TTL (4 bytes) +
@@ -208,9 +208,9 @@ class NET_EXPORT_PRIVATE DnsResponse {
bool WriteHeader(base::BigEndianWriter* writer,
const dns_protocol::Header& header);
bool WriteQuestion(base::BigEndianWriter* writer, const DnsQuery& query);
- bool WriteRecord(base::BigEndianWriter* wirter,
+ bool WriteRecord(base::BigEndianWriter* writer,
const DnsResourceRecord& record);
- bool WriteAnswer(base::BigEndianWriter* wirter,
+ bool WriteAnswer(base::BigEndianWriter* writer,
const DnsResourceRecord& answer,
const base::Optional<DnsQuery>& query);
diff --git a/chromium/net/dns/dns_test_util.cc b/chromium/net/dns/dns_test_util.cc
index 0497c197e4f..efcec21579d 100644
--- a/chromium/net/dns/dns_test_util.cc
+++ b/chromium/net/dns/dns_test_util.cc
@@ -166,77 +166,25 @@ DnsResourceRecord BuildServiceRecord(std::string name,
return record;
}
-void AppendU16LengthPrefixed(base::StringPiece in, std::string* out) {
- DCHECK(out);
- char buf[2];
- base::WriteBigEndian(buf, base::checked_cast<uint16_t>(in.size()));
- out->append(buf, 2);
- out->insert(out->end(), in.begin(), in.end());
-}
-
-// Builds an ESNI (TLS 1.3 Encrypted Server Name Indication, draft 4) record.
-//
-// An ESNI record associates an "ESNI key object" (an opaque string used
-// by the TLS library) with a collection of IP addresses.
-DnsResourceRecord BuildEsniRecord(std::string name, EsniContent esni_content) {
- DCHECK(!name.empty());
+
+
+DnsResourceRecord BuildIntegrityRecord(
+ std::string name,
+ const std::vector<uint8_t>& serialized_rdata) {
+ CHECK(!name.empty());
DnsResourceRecord record;
record.name = std::move(name);
- record.type = dns_protocol::kExperimentalTypeEsniDraft4;
+ record.type = dns_protocol::kExperimentalTypeIntegrity;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
- std::string rdata;
-
- // An esni_content struct corresponding to a single record
- // should have exactly one key object, along with zero or more addresses
- // corresponding to the key object.
- DCHECK_EQ(esni_content.keys().size(), 1u);
- rdata += *esni_content.keys().begin();
-
- if (esni_content.keys_for_addresses().empty()) {
- // No addresses: leave the "dns_extensions" field of the
- // ESNI record empty and conclude the rdata with the
- // "dns_extensions" field's length prefix (two zero bytes).
- rdata.push_back(0);
- rdata.push_back(0);
- record.SetOwnedRdata(std::move(rdata));
- return record;
- }
-
- // When the "dns_extensions" field of a draft-4 ESNI record is nonempty,
- // it stores an IP addresses: more specifically, it contains
- // - a 16-bit length prefix,
- // - the 16-bit "extension type" label of the single address_set
- // extension (the only type of extension) contained in the extensions object,
- // - a 16-bit length prefix for the address_set extension's contents, and
- // - the contents of the address_set extension, which is just a list
- // of type-prefixed network-order IP addresses.
- //
- // (See the draft spec for the complete definition.)
- std::string dns_extensions;
-
- std::string address_set;
- char buf[2];
- base::WriteBigEndian(buf, EsniRecordRdata::kAddressSetExtensionType);
- address_set.append(buf, 2);
-
- std::string serialized_addresses;
- for (const auto& kv : esni_content.keys_for_addresses()) {
- IPAddress address = kv.first;
-
- uint8_t address_type = address.IsIPv4() ? 4 : 6;
- serialized_addresses.push_back(address_type);
- serialized_addresses.insert(serialized_addresses.end(),
- address.bytes().begin(), address.bytes().end());
- }
+ std::string serialized_rdata_str(serialized_rdata.begin(),
+ serialized_rdata.end());
+ record.SetOwnedRdata(std::move(serialized_rdata_str));
- AppendU16LengthPrefixed(serialized_addresses, &address_set);
- AppendU16LengthPrefixed(address_set, &dns_extensions);
- rdata.append(dns_extensions);
+ CHECK_EQ(record.rdata.data(), record.owned_rdata.data());
- record.SetOwnedRdata(std::move(rdata));
return record;
}
@@ -257,28 +205,6 @@ DnsResourceRecord BuildTestAddressRecord(std::string name,
return record;
}
-const char kWellFormedEsniKeys[] = {
- 0xff, 0x3, 0x0, 0x1, 0xff, 0x0, 0x24, 0x0, 0x1d, 0x0, 0x20,
- 0xed, 0xed, 0xc8, 0x68, 0xc1, 0x71, 0xd6, 0x9e, 0xa9, 0xf0, 0xa2,
- 0xc9, 0xf5, 0xa9, 0xdc, 0xcf, 0xf9, 0xb8, 0xed, 0x15, 0x5c, 0xc4,
- 0x5a, 0xec, 0x6f, 0xb2, 0x86, 0x14, 0xb7, 0x71, 0x1b, 0x7c, 0x0,
- 0x2, 0x13, 0x1, 0x1, 0x4, 0x0, 0x0};
-const size_t kWellFormedEsniKeysSize = sizeof(kWellFormedEsniKeys);
-
-std::string GenerateWellFormedEsniKeys(base::StringPiece custom_data) {
- std::string well_formed_esni_keys(kWellFormedEsniKeys,
- kWellFormedEsniKeysSize);
- // Dead-reckon to the first byte after ESNIKeys.keys.group (0x001d).
- //
- // Overwrite at most 0x22 bytes: this is the length of the "keys" field
- // in the example struct (0x0024, specified as a 16-bit big-endian value
- // by the index-5 and index-6 bytes), minus 2 because the 0x0, 0x1d bytes
- // will not be overwritten.
- custom_data = custom_data.substr(0, 0x22);
- std::copy(custom_data.begin(), custom_data.end(),
- well_formed_esni_keys.begin() + 9);
- return well_formed_esni_keys;
-}
std::unique_ptr<DnsResponse> BuildTestDnsResponse(std::string name,
const IPAddress& ip) {
@@ -387,28 +313,23 @@ std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse(
std::vector<DnsResourceRecord>() /* additional_records */, query);
}
-std::unique_ptr<DnsResponse> BuildTestDnsEsniResponse(
+std::unique_ptr<DnsResponse> BuildTestDnsIntegrityResponse(
std::string hostname,
- std::vector<EsniContent> esni_records,
- std::string answer_name) {
- if (answer_name.empty())
- answer_name = hostname;
+ const std::vector<uint8_t>& serialized_rdata) {
+ CHECK(!hostname.empty());
- std::vector<DnsResourceRecord> answers;
- answers.reserve(esni_records.size());
- for (EsniContent& c : esni_records) {
- answers.push_back(BuildEsniRecord(answer_name, c));
- }
+ std::vector<DnsResourceRecord> answers{
+ BuildIntegrityRecord(hostname, serialized_rdata)};
std::string dns_name;
CHECK(DNSDomainFromDot(hostname, &dns_name));
base::Optional<DnsQuery> query(base::in_place, 0, dns_name,
- dns_protocol::kExperimentalTypeEsniDraft4);
+ dns_protocol::kExperimentalTypeIntegrity);
return std::make_unique<DnsResponse>(
0, false, std::move(answers),
- std::vector<DnsResourceRecord>() /* authority_records */,
- std::vector<DnsResourceRecord>() /* additional_records */, query);
+ std::vector<DnsResourceRecord>() /* authority_records */,
+ std::vector<DnsResourceRecord>() /* additional_records */, query);
}
MockDnsClientRule::Result::Result(ResultType type) : type(type) {}
@@ -560,15 +481,17 @@ class MockDnsTransactionFactory::MockTransaction
case MockDnsClientRule::NODOMAIN:
case MockDnsClientRule::FAIL:
std::move(callback_).Run(this, ERR_NAME_NOT_RESOLVED,
- result_.response.get());
+ result_.response.get(), base::nullopt);
break;
case MockDnsClientRule::EMPTY:
case MockDnsClientRule::OK:
case MockDnsClientRule::MALFORMED:
- std::move(callback_).Run(this, OK, result_.response.get());
+ std::move(callback_).Run(this, OK, result_.response.get(),
+ base::nullopt);
break;
case MockDnsClientRule::TIMEOUT:
- std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr);
+ std::move(callback_).Run(this, ERR_DNS_TIMED_OUT, nullptr,
+ base::nullopt);
break;
}
}
diff --git a/chromium/net/dns/dns_test_util.h b/chromium/net/dns/dns_test_util.h
index bc056cd8a80..40c619976a0 100644
--- a/chromium/net/dns/dns_test_util.h
+++ b/chromium/net/dns/dns_test_util.h
@@ -23,7 +23,6 @@
#include "net/dns/dns_response.h"
#include "net/dns/dns_transaction.h"
#include "net/dns/dns_util.h"
-#include "net/dns/esni_content.h"
#include "net/dns/public/dns_protocol.h"
#include "net/socket/socket_test_util.h"
@@ -184,22 +183,6 @@ static const char* const kT4IpAddresses[] = {"172.217.6.195"};
static const int kT4TTL = 0x0000012b;
static const unsigned kT4RecordCount = base::size(kT0IpAddresses);
-//--------------------------------------------------------------------
-// A well-formed ESNI (TLS 1.3 Encrypted Server Name Indication,
-// draft 4) keys object ("ESNIKeys" member of the ESNIRecord struct from
-// the spec).
-//
-// (This is cribbed from boringssl SSLTest.ESNIKeysDeserialize (CL 37704/13).)
-extern const char kWellFormedEsniKeys[];
-extern const size_t kWellFormedEsniKeysSize;
-
-// Returns a well-formed ESNI keys object identical to kWellFormedEsniKeys,
-// except that the first 0x22 bytes of |custom_data| are written over
-// fields of the keys object in a manner that leaves length prefixes
-// correct and enum members valid, and so that distinct values of
-// |custom_data| result in distinct returned keys.
-std::string GenerateWellFormedEsniKeys(base::StringPiece custom_data = "");
-
class AddressSorter;
class DnsClient;
class DnsSession;
@@ -241,10 +224,9 @@ std::unique_ptr<DnsResponse> BuildTestDnsServiceResponse(
std::vector<TestServiceRecord> service_records,
std::string answer_name = "");
-std::unique_ptr<DnsResponse> BuildTestDnsEsniResponse(
+std::unique_ptr<DnsResponse> BuildTestDnsIntegrityResponse(
std::string hostname,
- std::vector<EsniContent> esni_records,
- std::string answer_name = "");
+ const std::vector<uint8_t>& serialized_rdata);
struct MockDnsClientRule {
enum ResultType {
diff --git a/chromium/net/dns/dns_transaction.cc b/chromium/net/dns/dns_transaction.cc
index 8c58aeca906..60e97bf23f3 100644
--- a/chromium/net/dns/dns_transaction.cc
+++ b/chromium/net/dns/dns_transaction.cc
@@ -129,7 +129,7 @@ base::Value NetLogStartParams(const std::string& hostname, uint16_t qtype) {
// matches. Logging is done in the socket and in the outer DnsTransaction.
class DnsAttempt {
public:
- explicit DnsAttempt(int server_index)
+ explicit DnsAttempt(size_t server_index)
: result_(ERR_FAILED), server_index_(server_index) {}
virtual ~DnsAttempt() = default;
@@ -147,10 +147,9 @@ class DnsAttempt {
// Returns the net log bound to the source of the socket.
virtual const NetLogWithSource& GetSocketNetLog() const = 0;
- // Returns the index of the destination server within DnsConfig::nameservers.
- // If the server index is -1, indicates that no request was sent and that the
- // attempt was resolved synchronously with failure.
- int server_index() const { return server_index_; }
+ // Returns the index of the destination server within DnsConfig::nameservers
+ // (or DnsConfig::dns_over_https_servers for secure transactions).
+ size_t server_index() const { return server_index_; }
// Returns a Value representing the received response, along with a reference
// to the NetLog source source of the UDP socket used. The request must have
@@ -180,7 +179,7 @@ class DnsAttempt {
// Result of last operation.
int result_;
- const int server_index_;
+ const size_t server_index_;
DISALLOW_COPY_AND_ASSIGN(DnsAttempt);
};
@@ -570,7 +569,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
};
void ConstructDnsHTTPAttempt(DnsSession* session,
- int doh_server_index,
+ size_t doh_server_index,
std::string hostname,
uint16_t qtype,
const OptRecordRdata* opt_rdata,
@@ -589,9 +588,7 @@ void ConstructDnsHTTPAttempt(DnsSession* session,
query = attempts->at(0)->GetQuery()->CloneWithNewId(id);
}
- DCHECK_GE(doh_server_index, 0);
- DCHECK_LT(doh_server_index,
- (int)session->config().dns_over_https_servers.size());
+ DCHECK_LT(doh_server_index, session->config().dns_over_https_servers.size());
const DnsOverHttpsServerConfig& doh_config =
session->config().dns_over_https_servers[doh_server_index];
GURL gurl_without_parameters(
@@ -922,7 +919,7 @@ class DnsOverHttpsProbeRunner : public DnsProbeRunner {
base::WeakPtrFactory<ProbeStats> weak_factory{this};
};
- void ContinueProbe(int doh_server_index,
+ void ContinueProbe(size_t doh_server_index,
base::WeakPtr<ProbeStats> probe_stats,
bool network_change,
base::TimeTicks sequence_start_time) {
@@ -973,7 +970,7 @@ class DnsOverHttpsProbeRunner : public DnsProbeRunner {
}
void ProbeComplete(unsigned attempt_number,
- int doh_server_index,
+ size_t doh_server_index,
base::WeakPtr<ProbeStats> probe_stats,
bool network_change,
base::TimeTicks sequence_start_time,
@@ -1187,7 +1184,14 @@ class DnsTransactionImpl : public DnsTransaction,
net_log_.EndEventWithNetErrorCode(NetLogEventType::DNS_TRANSACTION,
result.rv);
- std::move(callback_).Run(this, result.rv, response);
+ base::Optional<std::string> doh_provider_id;
+ if (secure_ && result.attempt) {
+ size_t server_index = result.attempt->server_index();
+ doh_provider_id = GetDohProviderIdForHistogramFromDohConfig(
+ session_->config().dns_over_https_servers[server_index]);
+ }
+
+ std::move(callback_).Run(this, result.rv, response, doh_provider_id);
}
AttemptResult MakeAttempt() {
@@ -1406,7 +1410,7 @@ class DnsTransactionImpl : public DnsTransaction,
if (result.attempt) {
resolve_context_->RecordServerFailure(
result.attempt->server_index(), secure_ /* is_doh_server */,
- session_.get());
+ result.rv, session_.get());
}
if (MoreAttemptsAllowed()) {
result = MakeAttempt();
@@ -1424,14 +1428,20 @@ class DnsTransactionImpl : public DnsTransaction,
default:
// Server failure.
DCHECK(result.attempt);
+
+ // If attempt is not the most recent attempt, means this error is for
+ // an attempt that already timed out and was treated as complete but
+ // allowed to continue attempting in parallel with new attempts (see
+ // the ERR_DNS_TIMED_OUT case above). As the failure was already
+ // recorded at timeout time and is no longer being waited on, ignore
+ // this failure.
if (result.attempt != attempts_.back().get()) {
- // This attempt already timed out. Ignore it.
- DCHECK_GE(result.attempt->server_index(), 0);
- resolve_context_->RecordServerFailure(
- result.attempt->server_index(), secure_ /* is_doh_server */,
- session_.get());
return AttemptResult(ERR_IO_PENDING, nullptr);
}
+
+ resolve_context_->RecordServerFailure(result.attempt->server_index(),
+ secure_ /* is_doh_server */,
+ result.rv, session_.get());
if (!MoreAttemptsAllowed()) {
return result;
}
diff --git a/chromium/net/dns/dns_transaction.h b/chromium/net/dns/dns_transaction.h
index 7bb9501d09b..bc182ff7612 100644
--- a/chromium/net/dns/dns_transaction.h
+++ b/chromium/net/dns/dns_transaction.h
@@ -80,9 +80,14 @@ class NET_EXPORT_PRIVATE DnsTransactionFactory {
// Called with the response or NULL if no matching response was received.
// Note that the |GetDottedName()| of the response may be different than the
// original |hostname| as a result of suffix search.
+ //
+ // The |doh_provider_id| contains the provider ID for histograms of the last
+ // DoH server attempted. If the name is unavailable, or this is not a DoH
+ // transaction, |doh_provider_id| is nullopt.
typedef base::OnceCallback<void(DnsTransaction* transaction,
int neterror,
- const DnsResponse* response)>
+ const DnsResponse* response,
+ base::Optional<std::string> doh_provider_id)>
CallbackType;
DnsTransactionFactory();
diff --git a/chromium/net/dns/dns_transaction_unittest.cc b/chromium/net/dns/dns_transaction_unittest.cc
index e3196cfc21e..17f6bf62e72 100644
--- a/chromium/net/dns/dns_transaction_unittest.cc
+++ b/chromium/net/dns/dns_transaction_unittest.cc
@@ -28,6 +28,7 @@
#include "net/base/port_util.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/url_util.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_util.h"
#include "net/dns/dns_config.h"
#include "net/dns/dns_query.h"
@@ -324,7 +325,8 @@ class TransactionHelper {
void OnTransactionComplete(DnsTransaction* t,
int rv,
- const DnsResponse* response) {
+ const DnsResponse* response,
+ base::Optional<std::string> doh_provider_id) {
EXPECT_FALSE(completed_);
EXPECT_EQ(transaction_.get(), t);
@@ -1200,8 +1202,17 @@ TEST_F(DnsTransactionTestWithMockTime, ServerFallbackAndRotate) {
EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
size_t kOrder[] = {
- 0, 1, 2, 0, 1, // The first transaction.
- 1, 2, 0, // The second transaction starts from the next server.
+ // The first transaction.
+ 0,
+ 1,
+ 2,
+ 0,
+ 1,
+ // The second transaction starts from the next server, and 0 is skipped
+ // because it already has 2 consecutive failures.
+ 1,
+ 2,
+ 1,
};
CheckServerOrder(kOrder, base::size(kOrder));
}
@@ -2178,14 +2189,15 @@ class CookieCallback {
CookieCallback()
: result_(false), loop_to_quit_(std::make_unique<base::RunLoop>()) {}
- void SetCookieCallback(CanonicalCookie::CookieInclusionStatus result) {
+ void SetCookieCallback(CookieInclusionStatus result) {
result_ = result.IsInclude();
loop_to_quit_->Quit();
}
- void GetCookieListCallback(const net::CookieStatusList& list,
- const net::CookieStatusList& excluded_cookies) {
- list_ = cookie_util::StripStatuses(list);
+ void GetCookieListCallback(
+ const net::CookieAccessResultList& list,
+ const net::CookieAccessResultList& excluded_cookies) {
+ list_ = cookie_util::StripAccessResults(list);
loop_to_quit_->Quit();
}
@@ -2384,6 +2396,63 @@ TEST_F(DnsTransactionTest, HttpsPostLookupWithLog) {
EXPECT_EQ(observer.dict_count(), 3);
}
+// Test for when a slow DoH response is delayed until after the initial timeout
+// and no more attempts are configured.
+TEST_F(DnsTransactionTestWithMockTime, SlowHttpsResponse_SingleAttempt) {
+ config_.doh_attempts = 1;
+ ConfigureDohServers(false /* use_post */);
+
+ AddQueryAndTimeout(kT0HostName, kT0Qtype,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+
+ TransactionHelper helper(kT0HostName, kT0Qtype, true /* secure */,
+ ERR_DNS_TIMED_OUT, resolve_context_.get());
+ ASSERT_FALSE(helper.Run(transaction_factory_.get()));
+
+ // Only one attempt configured, so expect immediate failure after timeout
+ // period.
+ FastForwardBy(resolve_context_->NextDohTimeout(0 /* doh_server_index */,
+ session_.get()));
+ EXPECT_TRUE(helper.has_completed());
+}
+
+// Test for when a slow DoH response is delayed until after the initial timeout
+// but a retry is configured.
+TEST_F(DnsTransactionTestWithMockTime, SlowHttpsResponse_TwoAttempts) {
+ config_.doh_attempts = 2;
+ ConfigureDohServers(false /* use_post */);
+
+ // Simulate a slow response by using an ERR_IO_PENDING read error to delay
+ // until SequencedSocketData::Resume() is called.
+ auto data = std::make_unique<DnsSocketData>(
+ 1 /* id */, kT1HostName, kT1Qtype, ASYNC, Transport::HTTPS,
+ nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ data->AddReadError(ERR_IO_PENDING, ASYNC);
+ data->AddResponseData(kT1ResponseDatagram, base::size(kT1ResponseDatagram),
+ ASYNC);
+ SequencedSocketData* sequenced_socket_data = data->GetProvider();
+ AddSocketData(std::move(data));
+
+ TransactionHelper helper(kT1HostName, kT1Qtype, true /* secure */,
+ kT1RecordCount, resolve_context_.get());
+ ASSERT_FALSE(helper.Run(transaction_factory_.get()));
+ ASSERT_TRUE(sequenced_socket_data->IsPaused());
+
+ // Another attempt configured, so transaction should not fail after initial
+ // timeout. Setup the second attempt to never receive a response.
+ AddQueryAndTimeout(kT1HostName, kT1Qtype,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ FastForwardBy(resolve_context_->NextDohTimeout(0 /* doh_server_index */,
+ session_.get()));
+ EXPECT_FALSE(helper.has_completed());
+
+ // Expect first attempt to continue in parallel with retry, so expect the
+ // transaction to complete when the first query is allowed to resume.
+ sequenced_socket_data->Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(helper.has_completed());
+}
+
TEST_F(DnsTransactionTest, TCPLookup) {
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
@@ -3100,8 +3169,9 @@ TEST_F(DnsTransactionTestWithMockTime, RestartFinishedProbe) {
// Mark server unavailabe and restart runner.
for (int i = 0; i < ResolveContext::kAutomaticModeFailureLimit; ++i) {
- resolve_context_->RecordServerFailure(
- 0u /* server_index */, true /* is_doh_server */, session_.get());
+ resolve_context_->RecordServerFailure(0u /* server_index */,
+ true /* is_doh_server */, ERR_FAILED,
+ session_.get());
}
ASSERT_FALSE(resolve_context_->GetDohServerAvailability(
0u /* doh_server_index */, session_.get()));
@@ -3149,8 +3219,9 @@ TEST_F(DnsTransactionTestWithMockTime, FastProbeRestart) {
// becoming unavailable and might as well replecate real behavior for the
// test.
for (int i = 0; i < ResolveContext::kAutomaticModeFailureLimit; ++i) {
- resolve_context_->RecordServerFailure(
- 0u /* server_index */, true /* is_doh_server */, session_.get());
+ resolve_context_->RecordServerFailure(0u /* server_index */,
+ true /* is_doh_server */, ERR_FAILED,
+ session_.get());
}
ASSERT_FALSE(resolve_context_->GetDohServerAvailability(
0u /* doh_server_index */, session_.get()));
diff --git a/chromium/net/dns/dns_util.cc b/chromium/net/dns/dns_util.cc
index 49bfdfc8323..9ad7d53637c 100644
--- a/chromium/net/dns/dns_util.cc
+++ b/chromium/net/dns/dns_util.cc
@@ -21,7 +21,7 @@
#include "net/base/address_list.h"
#include "net/base/url_util.h"
#include "net/dns/public/dns_protocol.h"
-#include "net/dns/public/doh_provider_list.h"
+#include "net/dns/public/doh_provider_entry.h"
#include "net/dns/public/util.h"
#include "net/third_party/uri_template/uri_template.h"
#include "url/url_canon.h"
@@ -113,21 +113,21 @@ bool DNSDomainFromDot(const base::StringPiece& dotted,
return true;
}
-std::vector<const DohProviderEntry*> GetDohProviderEntriesFromNameservers(
+DohProviderEntry::List GetDohProviderEntriesFromNameservers(
const std::vector<IPEndPoint>& dns_servers,
const std::vector<std::string>& excluded_providers) {
- const std::vector<DohProviderEntry>& providers = GetDohProviderList();
- std::vector<const DohProviderEntry*> entries;
+ const DohProviderEntry::List& providers = DohProviderEntry::GetList();
+ DohProviderEntry::List entries;
for (const auto& server : dns_servers) {
- for (const auto& entry : providers) {
- if (base::Contains(excluded_providers, entry.provider))
+ for (const auto* entry : providers) {
+ if (base::Contains(excluded_providers, entry->provider))
continue;
// DoH servers should only be added once.
- if (base::Contains(entry.ip_addresses, server.address()) &&
- !base::Contains(entries, &entry)) {
- entries.push_back(&entry);
+ if (base::Contains(entry->ip_addresses, server.address()) &&
+ !base::Contains(entries, entry)) {
+ entries.push_back(entry);
}
}
}
@@ -289,8 +289,8 @@ uint16_t DnsQueryTypeToQtype(DnsQueryType dns_query_type) {
return dns_protocol::kTypePTR;
case DnsQueryType::SRV:
return dns_protocol::kTypeSRV;
- case DnsQueryType::ESNI:
- return dns_protocol::kExperimentalTypeEsniDraft4;
+ case DnsQueryType::INTEGRITY:
+ return dns_protocol::kExperimentalTypeIntegrity;
}
}
@@ -311,23 +311,21 @@ DnsQueryType AddressFamilyToDnsQueryType(AddressFamily address_family) {
std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromDotHostname(
const std::string& dot_server,
const std::vector<std::string>& excluded_providers) {
- const std::vector<DohProviderEntry>& entries = GetDohProviderList();
std::vector<DnsOverHttpsServerConfig> doh_servers;
if (dot_server.empty())
return doh_servers;
- for (const auto& entry : entries) {
- if (base::Contains(excluded_providers, entry.provider))
+ for (const auto* entry : DohProviderEntry::GetList()) {
+ if (base::Contains(excluded_providers, entry->provider))
continue;
- if (base::Contains(entry.dns_over_tls_hostnames, dot_server)) {
+ if (base::Contains(entry->dns_over_tls_hostnames, dot_server)) {
std::string server_method;
- CHECK(dns_util::IsValidDohTemplate(entry.dns_over_https_template,
+ CHECK(dns_util::IsValidDohTemplate(entry->dns_over_https_template,
&server_method));
- doh_servers.push_back(DnsOverHttpsServerConfig(
- entry.dns_over_https_template, server_method == "POST"));
- break;
+ doh_servers.emplace_back(entry->dns_over_https_template,
+ server_method == "POST");
}
}
return doh_servers;
@@ -336,38 +334,35 @@ std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromDotHostname(
std::vector<DnsOverHttpsServerConfig> GetDohUpgradeServersFromNameservers(
const std::vector<IPEndPoint>& dns_servers,
const std::vector<std::string>& excluded_providers) {
- std::vector<const DohProviderEntry*> entries =
+ const auto entries =
GetDohProviderEntriesFromNameservers(dns_servers, excluded_providers);
std::vector<DnsOverHttpsServerConfig> doh_servers;
- std::string server_method;
- for (const auto* entry : entries) {
- CHECK(dns_util::IsValidDohTemplate(entry->dns_over_https_template,
- &server_method));
- doh_servers.push_back(DnsOverHttpsServerConfig(
- entry->dns_over_https_template, server_method == "POST"));
- }
+ doh_servers.reserve(entries.size());
+ std::transform(entries.begin(), entries.end(),
+ std::back_inserter(doh_servers), [](const auto* entry) {
+ std::string server_method;
+ CHECK(dns_util::IsValidDohTemplate(
+ entry->dns_over_https_template, &server_method));
+ return DnsOverHttpsServerConfig(
+ entry->dns_over_https_template, server_method == "POST");
+ });
return doh_servers;
}
std::string GetDohProviderIdForHistogramFromDohConfig(
const DnsOverHttpsServerConfig& doh_server) {
- const std::vector<DohProviderEntry>& entries = GetDohProviderList();
- for (const auto& entry : entries) {
- if (doh_server.server_template == entry.dns_over_https_template) {
- return entry.provider;
- }
- }
- return "Other";
+ const auto& entries = DohProviderEntry::GetList();
+ const auto it =
+ std::find_if(entries.begin(), entries.end(), [&](const auto* entry) {
+ return entry->dns_over_https_template == doh_server.server_template;
+ });
+ return it != entries.end() ? (*it)->provider : "Other";
}
std::string GetDohProviderIdForHistogramFromNameserver(
const IPEndPoint& nameserver) {
- std::vector<const DohProviderEntry*> entries =
- GetDohProviderEntriesFromNameservers({nameserver}, {});
- if (entries.size() == 0)
- return "Other";
- else
- return entries[0]->provider;
+ const auto entries = GetDohProviderEntriesFromNameservers({nameserver}, {});
+ return entries.empty() ? "Other" : entries[0]->provider;
}
std::string SecureDnsModeToString(
diff --git a/chromium/net/dns/dns_util_unittest.cc b/chromium/net/dns/dns_util_unittest.cc
index f07c342e442..39a89880b4f 100644
--- a/chromium/net/dns/dns_util_unittest.cc
+++ b/chromium/net/dns/dns_util_unittest.cc
@@ -6,6 +6,7 @@
#include "base/stl_util.h"
#include "net/dns/public/dns_protocol.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -183,20 +184,24 @@ TEST_F(DNSUtilTest, GetDohUpgradeServersFromNameservers) {
doh_servers = GetDohUpgradeServersFromNameservers(nameservers,
std::vector<std::string>());
- EXPECT_EQ(3u, doh_servers.size());
- EXPECT_EQ("https://chrome.cloudflare-dns.com/dns-query",
- doh_servers[0].server_template);
- EXPECT_EQ("https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
- doh_servers[1].server_template);
- EXPECT_EQ("https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
- doh_servers[2].server_template);
+ EXPECT_THAT(
+ doh_servers,
+ testing::ElementsAre(
+ DnsOverHttpsServerConfig(
+ "https://chrome.cloudflare-dns.com/dns-query", true),
+ DnsOverHttpsServerConfig(
+ "https://doh.cleanbrowsing.org/doh/family-filter{?dns}", false),
+ DnsOverHttpsServerConfig(
+ "https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
+ false)));
doh_servers = GetDohUpgradeServersFromNameservers(
nameservers, std::vector<std::string>(
{"CleanBrowsingSecure", "Cloudflare", "Unexpected"}));
- EXPECT_EQ(1u, doh_servers.size());
- EXPECT_EQ("https://doh.cleanbrowsing.org/doh/family-filter{?dns}",
- doh_servers[0].server_template);
+ EXPECT_THAT(
+ doh_servers,
+ testing::ElementsAre(DnsOverHttpsServerConfig(
+ "https://doh.cleanbrowsing.org/doh/family-filter{?dns}", false)));
}
TEST_F(DNSUtilTest, GetDohProviderIdForHistogramFromDohConfig) {
diff --git a/chromium/net/dns/esni_content.cc b/chromium/net/dns/esni_content.cc
deleted file mode 100644
index 014d492942b..00000000000
--- a/chromium/net/dns/esni_content.cc
+++ /dev/null
@@ -1,63 +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.
-
-#include "net/dns/esni_content.h"
-
-namespace net {
-
-EsniContent::EsniContent() = default;
-EsniContent::EsniContent(const EsniContent& other) {
- MergeFrom(other);
-}
-EsniContent::EsniContent(EsniContent&& other) = default;
-EsniContent& EsniContent::operator=(const EsniContent& other) {
- MergeFrom(other);
- return *this;
-}
-EsniContent& EsniContent::operator=(EsniContent&& other) = default;
-EsniContent::~EsniContent() = default;
-
-bool operator==(const EsniContent& c1, const EsniContent& c2) {
- return c1.keys() == c2.keys() &&
- c1.keys_for_addresses() == c2.keys_for_addresses();
-}
-
-const std::set<std::string, EsniContent::StringPieceComparator>&
-EsniContent::keys() const {
- return keys_;
-}
-
-const std::map<IPAddress, std::set<base::StringPiece>>&
-EsniContent::keys_for_addresses() const {
- return keys_for_addresses_;
-}
-
-void EsniContent::AddKey(base::StringPiece key) {
- if (keys_.find(key) == keys_.end())
- keys_.insert(std::string(key));
-}
-
-void EsniContent::AddKeyForAddress(const IPAddress& address,
- base::StringPiece key) {
- auto key_it = keys_.find(key);
- if (key_it == keys_.end()) {
- bool key_was_added;
- std::tie(key_it, key_was_added) = keys_.insert(std::string(key));
- DCHECK(key_was_added);
- }
- keys_for_addresses_[address].insert(base::StringPiece(*key_it));
-}
-
-void EsniContent::MergeFrom(const EsniContent& other) {
- for (const auto& kv : other.keys_for_addresses()) {
- const IPAddress& address = kv.first;
- const auto& keys_for_address = kv.second;
- for (base::StringPiece key : keys_for_address)
- AddKeyForAddress(address, key);
- }
- for (const std::string& key : other.keys())
- AddKey(key);
-}
-
-} // namespace net
diff --git a/chromium/net/dns/esni_content.h b/chromium/net/dns/esni_content.h
deleted file mode 100644
index 8c6a8e0d0cc..00000000000
--- a/chromium/net/dns/esni_content.h
+++ /dev/null
@@ -1,84 +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 NET_DNS_ESNI_CONTENT_H_
-#define NET_DNS_ESNI_CONTENT_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "base/strings/string_piece.h"
-#include "net/base/ip_address.h"
-#include "net/base/net_export.h"
-
-namespace net {
-
-// An EsniContent struct represents an aggregation of the
-// content of several ESNI (TLS 1.3 Encrypted Server Name Indication,
-// draft 4) resource records.
-//
-// This aggregation contains:
-// (1) The ESNI key objects from each of the ESNI records, and
-// (2) A collection of IP addresses, each of which is associated
-// with one or more of the key objects. (Each key will likely also
-// be associated with several destination addresses.)
-class NET_EXPORT EsniContent {
- public:
- EsniContent();
- EsniContent(const EsniContent& other);
- EsniContent(EsniContent&& other);
- EsniContent& operator=(const EsniContent& other);
- EsniContent& operator=(EsniContent&& other);
- ~EsniContent();
-
- // Key objects (which might be up to ~50K in length) are stored
- // in a collection of std::string; use transparent comparison
- // to allow checking whether a given base::StringPiece is in
- // the collection without making copies.
- struct StringPieceComparator {
- using is_transparent = int;
-
- bool operator()(const base::StringPiece lhs,
- const base::StringPiece rhs) const {
- return lhs < rhs;
- }
- };
-
- const std::set<std::string, StringPieceComparator>& keys() const;
- const std::map<IPAddress, std::set<base::StringPiece>>& keys_for_addresses()
- const;
-
- // Adds |key| (if it is not already stored) without associating it
- // with any particular addresss; if this addition is performed, it
- // copies the underlying string.
- void AddKey(base::StringPiece key);
-
- // Associates a key with an address, copying the underlying string to
- // the internal collection of keys if it is not already stored.
- void AddKeyForAddress(const IPAddress& address, base::StringPiece key);
-
- // Merges the contents of |other|:
- // 1. unions the collection of stored keys with |other.keys()| and
- // 2. unions the stored address-key associations with
- // |other.keys_for_addresses()|.
- void MergeFrom(const EsniContent& other);
-
- private:
- // In order to keep the StringPieces in |keys_for_addresses_| valid,
- // |keys_| must be of a collection type guaranteeing stable pointers.
- std::set<std::string, StringPieceComparator> keys_;
-
- std::map<IPAddress, std::set<base::StringPiece>> keys_for_addresses_;
-};
-
-// Two EsniContent structs are equal if they have the same set of keys, the
-// same set of IP addresses, and the same subset of the keys corresponding to
-// each IP address.
-NET_EXPORT_PRIVATE
-bool operator==(const EsniContent& c1, const EsniContent& c2);
-
-} // namespace net
-
-#endif // NET_DNS_ESNI_CONTENT_H_
diff --git a/chromium/net/dns/esni_content_unittest.cc b/chromium/net/dns/esni_content_unittest.cc
deleted file mode 100644
index 50bc5d81dca..00000000000
--- a/chromium/net/dns/esni_content_unittest.cc
+++ /dev/null
@@ -1,170 +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.
-
-#include "net/dns/esni_content.h"
-
-#include "base/strings/string_number_conversions.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace {
-
-IPAddress MakeIPAddress() {
- // Introduce some (deterministic) variation in the IP addresses
- // generated.
- static uint8_t next_octet = 0;
- next_octet += 4;
-
- return IPAddress(next_octet, next_octet + 1, next_octet + 2, next_octet + 3);
-}
-
-// Make sure we can add keys.
-TEST(EsniContentTest, AddKey) {
- EsniContent c1;
- c1.AddKey("a");
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
- c1.AddKey("a");
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
- c1.AddKey("b");
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a", "b"));
-}
-
-// Make sure we can add key-address pairs.
-TEST(EsniContentTest, AddKeyForAddress) {
- EsniContent c1;
- auto address = MakeIPAddress();
- c1.AddKeyForAddress(address, "a");
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
- EXPECT_THAT(c1.keys_for_addresses(),
- ::testing::UnorderedElementsAre(::testing::Pair(
- address, ::testing::UnorderedElementsAre("a"))));
-}
-
-TEST(EsniContentTest, AssociateAddressWithExistingKey) {
- EsniContent c1;
- auto address = MakeIPAddress();
- c1.AddKey("a");
- c1.AddKeyForAddress(address, "a");
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
- EXPECT_THAT(c1.keys_for_addresses(),
- ::testing::UnorderedElementsAre(::testing::Pair(
- address, ::testing::UnorderedElementsAre("a"))));
-}
-
-// Merging to an empty EsniContent should make the result equal the source of
-// the merge.
-TEST(EsniContentTest, MergeToEmpty) {
- EsniContent c1;
- c1.AddKey("c");
- IPAddress address = MakeIPAddress();
-
- c1.AddKeyForAddress(address, "a");
- c1.AddKeyForAddress(address, "b");
- EsniContent empty;
- empty.MergeFrom(c1);
- EXPECT_EQ(c1, empty);
-}
-
-TEST(EsniContentTest, MergeFromEmptyNoOp) {
- EsniContent c1, c2;
- c1.AddKey("a");
- c2.AddKey("a");
- EsniContent empty;
- c1.MergeFrom(empty);
- EXPECT_EQ(c1, c2);
-}
-
-// Test that merging multiple keys corresponding to a single address works.
-TEST(EsniContentTest, MergeKeysForSingleHost) {
- EsniContent c1, c2;
- IPAddress address = MakeIPAddress();
-
- c1.AddKeyForAddress(address, "a");
- c1.AddKeyForAddress(address, "b");
- c2.AddKeyForAddress(address, "b");
- c2.AddKeyForAddress(address, "c");
- c1.MergeFrom(c2);
-
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a", "b", "c"));
- EXPECT_THAT(c1.keys_for_addresses(),
- ::testing::UnorderedElementsAre(::testing::Pair(
- address, ::testing::UnorderedElementsAre("a", "b", "c"))));
-}
-
-// Test that merging multiple addresss corresponding to a single key works.
-TEST(EsniContentTest, MergeHostsForSingleKey) {
- EsniContent c1, c2;
- IPAddress address = MakeIPAddress();
- IPAddress second_address = MakeIPAddress();
- c1.AddKeyForAddress(address, "a");
- c2.AddKeyForAddress(second_address, "a");
- c1.MergeFrom(c2);
-
- EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
- EXPECT_THAT(
- c1.keys_for_addresses(),
- ::testing::UnorderedElementsAre(
- ::testing::Pair(address, ::testing::UnorderedElementsAre("a")),
- ::testing::Pair(second_address,
- ::testing::UnorderedElementsAre("a"))));
-}
-
-// Test merging some more complex instances of the class.
-TEST(EsniContentTest, MergeSeveralHostsAndKeys) {
- EsniContent c1, c2, expected;
- for (int i = 0; i < 50; ++i) {
- IPAddress address = MakeIPAddress();
- std::string key = base::NumberToString(i);
- switch (i % 3) {
- case 0:
- c1.AddKey(key);
- expected.AddKey(key);
- break;
- case 1:
- c2.AddKey(key);
- expected.AddKey(key);
- break;
- }
- // Associate each address with a subset of the keys seen so far
- {
- int j = 0;
- for (auto key : c1.keys()) {
- if (j % 2) {
- c1.AddKeyForAddress(address, key);
- expected.AddKeyForAddress(address, key);
- }
- ++j;
- }
- }
- {
- int j = 0;
- for (auto key : c2.keys()) {
- if (j % 3 == 1) {
- c2.AddKeyForAddress(address, key);
- expected.AddKeyForAddress(address, key);
- }
- ++j;
- }
- }
- }
- {
- EsniContent merge_dest = c1;
- EsniContent merge_src = c2;
- merge_dest.MergeFrom(merge_src);
- EXPECT_EQ(merge_dest, expected);
- }
- {
- EsniContent merge_dest = c2;
- EsniContent merge_src = c1;
- merge_dest.MergeFrom(merge_src);
- EXPECT_EQ(merge_dest, expected);
- }
-}
-
-} // namespace
-
-} // namespace net
diff --git a/chromium/net/dns/host_cache.cc b/chromium/net/dns/host_cache.cc
index 647d44ae427..70805898089 100644
--- a/chromium/net/dns/host_cache.cc
+++ b/chromium/net/dns/host_cache.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
+#include "net/base/address_family.h"
#include "net/base/ip_endpoint.h"
#include "net/base/trace_constants.h"
#include "net/dns/host_resolver.h"
@@ -47,7 +48,6 @@ const char kAddressesKey[] = "addresses";
const char kTextRecordsKey[] = "text_records";
const char kHostnameResultsKey[] = "hostname_results";
const char kHostPortsKey[] = "host_ports";
-const char kEsniDataKey[] = "esni_data";
bool AddressListFromListValue(const base::ListValue* value,
base::Optional<AddressList>* out_list) {
@@ -69,67 +69,6 @@ bool AddressListFromListValue(const base::ListValue* value,
return true;
}
-// Serializes the cache's ESNI content as
-// {
-// key 0: [addresses for key 0],
-// ...,
-// key N: [address for key N]
-// }
-base::Value EsniContentToValue(const EsniContent& content) {
- base::Value addresses_for_keys_value(base::Value::Type::DICTIONARY);
-
- for (const auto& key : content.keys()) {
- addresses_for_keys_value.SetKey(key, base::Value(base::Value::Type::LIST));
- }
-
- for (const auto& kv : content.keys_for_addresses()) {
- const IPAddress& address = kv.first;
- const auto& keys_for_address = kv.second;
- for (base::StringPiece key : keys_for_address) {
- base::Value* addresses_for_key = addresses_for_keys_value.FindKey(key);
- DCHECK(addresses_for_key);
- addresses_for_key->Append(address.ToString());
- }
- }
-
- return addresses_for_keys_value;
-}
-
-bool EsniContentFromValue(const base::Value& esni_content_value,
- base::Optional<EsniContent>* out_esni_content) {
- EsniContent content_for_cache;
-
- // The esni_data cache member is encoded as a
- // { key: list of associated IP addresses } dictionary.
- if (!esni_content_value.is_dict())
- return false;
-
- for (const auto& kv : esni_content_value.DictItems()) {
- const std::string& key = kv.first;
- const base::Value& serialized_addresses = kv.second;
- if (!serialized_addresses.is_list())
- return false;
- if (serialized_addresses.GetList().empty()) {
- content_for_cache.AddKey(key);
- } else {
- for (const base::Value& serialized_address_value :
- serialized_addresses.GetList()) {
- if (!serialized_address_value.is_string())
- return false;
- const std::string& serialized_address =
- serialized_address_value.GetString();
- IPAddress address;
- if (!address.AssignFromIPLiteral(serialized_address))
- return false;
- content_for_cache.AddKeyForAddress(address, key);
- }
- }
- }
-
- *out_esni_content = std::move(content_for_cache);
- return true;
-}
-
template <typename T>
void MergeLists(base::Optional<T>* target, const base::Optional<T>& source) {
if (target->has_value() && source) {
@@ -220,11 +159,7 @@ HostCache::Entry HostCache::Entry::MergeEntries(Entry front, Entry back) {
front.MergeAddressesFrom(back);
MergeLists(&front.text_records_, back.text_records());
MergeLists(&front.hostnames_, back.hostnames());
- if (back.esni_data_ && !front.esni_data_) {
- front.esni_data_ = std::move(back.esni_data_);
- } else if (front.esni_data_ && back.esni_data_) {
- front.esni_data_->MergeFrom(back.esni_data_.value());
- }
+ MergeLists(&front.integrity_data_, back.integrity_data());
// Use canonical name from |back| iff empty in |front|.
if (front.addresses() && front.addresses().value().canonical_name().empty() &&
@@ -298,7 +233,7 @@ HostCache::Entry::Entry(const HostCache::Entry& entry,
addresses_(entry.addresses()),
text_records_(entry.text_records()),
hostnames_(entry.hostnames()),
- esni_data_(entry.esni_data()),
+ integrity_data_(entry.integrity_data()),
source_(entry.source()),
ttl_(entry.ttl()),
expires_(now + ttl),
@@ -308,7 +243,7 @@ HostCache::Entry::Entry(int error,
const base::Optional<AddressList>& addresses,
base::Optional<std::vector<std::string>>&& text_records,
base::Optional<std::vector<HostPortPair>>&& hostnames,
- base::Optional<EsniContent>&& esni_data,
+ base::Optional<std::vector<bool>>&& integrity_data,
Source source,
base::TimeTicks expires,
int network_changes)
@@ -316,11 +251,15 @@ HostCache::Entry::Entry(int error,
addresses_(addresses),
text_records_(std::move(text_records)),
hostnames_(std::move(hostnames)),
- esni_data_(std::move(esni_data)),
+ integrity_data_(std::move(integrity_data)),
source_(source),
expires_(expires),
network_changes_(network_changes) {}
+void HostCache::Entry::PrepareForCacheInsertion() {
+ integrity_data_.reset();
+}
+
bool HostCache::Entry::IsStale(base::TimeTicks now, int network_changes) const {
EntryStaleness stale;
stale.expired_by = now - expires_;
@@ -355,28 +294,11 @@ void HostCache::Entry::MergeAddressesFrom(const HostCache::Entry& source) {
addresses_->Deduplicate();
- auto has_keys = [&](const IPEndPoint& e) {
- return (esni_data() &&
- esni_data()->keys_for_addresses().count(e.address())) ||
- (source.esni_data() &&
- source.esni_data()->keys_for_addresses().count(e.address()));
- };
-
std::stable_sort(addresses_->begin(), addresses_->end(),
- [&](const IPEndPoint& lhs, const IPEndPoint& rhs) {
- // Prefer an address with ESNI keys to one without;
- // break ties by address family.
-
- // Store one lookup's result to avoid repeating the lookup.
- bool lhs_has_keys = has_keys(lhs);
- if (lhs_has_keys != has_keys(rhs))
- return lhs_has_keys;
-
- if ((lhs.GetFamily() == ADDRESS_FAMILY_IPV6) !=
- (rhs.GetFamily() == ADDRESS_FAMILY_IPV6))
- return (lhs.GetFamily() == ADDRESS_FAMILY_IPV6);
-
- return false;
+ [](const IPEndPoint& lhs, const IPEndPoint& rhs) {
+ // Return true iff |lhs < rhs|.
+ return lhs.GetFamily() == ADDRESS_FAMILY_IPV6 &&
+ rhs.GetFamily() == ADDRESS_FAMILY_IPV4;
});
}
@@ -433,10 +355,6 @@ base::DictionaryValue HostCache::Entry::GetAsValue(
entry_dict.SetKey(kHostnameResultsKey, std::move(hostnames_value));
entry_dict.SetKey(kHostPortsKey, std::move(host_ports_value));
}
-
- if (esni_data()) {
- entry_dict.SetKey(kEsniDataKey, EsniContentToValue(*esni_data()));
- }
}
return entry_dict;
@@ -632,7 +550,9 @@ void HostCache::Set(const Key& key,
EvictOneEntry(now);
}
- AddEntry(key, Entry(entry, now, ttl, network_changes_));
+ Entry entry_for_cache(entry, now, ttl, network_changes_);
+ entry_for_cache.PrepareForCacheInsertion();
+ AddEntry(key, std::move(entry_for_cache));
if (delegate_ && result_changed)
delegate_->ScheduleWrite();
@@ -801,7 +721,6 @@ bool HostCache::RestoreFromListValue(const base::ListValue& old_cache) {
const base::ListValue* text_records_value = nullptr;
const base::ListValue* hostname_records_value = nullptr;
const base::ListValue* host_ports_value = nullptr;
- const base::Value* esni_content_value = nullptr;
if (!entry_dict->GetInteger(kErrorKey, &error)) {
entry_dict->GetList(kAddressesKey, &addresses_value);
entry_dict->GetList(kTextRecordsKey, &text_records_value);
@@ -810,8 +729,6 @@ bool HostCache::RestoreFromListValue(const base::ListValue& old_cache) {
entry_dict->GetList(kHostPortsKey, &host_ports_value)) {
return false;
}
-
- entry_dict->Get(kEsniDataKey, &esni_content_value);
}
int64_t time_internal;
@@ -860,15 +777,12 @@ bool HostCache::RestoreFromListValue(const base::ListValue& old_cache) {
}
}
- base::Optional<EsniContent> esni_content;
- if (esni_content_value &&
- !EsniContentFromValue(*esni_content_value, &esni_content)) {
- return false;
- }
+ // We do not intend to serialize INTEGRITY records with the host cache.
+ base::Optional<std::vector<bool>> integrity_data;
// Assume an empty address list if we have an address type and no results.
if (IsAddressType(dns_query_type) && !address_list && !text_records &&
- !hostname_records && !esni_content) {
+ !hostname_records) {
address_list.emplace();
}
@@ -882,9 +796,9 @@ bool HostCache::RestoreFromListValue(const base::ListValue& old_cache) {
auto found = entries_.find(key);
if (found == entries_.end()) {
AddEntry(key, Entry(error, address_list, std::move(text_records),
- std::move(hostname_records), std::move(esni_content),
- Entry::SOURCE_UNKNOWN, expiration_time,
- network_changes_ - 1));
+ std::move(hostname_records),
+ std::move(integrity_data), Entry::SOURCE_UNKNOWN,
+ expiration_time, network_changes_ - 1));
restore_size_++;
}
}
diff --git a/chromium/net/dns/host_cache.h b/chromium/net/dns/host_cache.h
index 11f92932edd..a74f7dc5ba9 100644
--- a/chromium/net/dns/host_cache.h
+++ b/chromium/net/dns/host_cache.h
@@ -15,8 +15,8 @@
#include <utility>
#include <vector>
+#include "base/check.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/numerics/clamped_math.h"
#include "base/optional.h"
@@ -31,7 +31,6 @@
#include "net/base/net_export.h"
#include "net/base/network_isolation_key.h"
#include "net/dns/dns_util.h"
-#include "net/dns/esni_content.h"
#include "net/dns/host_resolver_source.h"
#include "net/dns/public/dns_query_type.h"
#include "net/log/net_log_capture_mode.h"
@@ -161,10 +160,13 @@ class NET_EXPORT HostCache {
void set_hostnames(base::Optional<std::vector<HostPortPair>> hostnames) {
hostnames_ = std::move(hostnames);
}
- const base::Optional<EsniContent>& esni_data() const { return esni_data_; }
- void set_esni_data(base::Optional<EsniContent> esni_data) {
- esni_data_ = std::move(esni_data);
+ const base::Optional<std::vector<bool>>& integrity_data() const {
+ return integrity_data_;
}
+ void set_integrity_data(base::Optional<std::vector<bool>> integrity_data) {
+ integrity_data_ = std::move(integrity_data);
+ }
+
Source source() const { return source_; }
bool has_ttl() const { return ttl_ >= base::TimeDelta(); }
base::TimeDelta ttl() const { return ttl_; }
@@ -176,16 +178,14 @@ class NET_EXPORT HostCache {
// Public for the net-internals UI.
int network_changes() const { return network_changes_; }
- // Merge |front| and |back|, representing results from multiple
- // transactions for the same overall host resolution query.
+ // Merge |front| and |back|, representing results from multiple transactions
+ // for the same overall host resolution query.
//
- // - When merging result hostname and text record lists, result
- // elements from |front| will be merged in front of elements from |back|.
- // - Merging address lists deduplicates addresses and sorts them in a stable
- // manner by (breaking ties by continuing down the list):
- // 1. Addresses with associated ESNI keys precede addresses without
- // 2. IPv6 addresses precede IPv4 addresses
- // - Fields that cannot be merged take precedence from |front|.
+ // Merges lists, placing elements from |front| before elements from |back|.
+ // Further, dedupes address lists and moves IPv6 addresses before IPv4
+ // addresses (maintaining stable order otherwise).
+ //
+ // Fields that cannot be merged take precedence from |front|.
static Entry MergeEntries(Entry front, Entry back);
// Creates a value representation of the entry for use with NetLog.
@@ -207,11 +207,13 @@ class NET_EXPORT HostCache {
const base::Optional<AddressList>& addresses,
base::Optional<std::vector<std::string>>&& text_results,
base::Optional<std::vector<HostPortPair>>&& hostnames,
- base::Optional<EsniContent>&& esni_data,
+ base::Optional<std::vector<bool>>&& integrity_data,
Source source,
base::TimeTicks expires,
int network_changes);
+ void PrepareForCacheInsertion();
+
void SetResult(AddressList addresses) { addresses_ = std::move(addresses); }
void SetResult(std::vector<std::string> text_records) {
text_records_ = std::move(text_records);
@@ -219,7 +221,9 @@ class NET_EXPORT HostCache {
void SetResult(std::vector<HostPortPair> hostnames) {
hostnames_ = std::move(hostnames);
}
- void SetResult(EsniContent esni_data) { esni_data_ = std::move(esni_data); }
+ void SetResult(std::vector<bool> integrity_data) {
+ integrity_data_ = std::move(integrity_data);
+ }
int total_hits() const { return total_hits_; }
int stale_hits() const { return stale_hits_; }
@@ -230,20 +234,11 @@ class NET_EXPORT HostCache {
int network_changes,
EntryStaleness* out) const;
- // Combines the addresses of |source| with those already stored,
- // resulting in the following order:
- //
- // 1. IPv6 addresses associated with ESNI keys
- // 2. IPv4 addresses associated with ESNI keys
- // 3. IPv6 addresses not associated with ESNI keys
- // 4. IPv4 addresses not associated with ESNI keys
- //
- // - Conducts the merge in a stable fashion (other things equal, addresses
- // from |*this| will precede those from |source|, and addresses earlier in
- // one entry's list will precede other addresses from later in the same
- // list).
- // - Deduplicates the entries during the merge so that |*this|'s
- // address list will not contain duplicates after the call.
+ // Merges addresses from |source| into the stored list of addresses and
+ // deduplicates. The address list can be accessed with |addresses()|. This
+ // method performs a stable sort to ensure IPv6 addresses precede IPv4
+ // addresses. IP versions being equal, addresses from |*this| will precede
+ // those from |source|.
void MergeAddressesFrom(const HostCache::Entry& source);
base::DictionaryValue GetAsValue(bool include_staleness) const;
@@ -253,7 +248,7 @@ class NET_EXPORT HostCache {
base::Optional<AddressList> addresses_;
base::Optional<std::vector<std::string>> text_records_;
base::Optional<std::vector<HostPortPair>> hostnames_;
- base::Optional<EsniContent> esni_data_;
+ base::Optional<std::vector<bool>> integrity_data_;
// Where results were obtained (e.g. DNS lookup, hosts file, etc).
Source source_ = SOURCE_UNKNOWN;
// TTL obtained from the nameserver. Negative if unknown.
diff --git a/chromium/net/dns/host_cache_unittest.cc b/chromium/net/dns/host_cache_unittest.cc
index b78a51f854c..61939a71a2c 100644
--- a/chromium/net/dns/host_cache_unittest.cc
+++ b/chromium/net/dns/host_cache_unittest.cc
@@ -939,7 +939,6 @@ TEST(HostCacheTest, SerializeAndDeserialize) {
EXPECT_TRUE(result1->first.secure);
ASSERT_TRUE(result1->second.addresses());
EXPECT_FALSE(result1->second.text_records());
- EXPECT_FALSE(result1->second.esni_data());
EXPECT_FALSE(result1->second.hostnames());
EXPECT_EQ(1u, result1->second.addresses().value().size());
EXPECT_EQ(address_ipv4,
@@ -1106,105 +1105,6 @@ TEST(HostCacheTest, SerializeAndDeserialize_Text) {
EXPECT_EQ(text_records, result->second.text_records().value());
}
-TEST(HostCacheTest, SerializeAndDeserialize_Esni) {
- base::TimeTicks now;
-
- base::TimeDelta ttl = base::TimeDelta::FromSeconds(99);
- HostCache::Key key("example.com", DnsQueryType::A, 0, HostResolverSource::DNS,
- NetworkIsolationKey());
- key.secure = true;
-
- const std::string kEsniKey = "a";
- const std::string kAddresslessEsniKey = "b";
- const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0);
- EsniContent esni_content;
- esni_content.AddKeyForAddress(kAddressBack, kEsniKey);
- esni_content.AddKey(kAddresslessEsniKey);
- HostCache::Entry entry(OK, esni_content, HostCache::Entry::SOURCE_DNS, ttl);
- ASSERT_TRUE(entry.esni_data());
-
- HostCache cache(kMaxCacheEntries);
- cache.Set(key, entry, now, ttl);
- EXPECT_EQ(1u, cache.size());
-
- base::ListValue serialized_cache;
- cache.GetAsListValue(&serialized_cache, false /* include_staleness */,
- HostCache::SerializationType::kRestorable);
- HostCache restored_cache(kMaxCacheEntries);
- restored_cache.RestoreFromListValue(serialized_cache);
-
- ASSERT_EQ(1u, restored_cache.size());
- HostCache::EntryStaleness staleness;
- const std::pair<const HostCache::Key, HostCache::Entry>* result =
- restored_cache.LookupStale(key, now, &staleness);
- ASSERT_TRUE(result);
- EXPECT_TRUE(result->first.secure);
-
- EXPECT_FALSE(result->second.addresses());
- EXPECT_FALSE(result->second.text_records());
- EXPECT_FALSE(result->second.hostnames());
- EXPECT_THAT(result->second.esni_data(), Optional(esni_content));
-}
-
-class HostCacheMalformedEsniSerializationTest : public ::testing::Test {
- public:
- HostCacheMalformedEsniSerializationTest()
- : serialized_cache_(),
- // We'll only need one entry.
- restored_cache_(1) {}
-
- protected:
- void SetUp() override {
- base::TimeTicks now;
-
- base::TimeDelta ttl = base::TimeDelta::FromSeconds(99);
- HostCache::Key key("example.com", DnsQueryType::A, 0,
- HostResolverSource::DNS, NetworkIsolationKey());
- key.secure = true;
-
- const std::string esni_key = "a";
- const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0);
- EsniContent esni_content;
- esni_content.AddKeyForAddress(kAddressBack, esni_key);
- HostCache::Entry entry(OK, esni_content, HostCache::Entry::SOURCE_DNS, ttl);
- ASSERT_TRUE(entry.esni_data());
- HostCache cache(kMaxCacheEntries);
- cache.Set(key, entry, now, ttl);
- EXPECT_EQ(1u, cache.size());
- cache.GetAsListValue(&serialized_cache_, true /* include_staleness */,
- HostCache::SerializationType::kRestorable);
- }
-
- base::ListValue serialized_cache_;
- HostCache restored_cache_;
-};
-
-// The key corresponds to kEsniDataKey from host_cache.cc.
-const char kEsniDataKey[] = "esni_data";
-
-TEST_F(HostCacheMalformedEsniSerializationTest, RejectsNonDictElement) {
- base::Value non_dict_element(base::Value::Type::LIST);
-
- base::Value::ListStorage cache_entries = serialized_cache_.TakeList();
- cache_entries[0].SetKey(kEsniDataKey, std::move(non_dict_element));
- serialized_cache_ = base::ListValue(std::move(cache_entries));
-
- EXPECT_FALSE(restored_cache_.RestoreFromListValue(serialized_cache_));
-}
-
-TEST_F(HostCacheMalformedEsniSerializationTest, RejectsNonStringAddress) {
- base::Value dict_with_non_string_value(base::Value::Type::DICTIONARY);
- dict_with_non_string_value.SetKey("a", base::Value(1));
-
- base::Value::ListStorage cache_entries = serialized_cache_.TakeList();
- cache_entries[0].SetKey(kEsniDataKey, std::move(dict_with_non_string_value));
- serialized_cache_ = base::ListValue(std::move(cache_entries));
-
- EXPECT_FALSE(restored_cache_.RestoreFromListValue(serialized_cache_));
-}
-
TEST(HostCacheTest, SerializeAndDeserialize_Hostname) {
base::TimeTicks now;
@@ -1234,7 +1134,6 @@ TEST(HostCacheTest, SerializeAndDeserialize_Hostname) {
EXPECT_FALSE(result->first.secure);
EXPECT_FALSE(result->second.addresses());
EXPECT_FALSE(result->second.text_records());
- EXPECT_FALSE(result->second.esni_data());
ASSERT_TRUE(result->second.hostnames());
EXPECT_EQ(hostnames, result->second.hostnames().value());
}
@@ -1394,136 +1293,25 @@ TEST(HostCacheTest, SortsAndDeduplicatesAddresses) {
ElementsAreArray(MakeEndpoints({"::3", "0.0.0.1", "0.0.0.2"})))));
}
-TEST(HostCacheTest, PrefersAddressesWithEsniContent) {
- IPAddressList front_addresses = MakeIPList({"0.0.0.2", "0.0.0.4"});
+TEST(HostCacheTest, PrefersAddressesWithIpv6) {
+ IPAddressList front_addresses = MakeIPList({"::1", "0.0.0.2", "0.0.0.4"});
IPAddressList back_addresses =
MakeIPList({"0.0.0.2", "0.0.0.2", "::3", "::3", "0.0.0.4"});
- EsniContent esni_content_front, esni_content_back;
- esni_content_front.AddKeyForAddress(MakeIP("0.0.0.4"), "key for 0.0.0.4");
- esni_content_back.AddKeyForAddress(MakeIP("::3"), "key for ::3");
-
HostCache::Entry front(
OK, AddressList::CreateFromIPAddressList(front_addresses, "front"),
HostCache::Entry::SOURCE_DNS);
- front.set_esni_data(esni_content_front);
HostCache::Entry back(
OK, AddressList::CreateFromIPAddressList(back_addresses, "back"),
HostCache::Entry::SOURCE_DNS);
- back.set_esni_data(esni_content_back);
-
- HostCache::Entry result =
- HostCache::Entry::MergeEntries(std::move(front), std::move(back));
-
- EXPECT_THAT(
- result.addresses(),
- Optional(Property(
- &AddressList::endpoints,
- ElementsAreArray(MakeEndpoints({"::3", "0.0.0.4", "0.0.0.2"})))));
-
- EXPECT_THAT(result.esni_data(),
- Optional(Property(
- &EsniContent::keys_for_addresses,
- UnorderedElementsAre(
- Pair(MakeIP("::3"), UnorderedElementsAre("key for ::3")),
- Pair(MakeIP("0.0.0.4"),
- UnorderedElementsAre("key for 0.0.0.4"))))));
-}
-
-TEST(HostCacheTest, MergesManyEntriesWithEsniContent) {
- IPAddressList front_addresses, back_addresses;
- EsniContent esni_content_front, esni_content_back;
-
- // Add several IPv4 and IPv6 addresses to both the front and
- // back ESNI structs and address_lists, and associate some of each
- // with ESNI keys.
- const std::string ipv4_prefix = "1.2.3.", ipv6_prefix = "::";
- for (int i = 0; i < 50; ++i) {
- IPAddress next =
- MakeIP((i % 2 ? ipv4_prefix : ipv6_prefix) + base::NumberToString(i));
- bool is_front = !!(i % 3);
- if (is_front) {
- front_addresses.push_back(next);
- } else {
- back_addresses.push_back(next);
- }
- if (i % 5) {
- std::string key = base::NumberToString(i % 5);
- if (is_front) {
- esni_content_front.AddKeyForAddress(next, key);
- } else {
- esni_content_back.AddKeyForAddress(next, key);
- }
- }
- }
-
- HostCache::Entry front(
- OK,
- AddressList::CreateFromIPAddressList(front_addresses, "front_canonname"),
- HostCache::Entry::SOURCE_DNS);
- front.set_esni_data(esni_content_front);
-
- HostCache::Entry back(
- OK,
- AddressList::CreateFromIPAddressList(back_addresses, "back_canonname"),
- HostCache::Entry::SOURCE_DNS);
- back.set_esni_data(esni_content_back);
HostCache::Entry result =
HostCache::Entry::MergeEntries(std::move(front), std::move(back));
- ASSERT_TRUE(result.addresses());
- EXPECT_EQ(result.addresses()->canonical_name(), "front_canonname");
-
- EXPECT_EQ(result.addresses()->size(),
- std::set<IPEndPoint>(result.addresses()->begin(),
- result.addresses()->end())
- .size())
- << "Addresses should have been deduplicated.";
-
- ASSERT_TRUE(result.esni_data());
-
- auto has_keys = [&](const IPEndPoint& e) {
- return !!result.esni_data()->keys_for_addresses().count(e.address());
- };
-
- // Helper for determining whether the resulting addresses are correctly
- // ordered. Returns true if it's an error for |e2| to come before |e1| in
- // *results.addresses().
- auto address_must_precede = [&](const IPEndPoint& e1,
- const IPEndPoint& e2) -> bool {
- if (has_keys(e1) != has_keys(e2)) {
- return has_keys(e1) && !has_keys(e2);
- }
- if (e1.address().IsIPv6() != e2.address().IsIPv6()) {
- return e1.address().IsIPv6() && !e2.address().IsIPv6();
- }
-
- // If e1 and e2 were in the same input entry, and they're otherwise
- // tied in the precedence ordering, then their order in the input entry
- // should be preserved in the output.
- bool e1_in_front = base::Contains(front_addresses, e1.address());
- bool e2_in_front = base::Contains(front_addresses, e2.address());
- bool e1_in_back = base::Contains(back_addresses, e1.address());
- bool e2_in_back = base::Contains(back_addresses, e2.address());
- if (e1_in_front == e2_in_front && e1_in_front != e1_in_back &&
- e2_in_front != e2_in_back) {
- const IPAddressList common_list =
- e1_in_front ? front_addresses : back_addresses;
- return std::find(common_list.begin(), common_list.end(), e1.address()) <
- std::find(common_list.begin(), common_list.end(), e2.address());
- }
- return false;
- };
-
- for (size_t i = 0; i < result.addresses()->size() - 1; ++i) {
- EXPECT_FALSE(address_must_precede((*result.addresses())[i + 1],
- (*result.addresses())[i]));
- }
-
- auto esni_content_merged = esni_content_front;
- esni_content_merged.MergeFrom(esni_content_back);
- EXPECT_THAT(result.esni_data(), Optional(esni_content_merged));
+ EXPECT_THAT(result.addresses(),
+ Optional(Property(&AddressList::endpoints,
+ ElementsAreArray(MakeEndpoints(
+ {"::1", "::3", "0.0.0.2", "0.0.0.4"})))));
}
TEST(HostCacheTest, MergeEntries_frontEmpty) {
@@ -1536,10 +1324,6 @@ TEST(HostCacheTest, MergeEntries_frontEmpty) {
HostCache::Entry::SOURCE_DNS,
base::TimeDelta::FromHours(4));
back.set_text_records(std::vector<std::string>{"text2"});
- EsniContent esni_content_back;
- const std::string esni_key = "a";
- esni_content_back.AddKeyForAddress(kAddressBack, esni_key);
- back.set_esni_data(esni_content_back);
const HostPortPair kHostnameBack("host", 2);
back.set_hostnames(std::vector<HostPortPair>{kHostnameBack});
@@ -1554,7 +1338,6 @@ TEST(HostCacheTest, MergeEntries_frontEmpty) {
ElementsAre(kEndpointBack));
EXPECT_THAT(result.text_records(), Optional(ElementsAre("text2")));
EXPECT_THAT(result.hostnames(), Optional(ElementsAre(kHostnameBack)));
- EXPECT_THAT(result.esni_data(), Optional(esni_content_back));
EXPECT_EQ(base::TimeDelta::FromHours(4), result.ttl());
}
@@ -1566,10 +1349,6 @@ TEST(HostCacheTest, MergeEntries_backEmpty) {
HostCache::Entry::SOURCE_DNS,
base::TimeDelta::FromMinutes(5));
front.set_text_records(std::vector<std::string>{"text1"});
- EsniContent esni_content_front;
- const std::string esni_key = "a";
- esni_content_front.AddKeyForAddress(kAddressFront, esni_key);
- front.set_esni_data(esni_content_front);
const HostPortPair kHostnameFront("host", 1);
front.set_hostnames(std::vector<HostPortPair>{kHostnameFront});
@@ -1586,7 +1365,6 @@ TEST(HostCacheTest, MergeEntries_backEmpty) {
ElementsAre(kEndpointFront));
EXPECT_THAT(result.text_records(), Optional(ElementsAre("text1")));
EXPECT_THAT(result.hostnames(), Optional(ElementsAre(kHostnameFront)));
- EXPECT_THAT(result.esni_data(), Optional(esni_content_front));
EXPECT_EQ(base::TimeDelta::FromMinutes(5), result.ttl());
}
@@ -1604,7 +1382,6 @@ TEST(HostCacheTest, MergeEntries_bothEmpty) {
EXPECT_FALSE(result.addresses());
EXPECT_FALSE(result.text_records());
EXPECT_FALSE(result.hostnames());
- EXPECT_FALSE(result.esni_data());
EXPECT_FALSE(result.has_ttl());
}
diff --git a/chromium/net/dns/host_resolver.cc b/chromium/net/dns/host_resolver.cc
index 4d7dee3f90c..2fb635a7a28 100644
--- a/chromium/net/dns/host_resolver.cc
+++ b/chromium/net/dns/host_resolver.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/check.h"
+#include "base/immediate_crash.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
@@ -56,11 +57,6 @@ class FailingRequestImpl : public HostResolver::ResolveHostRequest,
return *nullopt_result;
}
- const base::Optional<EsniContent>& GetEsniResults() const override {
- static const base::NoDestructor<base::Optional<EsniContent>> nullopt_result;
- return *nullopt_result;
- }
-
ResolveErrorInfo GetResolveErrorInfo() const override {
return ResolveErrorInfo(error_);
}
@@ -80,6 +76,11 @@ class FailingRequestImpl : public HostResolver::ResolveHostRequest,
} // namespace
+const base::Optional<std::vector<bool>>&
+HostResolver::ResolveHostRequest::GetIntegrityResultsForTesting() const {
+ IMMEDIATE_CRASH();
+}
+
const size_t HostResolver::ManagerOptions::kDefaultRetryAttempts =
static_cast<size_t>(-1);
@@ -107,14 +108,6 @@ HostResolver::ResolveHostParameters::ResolveHostParameters(
HostResolver::~HostResolver() = default;
-std::unique_ptr<HostResolver::ResolveHostRequest> HostResolver::CreateRequest(
- const HostPortPair& host,
- const NetLogWithSource& net_log,
- const base::Optional<ResolveHostParameters>& optional_parameters) {
- return CreateRequest(host, NetworkIsolationKey(), net_log,
- optional_parameters);
-}
-
std::unique_ptr<HostResolver::ProbeRequest>
HostResolver::CreateDohProbeRequest() {
// Should be overridden in any HostResolver implementation where this method
diff --git a/chromium/net/dns/host_resolver.h b/chromium/net/dns/host_resolver.h
index 264ab583500..87db841cf71 100644
--- a/chromium/net/dns/host_resolver.h
+++ b/chromium/net/dns/host_resolver.h
@@ -98,12 +98,10 @@ class NET_EXPORT HostResolver {
virtual const base::Optional<std::vector<HostPortPair>>&
GetHostnameResults() const = 0;
- // TLS 1.3 Encrypted Server Name Indication, draft 4 (ESNI,
- // https://tools.ietf.org/html/draft-ietf-tls-esni-04)
- // results of the request. Should only be called after
- // Start() signals completion, either by invoking the callback or by
- // returning a result other than |ERR_IO_PENDING|.
- virtual const base::Optional<EsniContent>& GetEsniResults() const = 0;
+ // INTEGRITY results for an initial experiment related to HTTPSSVC. Each
+ // boolean value indicates the intactness of an INTEGRITY record.
+ NET_EXPORT virtual const base::Optional<std::vector<bool>>&
+ GetIntegrityResultsForTesting() const;
// Error info for the request.
//
@@ -312,15 +310,6 @@ class NET_EXPORT HostResolver {
const NetLogWithSource& net_log,
const base::Optional<ResolveHostParameters>& optional_parameters) = 0;
- // Deprecated version of above method that uses an empty NetworkIsolationKey.
- //
- // TODO(mmenke): Once all consumers have been updated to use the other
- // overload instead, remove this method and make above method pure virtual.
- virtual std::unique_ptr<ResolveHostRequest> CreateRequest(
- const HostPortPair& host,
- const NetLogWithSource& net_log,
- const base::Optional<ResolveHostParameters>& optional_parameters);
-
// Creates a request to probe configured DoH servers to find which can be used
// successfully.
virtual std::unique_ptr<ProbeRequest> CreateDohProbeRequest();
diff --git a/chromium/net/dns/host_resolver_manager.cc b/chromium/net/dns/host_resolver_manager.cc
index 87bc925b8a0..82347fd6bf8 100644
--- a/chromium/net/dns/host_resolver_manager.cc
+++ b/chromium/net/dns/host_resolver_manager.cc
@@ -82,6 +82,7 @@
#include "net/dns/host_resolver_mdns_listener_impl.h"
#include "net/dns/host_resolver_mdns_task.h"
#include "net/dns/host_resolver_proc.h"
+#include "net/dns/httpssvc_metrics.h"
#include "net/dns/mdns_client.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/public/resolve_error_info.h"
@@ -499,7 +500,8 @@ class HostResolverManager::RequestImpl
const base::Optional<ResolveHostParameters>& optional_parameters,
ResolveContext* resolve_context,
HostCache* host_cache,
- base::WeakPtr<HostResolverManager> resolver)
+ base::WeakPtr<HostResolverManager> resolver,
+ const base::TickClock* tick_clock)
: source_net_log_(source_net_log),
request_host_(request_host),
network_isolation_key_(
@@ -516,7 +518,8 @@ class HostResolverManager::RequestImpl
priority_(parameters_.initial_priority),
job_(nullptr),
resolver_(resolver),
- complete_(false) {}
+ complete_(false),
+ tick_clock_(tick_clock) {}
~RequestImpl() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -544,7 +547,7 @@ class HostResolverManager::RequestImpl
} else {
DCHECK(!job_);
complete_ = true;
- LogFinishRequest(rv);
+ LogFinishRequest(rv, false /* async_completion */);
}
resolver_ = nullptr;
@@ -573,10 +576,12 @@ class HostResolverManager::RequestImpl
return results_ ? results_.value().hostnames() : *nullopt_result;
}
- const base::Optional<EsniContent>& GetEsniResults() const override {
+ const base::Optional<std::vector<bool>>& GetIntegrityResultsForTesting()
+ const override {
DCHECK(complete_);
- static const base::NoDestructor<base::Optional<EsniContent>> nullopt_result;
- return results_ ? results_.value().esni_data() : *nullopt_result;
+ static const base::NoDestructor<base::Optional<std::vector<bool>>>
+ nullopt_result;
+ return results_ ? results_.value().integrity_data() : *nullopt_result;
}
net::ResolveErrorInfo GetResolveErrorInfo() const override {
@@ -649,7 +654,7 @@ class HostResolverManager::RequestImpl
DCHECK(!complete_);
complete_ = true;
- LogFinishRequest(error);
+ LogFinishRequest(error, true /* async_completion */);
DCHECK(callback_);
std::move(callback_).Run(HostResolver::SquashErrorCode(error));
@@ -679,19 +684,12 @@ class HostResolverManager::RequestImpl
bool complete() const { return complete_; }
- base::TimeTicks request_time() const {
- DCHECK(!request_time_.is_null());
- return request_time_;
- }
- void set_request_time(base::TimeTicks request_time) {
- DCHECK(request_time_.is_null());
- DCHECK(!request_time.is_null());
- request_time_ = request_time;
- }
-
private:
- // Logs when a request has just been started.
+ // Logging and metrics for when a request has just been started.
void LogStartRequest() {
+ DCHECK(request_time_.is_null());
+ request_time_ = tick_clock_->NowTicks();
+
source_net_log_.BeginEvent(
NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, [this] {
base::Value dict(base::Value::Type::DICTIONARY);
@@ -708,10 +706,20 @@ class HostResolverManager::RequestImpl
});
}
- // Logs when a request has just completed (before its callback is run).
- void LogFinishRequest(int net_error) {
+ // Logging and metrics for when a request has just completed (before its
+ // callback is run).
+ void LogFinishRequest(int net_error, bool async_completion) {
source_net_log_.EndEventWithNetErrorCode(
NetLogEventType::HOST_RESOLVER_IMPL_REQUEST, net_error);
+
+ if (!parameters_.is_speculative) {
+ DCHECK(!request_time_.is_null());
+ base::TimeDelta duration = tick_clock_->NowTicks() - request_time_;
+
+ UMA_HISTOGRAM_MEDIUM_TIMES("Net.DNS.Request.TotalTime", duration);
+ if (async_completion)
+ UMA_HISTOGRAM_MEDIUM_TIMES("Net.DNS.Request.TotalTimeAsync", duration);
+ }
}
// Logs when a request has been cancelled.
@@ -744,6 +752,7 @@ class HostResolverManager::RequestImpl
base::Optional<HostCache::EntryStaleness> stale_info_;
ResolveErrorInfo error_info_;
+ const base::TickClock* const tick_clock_;
base::TimeTicks request_time_;
SEQUENCE_CHECKER(sequence_checker_);
@@ -1107,9 +1116,21 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
transactions_needed_.push(DnsQueryType::A);
transactions_needed_.push(DnsQueryType::AAAA);
- if (secure_ &&
- base::FeatureList::IsEnabled(features::kRequestEsniDnsRecords)) {
- transactions_needed_.push(DnsQueryType::ESNI);
+ // Queue up an INTEGRITY query if we are allowed to.
+ const bool is_httpssvc_experiment_domain =
+ httpssvc_domain_cache_.IsExperimental(hostname);
+ const bool is_httpssvc_control_domain =
+ httpssvc_domain_cache_.IsControl(hostname);
+ if (base::FeatureList::IsEnabled(features::kDnsHttpssvc) &&
+ features::kDnsHttpssvcUseIntegrity.Get() &&
+ (secure_ || features::kDnsHttpssvcEnableQueryOverInsecure.Get()) &&
+ (is_httpssvc_experiment_domain || is_httpssvc_control_domain)) {
+ // We should not be configured to query HTTPSSVC *and* INTEGRITY.
+ DCHECK(!features::kDnsHttpssvcUseHttpssvc.Get());
+
+ httpssvc_metrics_.emplace(
+ is_httpssvc_experiment_domain /* expect_intact */);
+ transactions_needed_.push(DnsQueryType::INTEGRITY);
}
}
num_needed_transactions_ = transactions_needed_.size();
@@ -1170,15 +1191,25 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
return trans;
}
- void OnEsniTransactionTimeout() {
- // Currently, the ESNI transaction timer only gets started
- // when all non-ESNI transactions have completed.
- DCHECK(TaskIsCompleteOrOnlyEsniTransactionsRemain());
+ void OnExperimentalQueryTimeout(uint16_t qtype,
+ base::Optional<std::string> doh_provider_id) {
+ // The experimental query timer is only started when all other transactions
+ // have completed.
+ DCHECK(TaskIsCompleteOrOnlyQtypeTransactionsRemain(qtype));
num_completed_transactions_ += transactions_started_.size();
DCHECK(num_completed_transactions_ == num_needed_transactions());
transactions_started_.clear();
+ if (qtype == dns_protocol::kExperimentalTypeIntegrity) {
+ DCHECK(httpssvc_metrics_);
+
+ // Record that this INTEGRITY query timed out in the metrics.
+ base::TimeDelta elapsed_time = tick_clock_->NowTicks() - task_start_time_;
+ httpssvc_metrics_->SaveForIntegrity(
+ doh_provider_id, HttpssvcDnsRcode::kTimedOut, {}, elapsed_time);
+ }
+
ProcessResultsOnCompletion();
}
@@ -1186,7 +1217,8 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
DnsQueryType dns_query_type,
DnsTransaction* transaction,
int net_error,
- const DnsResponse* response) {
+ const DnsResponse* response,
+ base::Optional<std::string> doh_provider_id) {
DCHECK(transaction);
// Once control leaves OnTransactionComplete, there's no further
@@ -1202,10 +1234,30 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
transactions_started_.erase(it);
}
+ base::TimeDelta elapsed_time = tick_clock_->NowTicks() - task_start_time_;
+ enum HttpssvcDnsRcode rcode_for_httpssvc = HttpssvcDnsRcode::kNoError;
+ if (httpssvc_metrics_) {
+ if (net_error == ERR_DNS_TIMED_OUT) {
+ rcode_for_httpssvc = HttpssvcDnsRcode::kTimedOut;
+ } else if (net_error == ERR_NAME_NOT_RESOLVED) {
+ rcode_for_httpssvc = HttpssvcDnsRcode::kNoError;
+ } else if (response == nullptr) {
+ rcode_for_httpssvc = HttpssvcDnsRcode::kMissingDnsResponse;
+ } else {
+ rcode_for_httpssvc =
+ TranslateDnsRcodeForHttpssvcExperiment(response->rcode());
+ }
+ }
+
if (net_error != OK && !(net_error == ERR_NAME_NOT_RESOLVED && response &&
response->IsValid())) {
- OnFailure(net_error, DnsResponse::DNS_PARSE_OK, base::nullopt);
- return;
+ if (dns_query_type == DnsQueryType::INTEGRITY) {
+ // Do not allow an INTEGRITY query to fail the whole DnsTask.
+ response = nullptr;
+ } else {
+ OnFailure(net_error, DnsResponse::DNS_PARSE_OK, base::nullopt);
+ return;
+ }
}
DnsResponse::Result parse_result = DnsResponse::DNS_PARSE_RESULT_MAX;
@@ -1228,8 +1280,9 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
case DnsQueryType::SRV:
parse_result = ParseServiceDnsResponse(response, &results);
break;
- case DnsQueryType::ESNI:
- parse_result = ParseEsniDnsResponse(response, &results);
+ case DnsQueryType::INTEGRITY:
+ // Parse the INTEGRITY records, condensing them into a vector<bool>.
+ parse_result = ParseIntegrityDnsResponse(response, &results);
break;
}
DCHECK_LT(parse_result, DnsResponse::DNS_PARSE_RESULT_MAX);
@@ -1239,6 +1292,21 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
return;
}
+ if (httpssvc_metrics_) {
+ if (dns_query_type != DnsQueryType::INTEGRITY) {
+ httpssvc_metrics_->SaveForNonIntegrity(doh_provider_id, elapsed_time,
+ rcode_for_httpssvc);
+ } else {
+ const base::Optional<std::vector<bool>>& condensed =
+ results.integrity_data();
+ CHECK(condensed.has_value());
+ // INTEGRITY queries can time out the normal way (here), or when the
+ // experimental query timer runs out (OnExperimentalQueryTimeout).
+ httpssvc_metrics_->SaveForIntegrity(doh_provider_id, rcode_for_httpssvc,
+ *condensed, elapsed_time);
+ }
+ }
+
// Merge results with saved results from previous transactions.
if (saved_results_) {
DCHECK_LE(2, num_needed_transactions());
@@ -1257,10 +1325,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
results = HostCache::Entry::MergeEntries(
std::move(results), std::move(saved_results_).value());
break;
- case DnsQueryType::ESNI:
- // It doesn't matter whether the ESNI record is the "front"
- // or the "back" argument to the merge, since the logic for
- // merging addresses from ESNI records is the same in each case.
+ case DnsQueryType::INTEGRITY:
results = HostCache::Entry::MergeEntries(
std::move(results), std::move(saved_results_).value());
break;
@@ -1277,13 +1342,16 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
++num_completed_transactions_;
if (num_completed_transactions_ < num_needed_transactions()) {
delegate_->OnIntermediateTransactionComplete();
- MaybeStartEsniTimer();
+ // If the experimental query times out, blame the provider that gave the
+ // last A/AAAA result. If we were being 100% correct, we would blame the
+ // provider associated with the experimental query.
+ MaybeStartExperimentalQueryTimer(doh_provider_id);
return;
}
- // Since all transactions are complete, in particular, all ESNI transactions
- // are complete (if any were started).
- esni_cancellation_timer_.Stop();
+ // Since all transactions are complete, in particular, all experimental
+ // transactions are complete (if any were started).
+ experimental_query_cancellation_timer_.Stop();
ProcessResultsOnCompletion();
}
@@ -1296,20 +1364,13 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
// If there are multiple addresses, and at least one is IPv6, need to
// sort them.
- // When there are no ESNI keys in the record, IPv6 addresses are always
- // put before IPv4 ones, so it's sufficient to just check the family of
- // the first address.
- // When there are ESNI keys, there could be ESNI-equipped
- // IPv4 addresses preceding the first IPv6 address, so it's necessary to
- // scan the list.
bool at_least_one_ipv6_address =
results.addresses() && !results.addresses().value().empty() &&
(results.addresses().value()[0].GetFamily() == ADDRESS_FAMILY_IPV6 ||
- (results.esni_data() &&
- std::any_of(results.addresses().value().begin(),
- results.addresses().value().end(), [](auto& e) {
- return e.GetFamily() == ADDRESS_FAMILY_IPV6;
- })));
+ std::any_of(results.addresses().value().begin(),
+ results.addresses().value().end(), [](auto& e) {
+ return e.GetFamily() == ADDRESS_FAMILY_IPV6;
+ }));
if (at_least_one_ipv6_address) {
// Sort addresses if needed. Sort could complete synchronously.
@@ -1326,6 +1387,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
DnsResponse::Result ParseAddressDnsResponse(const DnsResponse* response,
HostCache::Entry* out_results) {
+ DCHECK(response);
AddressList addresses;
base::TimeDelta ttl;
DnsResponse::Result parse_result =
@@ -1346,6 +1408,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
DnsResponse::Result ParseTxtDnsResponse(const DnsResponse* response,
HostCache::Entry* out_results) {
+ DCHECK(response);
std::vector<std::unique_ptr<const RecordParsed>> records;
base::Optional<base::TimeDelta> response_ttl;
DnsResponse::Result parse_result = ParseAndFilterResponseRecords(
@@ -1371,6 +1434,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
DnsResponse::Result ParsePointerDnsResponse(const DnsResponse* response,
HostCache::Entry* out_results) {
+ DCHECK(response);
std::vector<std::unique_ptr<const RecordParsed>> records;
base::Optional<base::TimeDelta> response_ttl;
DnsResponse::Result parse_result = ParseAndFilterResponseRecords(
@@ -1399,6 +1463,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
DnsResponse::Result ParseServiceDnsResponse(const DnsResponse* response,
HostCache::Entry* out_results) {
+ DCHECK(response);
std::vector<std::unique_ptr<const RecordParsed>> records;
base::Optional<base::TimeDelta> response_ttl;
DnsResponse::Result parse_result = ParseAndFilterResponseRecords(
@@ -1428,55 +1493,39 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
return DnsResponse::DNS_PARSE_OK;
}
- DnsResponse::Result ParseEsniDnsResponse(const DnsResponse* response,
- HostCache::Entry* out_results) {
- std::vector<std::unique_ptr<const RecordParsed>> records;
+ DnsResponse::Result ParseIntegrityDnsResponse(const DnsResponse* response,
+ HostCache::Entry* out_results) {
base::Optional<base::TimeDelta> response_ttl;
+ const HostCache::Entry default_entry(
+ OK, std::vector<bool>(), HostCache::Entry::SOURCE_DNS, response_ttl);
+
+ if (response == nullptr) {
+ *out_results = default_entry;
+ return DnsResponse::Result::DNS_PARSE_OK;
+ }
+
+ std::vector<std::unique_ptr<const RecordParsed>> records;
DnsResponse::Result parse_result = ParseAndFilterResponseRecords(
- response, dns_protocol::kExperimentalTypeEsniDraft4, &records,
+ response, dns_protocol::kExperimentalTypeIntegrity, &records,
&response_ttl);
if (parse_result != DnsResponse::DNS_PARSE_OK) {
- *out_results = GetMalformedResponseResult();
- return parse_result;
+ *out_results = default_entry;
+ return DnsResponse::Result::DNS_PARSE_OK;
}
- // Glom the ESNI response records into a single EsniContent;
- // this also dedups keys and (key, address) associations.
- EsniContent content;
+ // Condense results into a list of booleans. We do not cache the results,
+ // but this enables us to write some unit tests.
+ std::vector<bool> condensed_results;
for (const auto& record : records) {
- const EsniRecordRdata& rdata = *record->rdata<EsniRecordRdata>();
-
- for (const IPAddress& address : rdata.addresses())
- content.AddKeyForAddress(address, rdata.esni_keys());
- }
-
- // As a first pass, deliberately ignore ESNI records with no addresses
- // included. Later, the implementation can be extended to handle "at-large"
- // ESNI keys not specifically associated with collections of addresses.
- // (We're declining the "...clients MAY initiate..." choice in ESNI draft 4,
- // Section 4.2.2 Step 2.)
- if (content.keys_for_addresses().empty()) {
- *out_results =
- HostCache::Entry(ERR_NAME_NOT_RESOLVED, EsniContent(),
- HostCache::Entry::SOURCE_DNS, response_ttl);
- } else {
- AddressList addresses, ipv4_addresses_temporary;
- addresses.set_canonical_name(hostname_);
- for (const auto& kv : content.keys_for_addresses())
- (kv.first.IsIPv6() ? addresses : ipv4_addresses_temporary)
- .push_back(IPEndPoint(kv.first, 0));
- addresses.insert(addresses.end(), ipv4_addresses_temporary.begin(),
- ipv4_addresses_temporary.end());
-
- // Store the addresses separately from the ESNI key-address
- // associations, so that the addresses can be merged later with
- // addresses from A and AAAA records.
- *out_results = HostCache::Entry(
- OK, std::move(content), HostCache::Entry::SOURCE_DNS, response_ttl);
- out_results->set_addresses(std::move(addresses));
+ const IntegrityRecordRdata& rdata =
+ *record->rdata<IntegrityRecordRdata>();
+ condensed_results.push_back(rdata.IsIntact());
}
+ *out_results = HostCache::Entry(OK, std::move(condensed_results),
+ HostCache::Entry::SOURCE_DNS, response_ttl);
+ DCHECK_EQ(parse_result, DnsResponse::DNS_PARSE_OK);
return parse_result;
}
@@ -1605,6 +1654,9 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
void OnFailure(int net_error,
DnsResponse::Result parse_result,
base::Optional<base::TimeDelta> ttl) {
+ if (httpssvc_metrics_)
+ httpssvc_metrics_->SaveNonIntegrityFailure();
+
DCHECK_NE(OK, net_error);
HostCache::Entry results(net_error, HostCache::Entry::SOURCE_UNKNOWN);
@@ -1636,52 +1688,57 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
delegate_->OnDnsTaskComplete(task_start_time_, results, secure_);
}
- // Returns whether all transactions left to execute are of transaction
- // type ESNI. (In particular, this is the case if all transactions are
- // complete.)
- // Used for logging and starting the ESNI transaction timer (see
- // MaybeStartEsniTimer).
- bool TaskIsCompleteOrOnlyEsniTransactionsRemain() const {
- // Since DoH runs all transactions concurrently and
- // DnsQueryType::UNSPECIFIED-with-ESNI tasks are only run using DoH,
- // this method only needs to check the transactions in transactions_started_
- // because transactions_needed_ is empty from the time the first
- // transaction is started.
+ // Returns whether all transactions left to execute are of transaction type
+ // |qtype|. (In particular, this is the case if all transactions are
+ // complete.) Used for logging and starting the experimental query timer (see
+ // MaybeStartExperimentalQueryTimer).
+ bool TaskIsCompleteOrOnlyQtypeTransactionsRemain(uint16_t qtype) const {
+ // Since DoH runs all transactions concurrently and experimental types are
+ // only queried over DoH, this method only needs to check the transactions
+ // in transactions_started_ because transactions_needed_ is empty from the
+ // time the first transaction is started.
DCHECK(transactions_needed_.empty());
return std::all_of(
transactions_started_.begin(), transactions_started_.end(),
[&](const std::unique_ptr<DnsTransaction>& p) {
DCHECK(p);
- return p->GetType() == dns_protocol::kExperimentalTypeEsniDraft4;
+ return p->GetType() == qtype;
});
}
- // If ESNI transactions are being executed as part of this task
- // and all transactions except the ESNI transactions have finished, and the
- // ESNI transactions have not finished, starts a timer after which to abort
- // the ESNI transactions.
- //
- // This timer has duration equal to the shorter of two parameterized values:
- // - a fixed, absolute duration
- // - a relative duration (as a proportion of the total time taken for
- // the task's other transactions).
- void MaybeStartEsniTimer() {
+
+ void MaybeStartExperimentalQueryTimer(
+ base::Optional<std::string> doh_provider_id) {
DCHECK(!transactions_started_.empty());
- DCHECK(saved_results_);
- if (!esni_cancellation_timer_.IsRunning() &&
- TaskIsCompleteOrOnlyEsniTransactionsRemain()) {
- base::TimeDelta total_time_taken_for_other_transactions =
+
+ // Abort if neither HTTPSSVC nor INTEGRITY querying is enabled.
+ if (!base::FeatureList::IsEnabled(features::kDnsHttpssvc) ||
+ (!features::kDnsHttpssvcUseIntegrity.Get() &&
+ !features::kDnsHttpssvcUseHttpssvc.Get())) {
+ return;
+ }
+
+ if (!experimental_query_cancellation_timer_.IsRunning() &&
+ TaskIsCompleteOrOnlyQtypeTransactionsRemain(
+ dns_protocol::kExperimentalTypeIntegrity)) {
+ const base::TimeDelta kExtraTimeAbsolute =
+ features::dns_httpssvc_experiment::GetExtraTimeAbsolute();
+ const int kExtraTimePercent =
+ features::kDnsHttpssvcExtraTimePercent.Get();
+
+ base::TimeDelta total_time_for_other_transactions =
tick_clock_->NowTicks() - task_start_time_;
+ base::TimeDelta relative_timeout =
+ total_time_for_other_transactions * kExtraTimePercent / 100;
- esni_cancellation_timer_.Start(
- FROM_HERE,
- std::min(
- features::EsniDnsMaxAbsoluteAdditionalWait(),
- total_time_taken_for_other_transactions *
- (0.01 *
- features::kEsniDnsMaxRelativeAdditionalWaitPercent.Get())),
- this, &DnsTask::OnEsniTransactionTimeout);
+ base::TimeDelta timeout = std::min(kExtraTimeAbsolute, relative_timeout);
+
+ experimental_query_cancellation_timer_.Start(
+ FROM_HERE, timeout,
+ base::BindOnce(
+ &DnsTask::OnExperimentalQueryTimeout, base::Unretained(this),
+ dns_protocol::kExperimentalTypeIntegrity, doh_provider_id));
}
}
@@ -1711,16 +1768,12 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
const base::TickClock* tick_clock_;
base::TimeTicks task_start_time_;
- // In order to histogram the relative end-to-end elapsed times of
- // a task's ESNI and non-ESNI transactions, store the end-to-end time
- // elapsed from task start to the end of the task's ESNI transaction
- // (if any) and its final non-ESNI transaction.
- base::TimeDelta esni_elapsed_for_logging_;
- base::TimeDelta non_esni_elapsed_for_logging_;
+ HttpssvcExperimentDomainCache httpssvc_domain_cache_;
+ base::Optional<HttpssvcMetrics> httpssvc_metrics_;
- // Timer for early abort of ESNI transactions. See comments describing
- // the timeout parameters in net/base/features.h.
- base::OneShotTimer esni_cancellation_timer_;
+ // Timer for early abort of experimental queries. See comments describing the
+ // timeout parameters in net/base/features.h.
+ base::OneShotTimer experimental_query_cancellation_timer_;
DISALLOW_COPY_AND_ASSIGN(DnsTask);
};
@@ -2396,7 +2449,7 @@ class HostResolverManager::Job : public PrioritizedDispatcher::Job,
query_types.push_back(query_type_);
}
- MDnsClient* client;
+ MDnsClient* client = nullptr;
int rv = resolver_->GetOrCreateMdnsClient(&client);
mdns_task_ =
std::make_unique<HostResolverMdnsTask>(client, hostname_, query_types);
@@ -2454,23 +2507,6 @@ class HostResolverManager::Job : public PrioritizedDispatcher::Job,
if (had_non_speculative_request_) {
category = RESOLVE_SUCCESS;
UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveSuccessTime", duration);
- switch (query_type_) {
- case DnsQueryType::A:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveSuccessTime.IPV4",
- duration);
- break;
- case DnsQueryType::AAAA:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveSuccessTime.IPV6",
- duration);
- break;
- case DnsQueryType::UNSPECIFIED:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveSuccessTime.UNSPEC",
- duration);
- break;
- default:
- // No histogram for other query types.
- break;
- }
} else {
category = RESOLVE_SPECULATIVE_SUCCESS;
}
@@ -2482,23 +2518,6 @@ class HostResolverManager::Job : public PrioritizedDispatcher::Job,
if (had_non_speculative_request_) {
category = RESOLVE_FAIL;
UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveFailureTime", duration);
- switch (query_type_) {
- case DnsQueryType::A:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveFailureTime.IPV4",
- duration);
- break;
- case DnsQueryType::AAAA:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveFailureTime.IPV6",
- duration);
- break;
- case DnsQueryType::UNSPECIFIED:
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.ResolveFailureTime.UNSPEC",
- duration);
- break;
- default:
- // No histogram for other query types.
- break;
- }
} else {
category = RESOLVE_SPECULATIVE_FAIL;
}
@@ -2514,6 +2533,13 @@ class HostResolverManager::Job : public PrioritizedDispatcher::Job,
else
base::UmaHistogramSparse("Net.DNS.ResolveError.Slow", std::abs(error));
}
+
+ if (had_non_speculative_request_) {
+ UmaHistogramMediumTimes(
+ base::StringPrintf("Net.DNS.SecureDnsMode.%s.ResolveTime",
+ SecureDnsModeToString(secure_dns_mode_).c_str()),
+ duration);
+ }
}
void MaybeCacheResult(const HostCache::Entry& results,
@@ -2587,13 +2613,7 @@ class HostResolverManager::Job : public PrioritizedDispatcher::Job,
RequestImpl* req = requests_.head()->value();
req->RemoveFromList();
DCHECK_EQ(this, req->job());
- // Update the net log and notify registered observers.
- if (results.did_complete()) {
- // Record effective total time from creation to completion.
- resolver_->RecordTotalTime(
- req->parameters().is_speculative, false /* from_cache */,
- secure_dns_mode_, tick_clock_->NowTicks() - req->request_time());
- }
+
if (results.error() == OK && !req->parameters().is_speculative) {
req->set_results(
results.CopyWithDefaultPort(req->request_host().port()));
@@ -2808,7 +2828,7 @@ HostResolverManager::CreateRequest(
return std::make_unique<RequestImpl>(
net_log, host, network_isolation_key, optional_parameters,
- resolve_context, host_cache, weak_ptr_factory_.GetWeakPtr());
+ resolve_context, host_cache, weak_ptr_factory_.GetWeakPtr(), tick_clock_);
}
std::unique_ptr<HostResolverManager::CancellableProbeRequest>
@@ -2971,8 +2991,6 @@ int HostResolverManager::Resolve(RequestImpl* request) {
ResolveHostParameters::CacheUsage::ALLOWED);
DCHECK(!invalidation_in_progress_);
- request->set_request_time(tick_clock_->NowTicks());
-
DnsQueryType effective_query_type;
HostResolverFlags effective_host_resolver_flags;
DnsConfig::SecureDnsMode effective_secure_dns_mode;
@@ -2996,8 +3014,6 @@ int HostResolverManager::Resolve(RequestImpl* request) {
}
if (stale_info && !request->parameters().is_speculative)
request->set_stale_info(std::move(stale_info).value());
- RecordTotalTime(request->parameters().is_speculative, true /* from_cache */,
- effective_secure_dns_mode, base::TimeDelta());
request->set_error_info(results.error(),
false /* is_secure_network_error */);
return HostResolver::SquashErrorCode(results.error());
@@ -3317,24 +3333,6 @@ void HostResolverManager::CacheResult(HostCache* cache,
cache->Set(key, entry, tick_clock_->NowTicks(), ttl);
}
-// Record time from Request creation until a valid DNS response.
-void HostResolverManager::RecordTotalTime(
- bool speculative,
- bool from_cache,
- DnsConfig::SecureDnsMode secure_dns_mode,
- base::TimeDelta duration) const {
- if (!speculative) {
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.TotalTime", duration);
- UmaHistogramMediumTimes(
- base::StringPrintf("Net.DNS.SecureDnsMode.%s.TotalTime",
- SecureDnsModeToString(secure_dns_mode).c_str()),
- duration);
-
- if (!from_cache)
- UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.TotalTimeNotCached", duration);
- }
-}
-
std::unique_ptr<HostResolverManager::Job> HostResolverManager::RemoveJob(
JobMap::iterator job_it) {
DCHECK(job_it != jobs_.end());
diff --git a/chromium/net/dns/host_resolver_manager.h b/chromium/net/dns/host_resolver_manager.h
index 4c4799ea00f..c712824c3d1 100644
--- a/chromium/net/dns/host_resolver_manager.h
+++ b/chromium/net/dns/host_resolver_manager.h
@@ -414,12 +414,6 @@ class NET_EXPORT HostResolverManager
const HostCache::Entry& entry,
base::TimeDelta ttl);
- // Record time from Request creation until a valid DNS response.
- void RecordTotalTime(bool speculative,
- bool from_cache,
- DnsConfig::SecureDnsMode secure_dns_mode,
- base::TimeDelta duration) const;
-
// Removes |job_it| from |jobs_| and return.
std::unique_ptr<Job> RemoveJob(JobMap::iterator job_it);
diff --git a/chromium/net/dns/host_resolver_manager_fuzzer.cc b/chromium/net/dns/host_resolver_manager_fuzzer.cc
index 8380657fef5..a6ae1ddaf81 100644
--- a/chromium/net/dns/host_resolver_manager_fuzzer.cc
+++ b/chromium/net/dns/host_resolver_manager_fuzzer.cc
@@ -17,6 +17,7 @@
#include "net/base/address_family.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/request_priority.h"
#include "net/dns/context_host_resolver.h"
#include "net/dns/fuzzed_host_resolver_util.h"
@@ -161,7 +162,8 @@ class DnsRequest {
const char* hostname = data_provider_->PickValueInArray(kHostNames);
request_ = host_resolver_->CreateRequest(
- net::HostPortPair(hostname, 80), net::NetLogWithSource(), parameters);
+ net::HostPortPair(hostname, 80), net::NetworkIsolationKey(),
+ net::NetLogWithSource(), parameters);
int rv = request_->Start(
base::BindOnce(&DnsRequest::OnCallback, base::Unretained(this)));
if (rv != net::ERR_IO_PENDING)
diff --git a/chromium/net/dns/host_resolver_manager_unittest.cc b/chromium/net/dns/host_resolver_manager_unittest.cc
index 16d70163982..f467b8e1eac 100644
--- a/chromium/net/dns/host_resolver_manager_unittest.cc
+++ b/chromium/net/dns/host_resolver_manager_unittest.cc
@@ -86,6 +86,7 @@ using ::testing::AllOf;
using ::testing::Between;
using ::testing::ByMove;
using ::testing::Eq;
+using ::testing::IsEmpty;
using ::testing::Optional;
using ::testing::Pair;
using ::testing::Property;
@@ -2779,7 +2780,7 @@ TEST_F(HostResolverManagerTest, Mdns) {
CreateExpected("000a:0000:0000:0000:0001:0002:0003:0004", 80)));
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerTest, Mdns_AaaaOnly) {
@@ -2831,7 +2832,7 @@ TEST_F(HostResolverManagerTest, Mdns_Txt) {
EXPECT_THAT(response.request()->GetTextResults(),
testing::Optional(testing::ElementsAre("foo", "bar")));
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerTest, Mdns_Ptr) {
@@ -2856,7 +2857,7 @@ TEST_F(HostResolverManagerTest, Mdns_Ptr) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
EXPECT_THAT(
response.request()->GetHostnameResults(),
testing::Optional(testing::ElementsAre(HostPortPair("foo.com", 83))));
@@ -2884,7 +2885,7 @@ TEST_F(HostResolverManagerTest, Mdns_Srv) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
EXPECT_THAT(
response.request()->GetHostnameResults(),
testing::Optional(testing::ElementsAre(HostPortPair("foo.com", 8265))));
@@ -2912,7 +2913,7 @@ TEST_F(HostResolverManagerTest, Mdns_Srv_Unrestricted) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
EXPECT_THAT(
response.request()->GetHostnameResults(),
testing::Optional(testing::ElementsAre(HostPortPair("foo.com", 8265))));
@@ -2941,7 +2942,7 @@ TEST_F(HostResolverManagerTest, Mdns_Srv_Result_Unrestricted) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
EXPECT_THAT(response.request()->GetHostnameResults(),
testing::Optional(
testing::ElementsAre(HostPortPair("foo bar.local", 8265))));
@@ -3006,7 +3007,7 @@ TEST_F(HostResolverManagerTest, Mdns_NoResponse) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
test_task_runner->FastForwardUntilNoTasksRemain();
}
@@ -3050,7 +3051,7 @@ TEST_F(HostResolverManagerTest, Mdns_WrongType) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
test_task_runner->FastForwardUntilNoTasksRemain();
}
@@ -7815,7 +7816,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Order between separate DNS records is undefined, but each record should
// stay in order as that order may be meaningful.
@@ -7868,7 +7869,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_NonexistentDomain) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_Failure) {
@@ -7895,7 +7896,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_Failure) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_Timeout) {
@@ -7922,7 +7923,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_Timeout) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_Empty) {
@@ -7949,7 +7950,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_Empty) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_Malformed) {
@@ -7976,7 +7977,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_Malformed) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_MismatchedName) {
@@ -8000,7 +8001,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_MismatchedName) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, TxtQuery_WrongType) {
@@ -8025,7 +8026,7 @@ TEST_F(HostResolverManagerDnsTest, TxtQuery_WrongType) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
// Same as TxtQuery except we specify DNS HostResolverSource instead of relying
@@ -8058,7 +8059,7 @@ TEST_F(HostResolverManagerDnsTest, TxtDnsQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Order between separate DNS records is undefined, but each record should
// stay in order as that order may be meaningful.
@@ -8092,7 +8093,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Order between separate records is undefined.
EXPECT_THAT(response.request()->GetHostnameResults(),
@@ -8119,7 +8120,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_Ip) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Order between separate records is undefined.
EXPECT_THAT(response.request()->GetHostnameResults(),
@@ -8151,7 +8152,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_NonexistentDomain) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_Failure) {
@@ -8178,7 +8179,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_Failure) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_Timeout) {
@@ -8205,7 +8206,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_Timeout) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_Empty) {
@@ -8232,7 +8233,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_Empty) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_Malformed) {
@@ -8259,7 +8260,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_Malformed) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_MismatchedName) {
@@ -8283,7 +8284,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_MismatchedName) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, PtrQuery_WrongType) {
@@ -8308,7 +8309,7 @@ TEST_F(HostResolverManagerDnsTest, PtrQuery_WrongType) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
// Same as PtrQuery except we specify DNS HostResolverSource instead of relying
@@ -8335,7 +8336,7 @@ TEST_F(HostResolverManagerDnsTest, PtrDnsQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Order between separate records is undefined.
EXPECT_THAT(response.request()->GetHostnameResults(),
@@ -8366,7 +8367,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Expect ordered by priority, and random within a priority.
base::Optional<std::vector<HostPortPair>> results =
@@ -8411,7 +8412,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_ZeroWeight) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Expect ordered by priority, and random within a priority.
EXPECT_THAT(response.request()->GetHostnameResults(),
@@ -8443,7 +8444,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_NonexistentDomain) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_Failure) {
@@ -8470,7 +8471,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_Failure) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_Timeout) {
@@ -8497,7 +8498,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_Timeout) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_Empty) {
@@ -8524,7 +8525,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_Empty) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_Malformed) {
@@ -8551,7 +8552,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_Malformed) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_MismatchedName) {
@@ -8575,7 +8576,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_MismatchedName) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
TEST_F(HostResolverManagerDnsTest, SrvQuery_WrongType) {
@@ -8600,7 +8601,7 @@ TEST_F(HostResolverManagerDnsTest, SrvQuery_WrongType) {
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
}
// Same as SrvQuery except we specify DNS HostResolverSource instead of relying
@@ -8631,7 +8632,7 @@ TEST_F(HostResolverManagerDnsTest, SrvDnsQuery) {
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_FALSE(response.request()->GetAddressResults());
EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
+ EXPECT_FALSE(response.request()->GetIntegrityResultsForTesting());
// Expect ordered by priority, and random within a priority.
base::Optional<std::vector<HostPortPair>> results =
@@ -8653,6 +8654,542 @@ TEST_F(HostResolverManagerDnsTest, SrvDnsQuery) {
HostPortPair("google.com", 5)));
}
+class HostResolverManagerDnsTestIntegrity : public HostResolverManagerDnsTest {
+ public:
+ HostResolverManagerDnsTestIntegrity()
+ : HostResolverManagerDnsTest(
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+ const base::FieldTrialParams params = {
+ {"DnsHttpssvcUseIntegrity", "true"},
+ {"DnsHttpssvcExperimentDomains", "host"},
+ {"DnsHttpssvcControlDomains", ""},
+ {"DnsHttpssvcEnableQueryOverInsecure", "false"},
+ };
+ scoped_feature_list_.InitAndEnableFeatureWithParameters(
+ features::kDnsHttpssvc, params);
+ }
+
+ protected:
+ struct IntegrityAddRulesOptions {
+ bool add_a = true;
+ bool add_aaaa = true;
+ bool add_integrity = true;
+ bool integrity_mangled = false;
+
+ bool secure_a = true;
+ bool secure_aaaa = true;
+ bool secure_integrity = true;
+
+ bool delay_a = false;
+ bool delay_aaaa = false;
+ bool delay_integrity = false;
+ };
+
+ std::vector<uint8_t> GetValidIntegrityRdata() {
+ const IntegrityRecordRdata kValidRecord({'f', 'o', 'o'});
+ base::Optional<std::vector<uint8_t>> valid_serialized =
+ kValidRecord.Serialize();
+ CHECK(valid_serialized);
+ return *valid_serialized;
+ }
+
+ std::vector<uint8_t> GetMangledIntegrityRdata() {
+ std::vector<uint8_t> rdata = GetValidIntegrityRdata();
+ constexpr size_t kOffset = 2u;
+ CHECK_GT(rdata.size(), kOffset);
+ // Create a mangled version of |kValidRecord| by erasing a byte.
+ rdata.erase(rdata.begin() + kOffset);
+ return rdata;
+ }
+
+ void AddRules(MockDnsClientRuleList rules,
+ const IntegrityAddRulesOptions& options) {
+ if (options.add_a) {
+ rules.emplace_back("host", dns_protocol::kTypeA, options.secure_a,
+ MockDnsClientRule::Result(MockDnsClientRule::OK),
+ options.delay_a);
+ }
+
+ if (options.add_aaaa) {
+ rules.emplace_back("host", dns_protocol::kTypeAAAA, options.secure_aaaa,
+ MockDnsClientRule::Result(MockDnsClientRule::OK),
+ options.delay_aaaa);
+ }
+
+ if (options.add_integrity) {
+ std::vector<uint8_t> integrity_rdata = options.integrity_mangled
+ ? GetMangledIntegrityRdata()
+ : GetValidIntegrityRdata();
+ rules.emplace_back(
+ "host", dns_protocol::kExperimentalTypeIntegrity,
+ options.secure_integrity,
+ MockDnsClientRule::Result(BuildTestDnsIntegrityResponse(
+ "host", std::move(integrity_rdata))),
+ options.delay_integrity);
+ }
+
+ CreateResolver();
+ UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
+ }
+
+ std::unique_ptr<ResolveHostResponseHelper> DoIntegrityQuery(bool use_secure) {
+ if (use_secure) {
+ DnsConfigOverrides overrides;
+ overrides.secure_dns_mode = DnsConfig::SecureDnsMode::SECURE;
+ resolver_->SetDnsConfigOverrides(overrides);
+ }
+
+ return std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest(
+ HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
+ HostResolver::ResolveHostParameters(), resolve_context_.get(),
+ resolve_context_->host_cache()));
+ }
+
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(HostResolverManagerDnsTestIntegrity, IntegrityQuery) {
+ AddRules(CreateDefaultDnsRules(), IntegrityAddRulesOptions());
+
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ EXPECT_THAT(response->result_error(), IsOk());
+ base::Optional<std::vector<bool>> results =
+ response->request()->GetIntegrityResultsForTesting();
+
+ EXPECT_TRUE(response->request()->GetAddressResults());
+ EXPECT_FALSE(response->request()->GetTextResults());
+ EXPECT_THAT(results, Optional(UnorderedElementsAre(true)));
+}
+
+TEST_F(HostResolverManagerDnsTestIntegrity, IntegrityQueryMangled) {
+ IntegrityAddRulesOptions options;
+ options.integrity_mangled = true;
+ AddRules(CreateDefaultDnsRules(), options);
+
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ EXPECT_THAT(response->result_error(), IsOk());
+ base::Optional<std::vector<bool>> results =
+ response->request()->GetIntegrityResultsForTesting();
+
+ EXPECT_TRUE(response->request()->GetAddressResults());
+ EXPECT_FALSE(response->request()->GetTextResults());
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(UnorderedElementsAre(false)));
+}
+
+TEST_F(HostResolverManagerDnsTestIntegrity, IntegrityQueryOnlyOverSecure) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.secure_a = false;
+ rules_options.secure_aaaa = false;
+ rules_options.secure_integrity = false;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(false /* use_secure */);
+
+ EXPECT_THAT(response->result_error(), IsOk());
+ base::Optional<std::vector<bool>> results =
+ response->request()->GetIntegrityResultsForTesting();
+
+ EXPECT_FALSE(results);
+}
+
+// Ensure that the address results are preserved, even when the INTEGRITY query
+// completes last.
+TEST_F(HostResolverManagerDnsTestIntegrity, IntegrityQueryCompletesLast) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(1);
+
+ FastForwardBy(100 * kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ // Above, the A/AAAA queries took 100 time units. We only fast forward by 1
+ // time unit (1%) before answering the INTEGRITY query, to avoid triggering
+ // the timeout logic. This should work, assuming
+ // (1) the relative timeout is > 1% and
+ // (2) the absolute timeout is < (101 * kQuantum).
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+ // If this expectation fails, the INTEGRITY query was probably timed out.
+ // Check the |kDnsHttpssvcExtraTimeMs| and |kDnsHttpssvcExtraTimePercent|
+ // feature params in relation to this test's FastForward steps.
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(UnorderedElementsAre(true)));
+}
+
+// For symmetry with |IntegrityQueryCompletesLast|, test the case where the
+// INTEGRITY query completes first.
+TEST_F(HostResolverManagerDnsTestIntegrity, IntegrityQueryCompletesFirst) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(10);
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(UnorderedElementsAre(true)));
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+}
+
+// Ensure that the address results are preserved, even when the INTEGRITY query
+// completes last and fails.
+TEST_F(HostResolverManagerDnsTestIntegrity,
+ IntegrityQueryCompletesLastWithError) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.add_a = true;
+ rules_options.add_aaaa = true;
+ rules_options.add_integrity = false;
+
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(1);
+
+ FastForwardBy(100 * kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_FALSE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(IsEmpty()));
+}
+
+// Ensure that the address results are preserved, even when the INTEGRITY query
+// completes first and fails.
+TEST_F(HostResolverManagerDnsTestIntegrity,
+ IntegrityQueryCompletesFirstWithError) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.add_a = true;
+ rules_options.add_aaaa = true;
+ rules_options.add_integrity = false;
+
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(10);
+
+ FastForwardBy(kQuantum);
+
+ // This fails because there is no rule for the INTEGRITY query.
+ ASSERT_FALSE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(IsEmpty()));
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+}
+
+TEST_F(HostResolverManagerDnsTestIntegrity,
+ IntegrityQueryCompletesLastMangled) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.integrity_mangled = true;
+
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(1);
+
+ FastForwardBy(100 * kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(UnorderedElementsAre(false)));
+}
+
+TEST_F(HostResolverManagerDnsTestIntegrity,
+ IntegrityQueryCompletesFirstMangled) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.integrity_mangled = true;
+
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ constexpr base::TimeDelta kQuantum = base::TimeDelta::FromMilliseconds(10);
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(dns_client_->CompleteOneDelayedTransactionOfType(
+ DnsQueryType::INTEGRITY));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ FastForwardBy(kQuantum);
+
+ ASSERT_THAT(response->result_error(), IsOk());
+ EXPECT_THAT(response->request()->GetIntegrityResultsForTesting(),
+ Optional(UnorderedElementsAre(false)));
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+}
+
+// Make sure that INTEGRITY queries don't get cancelled *before* the configured
+// timeout, but do get cancelled after it, in the case where the absolute
+// timeout dominates.
+TEST_F(HostResolverManagerDnsTestIntegrity, RespectsAbsoluteTimeout) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.delay_a = true;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ // relative_timeout
+ // ┌────────────────────────────────┤
+ // │
+ // │ absolute_timeout
+ // ├────────────────────┤
+ // a_aaaa_elapsed │ time
+ // ├────────────────────┼─────────────────────────────────────────────────>
+ // Now â”” (moment when A and AAAA complete)
+ //
+ // When the A and AAAA queries complete, and only INTEGRITY remains, we start
+ // running the INTEGRITY timeout clock. This moment is |Now + a_aaaa_elapsed|,
+ // or just |a_aaaa_elapsed| if we let Now = 0. The INTEGRITY query is
+ // cancelled at the moment that |absolute_timeout| or |relative_timeout| runs
+ // out.
+ //
+ // The TimeDelta values of |absolute_timeout| and |relative_timeout| are
+ // computed from feature params.
+ //
+ // absolute_timeout = a_aaaa_elapsed + ExtraMs.
+ //
+ // relative_timeout = a_aaaa_elapsed * (1 + (ExtraPercent/100)).
+ //
+ // Assume ExtraMs > 0 and 0 < ExtraPercent < 100.
+ //
+ // For this test, we want the absolute timeout to happen *before* the relative
+ // timeout. Compute a value for a_aaaa_elapsed such that absolute_timeout
+ // comes before relative_timeout.
+ //
+ // Assuming ExtraPercent is not zero, we know that these two lines intersect
+ // for some value of a_aaaa_elapsed. Let's find it.
+ //
+ // Assume absolute_timeout = relative_timeout.
+ // a_aaaa_elapsed + ExtraMs = a_aaaa_elapsed * (1 + (ExtraPercent / 100)).
+ // ExtraMs = a_aaaa_elapsed * (1 + (ExtraPercent / 100)) - a_aaaa_elapsed.
+ // ExtraMs = a_aaaa_elapsed * ((1 + (ExtraPercent / 100)) - 1).
+ // ExtraMs / ((1 + (ExtraPercent / 100)) - 1) = a_aaaa_elapsed.
+ // Simplified:
+ // a_aaaa_elapsed = 100 * ExtraMs / ExtraPercent.
+ //
+ // For values of a_aaaa_elapsed < 100 * ExtraMs / ExtraPercent,
+ // relative_timeout < absolute_timeout. For larger values, absolute_timeout >
+ // relative_timeout.
+
+ base::TimeDelta absolute_timeout = base::TimeDelta::FromMilliseconds(
+ features::kDnsHttpssvcExtraTimeMs.Get());
+ base::TimeDelta intersection =
+ 100 * absolute_timeout / features::kDnsHttpssvcExtraTimePercent.Get();
+
+ // Let enough time pass during the A and AAAA transactions that the
+ // absolute timeout will be less than the relative timeout.
+ base::TimeDelta a_aaaa_elapsed = 50 * intersection;
+
+ FastForwardBy(a_aaaa_elapsed);
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ // Since the A and AAAA queries have only just completed, we shouldn't
+ // have timed out the INTEGRITY query.
+ EXPECT_FALSE(response->complete());
+
+ // After half of the absolute timeout, the query should still be alive.
+ FastForwardBy(absolute_timeout / 2);
+
+ // Since the absolute timeout has not yet elapsed, and it is shorter by
+ // design than the relative timeout, we shouldn't
+ // have timed out the INTEGRITY transaction.
+ EXPECT_FALSE(response->complete());
+
+ // After (more than) the timeout has passed, we should have cancelled
+ // the INTEGRITY transaction.
+ FastForwardBy(absolute_timeout);
+ ASSERT_THAT(response->result_error(), IsOk());
+
+ // Since we cancelled the transaction, we shouldn't have any INTEGRITY
+ // results.
+ EXPECT_FALSE(response->request()->GetIntegrityResultsForTesting());
+
+ // Out of paranoia, pass some more time to ensure no crashes occur.
+ FastForwardBy(base::TimeDelta::FromMilliseconds(100));
+}
+
+TEST_F(HostResolverManagerDnsTestIntegrity, RespectsRelativeTimeout) {
+ IntegrityAddRulesOptions rules_options;
+ rules_options.delay_a = false;
+ rules_options.delay_aaaa = true;
+ rules_options.delay_integrity = true;
+
+ AddRules(CreateDefaultDnsRules(), rules_options);
+
+ std::unique_ptr<ResolveHostResponseHelper> response =
+ DoIntegrityQuery(true /* use_secure */);
+
+ base::TimeDelta absolute_timeout = base::TimeDelta::FromMilliseconds(
+ features::kDnsHttpssvcExtraTimeMs.Get());
+ base::TimeDelta intersection =
+ 100 * absolute_timeout / features::kDnsHttpssvcExtraTimePercent.Get();
+
+ // Let little enough time pass during the A and AAAA transactions that the
+ // relative timeout will be less than the absolute timeout.
+ base::TimeDelta a_aaaa_elapsed = 0.05 * intersection;
+
+ // Since the A and AAAA queries haven't both completed yet, we shouldn't time
+ // out the INTEGRITY query.
+ FastForwardBy(a_aaaa_elapsed);
+
+ // Upon completing the AAAA transaction, the INTEGRITY timer should start
+ ASSERT_TRUE(
+ dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
+
+ base::TimeDelta relative_timeout =
+ a_aaaa_elapsed * features::kDnsHttpssvcExtraTimePercent.Get() / 100;
+
+ // After *less* than the relative timeout, the query shouldn't have concluded.
+ FastForwardBy(relative_timeout * 0.5);
+
+ EXPECT_FALSE(response->complete());
+
+ // After more than the relative timeout, the query should conclude by aborting
+ // the INTEGRITY query.
+ FastForwardBy(relative_timeout);
+
+ // The task should have completed with a cancelled INTEGRITY query.
+ ASSERT_THAT(response->result_error(), IsOk());
+ EXPECT_FALSE(response->request()->GetIntegrityResultsForTesting());
+ ASSERT_TRUE(response->request()->GetAddressResults());
+ EXPECT_THAT(response->request()->GetAddressResults()->endpoints(),
+ testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 108),
+ CreateExpected("::1", 108)));
+
+ // Out of paranoia, pass some more time to ensure no crashes occur.
+ FastForwardBy(base::TimeDelta::FromMilliseconds(100));
+}
+
TEST_F(HostResolverManagerDnsTest, DohProbeRequest) {
ChangeDnsConfig(CreateValidDnsConfig());
@@ -8787,349 +9324,6 @@ TEST_F(HostResolverManagerDnsTest, MultipleDohProbeRequests) {
EXPECT_FALSE(dns_client_->factory()->doh_probes_running());
}
-TEST_F(HostResolverManagerDnsTest, EsniQuery) {
- EsniContent c1, c2, c3;
- IPAddress a1(1, 2, 3, 4), a2(5, 6, 7, 8);
- IPAddress a3(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
-
- std::string kKey1 = GenerateWellFormedEsniKeys("a");
- std::string kKey2 = GenerateWellFormedEsniKeys("b");
- std::string kKey3 = GenerateWellFormedEsniKeys("c");
-
- c1.AddKey(kKey1);
-
- c2.AddKeyForAddress(a1, kKey2);
- c2.AddKeyForAddress(a2, kKey2);
- c2.AddKeyForAddress(a3, kKey2);
-
- c3.AddKeyForAddress(a1, kKey3);
-
- std::vector<EsniContent> esni_records = {c1, c2, c3};
-
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(BuildTestDnsEsniResponse(
- "host", std::move(esni_records))),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsOk());
-
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetTextResults());
-
- // The IPv6 address |a3| should come first, and the other
- // addresses should have been deduplicated.
- EXPECT_THAT(
- response.request()->GetAddressResults(),
- Optional(AllOf(Property(&AddressList::endpoints,
- UnorderedElementsAre(IPEndPoint(a3, 108),
- IPEndPoint(a1, 108),
- IPEndPoint(a2, 108))),
- Property(&AddressList::front, IPEndPoint(a3, 108)))));
-
- // During aggregation of ESNI query results, we drop ESNI keys
- // with no associated addresses, like key 1 here. (This is an implementation
- // decision declining a "MAY" behavior from the spec.)
- // So, we require that only keys 2 and 3 are surfaced.
- //
- // The Eq() wrappers are necessary here because keys_for_addresses
- // returns a container of StringPieces.
- EXPECT_THAT(
- response.request()->GetEsniResults(),
- Optional(AllOf(
- Property(&EsniContent::keys,
- UnorderedElementsAre(Eq(kKey2), Eq(kKey3))),
- Property(&EsniContent::keys_for_addresses,
- UnorderedElementsAre(
- Pair(a1, UnorderedElementsAre(Eq(kKey2), Eq(kKey3))),
- Pair(a2, UnorderedElementsAre(Eq(kKey2))),
- Pair(a3, UnorderedElementsAre(Eq(kKey2))))))));
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_InvalidConfig) {
- set_allow_fallback_to_proctask(false);
- // Set empty DnsConfig.
- InvalidateDnsConfig();
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_DNS_CACHE_MISS));
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_NonexistentDomain) {
- // Setup fallback to confirm it is not used for non-address results.
- set_allow_fallback_to_proctask(true);
- proc_->AddRuleForAllFamilies("host", "192.168.1.102");
- proc_->SignalMultiple(1u);
-
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::NODOMAIN),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_Failure) {
- // Setup fallback to confirm it is not used for non-address results.
- set_allow_fallback_to_proctask(true);
- proc_->AddRuleForAllFamilies("host", "192.168.1.102");
- proc_->SignalMultiple(1u);
-
- MockDnsClientRuleList rules;
- rules.emplace_back(
- "host", dns_protocol::kExperimentalTypeEsniDraft4, false /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::FAIL), false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_Timeout) {
- // Setup fallback to confirm it is not used for non-address results.
- set_allow_fallback_to_proctask(true);
- proc_->AddRuleForAllFamilies("host", "192.168.1.102");
- proc_->SignalMultiple(1u);
-
- MockDnsClientRuleList rules;
- rules.emplace_back(
- "host", dns_protocol::kExperimentalTypeEsniDraft4, false /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::TIMEOUT), false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_DNS_TIMED_OUT));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_Empty) {
- // Setup fallback to confirm it is not used for non-address results.
- set_allow_fallback_to_proctask(true);
- proc_->AddRuleForAllFamilies("host", "192.168.1.102");
- proc_->SignalMultiple(1u);
-
- MockDnsClientRuleList rules;
- rules.emplace_back(
- "host", dns_protocol::kExperimentalTypeEsniDraft4, false /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::EMPTY), false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_Malformed) {
- // Setup fallback to confirm it is not used for non-address results.
- set_allow_fallback_to_proctask(true);
- proc_->AddRuleForAllFamilies("host", "192.168.1.102");
- proc_->SignalMultiple(1u);
-
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::MALFORMED),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_DNS_MALFORMED_RESPONSE));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_MismatchedName) {
- EsniContent content;
- IPAddress address(1, 2, 3, 4);
- std::string key = GenerateWellFormedEsniKeys("a");
- content.AddKeyForAddress(address, key);
-
- std::vector<EsniContent> esni_records = {content};
-
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(BuildTestDnsEsniResponse(
- "host", std::move(esni_records), "not.host")),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_DNS_MALFORMED_RESPONSE));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-TEST_F(HostResolverManagerDnsTest, EsniQuery_WrongType) {
- // Respond to an ESNI query with an A response.
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(
- BuildTestDnsResponse("host", IPAddress(1, 2, 3, 4))),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- // Responses for the wrong type should be ignored.
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("ok", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
- EXPECT_FALSE(response.request()->GetAddressResults());
- EXPECT_FALSE(response.request()->GetTextResults());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-// Same as EsniQuery except we specify DNS HostResolverSource instead of relying
-// on automatic determination. Expect same results since DNS should be what we
-// automatically determine, but some slightly different logic paths are
-// involved.
-TEST_F(HostResolverManagerDnsTest, EsniDnsQuery) {
- EsniContent c1, c2, c3;
- IPAddress a1(1, 2, 3, 4), a2(5, 6, 7, 8);
-
- const std::string kKey1 = GenerateWellFormedEsniKeys("a");
- const std::string kKey2 = GenerateWellFormedEsniKeys("b");
- const std::string kKey3 = GenerateWellFormedEsniKeys("c");
-
- c1.AddKey(kKey1);
-
- c2.AddKeyForAddress(a1, kKey2);
- c2.AddKeyForAddress(a2, kKey2);
-
- c3.AddKeyForAddress(a1, kKey3);
-
- std::vector<EsniContent> esni_records = {c1, c2, c3};
-
- MockDnsClientRuleList rules;
- rules.emplace_back("host", dns_protocol::kExperimentalTypeEsniDraft4,
- false /* secure */,
- MockDnsClientRule::Result(BuildTestDnsEsniResponse(
- "host", std::move(esni_records))),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- HostResolver::ResolveHostParameters parameters;
- parameters.source = HostResolverSource::DNS;
- parameters.dns_query_type = DnsQueryType::ESNI;
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 108), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
- EXPECT_THAT(response.result_error(), IsOk());
- EXPECT_FALSE(response.request()->GetHostnameResults());
- EXPECT_FALSE(response.request()->GetTextResults());
-
- // The multiple ESNI records should have been merged when parsing
- // the results.
- c1.MergeFrom(c2);
- c1.MergeFrom(c3);
-
- // The ESNI records' addresses should have been merged into
- // the address list.
- ASSERT_TRUE(response.request()->GetAddressResults());
- EXPECT_THAT(
- response.request()->GetAddressResults()->endpoints(),
- testing::UnorderedElementsAre(IPEndPoint(a1, 108), IPEndPoint(a2, 108)));
-
- ASSERT_TRUE(response.request()->GetEsniResults().has_value());
-
- // During aggregation of ESNI query results, we drop ESNI keys
- // with no associated addresses, like key 1 here. (This is an implementation
- // decision declining a "MAY" behavior from the spec.) So, we require that
- // only keys 2 and 3 are surfaced.
- EXPECT_THAT(response.request()->GetEsniResults()->keys(),
- testing::UnorderedElementsAre(kKey2, kKey3));
- EXPECT_EQ(response.request()->GetEsniResults()->keys_for_addresses(),
- c1.keys_for_addresses());
-}
-
// Test that a newly-registered ResolveContext is immediately usable with a DNS
// configuration loaded before the context registration.
TEST_F(HostResolverManagerDnsTest,
@@ -9202,353 +9396,4 @@ TEST_F(HostResolverManagerDnsTest,
resolver_->DeregisterResolveContext(&context);
}
-class HostResolverManagerEsniTest : public HostResolverManagerDnsTest {
- public:
- HostResolverManagerEsniTest()
- : HostResolverManagerDnsTest(
- base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
- scoped_feature_list_.InitAndEnableFeature(features::kRequestEsniDnsRecords);
- }
-
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
-
- // Adds a rule returning a collection of ESNI records such that
- // - there is a lone key with no associated addresses
- // - there is an address associated with multiple keys
- // - there is a key associated with multiple addresses
- //
- // Returns a pair containing:
- // (1) a single merged EsniContent object which should be contained in
- // the eventual response.
- // (2) the collection of IPEndPoints corresponding to the
- // ESNI records' contained addresses; these are expected to
- // be contained in the eventual response's address list (assuming
- // no addresses are pruned by the address sorter, which will
- // be the case in the test, because MockAddressSorter no-ops)
- struct AddEsniRecordsRuleOptions {
- bool secure = true, delay = false;
- };
- std::pair<EsniContent, std::vector<IPEndPoint>> AddEsniRecordsRule(
- base::StringPiece hostname,
- AddEsniRecordsRuleOptions options,
- MockDnsClientRuleList* rules) {
- EsniContent c1, c2, c3;
- IPAddress a1(1, 2, 3, 4);
- IPAddress a2(5, 6, 7, 8);
-
- const std::string kKey1 = GenerateWellFormedEsniKeys("a");
- const std::string kKey2 = GenerateWellFormedEsniKeys("b");
- const std::string kKey3 = GenerateWellFormedEsniKeys("c");
-
- c1.AddKey(kKey1);
-
- c2.AddKeyForAddress(a1, kKey2);
- c2.AddKeyForAddress(a2, kKey2);
-
- c3.AddKeyForAddress(a1, kKey3);
-
- std::vector<EsniContent> esni_records = {c1, c2, c3};
- rules->emplace_back(std::string(hostname),
- dns_protocol::kExperimentalTypeEsniDraft4,
- options.secure,
- MockDnsClientRule::Result(BuildTestDnsEsniResponse(
- std::string(hostname), std::move(esni_records))),
- options.delay);
-
- // Key 1 will be dropped because it corresponds to no addresses;
- // section 4.2.2 of ESNI draft 4 gives implementors the option to associate
- // these with all IP addresses received in concurrent A and AAAA responses,
- // and we choose not to do this.
- c2.MergeFrom(c3);
- return std::make_pair(
- c2, std::vector<IPEndPoint>{IPEndPoint(a1, 80), IPEndPoint(a2, 80)});
- }
-};
-
-// Check that resolving ESNI queries alongside A and AAAA queries
-// results in a correct aggregation of addresses.
-TEST_F(HostResolverManagerEsniTest, AggregatesResults) {
- MockDnsClientRuleList rules;
-
- EsniContent esni_expectation;
- std::vector<IPEndPoint> expected_addresses;
- std::tie(esni_expectation, expected_addresses) =
- AddEsniRecordsRule("host", AddEsniRecordsRuleOptions(), &rules);
-
- rules.emplace_back("host", dns_protocol::kTypeA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- false /* delay */);
- rules.emplace_back("host", dns_protocol::kTypeAAAA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- false /* delay */);
- // Even though the A and AAAA results' addresses won't have any
- // associated ESNI keys, they should still be surfaced in GetAddressResults().
- expected_addresses.push_back(CreateExpected("127.0.0.1", 80));
- expected_addresses.push_back(CreateExpected("::1", 80));
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
- DnsConfigOverrides overrides;
- overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- resolver_->SetDnsConfigOverrides(overrides);
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
- HostResolver::ResolveHostParameters(), resolve_context_.get(),
- resolve_context_->host_cache()));
-
- ASSERT_THAT(response.result_error(), IsOk());
- EXPECT_THAT(response.request()->GetEsniResults(),
- testing::Optional(testing::Eq(esni_expectation)));
- // GetAddressResults() should surface addresses with and without
- // associated ESNI keys.
- ASSERT_THAT(response.request()->GetAddressResults()->endpoints(),
- testing::UnorderedElementsAreArray(expected_addresses));
-}
-
-// Test that addresses with associated ESNI keys are placed
-// first in the order provided to the address sorter.
-// (This corresponds to the order of the address list in the results
-// because MockAddressSorter's sort is a no-op.)
-TEST_F(HostResolverManagerEsniTest, EsniAddressesFirstInOrder) {
- MockDnsClientRuleList rules;
-
- EsniContent esni_expectation;
- std::vector<IPEndPoint> esni_addresses;
- std::tie(esni_expectation, esni_addresses) =
- AddEsniRecordsRule("host", AddEsniRecordsRuleOptions(), &rules);
-
- rules.emplace_back("host", dns_protocol::kTypeA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- false /* delay */);
- rules.emplace_back("host", dns_protocol::kTypeAAAA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- false /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
- DnsConfigOverrides overrides;
- overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- resolver_->SetDnsConfigOverrides(overrides);
-
- HostResolver::ResolveHostParameters parameters;
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
- parameters, resolve_context_.get(), resolve_context_->host_cache()));
-
- // Check that the IP addresses with associated
- // ESNI key objects occupy the initial entries of the
- // address list returned by the DNS query.
- ASSERT_THAT(response.result_error(), IsOk());
- ASSERT_TRUE(response.request()->GetAddressResults());
- const auto& result_addresses =
- response.request()->GetAddressResults()->endpoints();
- for (const IPEndPoint& address_with_esni_keys : esni_addresses) {
- int index = std::find(result_addresses.begin(), result_addresses.end(),
- address_with_esni_keys) -
- result_addresses.begin();
-
- // Since this address has associated ESNI keys, it should be in
- // the first esni_addresses.size() many entries of the result's
- // address list.
- ASSERT_TRUE(base::IsValueInRangeForNumericType<size_t>(index));
- EXPECT_LT(static_cast<size_t>(index), esni_addresses.size());
- }
-}
-
-TEST_F(HostResolverManagerEsniTest, OnlyMakesRequestOverSecureDns) {
- // Add some insecurely-accessible ESNI results alongside
- // the default (insecurely-accessible) IPv4 and IPv6 results
- // for the "ok" hostname.
- MockDnsClientRuleList rules = CreateDefaultDnsRules();
- AddEsniRecordsRuleOptions options;
- options.secure = false;
- AddEsniRecordsRule("ok", options, &rules);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("ok", 80), NetworkIsolationKey(), NetLogWithSource(),
- HostResolver::ResolveHostParameters(), resolve_context_.get(),
- resolve_context_->host_cache()));
-
- ASSERT_THAT(response.result_error(), IsOk());
-
- // Since the request wasn't secure, we shouldn't have
- // queried for any ESNI results.
- ASSERT_FALSE(response.request()->GetEsniResults());
-}
-
-// Make sure that ESNI queries don't get cancelled *before* the
-// configured timeout, but do get cancelled after it,
-// in the case where the absolute timeout dominates.
-TEST_F(HostResolverManagerEsniTest, RespectsAbsoluteTimeout) {
- // Add some delayed ESNI, IPv4, and IPv6 results
- MockDnsClientRuleList rules = CreateDefaultDnsRules();
- AddEsniRecordsRuleOptions options;
- options.delay = true;
- AddEsniRecordsRule("host", options, &rules);
- rules.emplace_back("host", dns_protocol::kTypeA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- true /* delay */);
- rules.emplace_back("host", dns_protocol::kTypeAAAA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- true /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
- DnsConfigOverrides overrides;
- overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- resolver_->SetDnsConfigOverrides(overrides);
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
- HostResolver::ResolveHostParameters(), resolve_context_.get(),
- resolve_context_->host_cache()));
-
- base::TimeDelta absolute_timeout =
- features::EsniDnsMaxAbsoluteAdditionalWait();
-
- // Let enough time pass during the A and AAAA transactions that the
- // absolute timeout will be less than the relative timeout.
- base::TimeDelta a_aaaa_elapsed =
- 50 * (100.0 / features::kEsniDnsMaxRelativeAdditionalWaitPercent.Get()) *
- absolute_timeout;
-
- FastForwardBy(a_aaaa_elapsed);
- ASSERT_TRUE(
- dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::A));
- ASSERT_TRUE(
- dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
-
- // Since the A and AAAA queries have only just completed, we shouldn't
- // have timed out the ESNI query.
- EXPECT_FALSE(response.complete());
-
- // After half of the absolute timeout, the query should still be alive.
- FastForwardBy(0.5 * absolute_timeout);
-
- // Since the absolute timeout has not yet elapsed, and it is shorter by
- // design than the relative timeout, we shouldn't
- // have timed out the ESNI transaction.
- EXPECT_FALSE(response.complete());
-
- // After (more than) the timeout has passed, we should have cancelled
- // the ESNI transaction.
- FastForwardBy(absolute_timeout);
- ASSERT_THAT(response.result_error(), IsOk());
-
- // Since we cancelled the transaction, we shouldn't have any ESNI results.
- EXPECT_FALSE(response.request()->GetEsniResults());
-}
-
-// Make sure that ESNI queries don't get cancelled *before* the
-// configured timeout, but do get cancelled after it,
-// in the case where the relative timeout dominates.
-TEST_F(HostResolverManagerEsniTest, RespectsRelativeTimeout) {
- // Add some delayed ESNI, IPv4, and IPv6 results
- MockDnsClientRuleList rules = CreateDefaultDnsRules();
- AddEsniRecordsRuleOptions options;
- options.delay = true;
- AddEsniRecordsRule("host", options, &rules);
- rules.emplace_back("host", dns_protocol::kTypeA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- false /* delay */);
- rules.emplace_back("host", dns_protocol::kTypeAAAA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- true /* delay */);
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
- DnsConfigOverrides overrides;
- overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- resolver_->SetDnsConfigOverrides(overrides);
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
- HostResolver::ResolveHostParameters(), resolve_context_.get(),
- resolve_context_->host_cache()));
-
- // Let little enough time pass during the A and AAAA transactions that the
- // relative timeout will be less than the absolute timeout.
- base::TimeDelta a_aaaa_elapsed =
- 0.05 * features::EsniDnsMaxAbsoluteAdditionalWait() *
- (100 / features::kEsniDnsMaxRelativeAdditionalWaitPercent.Get());
-
- // Since the A and AAAA queries haven't both completed yet, we shouldn't time
- // out the ESNI query.
- FastForwardBy(a_aaaa_elapsed);
-
- // Upon completing the AAAA transaction, the ESNI timer should start
- ASSERT_TRUE(
- dns_client_->CompleteOneDelayedTransactionOfType(DnsQueryType::AAAA));
-
- base::TimeDelta relative_timeout =
- 0.01 * features::kEsniDnsMaxRelativeAdditionalWaitPercent.Get() *
- a_aaaa_elapsed;
-
- // After *less* than the relative timeout, the query shouldn't have concluded.
- FastForwardBy(relative_timeout * 0.5);
-
- EXPECT_FALSE(response.complete());
-
- // After more than the relative timeout, the query should conclude by aborting
- // the ESNI query.
- FastForwardBy(relative_timeout * 0.5);
-
- // The task should have completed with a cancelled ESNI query.
- ASSERT_THAT(response.result_error(), IsOk());
- EXPECT_FALSE(response.request()->GetEsniResults());
- ASSERT_TRUE(response.request()->GetAddressResults());
- EXPECT_THAT(response.request()->GetAddressResults()->endpoints(),
- testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80),
- CreateExpected("::1", 80)));
-}
-
-// Test that we still receive delayed A/AAAA records
-// that arrive after a successful (non-delayed) ESNI transaction.
-TEST_F(HostResolverManagerEsniTest, WaitsForSlowAccompanyingQueries) {
- MockDnsClientRuleList rules;
-
- EsniContent esni_expectation;
- std::vector<IPEndPoint> expected_addresses;
- std::tie(esni_expectation, expected_addresses) =
- AddEsniRecordsRule("host", AddEsniRecordsRuleOptions(), &rules);
-
- rules.emplace_back("host", dns_protocol::kTypeA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- true /* delay */);
- expected_addresses.push_back(CreateExpected("127.0.0.1", 80));
-
- rules.emplace_back("host", dns_protocol::kTypeAAAA, true /* secure */,
- MockDnsClientRule::Result(MockDnsClientRule::OK),
- true /* delay */);
- expected_addresses.push_back(CreateExpected("::1", 80));
-
- CreateResolver();
- UseMockDnsClient(CreateValidDnsConfig(), std::move(rules));
- DnsConfigOverrides overrides;
- overrides.secure_dns_mode = DnsConfig::SecureDnsMode::AUTOMATIC;
- resolver_->SetDnsConfigOverrides(overrides);
-
- ResolveHostResponseHelper response(resolver_->CreateRequest(
- HostPortPair("host", 80), NetworkIsolationKey(), NetLogWithSource(),
- HostResolver::ResolveHostParameters(), resolve_context_.get(),
- resolve_context_->host_cache()));
-
- // Wait quite a long time. (If the timer were erroneously to have been
- // started, it should expire by the end of this elapsed window.)
- FastForwardBy(features::EsniDnsMaxAbsoluteAdditionalWait() * 10);
- dns_client_->CompleteDelayedTransactions();
-
- EXPECT_THAT(response.result_error(), IsOk());
- EXPECT_THAT(response.request()->GetEsniResults(),
- testing::Optional(testing::Eq(esni_expectation)));
- ASSERT_TRUE(response.request()->GetAddressResults());
- EXPECT_THAT(response.request()->GetAddressResults()->endpoints(),
- testing::UnorderedElementsAreArray(expected_addresses));
-}
-
} // namespace net
diff --git a/chromium/net/dns/host_resolver_mdns_listener_impl.cc b/chromium/net/dns/host_resolver_mdns_listener_impl.cc
index 88102dff25e..066cc635774 100644
--- a/chromium/net/dns/host_resolver_mdns_listener_impl.cc
+++ b/chromium/net/dns/host_resolver_mdns_listener_impl.cc
@@ -73,7 +73,7 @@ void HostResolverMdnsListenerImpl::OnRecordUpdate(
switch (query_type_) {
case DnsQueryType::UNSPECIFIED:
- case DnsQueryType::ESNI:
+ case DnsQueryType::INTEGRITY:
NOTREACHED();
break;
case DnsQueryType::A:
diff --git a/chromium/net/dns/host_resolver_mdns_task.cc b/chromium/net/dns/host_resolver_mdns_task.cc
index 551ab7ae25c..745b847eede 100644
--- a/chromium/net/dns/host_resolver_mdns_task.cc
+++ b/chromium/net/dns/host_resolver_mdns_task.cc
@@ -198,8 +198,8 @@ HostCache::Entry HostResolverMdnsTask::ParseResult(
switch (query_type) {
case DnsQueryType::UNSPECIFIED:
// Should create two separate transactions with specified type.
- case DnsQueryType::ESNI:
- // ESNI queries are not expected to be useful in mDNS, so they're not
+ case DnsQueryType::INTEGRITY:
+ // INTEGRITY queries are not expected to be useful in mDNS, so they're not
// supported.
NOTREACHED();
return HostCache::Entry(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
diff --git a/chromium/net/dns/httpssvc_metrics.cc b/chromium/net/dns/httpssvc_metrics.cc
new file mode 100644
index 00000000000..453e2a32ed2
--- /dev/null
+++ b/chromium/net/dns/httpssvc_metrics.cc
@@ -0,0 +1,254 @@
+// 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.
+
+#include "net/dns/httpssvc_metrics.h"
+
+#include "base/feature_list.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/notreached.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "net/base/features.h"
+#include "net/dns/dns_util.h"
+#include "net/dns/public/dns_protocol.h"
+
+namespace net {
+
+enum HttpssvcDnsRcode TranslateDnsRcodeForHttpssvcExperiment(uint8_t rcode) {
+ switch (rcode) {
+ case dns_protocol::kRcodeNOERROR:
+ return HttpssvcDnsRcode::kNoError;
+ case dns_protocol::kRcodeFORMERR:
+ return HttpssvcDnsRcode::kFormErr;
+ case dns_protocol::kRcodeSERVFAIL:
+ return HttpssvcDnsRcode::kServFail;
+ case dns_protocol::kRcodeNXDOMAIN:
+ return HttpssvcDnsRcode::kNxDomain;
+ case dns_protocol::kRcodeNOTIMP:
+ return HttpssvcDnsRcode::kNotImp;
+ case dns_protocol::kRcodeREFUSED:
+ return HttpssvcDnsRcode::kRefused;
+ default:
+ return HttpssvcDnsRcode::kUnrecognizedRcode;
+ }
+ NOTREACHED();
+}
+
+HttpssvcExperimentDomainCache::HttpssvcExperimentDomainCache() = default;
+HttpssvcExperimentDomainCache::~HttpssvcExperimentDomainCache() = default;
+
+bool HttpssvcExperimentDomainCache::ListContainsDomain(
+ const std::string& domain_list,
+ base::StringPiece domain,
+ base::Optional<base::flat_set<std::string>>& in_out_cached_list) {
+ if (!in_out_cached_list) {
+ in_out_cached_list = base::SplitString(
+ domain_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ }
+ return in_out_cached_list->find(domain) != in_out_cached_list->end();
+}
+
+bool HttpssvcExperimentDomainCache::IsExperimental(base::StringPiece domain) {
+ if (!base::FeatureList::IsEnabled(features::kDnsHttpssvc))
+ return false;
+ return ListContainsDomain(features::kDnsHttpssvcExperimentDomains.Get(),
+ domain, experimental_list_);
+}
+
+bool HttpssvcExperimentDomainCache::IsControl(base::StringPiece domain) {
+ std::vector<base::StringPiece> control_domains;
+ if (!base::FeatureList::IsEnabled(features::kDnsHttpssvc))
+ return false;
+ if (features::kDnsHttpssvcControlDomainWildcard.Get())
+ return !IsExperimental(domain);
+ return ListContainsDomain(features::kDnsHttpssvcControlDomains.Get(), domain,
+ control_list_);
+}
+
+HttpssvcMetrics::HttpssvcMetrics(bool expect_intact)
+ : expect_intact_(expect_intact) {}
+
+HttpssvcMetrics::~HttpssvcMetrics() {
+ RecordIntegrityMetrics();
+}
+
+void HttpssvcMetrics::SaveForNonIntegrity(
+ base::Optional<std::string> new_doh_provider_id,
+ base::TimeDelta resolve_time,
+ enum HttpssvcDnsRcode rcode) {
+ set_doh_provider_id(new_doh_provider_id);
+
+ non_integrity_resolve_times_.push_back(resolve_time);
+
+ if (rcode != HttpssvcDnsRcode::kNoError)
+ disqualified_ = true;
+}
+
+void HttpssvcMetrics::SaveNonIntegrityFailure() {
+ disqualified_ = true;
+}
+
+void HttpssvcMetrics::SaveForIntegrity(
+ base::Optional<std::string> new_doh_provider_id,
+ enum HttpssvcDnsRcode rcode_integrity,
+ const std::vector<bool>& condensed_records,
+ base::TimeDelta integrity_resolve_time) {
+ DCHECK(!rcode_integrity_.has_value());
+ set_doh_provider_id(new_doh_provider_id);
+
+ rcode_integrity_ = rcode_integrity;
+
+ num_integrity_records_ = condensed_records.size();
+
+ // We only record one "Integrity" sample per INTEGRITY query. In case
+ // multiple matching records are in present in the response, we
+ // combine their intactness values with logical AND.
+ const bool intact =
+ std::all_of(condensed_records.cbegin(), condensed_records.cend(),
+ [](bool b) { return b; });
+
+ DCHECK(!is_integrity_intact_.has_value());
+ is_integrity_intact_ = intact;
+
+ DCHECK(!integrity_resolve_time_.has_value());
+ integrity_resolve_time_ = integrity_resolve_time;
+}
+
+void HttpssvcMetrics::set_doh_provider_id(
+ base::Optional<std::string> new_doh_provider_id) {
+ // "Other" never gets updated.
+ if (doh_provider_id_.has_value() && *doh_provider_id_ == "Other")
+ return;
+
+ // If provider IDs mismatch, downgrade the new provider ID to "Other".
+ if ((doh_provider_id_.has_value() && !new_doh_provider_id.has_value()) ||
+ (doh_provider_id_.has_value() && new_doh_provider_id.has_value() &&
+ *doh_provider_id_ != *new_doh_provider_id)) {
+ new_doh_provider_id = "Other";
+ }
+
+ doh_provider_id_ = new_doh_provider_id;
+}
+
+std::string HttpssvcMetrics::BuildMetricName(
+ base::StringPiece leaf_name) const {
+ // Build shared pieces of the metric names.
+ const base::StringPiece expectation =
+ expect_intact_ ? "ExpectIntact" : "ExpectNoerror";
+ const std::string provider_id = doh_provider_id_.value_or("Other");
+
+ // Example INTEGRITY metric name:
+ // Net.DNS.HTTPSSVC.RecordIntegrity.CleanBrowsingAdult.ExpectIntact.DnsRcode
+ return base::JoinString({"Net.DNS.HTTPSSVC.RecordIntegrity",
+ provider_id.c_str(), expectation, leaf_name},
+ ".");
+}
+
+void HttpssvcMetrics::RecordIntegrityMetrics() {
+ // The HTTPSSVC experiment and its feature param indicating INTEGRITY must
+ // both be enabled.
+ DCHECK(base::FeatureList::IsEnabled(features::kDnsHttpssvc));
+ DCHECK(features::kDnsHttpssvcUseIntegrity.Get());
+
+ DCHECK(in_progress_);
+ in_progress_ = false;
+
+ // We really have no metrics to record without |integrity_resolve_time_| and
+ // |non_integrity_resolve_times_|. If this HttpssvcMetrics is in an
+ // inconsistent state, disqualify any metrics from being recorded.
+ if (!integrity_resolve_time_.has_value() ||
+ non_integrity_resolve_times_.empty()) {
+ disqualified_ = true;
+ }
+ if (disqualified_)
+ return;
+
+ // Record the metrics that the "ExpectIntact" and "ExpectNoerror" branches
+ // have in common.
+ RecordIntegrityCommonMetrics();
+
+ if (expect_intact_) {
+ // Record metrics that are unique to the "ExpectIntact" branch.
+ RecordIntegrityExpectIntactMetrics();
+ } else {
+ // Record metrics that are unique to the "ExpectNoerror" branch.
+ RecordIntegrityExpectNoerrorMetrics();
+ }
+}
+
+void HttpssvcMetrics::RecordIntegrityCommonMetrics() {
+ base::UmaHistogramMediumTimes(BuildMetricName("ResolveTimeIntegrityRecord"),
+ *integrity_resolve_time_);
+
+ const std::string kMetricResolveTimeNonIntegrityRecord =
+ BuildMetricName("ResolveTimeNonIntegrityRecord");
+ for (base::TimeDelta resolve_time_other : non_integrity_resolve_times_) {
+ base::UmaHistogramMediumTimes(kMetricResolveTimeNonIntegrityRecord,
+ resolve_time_other);
+ }
+
+ // ResolveTimeRatio is the INTEGRITY resolve time divided by the slower of the
+ // A or AAAA resolve times. Arbitrarily choosing precision at two decimal
+ // places.
+ std::vector<base::TimeDelta>::iterator slowest_non_integrity_resolve =
+ std::max_element(non_integrity_resolve_times_.begin(),
+ non_integrity_resolve_times_.end());
+ DCHECK(slowest_non_integrity_resolve != non_integrity_resolve_times_.end());
+
+ // Compute a percentage showing how much larger the INTEGRITY resolve time was
+ // compared to the slowest A or AAAA query.
+ //
+ // Computation happens on TimeDelta objects, which use CheckedNumeric. This
+ // will crash if the system clock leaps forward several hundred millennia
+ // (numeric_limits<int64_t>::max() microseconds ~= 292,000 years).
+ const int64_t resolve_time_percent =
+ (100 * *integrity_resolve_time_) / *slowest_non_integrity_resolve;
+
+ // Scale the value of |resolve_time_percent| by dividing by |kPercentScale|.
+ // Sample values are bounded between 1 and 20. A recorded sample of 10 means
+ // that the INTEGRITY resolve time took 100% of the slower A/AAAA resolve
+ // time. A sample of 20 means that the INTEGRITY resolve time was 200%
+ // relative to the A/AAAA resolve time, twice as long.
+ constexpr int64_t kMaxRatio = 20;
+ constexpr int64_t kPercentScale = 10;
+ base::UmaHistogramExactLinear(BuildMetricName("ResolveTimeRatio"),
+ resolve_time_percent / kPercentScale,
+ kMaxRatio);
+}
+
+void HttpssvcMetrics::RecordIntegrityExpectIntactMetrics() {
+ // Without |rocde_integrity_|, we can't make progress on any of these metrics.
+ DCHECK(rcode_integrity_.has_value());
+
+ // The ExpectIntact variant of the "DnsRcode" metric is only recorded when no
+ // records are received.
+ if (num_integrity_records_ == 0) {
+ base::UmaHistogramEnumeration(BuildMetricName("DnsRcode"),
+ *rcode_integrity_);
+ }
+ if (num_integrity_records_ > 0) {
+ if (*rcode_integrity_ == HttpssvcDnsRcode::kNoError) {
+ base::UmaHistogramBoolean(BuildMetricName("Integrity"),
+ is_integrity_intact_.value_or(false));
+ } else if (*rcode_integrity_ != HttpssvcDnsRcode::kNoError) {
+ // Record boolean indicating whether we received an INTEGRITY record and
+ // an error simultaneously.
+ base::UmaHistogramBoolean(BuildMetricName("RecordWithError"), true);
+ }
+ }
+}
+
+void HttpssvcMetrics::RecordIntegrityExpectNoerrorMetrics() {
+ if (rcode_integrity_.has_value()) {
+ base::UmaHistogramEnumeration(BuildMetricName("DnsRcode"),
+ *rcode_integrity_);
+ }
+ if (num_integrity_records_ > 0) {
+ base::UmaHistogramBoolean(BuildMetricName("RecordReceived"), true);
+ }
+}
+
+} // namespace net
diff --git a/chromium/net/dns/httpssvc_metrics.h b/chromium/net/dns/httpssvc_metrics.h
new file mode 100644
index 00000000000..76e4795cafc
--- /dev/null
+++ b/chromium/net/dns/httpssvc_metrics.h
@@ -0,0 +1,112 @@
+// 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.
+
+#ifndef NET_DNS_HTTPSSVC_METRICS_H_
+#define NET_DNS_HTTPSSVC_METRICS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/containers/flat_set.h"
+#include "base/optional.h"
+#include "base/strings/string_piece_forward.h"
+#include "base/time/time.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. (See HttpssvcDnsRcode in
+// tools/metrics/histograms/enums.xml.)
+enum HttpssvcDnsRcode {
+ kTimedOut = 0,
+ kUnrecognizedRcode,
+ kMissingDnsResponse,
+ kNoError,
+ kFormErr,
+ kServFail,
+ kNxDomain,
+ kNotImp,
+ kRefused,
+ kMaxValue = kRefused,
+};
+
+// Helper that classifies domains as experimental, control, or other. Queries
+// feature params and caches result to avoid repeated parsing.
+class NET_EXPORT_PRIVATE HttpssvcExperimentDomainCache {
+ public:
+ HttpssvcExperimentDomainCache();
+ ~HttpssvcExperimentDomainCache();
+ bool IsExperimental(base::StringPiece domain);
+ bool IsControl(base::StringPiece domain);
+
+ private:
+ bool ListContainsDomain(
+ const std::string& domain_list,
+ base::StringPiece domain,
+ base::Optional<base::flat_set<std::string>>& in_out_cached_list);
+
+ base::Optional<base::flat_set<std::string>> experimental_list_;
+ base::Optional<base::flat_set<std::string>> control_list_;
+};
+
+// Translate an RCODE value to the |HttpssvcDnsRcode| enum, which is used for
+// HTTPSSVC experimentation. The goal is to keep these values in a small,
+// contiguous range in order to satisfy the UMA enumeration function's
+// requirements. This function never returns |kTimedOut| |kUnrecognizedRcode|,
+// or |kMissingDnsResponse|.
+enum HttpssvcDnsRcode TranslateDnsRcodeForHttpssvcExperiment(uint8_t rcode);
+
+// Tool for aggregating HTTPSSVC and INTEGRITY metrics. Accumulates metrics via
+// the Save* methods. Records metrics to UMA on destruction.
+class NET_EXPORT_PRIVATE HttpssvcMetrics {
+ public:
+ explicit HttpssvcMetrics(bool expect_intact);
+ ~HttpssvcMetrics();
+ HttpssvcMetrics(HttpssvcMetrics&) = delete;
+ HttpssvcMetrics(HttpssvcMetrics&&) = delete;
+
+ // May be called many times.
+ void SaveForNonIntegrity(base::Optional<std::string> doh_provider_id,
+ base::TimeDelta resolve_time,
+ enum HttpssvcDnsRcode rcode);
+
+ // Save the fact that the non-integrity queries failed. Prevents metrics from
+ // being recorded.
+ void SaveNonIntegrityFailure();
+
+ // Must only be called once.
+ void SaveForIntegrity(base::Optional<std::string> doh_provider_id,
+ enum HttpssvcDnsRcode rcode,
+ const std::vector<bool>& condensed_records,
+ base::TimeDelta integrity_resolve_time);
+
+ private:
+ std::string BuildMetricName(base::StringPiece leaf_name) const;
+
+ // Records all the aggregated metrics to UMA.
+ void RecordIntegrityMetrics();
+ void RecordIntegrityCommonMetrics();
+ void RecordIntegrityExpectIntactMetrics();
+ void RecordIntegrityExpectNoerrorMetrics();
+
+ void set_doh_provider_id(base::Optional<std::string> doh_provider_id);
+
+ // RecordIntegrityMetrics() will do nothing when |disqualified_| is true.
+ bool disqualified_ = false;
+ const bool expect_intact_;
+ bool in_progress_ = true;
+ base::Optional<std::string> doh_provider_id_;
+ base::Optional<enum HttpssvcDnsRcode> rcode_integrity_;
+ size_t num_integrity_records_ = 0;
+ base::Optional<bool> is_integrity_intact_;
+ // We never make multiple INTEGRITY queries per DnsTask, so we only need
+ // one TimeDelta for the INTEGRITY query.
+ base::Optional<base::TimeDelta> integrity_resolve_time_;
+ std::vector<base::TimeDelta> non_integrity_resolve_times_;
+};
+
+} // namespace net
+
+#endif // NET_DNS_HTTPSSVC_METRICS_H_
diff --git a/chromium/net/dns/httpssvc_metrics_unittest.cc b/chromium/net/dns/httpssvc_metrics_unittest.cc
new file mode 100644
index 00000000000..1ce51cf7608
--- /dev/null
+++ b/chromium/net/dns/httpssvc_metrics_unittest.cc
@@ -0,0 +1,554 @@
+// 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.
+
+#include "net/dns/httpssvc_metrics.h"
+
+#include <string>
+#include <tuple>
+
+#include "base/feature_list.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "net/base/features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+// int: number of domains
+// bool: extra leading comma
+// bool: extra trailing comma
+using DomainListQuirksTuple = std::tuple<int, bool, bool>;
+
+// bool: DnsHttpssvc feature is enabled
+// bool: DnsHttpssvcUseIntegrity feature param
+// bool: DnsHttpssvcUseHttpssvc feature param
+// bool: DnsHttpssvcControlDomainWildcard feature param
+using HttpssvcFeatureTuple = std::tuple<bool, bool, bool, bool>;
+
+// DomainListQuirksTuple: quirks for the experimental domain list.
+// DomainListQuirksTuple: quirks for the control domain list.
+// HttpssvcFeatureTuple: config for the whole DnsHttpssvc feature.
+using ParsingTestParamTuple = std::
+ tuple<DomainListQuirksTuple, DomainListQuirksTuple, HttpssvcFeatureTuple>;
+
+// bool: whether we are querying for an experimental domain or a control domain
+// HttpssvcFeatureTuple: config for the whole DnsHttpssvc feature.
+using MetricsTestParamTuple = std::tuple<bool, HttpssvcFeatureTuple>;
+
+// Create a comma-separated list of |domains| with the given |quirks|.
+std::string FlattenDomainList(const std::vector<std::string>& domains,
+ DomainListQuirksTuple quirks) {
+ int num_domains;
+ bool leading_comma, trailing_comma;
+ std::tie(num_domains, leading_comma, trailing_comma) = quirks;
+
+ CHECK_EQ(static_cast<size_t>(num_domains), domains.size());
+ std::string flattened = base::JoinString(domains, ",");
+ if (leading_comma)
+ flattened.insert(flattened.begin(), ',');
+ if (trailing_comma)
+ flattened.push_back(',');
+ return flattened;
+}
+
+// Intermediate representation constructed from test parameters.
+struct HttpssvcFeatureConfig {
+ HttpssvcFeatureConfig() = default;
+
+ explicit HttpssvcFeatureConfig(const HttpssvcFeatureTuple& feature_tuple,
+ base::StringPiece experiment_domains,
+ base::StringPiece control_domains)
+ : experiment_domains(experiment_domains.as_string()),
+ control_domains(control_domains.as_string()) {
+ std::tie(enabled, use_integrity, use_httpssvc, control_domain_wildcard) =
+ feature_tuple;
+ }
+
+ void Apply(base::test::ScopedFeatureList* scoped_feature_list) const {
+ if (!enabled) {
+ scoped_feature_list->InitAndDisableFeature(features::kDnsHttpssvc);
+ return;
+ }
+ auto stringify = [](bool b) -> std::string { return b ? "true" : "false"; };
+ scoped_feature_list->InitAndEnableFeatureWithParameters(
+ features::kDnsHttpssvc,
+ {
+ {"DnsHttpssvcUseHttpssvc", stringify(use_httpssvc)},
+ {"DnsHttpssvcUseIntegrity", stringify(use_integrity)},
+ {"DnsHttpssvcEnableQueryOverInsecure", "false"},
+ {"DnsHttpssvcExperimentDomains", experiment_domains},
+ {"DnsHttpssvcControlDomains", control_domains},
+ {"DnsHttpssvcControlDomainWildcard",
+ stringify(control_domain_wildcard)},
+ });
+ }
+
+ bool enabled = false;
+ bool use_integrity = false;
+ bool use_httpssvc = false;
+ bool control_domain_wildcard = false;
+ std::string experiment_domains;
+ std::string control_domains;
+};
+
+std::vector<std::string> GenerateDomainList(base::StringPiece label, int n) {
+ std::vector<std::string> domains;
+ for (int i = 0; i < n; i++) {
+ domains.push_back(base::StrCat(
+ {"domain", base::NumberToString(i), ".", label, ".example"}));
+ }
+ return domains;
+}
+
+// Base for testing domain list parsing functions in
+// net::features::dns_httpssvc_experiment.
+class HttpssvcDomainParsingTest
+ : public ::testing::TestWithParam<ParsingTestParamTuple> {
+ public:
+ void SetUp() override {
+ DomainListQuirksTuple domain_quirks_experimental;
+ DomainListQuirksTuple domain_quirks_control;
+ HttpssvcFeatureTuple httpssvc_feature;
+ std::tie(domain_quirks_experimental, domain_quirks_control,
+ httpssvc_feature) = GetParam();
+
+ expected_experiment_domains_ = GenerateDomainList(
+ "experiment", std::get<0>(domain_quirks_experimental));
+ expected_control_domains_ =
+ GenerateDomainList("control", std::get<0>(domain_quirks_control));
+
+ config_ = HttpssvcFeatureConfig(
+ httpssvc_feature,
+ FlattenDomainList(expected_experiment_domains_,
+ domain_quirks_experimental),
+ FlattenDomainList(expected_control_domains_, domain_quirks_control));
+ config_.Apply(&scoped_feature_list_);
+ }
+
+ const HttpssvcFeatureConfig& config() { return config_; }
+
+ protected:
+ // The expected results of parsing the comma-separated domain lists in
+ // |experiment_domains| and |control_domains|, respectively.
+ std::vector<std::string> expected_experiment_domains_;
+ std::vector<std::string> expected_control_domains_;
+
+ private:
+ HttpssvcFeatureConfig config_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// This instantiation tests the domain list parser against various quirks,
+// e.g. leading comma.
+INSTANTIATE_TEST_SUITE_P(
+ HttpssvcMetricsTestDomainParsing,
+ HttpssvcDomainParsingTest,
+ testing::Combine(
+ // DomainListQuirksTuple for experimental domains. To fight back
+ // combinatorial explosion of tests, this tuple is pared down more than
+ // the one for control domains. This should not significantly hurt test
+ // coverage because |IsExperimentDomain| and |IsControlDomain| rely on a
+ // shared helper function.
+ testing::Combine(testing::Values(0, 1),
+ testing::Values(false),
+ testing::Values(false)),
+ // DomainListQuirksTuple for control domains.
+ testing::Combine(testing::Range(0, 3),
+ testing::Bool(),
+ testing::Bool()),
+ // HttpssvcFeatureTuple
+ testing::Combine(
+ testing::Bool() /* DnsHttpssvc feature enabled? */,
+ testing::Bool() /* DnsHttpssvcUseIntegrity */,
+ testing::Values(false) /* DnsHttpssvcUseHttpssvc */,
+ testing::Values(false) /* DnsHttpssvcControlDomainWildcard */)));
+
+// Base for testing the metrics collection code in |HttpssvcMetrics|.
+class HttpssvcMetricsTest
+ : public ::testing::TestWithParam<MetricsTestParamTuple> {
+ public:
+ void SetUp() override {
+ HttpssvcFeatureTuple httpssvc_feature;
+ std::tie(querying_experimental_, httpssvc_feature) = GetParam();
+ config_ = HttpssvcFeatureConfig(httpssvc_feature, "", "");
+ config_.Apply(&scoped_feature_list_);
+ }
+
+ std::string BuildMetricNamePrefix() const {
+ return base::StrCat(
+ {"Net.DNS.HTTPSSVC.RecordIntegrity.", doh_provider_, "."});
+ }
+
+ template <typename T>
+ void ExpectSample(base::StringPiece name, base::Optional<T> sample) const {
+ if (sample)
+ histo().ExpectUniqueSample(name, *sample, 1);
+ else
+ histo().ExpectTotalCount(name, 0);
+ }
+
+ void ExpectSample(base::StringPiece name,
+ base::Optional<base::TimeDelta> sample) const {
+ base::Optional<int64_t> sample_ms;
+ if (sample)
+ sample_ms = {sample->InMilliseconds()};
+ ExpectSample<int64_t>(name, sample_ms);
+ }
+
+ void VerifyMetricsForExpectIntact(
+ base::Optional<HttpssvcDnsRcode> rcode,
+ base::Optional<bool> integrity,
+ base::Optional<bool> record_with_error,
+ base::Optional<base::TimeDelta> resolve_time_integrity,
+ base::Optional<base::TimeDelta> resolve_time_non_integrity,
+ base::Optional<int> resolve_time_ratio) const {
+ const std::string kPrefix =
+ base::StrCat({BuildMetricNamePrefix(), "ExpectIntact."});
+ const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
+ const std::string kMetricIntegrity = base::StrCat({kPrefix, "Integrity"});
+ const std::string kMetricRecordWithError =
+ base::StrCat({kPrefix, "RecordWithError"});
+ const std::string kMetricResolveTimeIntegrity =
+ base::StrCat({kPrefix, "ResolveTimeIntegrityRecord"});
+ const std::string kMetricResolveTimeNonIntegrity =
+ base::StrCat({kPrefix, "ResolveTimeNonIntegrityRecord"});
+ const std::string kMetricResolveTimeRatio =
+ base::StrCat({kPrefix, "ResolveTimeRatio"});
+
+ ExpectSample(kMetricDnsRcode, rcode);
+ ExpectSample(kMetricIntegrity, integrity);
+ ExpectSample(kMetricRecordWithError, record_with_error);
+ ExpectSample(kMetricResolveTimeIntegrity, resolve_time_integrity);
+ ExpectSample(kMetricResolveTimeNonIntegrity, resolve_time_non_integrity);
+ ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
+ }
+
+ void VerifyMetricsForExpectNoerror(
+ base::Optional<HttpssvcDnsRcode> rcode,
+ base::Optional<int> record_received,
+ base::Optional<base::TimeDelta> resolve_time_integrity,
+ base::Optional<base::TimeDelta> resolve_time_non_integrity,
+ base::Optional<int> resolve_time_ratio) const {
+ const std::string kPrefix =
+ base::StrCat({BuildMetricNamePrefix(), "ExpectNoerror."});
+ const std::string kMetricDnsRcode = base::StrCat({kPrefix, "DnsRcode"});
+ const std::string kMetricRecordReceived =
+ base::StrCat({kPrefix, "RecordReceived"});
+ const std::string kMetricResolveTimeIntegrity =
+ base::StrCat({kPrefix, "ResolveTimeIntegrityRecord"});
+ const std::string kMetricResolveTimeNonIntegrity =
+ base::StrCat({kPrefix, "ResolveTimeNonIntegrityRecord"});
+ const std::string kMetricResolveTimeRatio =
+ base::StrCat({kPrefix, "ResolveTimeRatio"});
+
+ ExpectSample(kMetricDnsRcode, rcode);
+ ExpectSample(kMetricRecordReceived, record_received);
+ ExpectSample(kMetricResolveTimeIntegrity, resolve_time_integrity);
+ ExpectSample(kMetricResolveTimeNonIntegrity, resolve_time_non_integrity);
+ ExpectSample(kMetricResolveTimeRatio, resolve_time_ratio);
+ }
+
+ void VerifyMetricsForExpectIntact() {
+ VerifyMetricsForExpectIntact(base::nullopt, base::nullopt, base::nullopt,
+ base::nullopt, base::nullopt, base::nullopt);
+ }
+
+ void VerifyMetricsForExpectNoerror() {
+ VerifyMetricsForExpectNoerror(base::nullopt, base::nullopt, base::nullopt,
+ base::nullopt, base::nullopt);
+ }
+
+ const base::HistogramTester& histo() const { return histogram_; }
+ const HttpssvcFeatureConfig& config() const { return config_; }
+
+ protected:
+ bool querying_experimental_;
+
+ private:
+ HttpssvcFeatureConfig config_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+ base::HistogramTester histogram_;
+ std::string doh_provider_ = "Other";
+};
+
+// This instantiation focuses on whether the correct metrics are recorded. The
+// domain list parser is already tested against encoding quirks in
+// |HttpssvcMetricsTestDomainParsing|, so we fix the quirks at false.
+INSTANTIATE_TEST_SUITE_P(
+ HttpssvcMetricsTestSimple,
+ HttpssvcMetricsTest,
+ testing::Combine(
+ // Whether we are querying an experimental domain.
+ testing::Bool(),
+ // HttpssvcFeatureTuple
+ testing::Combine(
+ testing::Values(true) /* DnsHttpssvc feature enabled? */,
+ testing::Values(true) /* DnsHttpssvcUseIntegrity */,
+ testing::Values(false) /* DnsHttpssvcUseHttpssvc */,
+ testing::Values(false) /* DnsHttpssvcControlDomainWildcard */)));
+
+TEST_P(HttpssvcDomainParsingTest, ParseFeatureParamIntegrityDomains) {
+ HttpssvcExperimentDomainCache domain_cache;
+
+ // We are not testing this feature param yet.
+ CHECK(!config().use_httpssvc);
+
+ const std::string kReservedDomain = "neither.example";
+ EXPECT_FALSE(domain_cache.IsExperimental(kReservedDomain));
+ EXPECT_EQ(domain_cache.IsControl(kReservedDomain),
+ config().enabled && config().control_domain_wildcard);
+
+ // If |config().use_integrity| is true, then we expect all domains in
+ // |expected_experiment_domains_| to be experimental (same goes for
+ // control domains). Otherwise, no domain should be considered experimental or
+ // control.
+
+ if (!config().enabled) {
+ // When the HTTPSSVC feature is disabled, no domain should be considered
+ // experimental or control.
+ for (const std::string& experiment_domain : expected_experiment_domains_) {
+ EXPECT_FALSE(domain_cache.IsExperimental(experiment_domain));
+ EXPECT_FALSE(domain_cache.IsControl(experiment_domain));
+ }
+ for (const std::string& control_domain : expected_control_domains_) {
+ EXPECT_FALSE(domain_cache.IsExperimental(control_domain));
+ EXPECT_FALSE(domain_cache.IsControl(control_domain));
+ }
+ } else if (config().use_integrity) {
+ for (const std::string& experiment_domain : expected_experiment_domains_) {
+ EXPECT_TRUE(domain_cache.IsExperimental(experiment_domain));
+ EXPECT_FALSE(domain_cache.IsControl(experiment_domain));
+ }
+ for (const std::string& control_domain : expected_control_domains_) {
+ EXPECT_FALSE(domain_cache.IsExperimental(control_domain));
+ EXPECT_TRUE(domain_cache.IsControl(control_domain));
+ }
+ return;
+ }
+}
+
+// Only record metrics for a non-integrity query.
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityMissing) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+}
+
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityIntact) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ const base::TimeDelta kResolveTimeIntegrity =
+ base::TimeDelta::FromMilliseconds(15);
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForIntegrity(base::nullopt, HttpssvcDnsRcode::kNoError, {true},
+ kResolveTimeIntegrity);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ if (querying_experimental_) {
+ VerifyMetricsForExpectIntact(
+ base::nullopt /* rcode */, {true} /* integrity */,
+ base::nullopt /* record_with_error */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ VerifyMetricsForExpectIntact();
+
+ VerifyMetricsForExpectNoerror(
+ {HttpssvcDnsRcode::kNoError} /* rcode */, {1} /* record_received */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+}
+
+// This test simulates an INTEGRITY response that includes no INTEGRITY records,
+// but does have an error value for the RCODE.
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityMissingWithRcode) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ const base::TimeDelta kResolveTimeIntegrity =
+ base::TimeDelta::FromMilliseconds(15);
+
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForIntegrity(base::nullopt, HttpssvcDnsRcode::kNxDomain, {},
+ kResolveTimeIntegrity);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ if (querying_experimental_) {
+ VerifyMetricsForExpectIntact(
+ {HttpssvcDnsRcode::kNxDomain} /* rcode */,
+ base::nullopt /* integrity */, base::nullopt /* record_with_error */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ VerifyMetricsForExpectIntact();
+
+ VerifyMetricsForExpectNoerror(
+ {HttpssvcDnsRcode::kNxDomain} /* rcode */,
+ base::nullopt /* record_received */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+}
+
+// This test simulates an INTEGRITY response that includes an intact INTEGRITY
+// record, but also has an error RCODE.
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityIntactWithRcode) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ const base::TimeDelta kResolveTimeIntegrity =
+ base::TimeDelta::FromMilliseconds(15);
+
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForIntegrity(base::nullopt, HttpssvcDnsRcode::kNxDomain, {true},
+ kResolveTimeIntegrity);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ if (querying_experimental_) {
+ VerifyMetricsForExpectIntact(
+ // "DnsRcode" metric is omitted because we received an INTEGRITY record.
+ base::nullopt /* rcode */,
+ // "Integrity" metric is omitted because the RCODE is not NOERROR.
+ base::nullopt /* integrity */, {true} /* record_with_error */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ VerifyMetricsForExpectIntact();
+
+ VerifyMetricsForExpectNoerror(
+ {HttpssvcDnsRcode::kNxDomain} /* rcode */, {true} /* record_received */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+}
+
+// This test simulates an INTEGRITY response that includes a mangled INTEGRITY
+// record *and* has an error RCODE.
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityMangledWithRcode) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ const base::TimeDelta kResolveTimeIntegrity =
+ base::TimeDelta::FromMilliseconds(15);
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForIntegrity(base::nullopt, HttpssvcDnsRcode::kNxDomain, {false},
+ kResolveTimeIntegrity);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ if (querying_experimental_) {
+ VerifyMetricsForExpectIntact(
+ // "DnsRcode" metric is omitted because we received an INTEGRITY record.
+ base::nullopt /* rcode */,
+ // "Integrity" metric is omitted because the RCODE is not NOERROR.
+ base::nullopt /* integrity */, {true} /* record_with_error */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ VerifyMetricsForExpectIntact();
+
+ VerifyMetricsForExpectNoerror(
+ {HttpssvcDnsRcode::kNxDomain} /* rcode */, {true} /* record_received */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+}
+
+// This test simulates successful address queries and an INTEGRITY query that
+// timed out.
+TEST_P(HttpssvcMetricsTest, AddressAndIntegrityTimedOut) {
+ if (!config().enabled || !config().use_integrity) {
+ VerifyMetricsForExpectIntact();
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+ const base::TimeDelta kResolveTime = base::TimeDelta::FromMilliseconds(10);
+ const base::TimeDelta kResolveTimeIntegrity =
+ base::TimeDelta::FromMilliseconds(15);
+ base::Optional<HttpssvcMetrics> metrics(querying_experimental_);
+ metrics->SaveForIntegrity(base::nullopt, HttpssvcDnsRcode::kTimedOut, {},
+ kResolveTimeIntegrity);
+ metrics->SaveForNonIntegrity(base::nullopt, kResolveTime,
+ HttpssvcDnsRcode::kNoError);
+ metrics.reset(); // Record the metrics to UMA.
+
+ if (querying_experimental_) {
+ VerifyMetricsForExpectIntact(
+ {HttpssvcDnsRcode::kTimedOut} /* rcode */,
+ // "Integrity" metric is omitted because the RCODE is not NOERROR.
+ base::nullopt /* integrity */, base::nullopt /* record_with_error */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+
+ VerifyMetricsForExpectNoerror();
+ return;
+ }
+
+ VerifyMetricsForExpectIntact();
+
+ VerifyMetricsForExpectNoerror(
+ {HttpssvcDnsRcode::kTimedOut} /* rcode */,
+ base::nullopt /* record_received */,
+ {kResolveTimeIntegrity} /* resolve_time_integrity */,
+ {kResolveTime} /* resolve_time_non_integrity */,
+ {15} /* resolve_time_ratio */);
+}
+
+} // namespace net
diff --git a/chromium/net/dns/mock_host_resolver.cc b/chromium/net/dns/mock_host_resolver.cc
index d66b8e4a1fb..e0a23ae727b 100644
--- a/chromium/net/dns/mock_host_resolver.cc
+++ b/chromium/net/dns/mock_host_resolver.cc
@@ -139,12 +139,6 @@ class MockHostResolverBase::RequestImpl
return *nullopt_result;
}
- const base::Optional<EsniContent>& GetEsniResults() const override {
- DCHECK(complete_);
- static const base::NoDestructor<base::Optional<EsniContent>> nullopt_result;
- return *nullopt_result;
- }
-
net::ResolveErrorInfo GetResolveErrorInfo() const override {
DCHECK(complete_);
return resolve_error_info_;
@@ -1028,10 +1022,6 @@ class HangingHostResolver::RequestImpl
IMMEDIATE_CRASH();
}
- const base::Optional<EsniContent>& GetEsniResults() const override {
- IMMEDIATE_CRASH();
- }
-
net::ResolveErrorInfo GetResolveErrorInfo() const override {
IMMEDIATE_CRASH();
}
diff --git a/chromium/net/dns/public/BUILD.gn b/chromium/net/dns/public/BUILD.gn
index 04f2a9b57b3..832312ddeee 100644
--- a/chromium/net/dns/public/BUILD.gn
+++ b/chromium/net/dns/public/BUILD.gn
@@ -19,8 +19,8 @@ source_set("public") {
"dns_protocol.h",
"dns_query_type.cc",
"dns_query_type.h",
- "doh_provider_list.cc",
- "doh_provider_list.h",
+ "doh_provider_entry.cc",
+ "doh_provider_entry.h",
"resolve_error_info.cc",
"resolve_error_info.h",
"util.cc",
@@ -35,7 +35,7 @@ source_set("public") {
source_set("tests") {
testonly = true
sources = [
- "doh_provider_list_unittest.cc",
+ "doh_provider_entry_unittest.cc",
"util_unittest.cc",
]
diff --git a/chromium/net/dns/public/dns_protocol.h b/chromium/net/dns/public/dns_protocol.h
index ea9112feb00..c77dbaa7cd4 100644
--- a/chromium/net/dns/public/dns_protocol.h
+++ b/chromium/net/dns/public/dns_protocol.h
@@ -153,11 +153,6 @@ static const uint16_t kTypeANY = 255;
// Experimental DNS record types pending IANA assignment.
//
-// Record type proposed for TLS Encrypted Server Name Indication
-// (ESNI, draft 4) records:
-// https://tools.ietf.org/html/draft-ietf-tls-esni-04#section-8.3
-static const uint16_t kExperimentalTypeEsniDraft4 = 65439;
-
// The INTEGRITY RR type exists purely for measuring how the DNS ecosystem
// handles new RR types.
// https://docs.google.com/document/d/14eCqVyT_3MSj7ydqNFl1Yl0yg1fs6g24qmYUUdi5V-k/edit?usp=sharing
diff --git a/chromium/net/dns/public/dns_query_type.h b/chromium/net/dns/public/dns_query_type.h
index 7d407a62d01..ecc61ea597d 100644
--- a/chromium/net/dns/public/dns_query_type.h
+++ b/chromium/net/dns/public/dns_query_type.h
@@ -20,14 +20,15 @@ enum class DnsQueryType {
TXT,
PTR,
SRV,
- ESNI,
- MAX = ESNI
+ INTEGRITY,
+ MAX = INTEGRITY
};
const DnsQueryType kDnsQueryTypes[] = {
DnsQueryType::UNSPECIFIED, DnsQueryType::A, DnsQueryType::AAAA,
DnsQueryType::TXT, DnsQueryType::PTR, DnsQueryType::SRV,
- DnsQueryType::ESNI};
+ DnsQueryType::INTEGRITY,
+};
static_assert(base::size(kDnsQueryTypes) ==
static_cast<unsigned>(DnsQueryType::MAX) + 1,
diff --git a/chromium/net/dns/public/doh_provider_list.cc b/chromium/net/dns/public/doh_provider_entry.cc
index b5b2a50ef89..0422c8c6a7a 100644
--- a/chromium/net/dns/public/doh_provider_list.cc
+++ b/chromium/net/dns/public/doh_provider_entry.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/dns/public/doh_provider_list.h"
+#include "net/dns/public/doh_provider_entry.h"
#include <utility>
@@ -12,54 +12,28 @@
namespace net {
-DohProviderEntry::DohProviderEntry(
- std::string provider,
- base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
- std::set<std::string> ip_strs,
- std::set<std::string> dns_over_tls_hostnames,
- std::string dns_over_https_template,
- std::string ui_name,
- std::string privacy_policy,
- bool display_globally,
- std::set<std::string> display_countries)
- : provider(std::move(provider)),
- provider_id_for_histogram(std::move(provider_id_for_histogram)),
- dns_over_tls_hostnames(std::move(dns_over_tls_hostnames)),
- dns_over_https_template(std::move(dns_over_https_template)),
- ui_name(std::move(ui_name)),
- privacy_policy(std::move(privacy_policy)),
- display_globally(display_globally),
- display_countries(std::move(display_countries)) {
- DCHECK(!this->dns_over_https_template.empty());
- DCHECK(dns_util::IsValidDohTemplate(this->dns_over_https_template,
- nullptr /* server_method */));
+namespace {
- DCHECK(!display_globally || this->display_countries.empty());
- if (display_globally || !this->display_countries.empty()) {
- DCHECK(!this->ui_name.empty());
- DCHECK(!this->privacy_policy.empty());
- DCHECK(this->provider_id_for_histogram.has_value());
- }
- for (const auto& display_country : this->display_countries) {
- DCHECK_EQ(2u, display_country.size());
- }
- for (const std::string& ip_str : ip_strs) {
+std::set<IPAddress> ParseIPs(const std::set<base::StringPiece>& ip_strs) {
+ std::set<IPAddress> ip_addresses;
+ for (base::StringPiece ip_str : ip_strs) {
IPAddress ip_address;
bool success = ip_address.AssignFromIPLiteral(ip_str);
DCHECK(success);
- ip_addresses.insert(ip_address);
+ ip_addresses.insert(std::move(ip_address));
}
+ return ip_addresses;
}
-DohProviderEntry::DohProviderEntry(const DohProviderEntry& other) = default;
-DohProviderEntry::~DohProviderEntry() = default;
+} // namespace
-const std::vector<DohProviderEntry>& GetDohProviderList() {
+// static
+const DohProviderEntry::List& DohProviderEntry::GetList() {
// The provider names in these entries should be kept in sync with the
// DohProviderId histogram suffix list in
// tools/metrics/histograms/histograms.xml.
- static const base::NoDestructor<std::vector<DohProviderEntry>> providers{{
- DohProviderEntry(
+ static const base::NoDestructor<DohProviderEntry::List> providers{{
+ new DohProviderEntry(
"CleanBrowsingAdult", base::nullopt /* provider_id_for_histogram */,
{"185.228.168.10", "185.228.169.11", "2a0d:2a00:1::1",
"2a0d:2a00:2::1"},
@@ -67,7 +41,7 @@ const std::vector<DohProviderEntry>& GetDohProviderList() {
"https://doh.cleanbrowsing.org/doh/adult-filter{?dns}",
"" /* ui_name */, "" /* privacy_policy */,
false /* display_globally */, {} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"CleanBrowsingFamily",
DohProviderIdForHistogram::kCleanBrowsingFamily,
{"185.228.168.168", "185.228.169.168",
@@ -77,7 +51,7 @@ const std::vector<DohProviderEntry>& GetDohProviderList() {
"CleanBrowsing (Family Filter)" /* ui_name */,
"https://cleanbrowsing.org/privacy" /* privacy_policy */,
true /* display_globally */, {} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"CleanBrowsingSecure", base::nullopt /* provider_id_for_histogram */,
{"185.228.168.9", "185.228.169.9", "2a0d:2a00:1::2",
"2a0d:2a00:2::2"},
@@ -85,7 +59,7 @@ const std::vector<DohProviderEntry>& GetDohProviderList() {
"https://doh.cleanbrowsing.org/doh/security-filter{?dns}",
"" /* ui_name */, "" /* privacy_policy */,
false /* display_globally */, {} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"Cloudflare", DohProviderIdForHistogram::kCloudflare,
{"1.1.1.1", "1.0.0.1", "2606:4700:4700::1111",
"2606:4700:4700::1001"},
@@ -96,63 +70,64 @@ const std::vector<DohProviderEntry>& GetDohProviderList() {
"https://developers.cloudflare.com/1.1.1.1/privacy/"
"public-dns-resolver/" /* privacy_policy */,
true /* display_globally */, {} /* display_countries */),
- DohProviderEntry("Comcast", base::nullopt /* provider_id_for_histogram */,
- {"75.75.75.75", "75.75.76.76", "2001:558:feed::1",
- "2001:558:feed::2"},
- {"dot.xfinity.com"} /* dns_over_tls_hostnames */,
- "https://doh.xfinity.com/dns-query{?dns}",
- "" /* ui_name */, "" /* privacy_policy */,
- false /* display_globally */,
- {} /* display_countries */),
- DohProviderEntry("Cznic", base::nullopt /* provider_id_for_histogram */,
- {"185.43.135.1", "2001:148f:fffe::1"},
- {"odvr.nic.cz"} /* dns_over_tls_hostnames */,
- "https://odvr.nic.cz/doh", "" /* ui_name */,
- "" /* privacy_policy */, false /* display_globally */,
- {} /* display_countries */),
+ new DohProviderEntry(
+ "Comcast", base::nullopt /* provider_id_for_histogram */,
+ {"75.75.75.75", "75.75.76.76", "2001:558:feed::1",
+ "2001:558:feed::2"},
+ {"dot.xfinity.com"} /* dns_over_tls_hostnames */,
+ "https://doh.xfinity.com/dns-query{?dns}", "" /* ui_name */,
+ "" /* privacy_policy */, false /* display_globally */,
+ {} /* display_countries */),
+ new DohProviderEntry(
+ "Cznic", base::nullopt /* provider_id_for_histogram */,
+ {"185.43.135.1", "2001:148f:fffe::1"},
+ {"odvr.nic.cz"} /* dns_over_tls_hostnames */,
+ "https://odvr.nic.cz/doh", "" /* ui_name */, "" /* privacy_policy */,
+ false /* display_globally */, {} /* display_countries */),
// Note: DNS.SB has separate entries for autoupgrade and settings UI to
// allow the extra |no_ecs| parameter for autoupgrade. This parameter
// disables EDNS Client Subnet (ECS) handling in order to match the
// behavior of the upgraded-from classic DNS server.
- DohProviderEntry(
+ new DohProviderEntry(
"Dnssb", base::nullopt /* provider_id_for_histogram */,
{"185.222.222.222", "185.184.222.222", "2a09::", "2a09::1"},
{"dns.sb"} /* dns_over_tls_hostnames */,
"https://doh.dns.sb/dns-query?no_ecs=true{&dns}", "" /* ui_name */,
"" /* privacy_policy */, false /* display_globally */,
{} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"DnssbUserSelected", DohProviderIdForHistogram::kDnsSb,
{} /* ip_strs */, {} /* dns_over_tls_hostnames */,
"https://doh.dns.sb/dns-query{?dns}", "DNS.SB" /* ui_name */,
"https://dns.sb/privacy/" /* privacy_policy */,
false /* display_globally */, {"EE", "DE"} /* display_countries */),
- DohProviderEntry("Google", DohProviderIdForHistogram::kGoogle,
- {"8.8.8.8", "8.8.4.4", "2001:4860:4860::8888",
- "2001:4860:4860::8844"},
- {"dns.google", "dns.google.com",
- "8888.google"} /* dns_over_tls_hostnames */,
- "https://dns.google/dns-query{?dns}",
- "Google (Public DNS)" /* ui_name */,
- "https://developers.google.com/speed/public-dns/"
- "privacy" /* privacy_policy */,
- true /* display_globally */, {} /* display_countries */),
- DohProviderEntry("Iij", DohProviderIdForHistogram::kIij, {} /* ip_strs */,
- {} /* dns_over_tls_hostnames */,
- "https://public.dns.iij.jp/dns-query",
- "IIJ (Public DNS)" /* ui_name */,
- "https://public.dns.iij.jp/" /* privacy_policy */,
- false /* display_globally */,
- {"JP"} /* display_countries */),
- DohProviderEntry("OpenDNS", base::nullopt /* provider_id_for_histogram */,
- {"208.67.222.222", "208.67.220.220", "2620:119:35::35",
- "2620:119:53::53"},
- {""} /* dns_over_tls_hostnames */,
- "https://doh.opendns.com/dns-query{?dns}",
- "" /* ui_name */, "" /* privacy_policy */,
- false /* display_globally */,
- {} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry("Google", DohProviderIdForHistogram::kGoogle,
+ {"8.8.8.8", "8.8.4.4", "2001:4860:4860::8888",
+ "2001:4860:4860::8844"},
+ {"dns.google", "dns.google.com",
+ "8888.google"} /* dns_over_tls_hostnames */,
+ "https://dns.google/dns-query{?dns}",
+ "Google (Public DNS)" /* ui_name */,
+ "https://developers.google.com/speed/public-dns/"
+ "privacy" /* privacy_policy */,
+ true /* display_globally */,
+ {} /* display_countries */),
+ new DohProviderEntry("Iij", DohProviderIdForHistogram::kIij,
+ {} /* ip_strs */, {} /* dns_over_tls_hostnames */,
+ "https://public.dns.iij.jp/dns-query",
+ "IIJ (Public DNS)" /* ui_name */,
+ "https://public.dns.iij.jp/" /* privacy_policy */,
+ false /* display_globally */,
+ {"JP"} /* display_countries */),
+ new DohProviderEntry(
+ "OpenDNS", base::nullopt /* provider_id_for_histogram */,
+ {"208.67.222.222", "208.67.220.220", "2620:119:35::35",
+ "2620:119:53::53"},
+ {""} /* dns_over_tls_hostnames */,
+ "https://doh.opendns.com/dns-query{?dns}", "" /* ui_name */,
+ "" /* privacy_policy */, false /* display_globally */,
+ {} /* display_countries */),
+ new DohProviderEntry(
"OpenDNSFamily", base::nullopt /* provider_id_for_histogram */,
{"208.67.222.123", "208.67.220.123", "2620:119:35::123",
"2620:119:53::123"},
@@ -160,36 +135,94 @@ const std::vector<DohProviderEntry>& GetDohProviderList() {
"https://doh.familyshield.opendns.com/dns-query{?dns}",
"" /* ui_name */, "" /* privacy_policy */,
false /* display_globally */, {} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"Quad9Cdn", base::nullopt /* provider_id_for_histogram */,
{"9.9.9.11", "149.112.112.11", "2620:fe::11", "2620:fe::fe:11"},
{"dns11.quad9.net"} /* dns_over_tls_hostnames */,
"https://dns11.quad9.net/dns-query", "" /* ui_name */,
"" /* privacy_policy */, false /* display_globally */,
{} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"Quad9Insecure", base::nullopt /* provider_id_for_histogram */,
{"9.9.9.10", "149.112.112.10", "2620:fe::10", "2620:fe::fe:10"},
{"dns10.quad9.net"} /* dns_over_tls_hostnames */,
"https://dns10.quad9.net/dns-query", "" /* ui_name */,
"" /* privacy_policy */, false /* display_globally */,
{} /* display_countries */),
- DohProviderEntry(
+ new DohProviderEntry(
"Quad9Secure", DohProviderIdForHistogram::kQuad9Secure,
{"9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9"},
{"dns.quad9.net", "dns9.quad9.net"} /* dns_over_tls_hostnames */,
"https://dns.quad9.net/dns-query", "Quad9 (9.9.9.9)" /* ui_name */,
"https://www.quad9.net/home/privacy/" /* privacy_policy */,
true /* display_globally */, {} /* display_countries */),
- DohProviderEntry("Switch", base::nullopt /* provider_id_for_histogram */,
- {"130.59.31.251", "130.59.31.248", "2001:620:0:ff::2",
- "2001:620:0:ff::3"},
- {"dns.switch.ch"} /* dns_over_tls_hostnames */,
- "https://dns.switch.ch/dns-query", "" /* ui_name */,
- "" /* privacy_policy */, false /* display_globally */,
- {} /* display_countries */),
+ new DohProviderEntry(
+ "Switch", base::nullopt /* provider_id_for_histogram */,
+ {"130.59.31.251", "130.59.31.248", "2001:620:0:ff::2",
+ "2001:620:0:ff::3"},
+ {"dns.switch.ch"} /* dns_over_tls_hostnames */,
+ "https://dns.switch.ch/dns-query", "" /* ui_name */,
+ "" /* privacy_policy */, false /* display_globally */,
+ {} /* display_countries */),
}};
return *providers;
}
+// static
+DohProviderEntry DohProviderEntry::ConstructForTesting(
+ std::string provider,
+ base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
+ std::set<base::StringPiece> ip_strs,
+ std::set<std::string> dns_over_tls_hostnames,
+ std::string dns_over_https_template,
+ std::string ui_name,
+ std::string privacy_policy,
+ bool display_globally,
+ std::set<std::string> display_countries) {
+ return DohProviderEntry(provider, provider_id_for_histogram, ip_strs,
+ dns_over_tls_hostnames, dns_over_https_template,
+ ui_name, privacy_policy, display_globally,
+ display_countries);
+}
+
+DohProviderEntry::DohProviderEntry(DohProviderEntry&& other) = default;
+DohProviderEntry& DohProviderEntry::operator=(DohProviderEntry&& other) =
+ default;
+
+DohProviderEntry::~DohProviderEntry() = default;
+
+DohProviderEntry::DohProviderEntry(
+ std::string provider,
+ base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
+ std::set<base::StringPiece> ip_strs,
+ std::set<std::string> dns_over_tls_hostnames,
+ std::string dns_over_https_template,
+ std::string ui_name,
+ std::string privacy_policy,
+ bool display_globally,
+ std::set<std::string> display_countries)
+ : provider(std::move(provider)),
+ provider_id_for_histogram(std::move(provider_id_for_histogram)),
+ ip_addresses(ParseIPs(ip_strs)),
+ dns_over_tls_hostnames(std::move(dns_over_tls_hostnames)),
+ dns_over_https_template(std::move(dns_over_https_template)),
+ ui_name(std::move(ui_name)),
+ privacy_policy(std::move(privacy_policy)),
+ display_globally(display_globally),
+ display_countries(std::move(display_countries)) {
+ DCHECK(!this->dns_over_https_template.empty());
+ DCHECK(dns_util::IsValidDohTemplate(this->dns_over_https_template,
+ nullptr /* server_method */));
+
+ DCHECK(!display_globally || this->display_countries.empty());
+ if (display_globally || !this->display_countries.empty()) {
+ DCHECK(!this->ui_name.empty());
+ DCHECK(!this->privacy_policy.empty());
+ DCHECK(this->provider_id_for_histogram.has_value());
+ }
+ for (const auto& display_country : this->display_countries) {
+ DCHECK_EQ(2u, display_country.size());
+ }
+}
+
} // namespace net
diff --git a/chromium/net/dns/public/doh_provider_list.h b/chromium/net/dns/public/doh_provider_entry.h
index 5b3050874a3..150ea48bef5 100644
--- a/chromium/net/dns/public/doh_provider_list.h
+++ b/chromium/net/dns/public/doh_provider_entry.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 NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
-#define NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
+#ifndef NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
+#define NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
#include <set>
#include <string>
@@ -41,37 +41,56 @@ enum class DohProviderIdForHistogram {
// codes, if any, where the entry is eligible for being displayed in the
// dropdown menu.
struct NET_EXPORT DohProviderEntry {
- DohProviderEntry(
+ public:
+ using List = std::vector<const DohProviderEntry*>;
+
+ std::string provider;
+ // A provider_id_for_histogram is required for entries that are intended to
+ // be visible in the UI.
+ base::Optional<DohProviderIdForHistogram> provider_id_for_histogram;
+ std::set<IPAddress> ip_addresses;
+ std::set<std::string> dns_over_tls_hostnames;
+ std::string dns_over_https_template;
+ std::string ui_name;
+ std::string privacy_policy;
+ bool display_globally;
+ std::set<std::string> display_countries;
+
+ // Returns the full list of DoH providers. A subset of this list may be used
+ // to support upgrade in automatic mode or to populate the dropdown menu for
+ // secure mode.
+ static const List& GetList();
+
+ static DohProviderEntry ConstructForTesting(
std::string provider,
base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
- std::set<std::string> ip_strs,
+ std::set<base::StringPiece> ip_strs,
std::set<std::string> dns_over_tls_hostnames,
std::string dns_over_https_template,
std::string ui_name,
std::string privacy_policy,
bool display_globally,
std::set<std::string> display_countries);
- DohProviderEntry(const DohProviderEntry& other);
+
+ // Entries are move-only. This allows tests to construct a List but ensures
+ // that |const DohProviderEntry*| is a safe type for application code.
+ DohProviderEntry(DohProviderEntry&& other);
+ DohProviderEntry& operator=(DohProviderEntry&& other);
~DohProviderEntry();
- const std::string provider;
- // A provider_id_for_histogram is required for entries that are intended to
- // be visible in the UI.
- const base::Optional<DohProviderIdForHistogram> provider_id_for_histogram;
- std::set<IPAddress> ip_addresses;
- const std::set<std::string> dns_over_tls_hostnames;
- const std::string dns_over_https_template;
- const std::string ui_name;
- const std::string privacy_policy;
- bool display_globally;
- std::set<std::string> display_countries;
+ private:
+ DohProviderEntry(
+ std::string provider,
+ base::Optional<DohProviderIdForHistogram> provider_id_for_histogram,
+ std::set<base::StringPiece> ip_strs,
+ std::set<std::string> dns_over_tls_hostnames,
+ std::string dns_over_https_template,
+ std::string ui_name,
+ std::string privacy_policy,
+ bool display_globally,
+ std::set<std::string> display_countries);
};
-// Returns the full list of DoH providers. A subset of this list may be used
-// to support upgrade in automatic mode or to populate the dropdown menu for
-// secure mode.
-NET_EXPORT const std::vector<DohProviderEntry>& GetDohProviderList();
-
} // namespace net
-#endif // NET_DNS_PUBLIC_DOH_PROVIDER_LIST_H_
+#endif // NET_DNS_PUBLIC_DOH_PROVIDER_ENTRY_H_
diff --git a/chromium/net/dns/public/doh_provider_list_unittest.cc b/chromium/net/dns/public/doh_provider_entry_unittest.cc
index 60750e6d86a..e5cf5b79cf5 100644
--- a/chromium/net/dns/public/doh_provider_list_unittest.cc
+++ b/chromium/net/dns/public/doh_provider_entry_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/dns/public/doh_provider_list.h"
+#include "net/dns/public/doh_provider_entry.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -10,7 +10,7 @@ namespace net {
namespace {
TEST(DohProviderListTest, GetDohProviderList) {
- const std::vector<DohProviderEntry>& list = GetDohProviderList();
+ const DohProviderEntry::List& list = DohProviderEntry::GetList();
EXPECT_FALSE(list.empty());
}
diff --git a/chromium/net/dns/record_parsed.cc b/chromium/net/dns/record_parsed.cc
index 1ca18d8d22c..23c2f2eb4bc 100644
--- a/chromium/net/dns/record_parsed.cc
+++ b/chromium/net/dns/record_parsed.cc
@@ -62,9 +62,6 @@ std::unique_ptr<const RecordParsed> RecordParsed::CreateFrom(
case OptRecordRdata::kType:
rdata = OptRecordRdata::Create(record.rdata, *parser);
break;
- case EsniRecordRdata::kType:
- rdata = EsniRecordRdata::Create(record.rdata, *parser);
- break;
case IntegrityRecordRdata::kType:
rdata = IntegrityRecordRdata::Create(record.rdata);
break;
diff --git a/chromium/net/dns/record_rdata.cc b/chromium/net/dns/record_rdata.cc
index 74200808b57..08d89d4fc15 100644
--- a/chromium/net/dns/record_rdata.cc
+++ b/chromium/net/dns/record_rdata.cc
@@ -18,88 +18,12 @@
namespace net {
-namespace {
-
-// Helper function for parsing ESNI (TLS 1.3 Encrypted
-// Server Name Indication, draft 4) RDATA.
-//
-// Precondition: |reader| points to the beginning of an
-// incoming ESNI-type RecordRdata's data
-//
-// If the ESNIRecord contains a well-formed
-// ESNIKeys field, advances |reader| immediately past the field
-// and returns true. Otherwise, returns false.
-WARN_UNUSED_RESULT bool AdvancePastEsniKeysField(
- base::BigEndianReader* reader) {
- DCHECK(reader);
-
- // Skip |esni_keys.version|.
- if (!reader->Skip(2))
- return false;
-
- // Within esni_keys, skip |public_name|,
- // |keys|, and |cipher_suites|.
- base::StringPiece piece_for_skipping;
- for (int i = 0; i < 3; ++i) {
- if (!reader->ReadU16LengthPrefixed(&piece_for_skipping))
- return false;
- }
-
- // Skip the |esni_keys.padded_length| field.
- if (!reader->Skip(2))
- return false;
-
- // Skip the |esni_keys.extensions| field.
- return reader->ReadU16LengthPrefixed(&piece_for_skipping);
-}
-
-// Parses a single ESNI address set, appending the addresses to |out|.
-WARN_UNUSED_RESULT bool ParseEsniAddressSet(base::StringPiece address_set,
- std::vector<IPAddress>* out) {
- DCHECK(out);
-
- IPAddressBytes address_bytes;
- base::BigEndianReader address_set_reader(address_set.data(),
- address_set.size());
- while (address_set_reader.remaining()) {
- // enum AddressType, section 4.2.1 of ESNI draft 4
- // values: 4 (IPv4), 6 (IPv6)
- uint8_t address_type = 0;
- if (!address_set_reader.ReadU8(&address_type))
- return false;
-
- switch (address_type) {
- case 4: {
- address_bytes.Resize(IPAddress::kIPv4AddressSize);
- break;
- }
- case 6: {
- address_bytes.Resize(IPAddress::kIPv6AddressSize);
- break;
- }
- default: // invalid address type
- return false;
- }
- if (!address_set_reader.ReadBytes(address_bytes.data(),
- address_bytes.size()))
- return false;
- out->emplace_back(address_bytes);
- }
- return true;
-}
-
-} // namespace
-
static const size_t kSrvRecordMinimumSize = 6;
-// Source: https://tools.ietf.org/html/draft-ietf-tls-esni-04, section 4.1
-// (This isn't necessarily a tight bound, but it doesn't need to be:
-// |HasValidSize| is just used for sanity-check validation.)
-// - ESNIKeys field: 8 bytes of length prefixes, 4 bytes of mandatory u16
-// fields, >=7 bytes of length-prefixed fields' contents
-// - ESNIRecord field = ESNIKeys field + 2 bytes for |dns_extensions|'s
-// length prefix
-static const size_t kEsniDraft4MinimumSize = 21;
+// The simplest INTEGRITY record is a U16-length-prefixed nonce (containing zero
+// bytes) followed by its SHA256 digest.
+static constexpr size_t kIntegrityMinimumSize =
+ sizeof(uint16_t) + IntegrityRecordRdata::kDigestLen;
bool RecordRdata::HasValidSize(const base::StringPiece& data, uint16_t type) {
switch (type) {
@@ -109,8 +33,8 @@ bool RecordRdata::HasValidSize(const base::StringPiece& data, uint16_t type) {
return data.size() == IPAddress::kIPv4AddressSize;
case dns_protocol::kTypeAAAA:
return data.size() == IPAddress::kIPv6AddressSize;
- case dns_protocol::kExperimentalTypeEsniDraft4:
- return data.size() >= kEsniDraft4MinimumSize;
+ case dns_protocol::kExperimentalTypeIntegrity:
+ return data.size() >= kIntegrityMinimumSize;
case dns_protocol::kTypeCNAME:
case dns_protocol::kTypePTR:
case dns_protocol::kTypeTXT:
@@ -449,72 +373,6 @@ bool OptRecordRdata::Opt::operator==(const OptRecordRdata::Opt& other) const {
return code_ == other.code_ && data_ == other.data_;
}
-EsniRecordRdata::EsniRecordRdata() = default;
-
-EsniRecordRdata::~EsniRecordRdata() = default;
-
-// static
-std::unique_ptr<EsniRecordRdata> EsniRecordRdata::Create(
- base::StringPiece data,
- const DnsRecordParser& parser) {
- base::BigEndianReader reader(data.data(), data.size());
-
- // TODO: Once BoringSSL CL 37704 lands, replace
- // this with Boring's SSL_parse_esni_record,
- // which does the same thing.
- if (!AdvancePastEsniKeysField(&reader))
- return nullptr;
-
- size_t esni_keys_len = reader.ptr() - data.data();
-
- base::StringPiece dns_extensions;
- if (!reader.ReadU16LengthPrefixed(&dns_extensions) || reader.remaining() > 0)
- return nullptr;
-
- // Check defensively that we're not about to read OOB.
- CHECK_LT(esni_keys_len, data.size());
- auto rdata = base::WrapUnique(new EsniRecordRdata);
- rdata->esni_keys_ = std::string(data.begin(), esni_keys_len);
-
- base::BigEndianReader dns_extensions_reader(dns_extensions.data(),
- dns_extensions.size());
- if (dns_extensions_reader.remaining() == 0)
- return rdata;
-
- // ESNI Draft 4 only permits one extension type, address_set,
- // so reject if we see any other extension type.
- uint16_t dns_extension_type = 0;
- if (!dns_extensions_reader.ReadU16(&dns_extension_type) ||
- dns_extension_type != kAddressSetExtensionType)
- return nullptr;
-
- base::StringPiece address_set;
- if (!dns_extensions_reader.ReadU16LengthPrefixed(&address_set) ||
- !ParseEsniAddressSet(address_set, &rdata->addresses_))
- return nullptr;
-
- // In TLS, it's forbidden to send the same extension more than once in an
- // extension block; assuming that the same restriction applies here, the
- // record is ill-formed if any bytes follow the first (and only) extension.
- if (dns_extensions_reader.remaining() > 0)
- return nullptr;
-
- return rdata;
-}
-
-uint16_t EsniRecordRdata::Type() const {
- return EsniRecordRdata::kType;
-}
-
-bool EsniRecordRdata::IsEqual(const RecordRdata* other) const {
- if (other->Type() != Type())
- return false;
- const EsniRecordRdata* esni_other =
- static_cast<const EsniRecordRdata*>(other);
- return esni_keys_ == esni_other->esni_keys_ &&
- addresses_ == esni_other->addresses_;
-}
-
IntegrityRecordRdata::IntegrityRecordRdata(Nonce nonce)
: nonce_(std::move(nonce)), digest_(Hash(nonce_)), is_intact_(true) {}
diff --git a/chromium/net/dns/record_rdata.h b/chromium/net/dns/record_rdata.h
index 42d7c1c6111..d652eb7e7ab 100644
--- a/chromium/net/dns/record_rdata.h
+++ b/chromium/net/dns/record_rdata.h
@@ -11,8 +11,8 @@
#include <string>
#include <vector>
+#include "base/check_op.h"
#include "base/compiler_specific.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string_piece.h"
@@ -269,49 +269,6 @@ class NET_EXPORT_PRIVATE OptRecordRdata : public RecordRdata {
DISALLOW_COPY_AND_ASSIGN(OptRecordRdata);
};
-// TLS 1.3 Encrypted Server Name Indication
-// record format (https://tools.ietf.org/id/draft-ietf-tls-esni-04.txt)
-// struct {
-// ESNIKeys esni_keys; // see spec
-// Extension dns_extensions<0..2 ^ 16 - 1>;
-// } ESNIRecord;
-class NET_EXPORT EsniRecordRdata : public RecordRdata {
- public:
- static constexpr uint16_t kType = dns_protocol::kExperimentalTypeEsniDraft4;
- static constexpr uint16_t kAddressSetExtensionType = 0x1001u;
-
- ~EsniRecordRdata() override;
-
- // Parsing an ESNIRecord Rdata succeeds when all of the following hold:
- // 1. The esni_keys field is well-formed.
- // 2. The dns_extensions field is well-formed and, additionally, valid
- // in the sense that its enum members have values allowed by the spec.
- // 3. The Rdata field contains no data beyond the ESNIKeys and, optionally,
- // one DNS extension of type address_set.
- static std::unique_ptr<EsniRecordRdata> Create(base::StringPiece data,
- const DnsRecordParser& parser);
-
- // Two EsniRecordRdatas compare equal if their ESNIKeys fields agree
- // and their address sets contain the same addresses in the same order.
- bool IsEqual(const RecordRdata* other) const override;
- uint16_t Type() const override;
-
- // Returns the ESNIKeys field of the record. This is an opaque bitstring
- // passed to the SSL library.
- base::StringPiece esni_keys() const { return esni_keys_; }
-
- // Returns the IP addresses parsed from the address_set DNS extension, if any.
- const std::vector<IPAddress>& addresses() const { return addresses_; }
-
- private:
- EsniRecordRdata();
-
- std::string esni_keys_;
- std::vector<IPAddress> addresses_;
-
- DISALLOW_COPY_AND_ASSIGN(EsniRecordRdata);
-};
-
// This class parses and serializes the INTEGRITY DNS record.
//
// This RR was invented for a preliminary HTTPSSVC experiment. See the public
diff --git a/chromium/net/dns/record_rdata_unittest.cc b/chromium/net/dns/record_rdata_unittest.cc
index c70e674a2d9..88f4c2bd96f 100644
--- a/chromium/net/dns/record_rdata_unittest.cc
+++ b/chromium/net/dns/record_rdata_unittest.cc
@@ -136,472 +136,6 @@ TEST(RecordRdataTest, ParseCnameRecord) {
ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}
-// Appends a well-formed ESNIKeys struct to the stream owned by "writer".
-// Returns the length, in bytes, of this struct, or 0 on error.
-//
-// (There is no ambiguity in the return value because a well-formed
-// ESNIKeys struct has positive length.)
-void AppendWellFormedEsniKeys(base::BigEndianWriter* writer) {
- CHECK(writer);
- writer->WriteBytes(kWellFormedEsniKeys, kWellFormedEsniKeysSize);
-}
-
-// This helper checks |keys| against the well-formed sample ESNIKeys
-// struct; it's necessary because we can't implicitly convert
-// kWellFormedEsniKeys to a StringPiece (it's a byte array, not a
-// null-terminated string).
-void ExpectMatchesSampleKeys(base::StringPiece keys) {
- EXPECT_EQ(keys,
- base::StringPiece(kWellFormedEsniKeys, kWellFormedEsniKeysSize));
-}
-
-// Appends an IP address in network byte order, prepended by one byte
-// containing its version number, to |*serialized_addresses|. Appends
-// the corresponding IPAddress object to |*address_objects|.
-void AppendAnotherIPAddress(std::vector<uint8_t>* serialized_addresses,
- std::vector<IPAddress>* address_objects,
- int ip_version) {
- CHECK(serialized_addresses);
- CHECK(address_objects);
-
- // To make the addresses vary, but in a deterministic manner, assign octets
- // in increasing order as they're requested, potentially eventually wrapping
- // to 0.
- static uint8_t next_octet;
-
- CHECK(ip_version == 4 || ip_version == 6);
- const int address_num_bytes = ip_version == 4 ? 4 : 16;
-
- std::vector<uint8_t> address_bytes;
- for (int i = 0; i < address_num_bytes; ++i)
- address_bytes.push_back(next_octet++);
- IPAddress address(address_bytes.data(), address_num_bytes);
-
- serialized_addresses->push_back(ip_version);
- serialized_addresses->insert(serialized_addresses->end(),
- address_bytes.begin(), address_bytes.end());
- address_objects->push_back(address);
-}
-
-// Writes a dns_extensions ESNIRecord block containing given the address
-// set to |writer|. This involves:
-// - writing the 16-bit length prefix for the dns_extensions block
-// - writing the 16-bit extension type (0x1001 "address_set")
-// - writing the 16-bit length prefix for the address set extension
-// - writing the extension itself
-void AppendDnsExtensionsBlock(base::BigEndianWriter* writer,
- const std::vector<uint8_t>& address_list) {
- CHECK(writer);
- // 2 bytes for the DNS extension type
- writer->WriteU16(4 +
- address_list.size()); // length of the dns_extensions field
- writer->WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer->WriteU16(address_list.size()); // length of the address set
- writer->WriteBytes(address_list.data(), address_list.size());
-}
-
-// Test parsing a well-formed ESNI record with no DNS extensions.
-TEST(RecordRdataTest, ParseEsniRecordNoExtensions) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(0); // dns_extensions length
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
-
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
- ASSERT_THAT(record_obj, NotNull());
- EXPECT_TRUE(record_obj->IsEqual(record_obj.get()));
- EXPECT_EQ(record_obj->esni_keys(),
- std::string(kWellFormedEsniKeys, kWellFormedEsniKeysSize));
- EXPECT_EQ(record_obj->Type(), dns_protocol::kExperimentalTypeEsniDraft4);
-}
-
-// Test parsing a well-formed ESNI record bearing an address_set extension
-// containing a single IPv4 address.
-TEST(RecordRdataTest, ParseEsniRecordOneIPv4Address) {
- // ESNI record:
- // well-formed ESNI keys
- // extensions length
- // extension
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- std::vector<uint8_t> address_list;
- std::vector<IPAddress> addresses_for_validation;
-
- AppendAnotherIPAddress(&address_list, &addresses_for_validation,
- 4 /* ip_version */);
-
- AppendDnsExtensionsBlock(&writer, address_list);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
-
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
- ASSERT_THAT(record_obj, NotNull());
-
- const auto& addresses = record_obj->addresses();
-
- EXPECT_EQ(addresses, addresses_for_validation);
-
- EXPECT_TRUE(record_obj->IsEqual(record_obj.get()));
- ExpectMatchesSampleKeys(record_obj->esni_keys());
-}
-
-// Test parsing a well-formed ESNI record bearing an address_set extension
-// containing a single IPv6 address.
-TEST(RecordRdataTest, ParseEsniRecordOneIPv6Address) {
- // ESNI record:
- // well-formed ESNI keys
- // extensions length
- // extension
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- std::vector<uint8_t> address_list;
- std::vector<IPAddress> addresses_for_validation;
-
- AppendAnotherIPAddress(&address_list, &addresses_for_validation,
- 6 /* ip_version */);
-
- AppendDnsExtensionsBlock(&writer, address_list);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
-
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
- ASSERT_THAT(record_obj, NotNull());
-
- const auto& addresses = record_obj->addresses();
-
- EXPECT_EQ(addresses, addresses_for_validation);
-
- EXPECT_TRUE(record_obj->IsEqual(record_obj.get()));
- ExpectMatchesSampleKeys(record_obj->esni_keys());
-}
-
-// Test parsing a well-formed ESNI record bearing an address_set extension
-// containing several IPv4 and IPv6 addresses.
-TEST(RecordRdataTest, ParseEsniRecordManyAddresses) {
- // ESNI record:
- // well-formed ESNI keys
- // extensions length
- // extension
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- std::vector<uint8_t> address_list;
- std::vector<IPAddress> addresses_for_validation;
-
- for (int i = 0; i < 100; ++i)
- AppendAnotherIPAddress(&address_list, &addresses_for_validation,
- (i % 3) ? 4 : 6 /* ip_version */);
-
- AppendDnsExtensionsBlock(&writer, address_list);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
-
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
- ASSERT_THAT(record_obj, NotNull());
-
- const auto& addresses = record_obj->addresses();
-
- EXPECT_EQ(addresses, addresses_for_validation);
-
- EXPECT_TRUE(record_obj->IsEqual(record_obj.get()));
- ExpectMatchesSampleKeys(record_obj->esni_keys());
-}
-
-// Test that we correctly reject a record with an ill-formed ESNI keys field.
-//
-// This test makes sure that the //net-side record parser is able
-// correctly to handle the case where an external ESNI keys validation
-// subroutine reports that the keys are ill-formed; because this validation
-// will eventually be performed by BoringSSL once the corresponding
-// BSSL code lands, it's out of scope here to exercise the
-// validation logic itself.
-TEST(RecordRdataTest, EsniMalformedRecord_InvalidEsniKeys) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
-
- // Oops! This otherwise well-formed ESNIKeys struct is missing its
- // final byte, and the reader contains no content after this incomplete
- // struct.
- const char ill_formed_esni_keys[] = {
- 0xff, 0x3, 0x0, 0x0, 0x0, 0x24, 0x0, 0x1d, 0x0, 0x20,
- 0xed, 0xed, 0xc8, 0x68, 0xc1, 0x71, 0xd6, 0x9e, 0xa9, 0xf0,
- 0xa2, 0xc9, 0xf5, 0xa9, 0xdc, 0xcf, 0xf9, 0xb8, 0xed, 0x15,
- 0x5c, 0xc4, 0x5a, 0xec, 0x6f, 0xb2, 0x86, 0x14, 0xb7, 0x71,
- 0x1b, 0x7c, 0x0, 0x2, 0x13, 0x1, 0x1, 0x4, 0x0};
- writer.WriteBytes(ill_formed_esni_keys, sizeof(ill_formed_esni_keys));
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an empty address_set extension is correctly accepted.
-TEST(RecordRdataTest, ParseEsniRecord_EmptyAddressSet) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(4); // length of the dns_extensions field
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(0); // length of the (empty) address_set extension
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, NotNull());
-}
-
-// Test that we correctly reject a record invalid due to having extra
-// data within its dns_extensions block but after its last extension.
-TEST(RecordRdataTest, EsniMalformedRecord_TrailingDataWithinDnsExtensions) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(5); // length of the dns_extensions field
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(0); // length of the (empty) address_set extension
-
- // Pad the otherwise-valid extensions block with one byte of garbage.
- writer.WriteBytes(&"a", 1);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that we correctly reject a record with two well-formed
-// DNS extensions (only one extension of each type is permitted).
-TEST(RecordRdataTest, EsniMalformedRecord_TooManyExtensions) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(8); // length of the dns_extensions field
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(0); // length of the (empty) address_set extension
- // Write another (empty, but completely valid on its own) extension,
- // rendering the record invalid.
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(0);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNIRecord with an extension of invalid type
-// is correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_InvalidExtensionType) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- // 2 bytes for the DNS extension type
- writer.WriteU16(2); // length of the dns_extensions field
- writer.WriteU16(0xdead); // invalid address type
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an address_set extension missing a length field
-// is correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_MalformedAddressSetLength) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- // 3 bytes: 2 for the DNS extension type, and one for our
- // too-short address_set length
- writer.WriteU16(3); // length of the dns_extensions field
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- // oops! need two bytes for the address length
- writer.WriteU8(57);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with malformed dns_extensions length is
-// correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_MalformedDnsExtensionsLength) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- // Oops! Length field of dns_extensions should be 2 bytes.
- writer.WriteU8(57);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with invalid dns_extensions length is
-// correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_BadDnsExtensionsLength) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- // Length-prepend the dns_extensions field with value 5, even though
- // the extensions object will have length 4 (two U16's): this should
- // make the record be rejected as malformed.
- writer.WriteU16(5);
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(0); // length of the address_set extension
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with invalid address_set extension length is
-// correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_BadAddressSetLength) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(4); // 2 bytes for each of the U16s to be written
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- // Oops! Length-prepending the empty address_set field with the value 1.
- writer.WriteU16(1);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with an address_set entry of bad address
-// type is correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_InvalidAddressType) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- writer.WriteU16(9); // dns_extensions length: two U16's and a 5-byte address
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
-
- std::vector<uint8_t> address_list;
- IPAddress ipv4;
- ASSERT_TRUE(net::ParseURLHostnameToAddress("192.168.1.1", &ipv4));
- address_list.push_back(5); // Oops! "5" isn't a valid AddressType.
- std::copy(ipv4.bytes().begin(), ipv4.bytes().end(),
- std::back_inserter(address_list));
-
- writer.WriteU16(address_list.size());
- writer.WriteBytes(address_list.data(), address_list.size());
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with an address_set entry of bad address
-// type is correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_NotEnoughAddressData_IPv4) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- std::vector<uint8_t> address_list;
- std::vector<IPAddress> addresses_for_validation_unused;
- AppendAnotherIPAddress(&address_list, &addresses_for_validation_unused, 4);
-
- // dns_extensions length: 2 bytes for address type, 2 for address_set length
- // Subtract 1 because we're deliberately writing one byte too few for the
- // purposes of this test.
- writer.WriteU16(address_list.size() - 1 + 4);
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(address_list.size() - 1);
- // oops! missing the last byte of our IPv4 address
- writer.WriteBytes(address_list.data(), address_list.size() - 1);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
-// Test that an ESNI record with an address_set entry of bad address
-// type is correctly rejected.
-TEST(RecordRdataTest, EsniMalformedRecord_NotEnoughAddressData_IPv6) {
- char record[10000] = {};
- base::BigEndianWriter writer(record, sizeof(record));
- AppendWellFormedEsniKeys(&writer);
-
- std::vector<uint8_t> address_list;
- std::vector<IPAddress> addresses_for_validation_unused;
- AppendAnotherIPAddress(&address_list, &addresses_for_validation_unused, 6);
-
- // dns_extensions length: 2 bytes for address type, 2 for address_set length
- // Subtract 1 because we're deliberately writing one byte too few for the
- // purposes of this test.
- writer.WriteU16(address_list.size() - 1 + 4);
- writer.WriteU16(EsniRecordRdata::kAddressSetExtensionType);
- writer.WriteU16(address_list.size() - 1);
- // oops! missing the last byte of our IPv6 address
- writer.WriteBytes(address_list.data(), address_list.size() - 1);
-
- auto record_size = writer.ptr() - record;
- DnsRecordParser parser(record, record_size, 0 /* offset */);
- std::unique_ptr<EsniRecordRdata> record_obj =
- EsniRecordRdata::Create(std::string(record, record_size), parser);
-
- ASSERT_THAT(record_obj, IsNull());
-}
-
TEST(RecordRdataTest, ParsePtrRecord) {
// These are just the rdata portions of the DNS records, rather than complete
// records, but it works well enough for this test.
diff --git a/chromium/net/dns/resolve_context.cc b/chromium/net/dns/resolve_context.cc
index fd7f7c6f17f..3b15cf320ec 100644
--- a/chromium/net/dns/resolve_context.cc
+++ b/chromium/net/dns/resolve_context.cc
@@ -7,7 +7,6 @@
#include <algorithm>
#include <cstdlib>
#include <limits>
-#include <string>
#include <utility>
#include "base/check_op.h"
@@ -15,6 +14,7 @@
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "base/metrics/sample_vector.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
@@ -150,10 +150,27 @@ size_t ResolveContext::NumAvailableDohServers(const DnsSession* session) const {
void ResolveContext::RecordServerFailure(size_t server_index,
bool is_doh_server,
+ int rv,
const DnsSession* session) {
+ DCHECK(rv != OK && rv != ERR_NAME_NOT_RESOLVED && rv != ERR_IO_PENDING);
+
if (!IsCurrentSession(session))
return;
+ // "FailureError" metric is only recorded for secure queries.
+ if (is_doh_server) {
+ std::string query_type =
+ GetQueryTypeForUma(server_index, true /* is_doh_server */, session);
+ DCHECK_NE(query_type, "Insecure");
+ std::string provider_id =
+ GetDohProviderIdForUma(server_index, true /* is_doh_server */, session);
+
+ base::UmaHistogramSparse(
+ base::StringPrintf("Net.DNS.DnsTransaction.%s.%s.FailureError",
+ query_type.c_str(), provider_id.c_str()),
+ std::abs(rv));
+ }
+
size_t num_available_doh_servers_before = NumAvailableDohServers(session);
ServerStats* stats = GetServerStats(server_index, is_doh_server);
@@ -200,10 +217,11 @@ void ResolveContext::RecordRtt(size_t server_index,
if (!IsCurrentSession(session))
return;
- RecordRttForUma(server_index, is_doh_server, rtt, rv, session);
-
ServerStats* stats = GetServerStats(server_index, is_doh_server);
+ base::TimeDelta base_timeout = NextTimeoutHelper(stats, 0 /* num_backoffs */);
+ RecordRttForUma(server_index, is_doh_server, rtt, rv, base_timeout, session);
+
// RTT values shouldn't be less than 0, but it shouldn't cause a crash if
// they are anyway, so clip to 0. See https://crbug.com/753568.
if (rtt < base::TimeDelta())
@@ -367,43 +385,71 @@ void ResolveContext::RecordRttForUma(size_t server_index,
bool is_doh_server,
base::TimeDelta rtt,
int rv,
+ base::TimeDelta base_timeout,
const DnsSession* session) {
DCHECK(IsCurrentSession(session));
- std::string query_type;
- std::string provider_id;
- if (is_doh_server) {
- // Secure queries are validated if the DoH server state is available.
- if (GetDohServerAvailability(server_index, session))
- query_type = "SecureValidated";
- else
- query_type = "SecureNotValidated";
- provider_id = GetDohProviderIdForHistogramFromDohConfig(
- current_session_->config().dns_over_https_servers[server_index]);
- } else {
- query_type = "Insecure";
- provider_id = GetDohProviderIdForHistogramFromNameserver(
- current_session_->config().nameservers[server_index]);
- }
+ std::string query_type =
+ GetQueryTypeForUma(server_index, is_doh_server, session);
+ std::string provider_id =
+ GetDohProviderIdForUma(server_index, is_doh_server, session);
+
if (rv == OK || rv == ERR_NAME_NOT_RESOLVED) {
base::UmaHistogramMediumTimes(
base::StringPrintf("Net.DNS.DnsTransaction.%s.%s.SuccessTime",
query_type.c_str(), provider_id.c_str()),
rtt);
+ if (query_type == "SecureValidated") {
+ DCHECK(is_doh_server);
+
+ // Only for SecureValidated requests, record the ratio between successful
+ // RTT and the base timeout for the server. Note that RTT could be much
+ // longer than the timeout as previous attempts are often allowed to
+ // continue in parallel with new attempts made by the transaction. Scale
+ // the ratio up by 10 for sub-integer granularity.
+ // TODO(crbug.com/1105138): Remove after determining good timeout logic.
+ int timeout_ratio = 10 * rtt / base_timeout;
+ UMA_HISTOGRAM_COUNTS_1000(
+ "Net.DNS.DnsTransaction.SecureValidated.SuccessTimeoutRatio",
+ timeout_ratio);
+ }
} else {
base::UmaHistogramMediumTimes(
base::StringPrintf("Net.DNS.DnsTransaction.%s.%s.FailureTime",
query_type.c_str(), provider_id.c_str()),
rtt);
- if (is_doh_server) {
- base::UmaHistogramSparse(
- base::StringPrintf("Net.DNS.DnsTransaction.%s.%s.FailureError",
- query_type.c_str(), provider_id.c_str()),
- std::abs(rv));
- }
}
}
+std::string ResolveContext::GetQueryTypeForUma(size_t server_index,
+ bool is_doh_server,
+ const DnsSession* session) {
+ DCHECK(IsCurrentSession(session));
+
+ if (!is_doh_server)
+ return "Insecure";
+
+ // Secure queries are validated if the DoH server state is available.
+ if (GetDohServerAvailability(server_index, session))
+ return "SecureValidated";
+
+ return "SecureNotValidated";
+}
+
+std::string ResolveContext::GetDohProviderIdForUma(size_t server_index,
+ bool is_doh_server,
+ const DnsSession* session) {
+ DCHECK(IsCurrentSession(session));
+
+ if (is_doh_server) {
+ return GetDohProviderIdForHistogramFromDohConfig(
+ session->config().dns_over_https_servers[server_index]);
+ }
+
+ return GetDohProviderIdForHistogramFromNameserver(
+ session->config().nameservers[server_index]);
+}
+
void ResolveContext::NotifyDohStatusObserversOfSessionChanged() {
for (auto& observer : doh_status_observers_)
observer.OnSessionChanged();
diff --git a/chromium/net/dns/resolve_context.h b/chromium/net/dns/resolve_context.h
index 8b3ec4fd388..bcbac646da5 100644
--- a/chromium/net/dns/resolve_context.h
+++ b/chromium/net/dns/resolve_context.h
@@ -6,6 +6,7 @@
#define NET_DNS_RESOLVE_CONTEXT_H_
#include <memory>
+#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
@@ -92,9 +93,12 @@ class NET_EXPORT_PRIVATE ResolveContext : public base::CheckedObserver {
// Record that server failed to respond (due to SRV_FAIL or timeout). If
// |is_doh_server| and the number of failures has surpassed a threshold,
// sets the DoH probe state to unavailable. Noop if |session| is not the
- // current session.
+ // current session. Should only be called with with server failure |rv|s,
+ // not eg OK, ERR_NAME_NOT_RESOLVED (which at the transaction level is
+ // expected to be nxdomain), or ERR_IO_PENDING.
void RecordServerFailure(size_t server_index,
bool is_doh_server,
+ int rv,
const DnsSession* session);
// Record that server responded successfully. Noop if |session| is not the
@@ -199,7 +203,14 @@ class NET_EXPORT_PRIVATE ResolveContext : public base::CheckedObserver {
bool is_doh_server,
base::TimeDelta rtt,
int rv,
+ base::TimeDelta base_timeout,
const DnsSession* session);
+ std::string GetQueryTypeForUma(size_t server_index,
+ bool is_doh_server,
+ const DnsSession* session);
+ std::string GetDohProviderIdForUma(size_t server_index,
+ bool is_doh_server,
+ const DnsSession* session);
void NotifyDohStatusObserversOfSessionChanged();
void NotifyDohStatusObserversOfUnavailable(bool network_change);
diff --git a/chromium/net/dns/resolve_context_unittest.cc b/chromium/net/dns/resolve_context_unittest.cc
index 4701feff6db..5de6a10e3f3 100644
--- a/chromium/net/dns/resolve_context_unittest.cc
+++ b/chromium/net/dns/resolve_context_unittest.cc
@@ -197,7 +197,7 @@ TEST_F(ResolveContextTest, DohServerAvailability_DifferentSession) {
ASSERT_TRUE(context.GetDohServerAvailability(1u, session2.get()));
for (int i = 0; i < ResolveContext::kAutomaticModeFailureLimit; ++i) {
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session1.get());
+ ERR_FAILED, session1.get());
}
EXPECT_TRUE(context.GetDohServerAvailability(1u, session2.get()));
}
@@ -300,7 +300,7 @@ TEST_F(ResolveContextTest, DohServerAvailabilityNotification) {
for (int i = 0; i < ResolveContext::kAutomaticModeFailureLimit; ++i) {
ASSERT_EQ(2u, context.NumAvailableDohServers(session.get()));
context.RecordServerFailure(0u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
base::RunLoop().RunUntilIdle(); // Notifications are async.
EXPECT_EQ(1, config_observer.dns_changed_calls());
}
@@ -313,7 +313,7 @@ TEST_F(ResolveContextTest, DohServerAvailabilityNotification) {
EXPECT_EQ(1, config_observer.dns_changed_calls());
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
ASSERT_EQ(0u, context.NumAvailableDohServers(session.get()));
base::RunLoop().RunUntilIdle(); // Notifications are async.
@@ -418,7 +418,8 @@ TEST_F(ResolveContextTest, Failures_Consecutive) {
EXPECT_EQ(classic_itr->GetNextAttemptIndex(), 1u);
context.RecordServerFailure(1u /* server_index */,
- false /* is_doh_server */, session.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session.get());
}
{
@@ -464,7 +465,8 @@ TEST_F(ResolveContextTest, Failures_NonConsecutive) {
EXPECT_EQ(classic_itr->GetNextAttemptIndex(), 1u);
context.RecordServerFailure(1u /* server_index */,
- false /* is_doh_server */, session.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session.get());
}
{
@@ -491,7 +493,7 @@ TEST_F(ResolveContextTest, Failures_NonConsecutive) {
// Expect server stay preferred through non-consecutive failures.
context.RecordServerFailure(1u /* server_index */, false /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
{
std::unique_ptr<DnsServerIterator> classic_itr =
context.GetClassicDnsIterator(session->config(), session.get());
@@ -518,7 +520,8 @@ TEST_F(ResolveContextTest, Failures_NoSession) {
EXPECT_FALSE(classic_itr->AttemptAvailable());
context.RecordServerFailure(1u /* server_index */,
- false /* is_doh_server */, session.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session.get());
}
std::unique_ptr<DnsServerIterator> classic_itr =
context.GetClassicDnsIterator(session->config(), session.get());
@@ -551,7 +554,8 @@ TEST_F(ResolveContextTest, Failures_DifferentSession) {
EXPECT_EQ(classic_itr->GetNextAttemptIndex(), 1u);
context.RecordServerFailure(1u /* server_index */,
- false /* is_doh_server */, session1.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session1.get());
}
std::unique_ptr<DnsServerIterator> classic_itr =
context.GetClassicDnsIterator(session2->config(), session2.get());
@@ -586,9 +590,11 @@ TEST_F(ResolveContextTest, TwoFailures) {
EXPECT_EQ(classic_itr->GetNextAttemptIndex(), 2u);
context.RecordServerFailure(0u /* server_index */,
- false /* is_doh_server */, session.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session.get());
context.RecordServerFailure(1u /* server_index */,
- false /* is_doh_server */, session.get());
+ false /* is_doh_server */, ERR_FAILED,
+ session.get());
}
{
std::unique_ptr<DnsServerIterator> classic_itr =
@@ -661,7 +667,7 @@ TEST_F(ResolveContextTest, DohFailures_Consecutive) {
EXPECT_EQ(1u, context.NumAvailableDohServers(session.get()));
EXPECT_EQ(0, observer.server_unavailable_notifications());
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
std::unique_ptr<DnsServerIterator> doh_itr = context.GetDohIterator(
session->config(), DnsConfig::SecureDnsMode::AUTOMATIC, session.get());
@@ -696,7 +702,7 @@ TEST_F(ResolveContextTest, DohFailures_NonConsecutive) {
EXPECT_EQ(doh_itr->GetNextAttemptIndex(), 1u);
EXPECT_EQ(1u, context.NumAvailableDohServers(session.get()));
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
{
std::unique_ptr<DnsServerIterator> doh_itr = context.GetDohIterator(
@@ -721,7 +727,7 @@ TEST_F(ResolveContextTest, DohFailures_NonConsecutive) {
// Expect a single additional failure should not make a DoH server unavailable
// because the success resets failure tracking.
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
{
std::unique_ptr<DnsServerIterator> doh_itr = context.GetDohIterator(
session->config(), DnsConfig::SecureDnsMode::AUTOMATIC, session.get());
@@ -752,7 +758,7 @@ TEST_F(ResolveContextTest, DohFailures_SuccessAfterFailures) {
for (size_t i = 0; i < ResolveContext::kAutomaticModeFailureLimit; i++) {
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
ASSERT_EQ(0u, context.NumAvailableDohServers(session.get()));
EXPECT_EQ(1, observer.server_unavailable_notifications());
@@ -787,7 +793,7 @@ TEST_F(ResolveContextTest, DohFailures_NoSession) {
for (size_t i = 0; i < ResolveContext::kAutomaticModeFailureLimit; i++) {
EXPECT_EQ(0u, context.NumAvailableDohServers(session.get()));
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
EXPECT_EQ(0u, context.NumAvailableDohServers(session.get()));
}
@@ -814,7 +820,7 @@ TEST_F(ResolveContextTest, DohFailures_DifferentSession) {
for (size_t i = 0; i < ResolveContext::kAutomaticModeFailureLimit; i++) {
EXPECT_EQ(1u, context.NumAvailableDohServers(session2.get()));
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session1.get());
+ ERR_FAILED, session1.get());
}
EXPECT_EQ(1u, context.NumAvailableDohServers(session2.get()));
}
@@ -849,9 +855,9 @@ TEST_F(ResolveContextTest, TwoDohFailures) {
EXPECT_EQ(doh_itr->GetNextAttemptIndex(), 2u);
context.RecordServerFailure(0u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
context.RecordServerFailure(1u /* server_index */, true /* is_doh_server */,
- session.get());
+ ERR_FAILED, session.get());
}
std::unique_ptr<DnsServerIterator> doh_itr = context.GetDohIterator(
diff --git a/chromium/net/dns/test_dns_config_service.h b/chromium/net/dns/test_dns_config_service.h
index 3b61c361c6c..1b63ec766f6 100644
--- a/chromium/net/dns/test_dns_config_service.h
+++ b/chromium/net/dns/test_dns_config_service.h
@@ -7,7 +7,7 @@
#include <utility>
-#include "base/logging.h"
+#include "base/check.h"
#include "base/optional.h"
#include "net/dns/dns_config_service.h"
diff --git a/chromium/net/docs/bug-triage-labels.md b/chromium/net/docs/bug-triage-labels.md
index d32cde11826..1a9724e9221 100644
--- a/chromium/net/docs/bug-triage-labels.md
+++ b/chromium/net/docs/bug-triage-labels.md
@@ -10,22 +10,11 @@
that die in the SSL negotiation phase, in particular, this is often the
correct component.
-* **Internals>Network>DataProxy**
-
- Flywheel / the Data Reduction Proxy. Issues require "Reduce Data Usage" be
- turned on. Proxy URL is [https://proxy.googlezip.net:443](#), with
- [http://compress.googlezip.net:80](#) as a fallback. Currently Android and
- iOS only.
-
* **Internals>Network>Cache**
The cache is the layer that handles most range request logic (Though range
requests may also be issued by the PDF plugin, XHRs, or other components).
-* **Internals>Network>SPDY**
-
- Covers HTTP2 as well.
-
* **Internals>Network>HTTP**
Typically not used. Unclear what it covers, and there's no specific HTTP
diff --git a/chromium/net/docs/bug-triage-suggested-workflow.md b/chromium/net/docs/bug-triage-suggested-workflow.md
deleted file mode 100644
index 4807c72b95a..00000000000
--- a/chromium/net/docs/bug-triage-suggested-workflow.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# Chrome Network Bug Triage : Suggested Workflow
-
-[TOC]
-
-## Identifying unlabeled network bugs on the tracker
-
-* Look at new unconfirmed bugs since noon PST on the last triager's rotation.
- [Use this issue tracker
- query](https://bugs.chromium.org/p/chromium/issues/list?q=status%3Aunconfirmed&sort=-id&num=1000).
-
-* Read the title of the bug.
-
-* If a bug looks like it might be network related, middle click (or
- command-click on OSX) to open it in a new tab.
-
-* If a user provides a crash ID for a crasher for a bug that could be
- net-related, see the [internal instructions on dealing with a crash ID](https://goto.google.com/network_triage_internal#dealing-with-a-crash-id)
-
-* If network causes are possible, ask for a net-export log (If it's not a
- browser crash) and attach the most specific internals-network label that's
- applicable. If there isn't an applicable narrower component, a clear owner
- for the issue, or there are multiple possibilities, attach the
- Internals>Network component and proceed with further investigation.
-
-* If non-network causes also seem possible, attach those components as well.
-
-## Investigating component=Internals>Network bugs
-
-* Note that you may want to investigate Needs-Feedback bugs first, as
- that may result in some bugs being added to this list.
-
-* It's recommended that while on triage duty, you subscribe to the
- Internals>Network component (but not its subcomponents). To do this, go
- to the issue tracker and then click "Saved Queries".
- Add a query with these settings:
- * Saved query name: Network Bug Triage
- * Project: chromium
- * Query: component=Internals>Network
- * Subscription options: Notify Immediately
-
-* Look through unconfirmed and untriaged component=Internals>Network bugs,
- prioritizing those updated within the last week. [Use this issue tracker
- query](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified).
-
-* If more information is needed from the reporter, ask for it and add the
- Needs-Feedback label.
-
-* While investigating a new issue, change the status to Untriaged.
-
-* If a bug is a potential security issue (Allows for code execution from remote
- site, allows crossing security boundaries, unchecked array bounds, etc) mark
- it Type-Bug-Security. If it has privacy implication (History, cookies
- discoverable by an entity that shouldn't be able to do so, incognito state
- being saved in memory or on disk beyond the lifetime of incognito tabs, etc),
- mark it with component Privacy.
-
-* For bugs that already have a more specific network component, go ahead and
- remove the Internals>Network component to get them off the next triager's
- radar and move on.
-
-* Try to figure out if it's really a network bug. See common non-network
- components section for description of common components for issues incorrectly
- tagged as Internals>Network.
-
-* If it's not, attach appropriate labels/components and go no further.
-
-* If it may be a network bug, attach additional possibly relevant component if
- any, and continue investigating. Once you either determine it's a
- non-network bug, or figure out accurate more specific network components, your
- job is done, though you should still ask for a net-export dump if it seems
- likely to be useful.
-
-* Note that Chrome-OS-specific network-related code (Captive portal detection,
- connectivity detection, login, etc) may not all have appropriate more
- specific subcomponents, but are not in areas handled by the network stack
- team. Just make sure those have the OS-Chrome label, and any more specific
- labels if applicable, and then move on.
-
-* Gather data and investigate.
- * Remember to add the Needs-Feedback label whenever waiting for the user to
- respond with more information, and remove it when not waiting on the
- user.
- * Try to reproduce locally. If you can, and it's a regression, use
- src/tools/bisect-builds.py to figure out when it regressed.
- * Ask more data from the user as needed (net-export dumps, repro case,
- crash ID from chrome://crashes, run tests, etc).
- * If asking for a chrome://net-export dump, provide this link:
- https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details.
-
-* Try to figure out what's going on, and which more specific network component
- is most appropriate.
-
-* If it's a regression, browse through the git history of relevant files to try
- and figure out when it regressed. CC authors / primary reviewers of any
- strongly suspect CLs.
-
-* If you are having trouble with an issue, particularly for help understanding
- net-export logs, email the public net-dev@chromium.org list for help
- debugging. If it's a crasher, or for some other reason discussion needs to
- be done in private, see [internal documentation for details](https://goto.google.com/network_triage_internal#getting-help-with-a-bug)
-
-* If it appears to be a bug in the unowned core of the network stack (i.e. no
- subcomponent applies, or only the Internals>Network>HTTP subcomponent
- applies, and there's no clear owner), try to figure out the exact cause.
-
-## Crashes
-
-For guidance on crashes see the internal documentation:
-
-* [Dealing with a crash ID](https://goto.google.com/network_triage_internal#dealing-with-a-crash-id)
-* [Looking for new crashers](https://goto.google.com/network_triage_internal#looking-for-new-crashers)
-* [Investigating crashers](https://goto.google.com/network_triage_internal#investigating-crashers)
diff --git a/chromium/net/docs/bug-triage.md b/chromium/net/docs/bug-triage.md
index 25348795d97..ab02bbe8ff8 100644
--- a/chromium/net/docs/bug-triage.md
+++ b/chromium/net/docs/bug-triage.md
@@ -1,115 +1,96 @@
# Chrome Network Bug Triage
-The Chrome network team uses a two day bug triage rotation. The main goals are
-to identify and label new network bugs, and investigate network bugs when no
-label seems suitable.
+The Chrome network team uses a two day bug triage rotation. The goal is to
+review outstanding issues and keep things moving forward. The rotation is time
+based rather than objective based. Sheriffs are expected to spend the majority
+of their two days working on bug triage/investigation.
+
+## 1. Review untriaged bugs
+
+Look through [this list of untriaged
+bugs](https://bugs.chromium.org/p/chromium/issues/list?sort=pri%20-stars%20-opened&q=component%3AInternals%3ENetwork%20status%3Aunconfirmed%2Cuntriaged%20-component%3AInternals%3ENetwork%3ECookies%20-component%3AInternals%3ENetwork%3EDNS%20-component%3AInternals%3ENetwork%3ECookies%20-component%3AInternals%3ENetwork%3ECertificate%20-component%3AInternals%3ENetwork%3EReportingAndNEL%20-component%3AInternals%3ENetwork%3EDataUse%20-component%3AInternals%3ENetwork%3EEV%20-component%3AInternals%3ENetwork%3EDataProxy%20-component%3AInternals%3ENetwork%3ECertTrans%20-component%3AInternals%3ENetwork%3ENetworkQuality%20-component%3AInternals%3ENetwork%3EDoH%20-component%3AInternals%3ENetwork%3ENetInfo%20-component%3AInternals%3ENetwork%3EVPN%20-Needs%3DFeedback).
+
+* Go through them in the given order (top to bottom).
+ The link sorts them by priority and then recency.
+* The goal is to move them out of the untriaged bug queue and give them a priority.
+
+For each bug try to:
+
+* Remove the `Internals>Network` component if it belongs elsewhere
+* Dupe it against an existing bug
+* Close it `WontFix` if appropriate
+* Give the bug a priority. Refer to [this (internal) document for guidelines](https://goto.google.com/xnzwn)
+* If the bug is a potential security issue (Allows for code execution from remote
+ site, allows crossing security boundaries, unchecked array bounds, etc) mark
+ it `Type-Bug-Security`.
+* If the bug has privacy implications mark it with component `Privacy`.
+* Mark it as a feature request or task if appropriate
+* Ask the reporter to narrow down regressions, possibly by using
+ [bisect-builds-py](https://www.chromium.org/developers/bisect-builds-py). To
+ view suspicious changelists in a regression window, you can use the Change Log
+ form on [OmahaProxy](https://omahaproxy.appspot.com/)
+* CC others who may be able to help
+* Mark it as `Needs-Feedback` and request more information if needed.
+* Request a NetLog that captures the problem. You can paste this on the bug:
+ ```
+ Please collect and attach a chrome://net-export log.
+ Instructions can be found here:
+ https://chromium.org/for-testers/providing-network-details
+ ```
+* If a NetLog was provided, try to spend a bit of time reviewing it. See
+ [crash-course-in-net-internals.md](crash-course-in-net-internals.md) for an
+ introduction.
+* Move to a subcomponent of `Internals>Network` if appropriate. See
+ [bug-triage-labels.md](bug-triage-labels.md) for an overview of the components.
+* If the bug is a crash, see [internal: Dealing with a crash
+ ID](https://goto.google.com/network_triage_internal#dealing-with-a-crash-id)
+and [internal: Investigating
+crashers](https://goto.google.com/network_triage_internal#investigating-crashers)
+
+## 2. Follow-up on issues with the Needs-Feedback label
+
+Look through [this list of Needs=Feedback
+bugs](https://bugs.chromium.org/p/chromium/issues/list?sort=pri%20-modified&q=component%3AInternals%3ENetwork%20Needs%3DFeedback%20-component%3AInternals%3ENetwork%3ECookies%20-component%3AInternals%3ENetwork%3EDNS%20-component%3AInternals%3ENetwork%3ECookies%20-component%3AInternals%3ENetwork%3ECertificate%20-component%3AInternals%3ENetwork%3EReportingAndNEL%20-component%3AInternals%3ENetwork%3EDataUse%20-component%3AInternals%3ENetwork%3EEV%20-component%3AInternals%3ENetwork%3EDataProxy%20-component%3AInternals%3ENetwork%3ECertTrans%20-component%3AInternals%3ENetwork%3ENetworkQuality%20-component%3AInternals%3ENetwork%3EDoH%20-component%3AInternals%3ENetwork%3ENetInfo%20-component%3AInternals%3ENetwork%3EVPN).
+
+* Go through them in the given order (top to bottom).
+ The link sorts them by priority and then recency.
+* If the requested feedback was provided, review the new information and repeat
+ the same steps as (1) to re-triage based on the new information.
+* If the bug had the `Needs-Feedback` label for over a week and the
+ feedback needed to make progress was not yet provided, archive the bug.
+
+## 3. (Optional) Look through crash reports
+
+Top crashes will already be entered into the bug system by a different process,
+so will be handled by the triage steps above.
+
+However if you have time to look through lower threshold crashes, see
+[internal: Looking for new crashers](https://goto.google.com/network_triage_internal#looking-for-new-crashers)
+
+## 4. Send out a sheriff report
+
+On the final day of your rotation, send a brief summary to net-dev@chromium.org
+detailing any interesting or concerning trends. Do not discuss any restricted
+bugs on the public mailing list.
## Management
-Owners for the network bug triage rotation can find instructions on
-generating and modifying shifts
-[here (internal-only)](https://goto.google.com/pflvb).
-
-## Responsibilities
-
-### Required, in rough order of priority:
-* Identify new network bugs on the tracker.
-* Investigate recent `Internals>Network` issues with no subcomponent.
-* Follow up on `Needs-Feedback` issues for all network components.
-* Identify and file bugs for significant new crashers.
-
-### Best effort, also in rough priority order:
-* Investigate unowned and owned-but-forgotten net/ crashers.
-* Investigate old bugs.
-* Close obsolete bugs.
-
-All of the above is to be done on each rotation. These responsibilities should
-be tracked, and anything left undone at the end of a rotation should be handed
-off to the next triager. The downside to passing along bug investigations like
-this is each new triager has to get back up to speed on bugs the previous
-triager was investigating. The upside is that triagers don't get stuck
-investigating issues after their time after their rotation, and it results in a
-uniform, predictable two day commitment for all triagers.
-
-## Details
-
-### Required:
-
-* Identify new network bugs on the bug tracker, looking at [this issue tracker
- query](https://bugs.chromium.org/p/chromium/issues/list?q=status%3Aunconfirmed+-commentby=425761728072-pa1bs18esuhp2cp2qfa1u9vb6p1v6kfu@developer.gserviceaccount.com&sort=-id&num=1000).
-
- * All Unconfirmed issues filed during your triage rotation should be scanned
- for suspected network bugs, a network component assigned and a
- chrome://net-export/ log requested. Suggested text: "Please collect and
- attach a chrome://net-export log. Instructions can be found here:
- https://chromium.org/for-testers/providing-network-details".
- A link to the instructions appears on net-export, for easy reference.
- When asking for a log or more details, attach the Needs-Feedback label.
-
- * A triager is responsible for looking at bugs reported from noon PST /
- 3:00 pm EST of the last day of the previous triager's rotation until the
- same time on the last day of their rotation.
-
-* Investigate [Unconfirmed / Untriaged Internals>Network issues that don't belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified),
- prioritizing the most recent issues, ones with the most responsive reporters,
- and major crashers. This will generally take up the majority of your time as
- triager. Continue digging until you can do one of the following:
-
- * Mark it as `WontFix` (working as intended, obsolete issue) or a
- duplicate.
-
- * Mark it as a feature request.
+* Your rotation will appear in Google Calendar as two days. You are expected to
+ work on it full-time (as best you can) during those calendar days, during your
+ ordinary working hours.
- * Mark it as `Needs-Feedback`.
+* Google Calendar [google.com_52n2p39ad82hah9v7j26vek830@group.calendar.google.com](https://calendar.google.com/calendar/embed?src=google.com_52n2p39ad82hah9v7j26vek830%40group.calendar.google.com&ctz=America%2FLos_Angeles)
- * Remove the `Internals>Network` component, replacing it with at least one
- more specific network component or non-network component. Replacing the
- `Internals>Network` component gets it off the next triager's radar, and
- in front of someone more familiar with the relevant code. Note that
- due to the way the bug report wizard works, a lot of bugs incorrectly end
- up with the network component.
-
- * The issue is assigned to an appropriate owner. Make sure to mark it as
- "assigned" so the next triager doesn't run into it.
-
- * If there is no more specific component for a bug, it should be
- investigated by the triager until we have a good understanding of the
- cause of the problem, and some idea how it should be fixed, at which point
- its status should be set to Available. Future triagers should ignore bugs
- with this status, unless investigating stale bugs.
-
-* Follow up on [Needs-Feedback issues for all components owned by the network stack team](https://bugs.chromium.org/p/chromium/issues/list?q=component%3AInternals%3ENetwork+-component%3AInternals%3ENetwork%3EDataProxy+-component%3AInternals%3ENetwork%3EDataUse+-component%3AInternals%3ENetwork%3EVPN+Needs%3DFeedback&sort=-modified).
-
- * Remove label once feedback is provided. Continue to investigate, if
- the previous section applies.
-
- * If the `Needs-Feedback` label has been present for one week, ping the
- reporter.
-
- * Archive after two weeks with no feedback, telling users to file a new
- bug if they still have the issue, with the requested information, unless
- the reporter indicates they'll provide data when they can. In that case,
- use your own judgment for further pings or archiving.
-
-* Identify significant new crashes. See [internal documentation](https://goto.google.com/network_triage_internal#looking-for-new-crashers).
-
-### Best Effort (As you have time):
-
-* Investigate old bugs, and bugs associated with `Internals>Network`
- subcomponents.
-
-* Investigate unowned and owned but forgotten net/ crashers that are still
- occurring (As indicated by
- [go/chromenetcrash](https://goto.google.com/chromenetcrash)), prioritizing
- frequent and long standing crashers.
-
-* Close obsolete bugs.
+* Owners for the network bug triage rotation can find instructions on
+generating and modifying shifts
+[here (internal-only)](https://goto.google.com/pflvb).
-See [bug-triage-suggested-workflow.md](bug-triage-suggested-workflow.md) for
-suggested workflows.
+* An overview of bug trends can be seen on [Chromium
+ Dashboard](https://chromiumdash.appspot.com/components/Internals/Network?project=Chromium)
-See [bug-triage-labels.md](bug-triage-labels.md) for labeling tips for network
-and non-network bugs.
+* There is also an [internal dashboard with bug trends for Web
+ Platform](https://goto.google.com/vufyq) that includes network issues.
-See [crash-course-in-net-internals.md](crash-course-in-net-internals.md) for
-some help on getting started with chrome://net-internals debugging.
+* The issue tracker doesn't track any official mappings between components and
+ OWNERS. This [internal document](https://goto.google.com/kojfj) enumerates
+ the known owners for subcomponents.
diff --git a/chromium/net/docs/certificate_lifetimes.md b/chromium/net/docs/certificate_lifetimes.md
new file mode 100644
index 00000000000..ee413ef9157
--- /dev/null
+++ b/chromium/net/docs/certificate_lifetimes.md
@@ -0,0 +1,78 @@
+# Certificate Lifetimes
+
+As part of our ongoing commitment to ensuring users’ security, Google is
+reducing the maximum allowed lifetimes of TLS certificates.
+
+## Upcoming Changes
+
+Beginning with Chrome 85, TLS server certificates issued on or after
+2020-09-01 00:00:00 UTC will be required to have a validity period of 398 days
+or less. This will only apply to TLS server certificates from CAs that are
+trusted in a default installation of Google Chrome, commonly known as
+"publicly trusted CAs", and will not apply to locally-operated CAs that have
+been manually configured.
+
+Certificates that do not comply with this requirement will not work, and may
+cause webpages to fail to load or to render incorrectly.
+
+If a certificate that does not comply with this requirement is issued by a CA
+trusted in a default installation of Google Chrome, this will be treated as a
+failure to comply with the security policies necessary to being a trusted CA,
+and may result in the removal of trust of that CA’s certificates.
+
+## Technical Details
+
+* A certificate will be impacted by this restriction if either the notBefore
+ of the certificate is on or after 2020-09-01 00:00:00 UTC, or if the first
+ precertificate logged by the CA to a Certificate Transparency Log that is
+ qualified at time of issuance is on or after this date.
+* The validity period of a certificate is defined within RFC 5280, Section
+ 4.1.2.5, as "the period of time from notBefore through notAfter, inclusive."
+* 398 days is measured with a day being equal to 86,400 seconds. Any time
+ greater than this indicates an additional day of validity.
+* To avoid the risk of misissuance, such as due to leap seconds or
+ CA-configured randomization, CAs SHOULD issue such server certificates with
+ validity periods of 397 days or less.
+
+## Frequently Asked Questions
+
+* Does this apply to locally-operated CAs, such as those used within
+ enterprises that use enterprise-configured configured CAs?
+ * No. This only applies to the set of CAs that are trusted by default by
+ Google Chrome, and not CAs that are operated by an enterprise and that
+ have no certification paths to CAs that are trusted by default.
+* Is there an enterprise policy to disable this enforcement?
+ * No. These changes are transparent and do not offer an enterprise control
+ to override, as they only apply to so-called "publicly trusted" CAs.
+ Enterprises that wish to have certificates with validity periods longer
+ than 398 days may do so by using a locally-operated CA that does not have
+ any certification paths up to a publicly trusted CA.
+* Does this mean I have to replace my existing certificates?
+ * No. This requirement only applies to new certificate issuance on or after
+ 2020-09-01 00:00:00 UTC. Existing certificates whose validity period
+ exceeds 398 days will continue to work, while new certificates must comply
+ with these new requirements, such as when they are renewed or replaced.
+* Will this make certificates more expensive?
+ * As with past changes to the maximum certificate lifetimes, many CAs have
+ committed to providing additional certificates, as needed by the shortened
+ maximum lifetime, at no additional cost.
+* What will happen if a certificate is issued that does not meet these
+ requirements?
+ * Google Chrome will reject such certificates as having too long a validity
+ period, consistent with existing validity-period based enforcement.
+ Additionally, such certificates will be treated as a critical security
+ failure by the CA, and may result in further action taken on the CA that
+ may affect how current or future certificates from that CA function.
+ Chromium-based browsers will have this enforcement enabled by default, and
+ will need to modify the source to disable this.
+* What are other browsers doing?
+ * Apple previously announced this change for versions of iOS, iPadOS, macOS,
+ tvOS, and watchOS, as documented at
+ https://support.apple.com/en-us/HT211025, which will apply to all
+ applications, and not just those of Safari. This certificate lifetime
+ requirement is fully interoperable with Apple’s requirements.
+
+ Microsoft, Mozilla, Opera, and 360 have previously indicated their support
+ for these requirements, although have not yet made announcements at the
+ time of this post (2020-06-22). Other browsers, including those browsers
+ based on Chromium, may provide additional guidance or clarification.
diff --git a/chromium/net/docs/net-log.md b/chromium/net/docs/net-log.md
index 4097bc87a1d..ebf7ceee681 100644
--- a/chromium/net/docs/net-log.md
+++ b/chromium/net/docs/net-log.md
@@ -69,10 +69,9 @@ That said, changing core events may have consequences for external consumers of
NetLogs, which rely on the structure and parameters to events for pretty
printing and log analysis.
-The [NetLog
-viewer](https://chromium.googlesource.com/catapult/+/master/netlog_viewer/) for
-instance pretty prints certain parameters based on their names, and the event
-name that added them.
+The [NetLog viewer](https://netlog-viewer.appspot.com/) for instance pretty
+prints certain parameters based on their names, and the event name that added
+them.
### Example 1
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index 26ed5f2ad0d..474db6ecaa0 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -77,20 +77,10 @@ enum CookieCommitProblem {
COOKIE_COMMIT_PROBLEM_ADD = 1,
COOKIE_COMMIT_PROBLEM_UPDATE_ACCESS = 2,
COOKIE_COMMIT_PROBLEM_DELETE = 3,
+ COOKIE_COMMIT_PROBLEM_TRANSACTION_COMMIT = 4,
COOKIE_COMMIT_PROBLEM_LAST_ENTRY
};
-// Used to report a histogram on status of cookie commit to disk.
-//
-// Please do not reorder or remove entries. New entries must be added to the
-// end of the list, just before BACKING_STORE_RESULTS_LAST_ENTRY.
-enum BackingStoreResults {
- BACKING_STORE_RESULTS_SUCCESS = 0,
- BACKING_STORE_RESULTS_FAILURE = 1,
- BACKING_STORE_RESULTS_MIXED = 2,
- BACKING_STORE_RESULTS_LAST_ENTRY
-};
-
void RecordCookieLoadProblem(CookieLoadProblem event) {
UMA_HISTOGRAM_ENUMERATION("Cookie.LoadProblem", event,
COOKIE_LOAD_PROBLEM_LAST_ENTRY);
@@ -1221,7 +1211,6 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
if (!transaction.Begin())
return;
- bool trouble = false;
for (auto& kv : ops) {
for (std::unique_ptr<PendingOperation>& po_entry : kv.second) {
// Free the cookies as we commit them to the database.
@@ -1237,7 +1226,6 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
if (!crypto_->EncryptString(po->cc().Value(), &encrypted_value)) {
DLOG(WARNING) << "Could not encrypt a cookie, skipping add.";
RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_ENCRYPT_FAILED);
- trouble = true;
continue;
}
add_smt.BindCString(3, ""); // value
@@ -1263,7 +1251,6 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
if (!add_smt.Run()) {
DLOG(WARNING) << "Could not add a cookie to the DB.";
RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_ADD);
- trouble = true;
}
break;
@@ -1278,7 +1265,6 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
DLOG(WARNING)
<< "Could not update cookie last access time in the DB.";
RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_UPDATE_ACCESS);
- trouble = true;
}
break;
@@ -1290,7 +1276,6 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
if (!del_smt.Run()) {
DLOG(WARNING) << "Could not delete a cookie from the DB.";
RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_DELETE);
- trouble = true;
}
break;
@@ -1300,13 +1285,10 @@ void SQLitePersistentCookieStore::Backend::DoCommit() {
}
}
}
- bool succeeded = transaction.Commit();
- UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults",
- succeeded
- ? (trouble ? BACKING_STORE_RESULTS_MIXED
- : BACKING_STORE_RESULTS_SUCCESS)
- : BACKING_STORE_RESULTS_FAILURE,
- BACKING_STORE_RESULTS_LAST_ENTRY);
+ bool commit_ok = transaction.Commit();
+ if (!commit_ok) {
+ RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_TRANSACTION_COMMIT);
+ }
}
size_t SQLitePersistentCookieStore::Backend::GetQueueLengthForTesting() {
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
index 7555e39ea88..79fa984d105 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -31,6 +31,7 @@
#include "net/base/test_completion_callback.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/extras/sqlite/cookie_crypto_delegate.h"
#include "net/log/net_log_capture_mode.h"
@@ -1273,16 +1274,14 @@ TEST_F(SQLitePersistentCookieStoreTest, KeyInconsistency) {
cookie_scheme_callback1.MakeCallback());
cookie_scheme_callback1.WaitUntilDone();
EXPECT_TRUE(cookie_scheme_callback1.result());
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
GURL ftp_url("ftp://subdomain.ftperiffic.com/page/");
auto cookie =
CanonicalCookie::Create(ftp_url, "A=B; max-age=3600", base::Time::Now(),
base::nullopt /* server_time */);
cookie_monster->SetCanonicalCookieAsync(
std::move(cookie), ftp_url, CookieOptions::MakeAllInclusive(),
- base::BindOnce(&ResultSavingCookieCallback<
- CanonicalCookie::CookieInclusionStatus>::Run,
+ base::BindOnce(&ResultSavingCookieCallback<CookieInclusionStatus>::Run,
base::Unretained(&set_cookie_callback)));
set_cookie_callback.WaitUntilDone();
EXPECT_TRUE(set_cookie_callback.result().IsInclude());
@@ -1290,16 +1289,14 @@ TEST_F(SQLitePersistentCookieStoreTest, KeyInconsistency) {
// Also insert a whole bunch of cookies to slow down the background loading of
// all the cookies.
for (int i = 0; i < 50; ++i) {
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback2;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback2;
GURL url(base::StringPrintf("http://example%d.com/", i));
auto canonical_cookie =
CanonicalCookie::Create(url, "A=B; max-age=3600", base::Time::Now(),
base::nullopt /* server_time */);
cookie_monster->SetCanonicalCookieAsync(
std::move(canonical_cookie), url, CookieOptions::MakeAllInclusive(),
- base::BindOnce(&ResultSavingCookieCallback<
- CanonicalCookie::CookieInclusionStatus>::Run,
+ base::BindOnce(&ResultSavingCookieCallback<CookieInclusionStatus>::Run,
base::Unretained(&set_cookie_callback2)));
set_cookie_callback2.WaitUntilDone();
EXPECT_TRUE(set_cookie_callback2.result().IsInclude());
@@ -1347,16 +1344,14 @@ TEST_F(SQLitePersistentCookieStoreTest, OpsIfInitFailed) {
std::unique_ptr<CookieMonster> cookie_monster =
std::make_unique<CookieMonster>(store_.get(), nullptr);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- set_cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> set_cookie_callback;
GURL url("http://www.example.com/");
auto cookie =
CanonicalCookie::Create(url, "A=B; max-age=3600", base::Time::Now(),
base::nullopt /* server_time */);
cookie_monster->SetCanonicalCookieAsync(
std::move(cookie), url, CookieOptions::MakeAllInclusive(),
- base::BindOnce(&ResultSavingCookieCallback<
- CanonicalCookie::CookieInclusionStatus>::Run,
+ base::BindOnce(&ResultSavingCookieCallback<CookieInclusionStatus>::Run,
base::Unretained(&set_cookie_callback)));
set_cookie_callback.WaitUntilDone();
EXPECT_TRUE(set_cookie_callback.result().IsInclude());
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc b/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
index 55d28e49413..c4fbb1e586d 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
@@ -582,8 +582,6 @@ bool SQLitePersistentReportingAndNelStore::Backend::CreateDatabaseSchema() {
base::Optional<int>
SQLitePersistentReportingAndNelStore::Backend::DoMigrateDatabaseSchema() {
int cur_version = meta_table()->GetVersionNumber();
- if (cur_version != 1)
- return base::nullopt;
// Future database upgrade statements go here.
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc b/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc
index 1faaac6612e..aed51b9a5d7 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc
@@ -16,12 +16,15 @@
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/test/bind_test_util.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_test_util.h"
#include "net/test/test_with_task_environment.h"
+#include "sql/database.h"
+#include "sql/meta_table.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -199,8 +202,7 @@ class SQLitePersistentReportingAndNelStoreTest
info.priority = priority;
info.weight = weight;
ReportingEndpoint endpoint(
- ReportingEndpointGroupKey(NetworkIsolationKey::Todo(), origin,
- group_name),
+ ReportingEndpointGroupKey(NetworkIsolationKey(), origin, group_name),
std::move(info));
return endpoint;
}
@@ -212,8 +214,7 @@ class SQLitePersistentReportingAndNelStoreTest
OriginSubdomains include_subdomains = OriginSubdomains::DEFAULT,
base::Time expires = kExpires) {
return CachedReportingEndpointGroup(
- ReportingEndpointGroupKey(NetworkIsolationKey::Todo(), origin,
- group_name),
+ ReportingEndpointGroupKey(NetworkIsolationKey(), origin, group_name),
include_subdomains, expires, last_used);
}
@@ -237,6 +238,72 @@ TEST_F(SQLitePersistentReportingAndNelStoreTest, CreateDBAndTables) {
EXPECT_NE(std::string::npos, contents.find("reporting_endpoint_groups"));
}
+TEST_F(SQLitePersistentReportingAndNelStoreTest, TestInvalidMetaTableRecovery) {
+ CreateStore();
+ InitializeStore();
+ base::Time now = base::Time::Now();
+ NetworkErrorLoggingService::NelPolicy policy1 =
+ MakeNelPolicy(url::Origin::Create(GURL("https://www.foo.test")), now);
+ store_->AddNelPolicy(policy1);
+
+ // Close and reopen the database.
+ DestroyStore();
+ CreateStore();
+
+ // Load the stored policy.
+ std::vector<NetworkErrorLoggingService::NelPolicy> policies;
+ LoadNelPolicies(&policies);
+ ASSERT_EQ(1u, policies.size());
+ EXPECT_EQ(policy1.origin, policies[0].origin);
+ EXPECT_EQ(policy1.received_ip_address, policies[0].received_ip_address);
+ EXPECT_EQ(policy1.report_to, policies[0].report_to);
+ EXPECT_TRUE(WithinOneMicrosecond(policy1.expires, policies[0].expires));
+ EXPECT_EQ(policy1.include_subdomains, policies[0].include_subdomains);
+ EXPECT_EQ(policy1.success_fraction, policies[0].success_fraction);
+ EXPECT_EQ(policy1.failure_fraction, policies[0].failure_fraction);
+ EXPECT_TRUE(WithinOneMicrosecond(policy1.last_used, policies[0].last_used));
+ DestroyStore();
+ policies.clear();
+
+ // Now corrupt the meta table.
+ {
+ sql::Database db;
+ ASSERT_TRUE(
+ db.Open(temp_dir_.GetPath().Append(kReportingAndNELStoreFilename)));
+ sql::MetaTable meta_table;
+ meta_table.Init(&db, 1, 1);
+ ASSERT_TRUE(db.Execute("DELETE FROM meta"));
+ db.Close();
+ }
+
+ base::HistogramTester hist_tester;
+
+ // Upon loading, the database should be reset to a good, blank state.
+ CreateStore();
+ LoadNelPolicies(&policies);
+ ASSERT_EQ(0U, policies.size());
+
+ hist_tester.ExpectUniqueSample("ReportingAndNEL.CorruptMetaTable", 1, 1);
+
+ // Verify that, after, recovery, the database persists properly.
+ NetworkErrorLoggingService::NelPolicy policy2 =
+ MakeNelPolicy(url::Origin::Create(GURL("https://www.bar.test")), now);
+ store_->AddNelPolicy(policy2);
+ DestroyStore();
+
+ CreateStore();
+ LoadNelPolicies(&policies);
+ ASSERT_EQ(1u, policies.size());
+ EXPECT_EQ(policy2.origin, policies[0].origin);
+ EXPECT_EQ(policy2.received_ip_address, policies[0].received_ip_address);
+ EXPECT_EQ(policy2.report_to, policies[0].report_to);
+ EXPECT_TRUE(WithinOneMicrosecond(policy2.expires, policies[0].expires));
+ EXPECT_EQ(policy2.include_subdomains, policies[0].include_subdomains);
+ EXPECT_EQ(policy2.success_fraction, policies[0].success_fraction);
+ EXPECT_EQ(policy2.failure_fraction, policies[0].failure_fraction);
+ EXPECT_TRUE(WithinOneMicrosecond(policy2.last_used, policies[0].last_used));
+}
+
TEST_F(SQLitePersistentReportingAndNelStoreTest, PersistNelPolicy) {
CreateStore();
InitializeStore();
diff --git a/chromium/net/http/alternative_service.cc b/chromium/net/http/alternative_service.cc
index 56273b992fc..e43ce7d71f2 100644
--- a/chromium/net/http/alternative_service.cc
+++ b/chromium/net/http/alternative_service.cc
@@ -47,13 +47,14 @@ quic::ParsedQuicVersion ParsedQuicVersionFromAlpn(
if (AlpnForVersion(version) == str)
return version;
}
- return {quic::PROTOCOL_UNSUPPORTED, quic::QUIC_VERSION_UNSUPPORTED};
+ return quic::ParsedQuicVersion::Unsupported();
}
} // anonymous namespace
void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage,
- bool proxy_server_used) {
+ bool proxy_server_used,
+ bool is_google_host) {
if (proxy_server_used) {
DCHECK_LE(usage, ALTERNATE_PROTOCOL_USAGE_LOST_RACE);
LOCAL_HISTOGRAM_ENUMERATION("Net.QuicAlternativeProxy.Usage",
@@ -62,6 +63,10 @@ void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage,
} else {
UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsage", usage,
ALTERNATE_PROTOCOL_USAGE_MAX);
+ if (is_google_host) {
+ UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsageGoogle", usage,
+ ALTERNATE_PROTOCOL_USAGE_MAX);
+ }
}
}
@@ -201,8 +206,7 @@ AlternativeServiceInfoVector ProcessAlternativeServices(
} else if (!IsAlternateProtocolValid(protocol)) {
quic::ParsedQuicVersion version = ParsedQuicVersionFromAlpn(
alternative_service_entry.protocol_id, supported_quic_versions);
- if (version.handshake_protocol == quic::PROTOCOL_UNSUPPORTED ||
- version.transport_version == quic::QUIC_VERSION_UNSUPPORTED) {
+ if (version == quic::ParsedQuicVersion::Unsupported()) {
continue;
}
protocol = kProtoQUIC;
diff --git a/chromium/net/http/alternative_service.h b/chromium/net/http/alternative_service.h
index aaf32b77779..eaaae3e6f8f 100644
--- a/chromium/net/http/alternative_service.h
+++ b/chromium/net/http/alternative_service.h
@@ -41,7 +41,8 @@ enum AlternateProtocolUsage {
// Log a histogram to reflect |usage|.
NET_EXPORT void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage,
- bool proxy_server_used);
+ bool proxy_server_used,
+ bool is_google_host);
enum BrokenAlternateProtocolLocation {
BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB = 0,
diff --git a/chromium/net/http/failing_http_transaction_factory.cc b/chromium/net/http/failing_http_transaction_factory.cc
deleted file mode 100644
index 7f367a8d38e..00000000000
--- a/chromium/net/http/failing_http_transaction_factory.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2014 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/http/failing_http_transaction_factory.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/check_op.h"
-#include "base/compiler_specific.h"
-#include "base/location.h"
-#include "base/notreached.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "net/base/completion_once_callback.h"
-#include "net/base/load_timing_info.h"
-#include "net/base/net_error_details.h"
-#include "net/http/http_response_info.h"
-#include "net/socket/connection_attempts.h"
-
-namespace net {
-
-class AuthCredentials;
-class HttpRequestHeaders;
-class IOBuffer;
-class NetLogWithSource;
-class SSLPrivateKey;
-class X509Certificate;
-
-namespace {
-
-// A simple class to interpose between the cache and network http layers.
-// These transactions can be generated by the FailingHttpTransactionFactory
-// to test interactions between cache and network.
-class FailingHttpTransaction : public HttpTransaction {
- public:
- explicit FailingHttpTransaction(Error error);
- ~FailingHttpTransaction() override;
-
- // HttpTransaction
- int Start(const HttpRequestInfo* request_info,
- CompletionOnceCallback callback,
- const NetLogWithSource& net_log) override;
- int RestartIgnoringLastError(CompletionOnceCallback callback) override;
- int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
- scoped_refptr<SSLPrivateKey> client_private_key,
- CompletionOnceCallback callback) override;
- int RestartWithAuth(const AuthCredentials& credentials,
- CompletionOnceCallback callback) override;
- bool IsReadyToRestartForAuth() override;
- int Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override;
- void StopCaching() override;
- int64_t GetTotalReceivedBytes() const override;
- int64_t GetTotalSentBytes() const override;
- void DoneReading() override;
- const HttpResponseInfo* GetResponseInfo() const override;
- LoadState GetLoadState() const override;
- void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
- bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
- bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
- void PopulateNetErrorDetails(NetErrorDetails* details) const override;
- void SetPriority(RequestPriority priority) override;
- void SetWebSocketHandshakeStreamCreateHelper(
- WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
- void SetBeforeNetworkStartCallback(
- const BeforeNetworkStartCallback& callback) override;
- int ResumeNetworkStart() override;
- void GetConnectionAttempts(ConnectionAttempts* out) const override;
- void SetRequestHeadersCallback(RequestHeadersCallback) override {}
- void SetResponseHeadersCallback(ResponseHeadersCallback) override {}
-
- private:
- Error error_;
- HttpResponseInfo response_;
-};
-
-FailingHttpTransaction::FailingHttpTransaction(Error error) : error_(error) {
- DCHECK_LT(error, OK);
-}
-
-FailingHttpTransaction::~FailingHttpTransaction() = default;
-
-int FailingHttpTransaction::Start(const HttpRequestInfo* request_info,
- CompletionOnceCallback callback,
- const NetLogWithSource& net_log) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), error_));
- return ERR_IO_PENDING;
-}
-
-int FailingHttpTransaction::RestartIgnoringLastError(
- CompletionOnceCallback callback) {
- return ERR_FAILED;
-}
-
-int FailingHttpTransaction::RestartWithCertificate(
- scoped_refptr<X509Certificate> client_cert,
- scoped_refptr<SSLPrivateKey> client_private_key,
- CompletionOnceCallback callback) {
- return ERR_FAILED;
-}
-
-int FailingHttpTransaction::RestartWithAuth(const AuthCredentials& credentials,
- CompletionOnceCallback callback) {
- return ERR_FAILED;
-}
-
-bool FailingHttpTransaction::IsReadyToRestartForAuth() {
- return false;
-}
-
-int FailingHttpTransaction::Read(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) {
- NOTREACHED();
- return ERR_FAILED;
-}
-
-void FailingHttpTransaction::StopCaching() {}
-
-int64_t FailingHttpTransaction::GetTotalReceivedBytes() const {
- return 0;
-}
-
-int64_t FailingHttpTransaction::GetTotalSentBytes() const {
- return 0;
-}
-
-void FailingHttpTransaction::DoneReading() {
- NOTREACHED();
-}
-
-const HttpResponseInfo* FailingHttpTransaction::GetResponseInfo() const {
- return &response_;
-}
-
-LoadState FailingHttpTransaction::GetLoadState() const {
- return LOAD_STATE_IDLE;
-}
-
-void FailingHttpTransaction::SetQuicServerInfo(
- QuicServerInfo* quic_server_info) {
-}
-
-bool FailingHttpTransaction::GetLoadTimingInfo(
- LoadTimingInfo* load_timing_info) const {
- return false;
-}
-
-bool FailingHttpTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
- return false;
-}
-
-void FailingHttpTransaction::PopulateNetErrorDetails(
- NetErrorDetails* /*details*/) const {
- return;
-}
-
-void FailingHttpTransaction::SetPriority(RequestPriority priority) {}
-
-void FailingHttpTransaction::SetWebSocketHandshakeStreamCreateHelper(
- WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
- NOTREACHED();
-}
-
-void FailingHttpTransaction::SetBeforeNetworkStartCallback(
- const BeforeNetworkStartCallback& callback) {
-}
-
-int FailingHttpTransaction::ResumeNetworkStart() {
- NOTREACHED();
- return ERR_FAILED;
-}
-
-void FailingHttpTransaction::GetConnectionAttempts(
- ConnectionAttempts* out) const {
- NOTIMPLEMENTED();
-}
-
-} // namespace
-
-FailingHttpTransactionFactory::FailingHttpTransactionFactory(
- HttpNetworkSession* session,
- Error error) : session_(session), error_(error) {
- DCHECK_LT(error, OK);
-}
-
-FailingHttpTransactionFactory::~FailingHttpTransactionFactory() = default;
-
-// HttpTransactionFactory:
-int FailingHttpTransactionFactory::CreateTransaction(
- RequestPriority priority,
- std::unique_ptr<HttpTransaction>* trans) {
- trans->reset(new FailingHttpTransaction(error_));
- return OK;
-}
-
-HttpCache* FailingHttpTransactionFactory::GetCache() {
- return nullptr;
-}
-
-HttpNetworkSession* FailingHttpTransactionFactory::GetSession() {
- return session_;
-}
-
-} // namespace net
diff --git a/chromium/net/http/failing_http_transaction_factory.h b/chromium/net/http/failing_http_transaction_factory.h
deleted file mode 100644
index 0830d57c1a6..00000000000
--- a/chromium/net/http/failing_http_transaction_factory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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 NET_HTTP_FAILING_HTTP_TRANSACTION_FACTORY_H_
-#define NET_HTTP_FAILING_HTTP_TRANSACTION_FACTORY_H_
-
-#include <memory>
-
-#include "net/base/net_errors.h"
-#include "net/base/net_export.h"
-#include "net/base/request_priority.h"
-#include "net/http/http_transaction.h"
-#include "net/http/http_transaction_factory.h"
-
-namespace net {
-
-class HttpCache;
-class HttpNetworkSession;
-
-// Creates transactions that always (asynchronously) return a specified
-// error. The error is returned asynchronously, just after the transaction is
-// started.
-class NET_EXPORT FailingHttpTransactionFactory : public HttpTransactionFactory {
- public:
- // The caller must guarantee that |session| outlives this object.
- FailingHttpTransactionFactory(HttpNetworkSession* session, Error error);
- ~FailingHttpTransactionFactory() override;
-
- // HttpTransactionFactory:
- int CreateTransaction(RequestPriority priority,
- std::unique_ptr<HttpTransaction>* trans) override;
- HttpCache* GetCache() override;
- HttpNetworkSession* GetSession() override;
-
- private:
- HttpNetworkSession* session_;
- Error error_;
-};
-
-} // namespace net
-
-#endif // NET_HTTP_FAILING_HTTP_TRANSACTION_FACTORY_H_
diff --git a/chromium/net/http/http_auth.cc b/chromium/net/http/http_auth.cc
index 57d4c9029ef..986f0330f7e 100644
--- a/chromium/net/http/http_auth.cc
+++ b/chromium/net/http/http_auth.cc
@@ -37,6 +37,7 @@ void HttpAuth::ChooseBestChallenge(
HttpAuthHandlerFactory* http_auth_handler_factory,
const HttpResponseHeaders& response_headers,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
Target target,
const GURL& origin,
const std::set<Scheme>& disabled_schemes,
@@ -54,7 +55,8 @@ void HttpAuth::ChooseBestChallenge(
while (response_headers.EnumerateHeader(&iter, header_name, &cur_challenge)) {
std::unique_ptr<HttpAuthHandler> cur;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
- cur_challenge, target, ssl_info, origin, net_log, host_resolver, &cur);
+ cur_challenge, target, ssl_info, network_isolation_key, origin, net_log,
+ host_resolver, &cur);
if (rv != OK) {
VLOG(1) << "Unable to create AuthHandler. Status: "
<< ErrorToString(rv) << " Challenge: " << cur_challenge;
diff --git a/chromium/net/http/http_auth.h b/chromium/net/http/http_auth.h
index 622015423a9..78b46f3ff2c 100644
--- a/chromium/net/http/http_auth.h
+++ b/chromium/net/http/http_auth.h
@@ -173,6 +173,7 @@ class NET_EXPORT_PRIVATE HttpAuth {
HttpAuthHandlerFactory* http_auth_handler_factory,
const HttpResponseHeaders& response_headers,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
Target target,
const GURL& origin,
const std::set<Scheme>& disabled_schemes,
diff --git a/chromium/net/http/http_auth_controller.cc b/chromium/net/http/http_auth_controller.cc
index 1ef08d8c87a..fc335665bc1 100644
--- a/chromium/net/http/http_auth_controller.cc
+++ b/chromium/net/http/http_auth_controller.cc
@@ -231,8 +231,8 @@ bool HttpAuthController::SelectPreemptiveAuth(
std::unique_ptr<HttpAuthHandler> handler_preemptive;
int rv_create =
http_auth_handler_factory_->CreatePreemptiveAuthHandlerFromString(
- entry->auth_challenge(), target_, auth_origin_,
- entry->IncrementNonceCount(), net_log_, host_resolver_,
+ entry->auth_challenge(), target_, network_isolation_key_,
+ auth_origin_, entry->IncrementNonceCount(), net_log_, host_resolver_,
&handler_preemptive);
if (rv_create != OK)
return false;
@@ -328,9 +328,10 @@ int HttpAuthController::HandleAuthChallenge(
do {
if (!handler_.get() && can_send_auth) {
// Find the best authentication challenge that we support.
- HttpAuth::ChooseBestChallenge(
- http_auth_handler_factory_, *headers, ssl_info, target_, auth_origin_,
- disabled_schemes_, net_log_, host_resolver_, &handler_);
+ HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, *headers,
+ ssl_info, network_isolation_key_, target_,
+ auth_origin_, disabled_schemes_, net_log_,
+ host_resolver_, &handler_);
if (handler_.get())
HistogramAuthEvent(handler_.get(), AUTH_EVENT_START);
}
diff --git a/chromium/net/http/http_auth_controller_unittest.cc b/chromium/net/http/http_auth_controller_unittest.cc
index 1f78cacf18d..a6dc2f86c12 100644
--- a/chromium/net/http/http_auth_controller_unittest.cc
+++ b/chromium/net/http/http_auth_controller_unittest.cc
@@ -183,8 +183,9 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
protected:
bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) override {
- HttpAuthHandlerMock::Init(challenge, ssl_info);
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override {
+ HttpAuthHandlerMock::Init(challenge, ssl_info, network_isolation_key);
set_allows_default_credentials(true);
set_allows_explicit_credentials(false);
set_connection_based(true);
diff --git a/chromium/net/http/http_auth_handler.cc b/chromium/net/http/http_auth_handler.cc
index b62f870a755..4d2164e47df 100644
--- a/chromium/net/http/http_auth_handler.cc
+++ b/chromium/net/http/http_auth_handler.cc
@@ -25,11 +25,13 @@ HttpAuthHandler::HttpAuthHandler()
HttpAuthHandler::~HttpAuthHandler() = default;
-bool HttpAuthHandler::InitFromChallenge(HttpAuthChallengeTokenizer* challenge,
- HttpAuth::Target target,
- const SSLInfo& ssl_info,
- const GURL& origin,
- const NetLogWithSource& net_log) {
+bool HttpAuthHandler::InitFromChallenge(
+ HttpAuthChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
+ const GURL& origin,
+ const NetLogWithSource& net_log) {
origin_ = origin;
target_ = target;
score_ = -1;
@@ -38,7 +40,7 @@ bool HttpAuthHandler::InitFromChallenge(HttpAuthChallengeTokenizer* challenge,
auth_challenge_ = challenge->challenge_text();
net_log_.BeginEvent(NetLogEventType::AUTH_HANDLER_INIT);
- bool ok = Init(challenge, ssl_info);
+ bool ok = Init(challenge, ssl_info, network_isolation_key);
net_log_.AddEntryWithBoolParams(NetLogEventType::AUTH_HANDLER_INIT,
NetLogEventPhase::END, "succeeded", ok);
diff --git a/chromium/net/http/http_auth_handler.h b/chromium/net/http/http_auth_handler.h
index c8d3b9f4761..1a17af7a43f 100644
--- a/chromium/net/http/http_auth_handler.h
+++ b/chromium/net/http/http_auth_handler.h
@@ -15,6 +15,7 @@
namespace net {
+class NetworkIsolationKey;
class HttpAuthChallengeTokenizer;
struct HttpRequestInfo;
class SSLInfo;
@@ -43,10 +44,13 @@ class NET_EXPORT_PRIVATE HttpAuthHandler {
// |target| and |origin| are both stored for later use, and are not part of
// the initial challenge.
// |ssl_info| must be valid if the underlying connection used a certificate.
+ // |network_isolation_key| the NetworkIsolationKey associated with the
+ // challenge. Used for host resolutions, if any are needed.
// |net_log| to be used for logging.
bool InitFromChallenge(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
const NetLogWithSource& net_log);
@@ -178,10 +182,13 @@ class NET_EXPORT_PRIVATE HttpAuthHandler {
// If the request was sent over an encrypted connection, |ssl_info| is valid
// and describes the connection.
//
+ // NetworkIsolationKey is the NetworkIsolationKey associated with the request.
+ //
// Implementations are expected to initialize the following members:
// scheme_, realm_, score_, properties_
virtual bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) = 0;
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) = 0;
// |GenerateAuthTokenImpl()} is the auth-scheme specific implementation
// of generating the next auth token. Callers should use |GenerateAuthToken()|
diff --git a/chromium/net/http/http_auth_handler_basic.cc b/chromium/net/http/http_auth_handler_basic.cc
index 696aaf0e8dc..4692c02b248 100644
--- a/chromium/net/http/http_auth_handler_basic.cc
+++ b/chromium/net/http/http_auth_handler_basic.cc
@@ -55,8 +55,10 @@ bool ParseRealm(const HttpAuthChallengeTokenizer& tokenizer,
} // namespace
-bool HttpAuthHandlerBasic::Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) {
+bool HttpAuthHandlerBasic::Init(
+ HttpAuthChallengeTokenizer* challenge,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
auth_scheme_ = HttpAuth::AUTH_SCHEME_BASIC;
score_ = 1;
properties_ = 0;
@@ -111,6 +113,7 @@ int HttpAuthHandlerBasic::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -120,9 +123,10 @@ int HttpAuthHandlerBasic::Factory::CreateAuthHandler(
// TODO(cbentzel): Move towards model of parsing in the factory
// method and only constructing when valid.
std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerBasic());
- if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log)) {
return ERR_INVALID_RESPONSE;
+ }
handler->swap(tmp_handler);
return OK;
}
diff --git a/chromium/net/http/http_auth_handler_basic.h b/chromium/net/http/http_auth_handler_basic.h
index 6f4a00950a0..8042182b315 100644
--- a/chromium/net/http/http_auth_handler_basic.h
+++ b/chromium/net/http/http_auth_handler_basic.h
@@ -26,6 +26,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerBasic : public HttpAuthHandler {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -37,7 +38,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerBasic : public HttpAuthHandler {
private:
// HttpAuthHandler
bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) override;
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
diff --git a/chromium/net/http/http_auth_handler_basic_fuzzer.cc b/chromium/net/http/http_auth_handler_basic_fuzzer.cc
index 5c1b7b24993..498452e96ab 100644
--- a/chromium/net/http/http_auth_handler_basic_fuzzer.cc
+++ b/chromium/net/http/http_auth_handler_basic_fuzzer.cc
@@ -5,6 +5,7 @@
#include <memory>
#include <string>
+#include "net/base/network_isolation_key.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_basic.h"
@@ -23,8 +24,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::unique_ptr<net::HttpAuthHandler> basic;
net::HttpAuthHandlerBasic::Factory factory;
- factory.CreateAuthHandlerFromString(
- challenge, net::HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- net::NetLogWithSource(), host_resolver.get(), &basic);
+ factory.CreateAuthHandlerFromString(challenge, net::HttpAuth::AUTH_SERVER,
+ null_ssl_info, net::NetworkIsolationKey(),
+ origin, net::NetLogWithSource(),
+ host_resolver.get(), &basic);
return 0;
}
diff --git a/chromium/net/http/http_auth_handler_basic_unittest.cc b/chromium/net/http/http_auth_handler_basic_unittest.cc
index f2c80e641bd..9754d230684 100644
--- a/chromium/net/http/http_auth_handler_basic_unittest.cc
+++ b/chromium/net/http/http_auth_handler_basic_unittest.cc
@@ -11,6 +11,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_challenge_tokenizer.h"
@@ -47,8 +48,9 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) {
auto host_resolver = std::make_unique<MockHostResolver>();
std::unique_ptr<HttpAuthHandler> basic;
EXPECT_EQ(OK, factory.CreateAuthHandlerFromString(
- challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- NetLogWithSource(), host_resolver.get(), &basic));
+ challenge, HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), origin, NetLogWithSource(),
+ host_resolver.get(), &basic));
AuthCredentials credentials(base::ASCIIToUTF16(tests[i].username),
base::ASCIIToUTF16(tests[i].password));
HttpRequestInfo request_info;
@@ -103,7 +105,8 @@ TEST(HttpAuthHandlerBasicTest, HandleAnotherChallenge) {
std::unique_ptr<HttpAuthHandler> basic;
EXPECT_EQ(OK, factory.CreateAuthHandlerFromString(
tests[0].challenge, HttpAuth::AUTH_SERVER, null_ssl_info,
- origin, NetLogWithSource(), host_resolver.get(), &basic));
+ NetworkIsolationKey(), origin, NetLogWithSource(),
+ host_resolver.get(), &basic));
for (size_t i = 0; i < base::size(tests); ++i) {
std::string challenge(tests[i].challenge);
@@ -204,8 +207,8 @@ TEST(HttpAuthHandlerBasicTest, InitFromChallenge) {
auto host_resolver = std::make_unique<MockHostResolver>();
std::unique_ptr<HttpAuthHandler> basic;
int rv = factory.CreateAuthHandlerFromString(
- challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- NetLogWithSource(), host_resolver.get(), &basic);
+ challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ origin, NetLogWithSource(), host_resolver.get(), &basic);
EXPECT_EQ(tests[i].expected_rv, rv);
if (rv == OK)
EXPECT_EQ(tests[i].expected_realm, basic->realm());
diff --git a/chromium/net/http/http_auth_handler_digest.cc b/chromium/net/http/http_auth_handler_digest.cc
index 64c2f6de57d..71289867729 100644
--- a/chromium/net/http/http_auth_handler_digest.cc
+++ b/chromium/net/http/http_auth_handler_digest.cc
@@ -92,6 +92,7 @@ int HttpAuthHandlerDigest::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -102,15 +103,18 @@ int HttpAuthHandlerDigest::Factory::CreateAuthHandler(
// method and only constructing when valid.
std::unique_ptr<HttpAuthHandler> tmp_handler(
new HttpAuthHandlerDigest(digest_nonce_count, nonce_generator_.get()));
- if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log)) {
return ERR_INVALID_RESPONSE;
+ }
handler->swap(tmp_handler);
return OK;
}
-bool HttpAuthHandlerDigest::Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) {
+bool HttpAuthHandlerDigest::Init(
+ HttpAuthChallengeTokenizer* challenge,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
return ParseChallenge(challenge);
}
diff --git a/chromium/net/http/http_auth_handler_digest.h b/chromium/net/http/http_auth_handler_digest.h
index b4f847d721b..b8688ceb905 100644
--- a/chromium/net/http/http_auth_handler_digest.h
+++ b/chromium/net/http/http_auth_handler_digest.h
@@ -70,6 +70,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -84,7 +85,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler {
private:
// HttpAuthHandler
bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) override;
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
diff --git a/chromium/net/http/http_auth_handler_digest_fuzzer.cc b/chromium/net/http/http_auth_handler_digest_fuzzer.cc
index caaf1fd8c39..20e452bd11d 100644
--- a/chromium/net/http/http_auth_handler_digest_fuzzer.cc
+++ b/chromium/net/http/http_auth_handler_digest_fuzzer.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include "net/base/network_isolation_key.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_handler.h"
@@ -28,9 +29,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::unique_ptr<net::HttpAuthHandler> handler;
net::HttpAuthHandlerDigest::Factory factory;
- factory.CreateAuthHandlerFromString(
- challenge, net::HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- net::NetLogWithSource(), host_resolver.get(), &handler);
+ factory.CreateAuthHandlerFromString(challenge, net::HttpAuth::AUTH_SERVER,
+ null_ssl_info, net::NetworkIsolationKey(),
+ origin, net::NetLogWithSource(),
+ host_resolver.get(), &handler);
if (handler) {
auto followup = "Digest " + data_provider.ConsumeRemainingBytesAsString();
diff --git a/chromium/net/http/http_auth_handler_digest_unittest.cc b/chromium/net/http/http_auth_handler_digest_unittest.cc
index f13ae108886..200508ba908 100644
--- a/chromium/net/http/http_auth_handler_digest_unittest.cc
+++ b/chromium/net/http/http_auth_handler_digest_unittest.cc
@@ -8,6 +8,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_challenge_tokenizer.h"
@@ -64,8 +65,9 @@ bool RespondToChallenge(HttpAuth::Target target,
SSLInfo null_ssl_info;
GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name);
int rv_create = factory->CreateAuthHandlerFromString(
- challenge, target, null_ssl_info, url_origin.GetOrigin(),
- NetLogWithSource(), host_resolver.get(), &handler);
+ challenge, target, null_ssl_info, NetworkIsolationKey(),
+ url_origin.GetOrigin(), NetLogWithSource(), host_resolver.get(),
+ &handler);
if (rv_create != OK || handler.get() == nullptr) {
ADD_FAILURE() << "Unable to create auth handler.";
return false;
@@ -366,8 +368,9 @@ TEST(HttpAuthHandlerDigestTest, ParseChallenge) {
auto host_resolver = std::make_unique<MockHostResolver>();
std::unique_ptr<HttpAuthHandler> handler;
int rv = factory->CreateAuthHandlerFromString(
- tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- NetLogWithSource(), host_resolver.get(), &handler);
+ tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), origin, NetLogWithSource(), host_resolver.get(),
+ &handler);
if (tests[i].parsed_success) {
EXPECT_THAT(rv, IsOk());
} else {
@@ -531,8 +534,9 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) {
auto host_resolver = std::make_unique<MockHostResolver>();
std::unique_ptr<HttpAuthHandler> handler;
int rv = factory->CreateAuthHandlerFromString(
- tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- NetLogWithSource(), host_resolver.get(), &handler);
+ tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), origin, NetLogWithSource(), host_resolver.get(),
+ &handler);
EXPECT_THAT(rv, IsOk());
ASSERT_TRUE(handler != nullptr);
@@ -561,8 +565,9 @@ TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) {
GURL origin("intranet.google.com");
SSLInfo null_ssl_info;
int rv = factory->CreateAuthHandlerFromString(
- default_challenge, HttpAuth::AUTH_SERVER, null_ssl_info, origin,
- NetLogWithSource(), host_resolver.get(), &handler);
+ default_challenge, HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), origin, NetLogWithSource(), host_resolver.get(),
+ &handler);
EXPECT_THAT(rv, IsOk());
ASSERT_TRUE(handler.get() != nullptr);
HttpAuthChallengeTokenizer tok_default(default_challenge.begin(),
diff --git a/chromium/net/http/http_auth_handler_factory.cc b/chromium/net/http/http_auth_handler_factory.cc
index 05a7a8c21a8..c5d50949623 100644
--- a/chromium/net/http/http_auth_handler_factory.cc
+++ b/chromium/net/http/http_auth_handler_factory.cc
@@ -32,18 +32,21 @@ int HttpAuthHandlerFactory::CreateAuthHandlerFromString(
const std::string& challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
const NetLogWithSource& net_log,
HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) {
HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end());
- return CreateAuthHandler(&props, target, ssl_info, origin, CREATE_CHALLENGE,
- 1, net_log, host_resolver, handler);
+ return CreateAuthHandler(&props, target, ssl_info, network_isolation_key,
+ origin, CREATE_CHALLENGE, 1, net_log, host_resolver,
+ handler);
}
int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
const std::string& challenge,
HttpAuth::Target target,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
int digest_nonce_count,
const NetLogWithSource& net_log,
@@ -51,9 +54,9 @@ int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
std::unique_ptr<HttpAuthHandler>* handler) {
HttpAuthChallengeTokenizer props(challenge.begin(), challenge.end());
SSLInfo null_ssl_info;
- return CreateAuthHandler(&props, target, null_ssl_info, origin,
- CREATE_PREEMPTIVE, digest_nonce_count, net_log,
- host_resolver, handler);
+ return CreateAuthHandler(&props, target, null_ssl_info, network_isolation_key,
+ origin, CREATE_PREEMPTIVE, digest_nonce_count,
+ net_log, host_resolver, handler);
}
namespace {
@@ -194,6 +197,7 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -211,9 +215,9 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
return ERR_UNSUPPORTED_AUTH_SCHEME;
}
DCHECK(it->second);
- return it->second->CreateAuthHandler(challenge, target, ssl_info, origin,
- reason, digest_nonce_count, net_log,
- host_resolver, handler);
+ return it->second->CreateAuthHandler(
+ challenge, target, ssl_info, network_isolation_key, origin, reason,
+ digest_nonce_count, net_log, host_resolver, handler);
}
} // namespace net
diff --git a/chromium/net/http/http_auth_handler_factory.h b/chromium/net/http/http_auth_handler_factory.h
index c38a368fe3d..aeba0b8429f 100644
--- a/chromium/net/http/http_auth_handler_factory.h
+++ b/chromium/net/http/http_auth_handler_factory.h
@@ -28,6 +28,7 @@ class HttpAuthHandler;
class HttpAuthHandlerRegistryFactory;
class HttpAuthPreferences;
class NetLogWithSource;
+class NetworkIsolationKey;
// An HttpAuthHandlerFactory is used to create HttpAuthHandler objects.
// The HttpAuthHandlerFactory object _must_ outlive any of the HttpAuthHandler
@@ -90,28 +91,32 @@ class NET_EXPORT HttpAuthHandlerFactory {
// scheme is used and the factory was created with
// |negotiate_disable_cname_lookup| false, |host_resolver| must not be null,
// and it must remain valid for the lifetime of the created |handler|.
- virtual int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
- HttpAuth::Target target,
- const SSLInfo& ssl_info,
- const GURL& origin,
- CreateReason create_reason,
- int digest_nonce_count,
- const NetLogWithSource& net_log,
- HostResolver* host_resolver,
- std::unique_ptr<HttpAuthHandler>* handler) = 0;
+ virtual int CreateAuthHandler(
+ HttpAuthChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
+ const GURL& origin,
+ CreateReason create_reason,
+ int digest_nonce_count,
+ const NetLogWithSource& net_log,
+ HostResolver* host_resolver,
+ std::unique_ptr<HttpAuthHandler>* handler) = 0;
// Creates an HTTP authentication handler based on the authentication
// challenge string |challenge|.
// This is a convenience function which creates a ChallengeTokenizer for
// |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
// more details on return values.
- int CreateAuthHandlerFromString(const std::string& challenge,
- HttpAuth::Target target,
- const SSLInfo& ssl_info,
- const GURL& origin,
- const NetLogWithSource& net_log,
- HostResolver* host_resolver,
- std::unique_ptr<HttpAuthHandler>* handler);
+ int CreateAuthHandlerFromString(
+ const std::string& challenge,
+ HttpAuth::Target target,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
+ const GURL& origin,
+ const NetLogWithSource& net_log,
+ HostResolver* host_resolver,
+ std::unique_ptr<HttpAuthHandler>* handler);
// Creates an HTTP authentication handler based on the authentication
// challenge string |challenge|.
@@ -121,6 +126,7 @@ class NET_EXPORT HttpAuthHandlerFactory {
int CreatePreemptiveAuthHandlerFromString(
const std::string& challenge,
HttpAuth::Target target,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
int digest_nonce_count,
const NetLogWithSource& net_log,
@@ -219,6 +225,7 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
diff --git a/chromium/net/http/http_auth_handler_factory_unittest.cc b/chromium/net/http/http_auth_handler_factory_unittest.cc
index 0a99c6fec8c..7b1d0f3f3bc 100644
--- a/chromium/net/http/http_auth_handler_factory_unittest.cc
+++ b/chromium/net/http/http_auth_handler_factory_unittest.cc
@@ -8,6 +8,7 @@
#include "build/build_config.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler.h"
@@ -37,6 +38,7 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int nonce_count,
@@ -73,49 +75,57 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) {
std::unique_ptr<HttpAuthHandler> handler;
// No schemes should be supported in the beginning.
- EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
- registry_factory.CreateAuthHandlerFromString(
- "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
// Test what happens with a single scheme.
registry_factory.RegisterSchemeFactory("Basic", mock_factory_basic);
- EXPECT_EQ(kBasicReturnCode,
- registry_factory.CreateAuthHandlerFromString(
- "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
- EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
- registry_factory.CreateAuthHandlerFromString(
- "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
// Test multiple schemes
registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest);
- EXPECT_EQ(kBasicReturnCode,
- registry_factory.CreateAuthHandlerFromString(
- "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
- EXPECT_EQ(kDigestReturnCode,
- registry_factory.CreateAuthHandlerFromString(
- "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kDigestReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
// Test case-insensitivity
- EXPECT_EQ(kBasicReturnCode,
- registry_factory.CreateAuthHandlerFromString(
- "basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
// Test replacement of existing auth scheme
registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest_replace);
- EXPECT_EQ(kBasicReturnCode,
- registry_factory.CreateAuthHandlerFromString(
- "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
- EXPECT_EQ(kDigestReturnCodeReplace,
- registry_factory.CreateAuthHandlerFromString(
- "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
+ EXPECT_EQ(
+ kDigestReturnCodeReplace,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resovler.get(), &handler));
}
TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
@@ -132,7 +142,8 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
std::unique_ptr<HttpAuthHandler> handler;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
"Basic realm=\"FooBar\"", HttpAuth::AUTH_SERVER, null_ssl_info,
- server_origin, NetLogWithSource(), host_resolver.get(), &handler);
+ NetworkIsolationKey(), server_origin, NetLogWithSource(),
+ host_resolver.get(), &handler);
EXPECT_THAT(rv, IsOk());
ASSERT_FALSE(handler.get() == nullptr);
EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, handler->auth_scheme());
@@ -145,7 +156,8 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
std::unique_ptr<HttpAuthHandler> handler;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
"UNSUPPORTED realm=\"FooBar\"", HttpAuth::AUTH_SERVER, null_ssl_info,
- server_origin, NetLogWithSource(), host_resolver.get(), &handler);
+ NetworkIsolationKey(), server_origin, NetLogWithSource(),
+ host_resolver.get(), &handler);
EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME));
EXPECT_TRUE(handler.get() == nullptr);
}
@@ -153,8 +165,8 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
std::unique_ptr<HttpAuthHandler> handler;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
"Digest realm=\"FooBar\", nonce=\"xyz\"", HttpAuth::AUTH_PROXY,
- null_ssl_info, proxy_origin, NetLogWithSource(), host_resolver.get(),
- &handler);
+ null_ssl_info, NetworkIsolationKey(), proxy_origin, NetLogWithSource(),
+ host_resolver.get(), &handler);
EXPECT_THAT(rv, IsOk());
ASSERT_FALSE(handler.get() == nullptr);
EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, handler->auth_scheme());
@@ -166,8 +178,8 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
{
std::unique_ptr<HttpAuthHandler> handler;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
- "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, server_origin,
- NetLogWithSource(), host_resolver.get(), &handler);
+ "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ server_origin, NetLogWithSource(), host_resolver.get(), &handler);
EXPECT_THAT(rv, IsOk());
ASSERT_FALSE(handler.get() == nullptr);
EXPECT_EQ(HttpAuth::AUTH_SCHEME_NTLM, handler->auth_scheme());
@@ -179,8 +191,9 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
{
std::unique_ptr<HttpAuthHandler> handler;
int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
- "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, server_origin,
- NetLogWithSource(), host_resolver.get(), &handler);
+ "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), server_origin, NetLogWithSource(),
+ host_resolver.get(), &handler);
// Note the default factory doesn't support Kerberos on Android
#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
EXPECT_THAT(rv, IsOk());
diff --git a/chromium/net/http/http_auth_handler_mock.cc b/chromium/net/http/http_auth_handler_mock.cc
index dd3000d5b65..951b0d49e12 100644
--- a/chromium/net/http/http_auth_handler_mock.cc
+++ b/chromium/net/http/http_auth_handler_mock.cc
@@ -70,8 +70,10 @@ bool HttpAuthHandlerMock::AllowsExplicitCredentials() {
return allows_explicit_credentials_;
}
-bool HttpAuthHandlerMock::Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) {
+bool HttpAuthHandlerMock::Init(
+ HttpAuthChallengeTokenizer* challenge,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
EXPECT_EQ(State::WAIT_FOR_INIT, state_);
state_ = State::WAIT_FOR_GENERATE_AUTH_TOKEN;
auth_scheme_ = HttpAuth::AUTH_SCHEME_MOCK;
@@ -161,6 +163,7 @@ int HttpAuthHandlerMock::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int nonce_count,
@@ -174,9 +177,10 @@ int HttpAuthHandlerMock::Factory::CreateAuthHandler(
std::vector<std::unique_ptr<HttpAuthHandler>>& handlers = handlers_[target];
handlers.erase(handlers.begin());
if (do_init_from_challenge_ &&
- !tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ !tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log)) {
return ERR_INVALID_RESPONSE;
+ }
handler->swap(tmp_handler);
return OK;
}
diff --git a/chromium/net/http/http_auth_handler_mock.h b/chromium/net/http/http_auth_handler_mock.h
index 5e7e32c82f1..e44388bcf83 100644
--- a/chromium/net/http/http_auth_handler_mock.h
+++ b/chromium/net/http/http_auth_handler_mock.h
@@ -46,6 +46,7 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int nonce_count,
@@ -90,7 +91,8 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
bool AllowsDefaultCredentials() override;
bool AllowsExplicitCredentials() override;
bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) override;
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
diff --git a/chromium/net/http/http_auth_handler_negotiate.cc b/chromium/net/http/http_auth_handler_negotiate.cc
index e6efffe07e7..281e62f6185 100644
--- a/chromium/net/http/http_auth_handler_negotiate.cc
+++ b/chromium/net/http/http_auth_handler_negotiate.cc
@@ -86,6 +86,7 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -131,9 +132,10 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
negotiate_auth_system_factory_),
http_auth_preferences(), host_resolver));
#endif
- if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log)) {
return ERR_INVALID_RESPONSE;
+ }
handler->swap(tmp_handler);
return OK;
}
@@ -171,8 +173,11 @@ bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() {
// The Negotiate challenge header looks like:
// WWW-Authenticate: NEGOTIATE auth-data
-bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) {
+bool HttpAuthHandlerNegotiate::Init(
+ HttpAuthChallengeTokenizer* challenge,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
+ network_isolation_key_ = network_isolation_key;
#if defined(OS_POSIX)
if (!auth_system_->Init(net_log())) {
VLOG(1) << "can't initialize GSSAPI library";
@@ -341,8 +346,9 @@ int HttpAuthHandlerNegotiate::DoResolveCanonicalName() {
// TODO(cbentzel): Add reverse DNS lookup for numeric addresses.
HostResolver::ResolveHostParameters parameters;
parameters.include_canonical_name = true;
- resolve_host_request_ = resolver_->CreateRequest(
- HostPortPair(origin_.host(), 0), net_log(), parameters);
+ resolve_host_request_ =
+ resolver_->CreateRequest(HostPortPair(origin_.host(), 0),
+ network_isolation_key_, net_log(), parameters);
return resolve_host_request_->Start(base::BindOnce(
&HttpAuthHandlerNegotiate::OnIOComplete, base::Unretained(this)));
}
diff --git a/chromium/net/http/http_auth_handler_negotiate.h b/chromium/net/http/http_auth_handler_negotiate.h
index e9c98d1c1ff..651e4a61522 100644
--- a/chromium/net/http/http_auth_handler_negotiate.h
+++ b/chromium/net/http/http_auth_handler_negotiate.h
@@ -12,6 +12,7 @@
#include "build/build_config.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
+#include "net/base/network_isolation_key.h"
#include "net/dns/host_resolver.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
@@ -63,6 +64,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -94,7 +96,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
protected:
// HttpAuthHandler
bool Init(HttpAuthChallengeTokenizer* challenge,
- const SSLInfo& ssl_info) override;
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
@@ -126,6 +129,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
std::unique_ptr<HttpAuthMechanism> auth_system_;
HostResolver* const resolver_;
+ NetworkIsolationKey network_isolation_key_;
+
// Members which are needed for DNS lookup + SPN.
std::unique_ptr<HostResolver::ResolveHostRequest> resolve_host_request_;
diff --git a/chromium/net/http/http_auth_handler_negotiate_unittest.cc b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
index a94c5e40dd5..40f80012da0 100644
--- a/chromium/net/http/http_auth_handler_negotiate_unittest.cc
+++ b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
@@ -12,7 +12,9 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
+#include "net/base/features.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
@@ -53,12 +55,15 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest,
public WithTaskEnvironment {
public:
void SetUp() override {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kSplitHostCacheByNetworkIsolationKey);
+ network_isolation_key_ = NetworkIsolationKey::CreateTransient();
#if defined(OS_WIN)
auth_library_ = new MockAuthLibrary(const_cast<wchar_t*>(NEGOSSP_NAME));
#else
auth_library_ = new MockAuthLibrary();
#endif
- resolver_.reset(new MockHostResolver());
+ resolver_ = std::make_unique<MockCachingHostResolver>();
resolver_->rules_map()[HostResolverSource::ANY]->AddIPLiteralRule(
"alias", "10.0.0.2", "canonical.example.com");
@@ -227,8 +232,9 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest,
std::unique_ptr<HttpAuthHandler> generic_handler;
SSLInfo null_ssl_info;
int rv = factory_->CreateAuthHandlerFromString(
- "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), resolver_.get(), &generic_handler);
+ "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info,
+ network_isolation_key(), gurl, NetLogWithSource(), resolver_.get(),
+ &generic_handler);
if (rv != OK)
return rv;
HttpAuthHandlerNegotiate* negotiate_handler =
@@ -238,12 +244,20 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest,
}
MockAuthLibrary* AuthLibrary() { return auth_library_; }
- MockHostResolver* resolver() { return resolver_.get(); }
+ MockCachingHostResolver* resolver() { return resolver_.get(); }
MockAllowHttpAuthPreferences* http_auth_preferences() {
return http_auth_preferences_.get();
}
+ const NetworkIsolationKey& network_isolation_key() const {
+ return network_isolation_key_;
+ }
+
private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ NetworkIsolationKey network_isolation_key_;
+
#if defined(OS_WIN)
std::unique_ptr<SecPkgInfoW> security_package_;
#endif
@@ -251,7 +265,7 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest,
// can't be a scoped pointer to it since the tests need access when they set
// up the mocks after passing ownership.
MockAuthLibrary* auth_library_;
- std::unique_ptr<MockHostResolver> resolver_;
+ std::unique_ptr<MockCachingHostResolver> resolver_;
std::unique_ptr<MockAllowHttpAuthPreferences> http_auth_preferences_;
std::unique_ptr<HttpAuthHandlerNegotiate::Factory> factory_;
};
@@ -314,8 +328,8 @@ TEST_F(HttpAuthHandlerNegotiateTest, DisableCnameNonstandardPort) {
TEST_F(HttpAuthHandlerNegotiateTest, CnameSync) {
SetupMocks(AuthLibrary());
std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
- EXPECT_EQ(OK, CreateHandler(
- false, false, true, "http://alias:500", &auth_handler));
+ const std::string url_string = "http://alias:500";
+ EXPECT_EQ(OK, CreateHandler(false, false, true, url_string, &auth_handler));
ASSERT_TRUE(auth_handler.get() != nullptr);
TestCompletionCallback callback;
HttpRequestInfo request_info;
@@ -327,13 +341,35 @@ TEST_F(HttpAuthHandlerNegotiateTest, CnameSync) {
#else
EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn_for_testing());
#endif
+
+ // Make sure a cache-only lookup with the wrong NetworkIsolationKey (an empty
+ // one) fails, to make sure the right NetworkIsolationKey was used.
+ HostPortPair host_port_pair = HostPortPair::FromURL(GURL(url_string));
+ HostResolver::ResolveHostParameters resolve_params;
+ resolve_params.include_canonical_name = true;
+ resolve_params.source = HostResolverSource::LOCAL_ONLY;
+ std::unique_ptr<HostResolver::ResolveHostRequest> host_request1 =
+ resolver()->CreateRequest(host_port_pair, NetworkIsolationKey(),
+ NetLogWithSource(), resolve_params);
+ TestCompletionCallback callback2;
+ int result = host_request1->Start(callback2.callback());
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback2.GetResult(result));
+
+ // Make sure a cache-only lookup with the same NetworkIsolationKey succeeds,
+ // to make sure the right NetworkIsolationKey was used.
+ std::unique_ptr<HostResolver::ResolveHostRequest> host_request2 =
+ resolver()->CreateRequest(host_port_pair, network_isolation_key(),
+ NetLogWithSource(), resolve_params);
+ TestCompletionCallback callback3;
+ result = host_request2->Start(callback3.callback());
+ EXPECT_EQ(OK, callback3.GetResult(result));
}
TEST_F(HttpAuthHandlerNegotiateTest, CnameAsync) {
SetupMocks(AuthLibrary());
std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
- EXPECT_EQ(OK, CreateHandler(
- false, false, false, "http://alias:500", &auth_handler));
+ const std::string url_string = "http://alias:500";
+ EXPECT_EQ(OK, CreateHandler(false, false, false, url_string, &auth_handler));
ASSERT_TRUE(auth_handler.get() != nullptr);
TestCompletionCallback callback;
HttpRequestInfo request_info;
@@ -347,6 +383,28 @@ TEST_F(HttpAuthHandlerNegotiateTest, CnameAsync) {
#else
EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn_for_testing());
#endif
+
+ // Make sure a cache-only lookup with the wrong NetworkIsolationKey (an empty
+ // one) fails, to make sure the right NetworkIsolationKey was used.
+ HostPortPair host_port_pair = HostPortPair::FromURL(GURL(url_string));
+ HostResolver::ResolveHostParameters resolve_params;
+ resolve_params.include_canonical_name = true;
+ resolve_params.source = HostResolverSource::LOCAL_ONLY;
+ std::unique_ptr<HostResolver::ResolveHostRequest> host_request1 =
+ resolver()->CreateRequest(host_port_pair, NetworkIsolationKey(),
+ NetLogWithSource(), resolve_params);
+ TestCompletionCallback callback2;
+ int result = host_request1->Start(callback2.callback());
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback2.GetResult(result));
+
+ // Make sure a cache-only lookup with the same NetworkIsolationKey succeeds,
+ // to make sure the right NetworkIsolationKey was used.
+ std::unique_ptr<HostResolver::ResolveHostRequest> host_request2 =
+ resolver()->CreateRequest(host_port_pair, network_isolation_key(),
+ NetLogWithSource(), resolve_params);
+ TestCompletionCallback callback3;
+ result = host_request2->Start(callback3.callback());
+ EXPECT_EQ(OK, callback3.GetResult(result));
}
#if defined(OS_POSIX)
@@ -397,8 +455,8 @@ TEST_F(HttpAuthHandlerNegotiateTest, MissingGSSAPI) {
GURL gurl("http://www.example.com");
std::unique_ptr<HttpAuthHandler> generic_handler;
int rv = negotiate_factory->CreateAuthHandlerFromString(
- "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(), gurl, NetLogWithSource(),
- resolver(), &generic_handler);
+ "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(), NetworkIsolationKey(),
+ gurl, NetLogWithSource(), resolver(), &generic_handler);
EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME));
EXPECT_TRUE(generic_handler.get() == nullptr);
}
@@ -470,8 +528,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, OverrideAuthSystem) {
GURL gurl("http://www.example.com");
std::unique_ptr<HttpAuthHandler> handler;
EXPECT_EQ(OK, negotiate_factory->CreateAuthHandlerFromString(
- "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(), gurl,
- NetLogWithSource(), resolver(), &handler));
+ "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(),
+ NetworkIsolationKey(), gurl, NetLogWithSource(), resolver(),
+ &handler));
EXPECT_TRUE(handler);
TestCompletionCallback callback;
diff --git a/chromium/net/http/http_auth_handler_ntlm.cc b/chromium/net/http/http_auth_handler_ntlm.cc
index 1433411a8dd..5ea166db493 100644
--- a/chromium/net/http/http_auth_handler_ntlm.cc
+++ b/chromium/net/http/http_auth_handler_ntlm.cc
@@ -15,8 +15,10 @@ HttpAuthHandlerNTLM::Factory::Factory() = default;
HttpAuthHandlerNTLM::Factory::~Factory() = default;
-bool HttpAuthHandlerNTLM::Init(HttpAuthChallengeTokenizer* tok,
- const SSLInfo& ssl_info) {
+bool HttpAuthHandlerNTLM::Init(
+ HttpAuthChallengeTokenizer* tok,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
auth_scheme_ = HttpAuth::AUTH_SCHEME_NTLM;
score_ = 3;
properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
diff --git a/chromium/net/http/http_auth_handler_ntlm.h b/chromium/net/http/http_auth_handler_ntlm.h
index 34ce35e1290..ce7ed585507 100644
--- a/chromium/net/http/http_auth_handler_ntlm.h
+++ b/chromium/net/http/http_auth_handler_ntlm.h
@@ -51,6 +51,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -90,7 +91,9 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
protected:
// HttpAuthHandler
- bool Init(HttpAuthChallengeTokenizer* tok, const SSLInfo& ssl_info) override;
+ bool Init(HttpAuthChallengeTokenizer* tok,
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) override;
int GenerateAuthTokenImpl(const AuthCredentials* credentials,
const HttpRequestInfo* request,
CompletionOnceCallback callback,
diff --git a/chromium/net/http/http_auth_handler_ntlm_portable.cc b/chromium/net/http/http_auth_handler_ntlm_portable.cc
index 484565d97c8..5f932f99826 100644
--- a/chromium/net/http/http_auth_handler_ntlm_portable.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_portable.cc
@@ -15,6 +15,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -29,8 +30,8 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
// of NTLM.
std::unique_ptr<HttpAuthHandler> tmp_handler(
new HttpAuthHandlerNTLM(http_auth_preferences()));
- if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log))
return ERR_INVALID_RESPONSE;
handler->swap(tmp_handler);
return OK;
diff --git a/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc b/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc
index 009e0fd7e03..473134ec2eb 100644
--- a/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_portable_unittest.cc
@@ -10,6 +10,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_challenge_tokenizer.h"
@@ -52,8 +53,8 @@ class HttpAuthHandlerNtlmPortableTest : public PlatformTest {
SSLInfo null_ssl_info;
return factory_->CreateAuthHandlerFromString(
- "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, gurl, NetLogWithSource(),
- nullptr, &auth_handler_);
+ "NTLM", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), nullptr, &auth_handler_);
}
std::string CreateNtlmAuthHeader(base::span<const uint8_t> buffer) {
diff --git a/chromium/net/http/http_auth_handler_ntlm_win.cc b/chromium/net/http/http_auth_handler_ntlm_win.cc
index 26b48a7a10c..0fdae59ace3 100644
--- a/chromium/net/http/http_auth_handler_ntlm_win.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_win.cc
@@ -22,6 +22,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int digest_nonce_count,
@@ -34,8 +35,8 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
// method and only constructing when valid.
std::unique_ptr<HttpAuthHandler> tmp_handler(
new HttpAuthHandlerNTLM(sspi_library_.get(), http_auth_preferences()));
- if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, origin,
- net_log))
+ if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info,
+ network_isolation_key, origin, net_log))
return ERR_INVALID_RESPONSE;
handler->swap(tmp_handler);
return OK;
diff --git a/chromium/net/http/http_auth_handler_unittest.cc b/chromium/net/http/http_auth_handler_unittest.cc
index fed58146ca8..da80db140f0 100644
--- a/chromium/net/http/http_auth_handler_unittest.cc
+++ b/chromium/net/http/http_auth_handler_unittest.cc
@@ -8,6 +8,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/test/task_environment.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_handler_mock.h"
@@ -42,7 +43,8 @@ TEST(HttpAuthHandlerTest, NetLog) {
// call after GenerateAuthToken() is expected and does not result in
// AUTHORIZATION_RESULT_REJECT.
mock_handler.set_connection_based(true);
- mock_handler.InitFromChallenge(&tokenizer, target, SSLInfo(), origin,
+ mock_handler.InitFromChallenge(&tokenizer, target, SSLInfo(),
+ NetworkIsolationKey(), origin,
test_net_log.bound());
mock_handler.SetGenerateExpectation(async, OK);
mock_handler.GenerateAuthToken(&credentials, &request,
diff --git a/chromium/net/http/http_auth_sspi_win.cc b/chromium/net/http/http_auth_sspi_win.cc
index 5e11b9ff147..0716b6e99e9 100644
--- a/chromium/net/http/http_auth_sspi_win.cc
+++ b/chromium/net/http/http_auth_sspi_win.cc
@@ -547,7 +547,12 @@ int HttpAuthSSPI::GetNextSecurityToken(const std::string& spn,
if (delegation_type_ != DelegationType::kNone)
context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH);
- net_log.BeginEvent(NetLogEventType::AUTH_LIBRARY_INIT_SEC_CTX);
+ net_log.BeginEvent(NetLogEventType::AUTH_LIBRARY_INIT_SEC_CTX, [&] {
+ base::Value params{base::Value::Type::DICTIONARY};
+ params.SetStringKey("spn", spn);
+ params.SetKey("flags", ContextFlagsToValue(context_flags));
+ return params;
+ });
// This returns a token that is passed to the remote server.
DWORD context_attributes = 0;
diff --git a/chromium/net/http/http_auth_sspi_win_unittest.cc b/chromium/net/http/http_auth_sspi_win_unittest.cc
index 09ddf1d6593..bad9b9ba25c 100644
--- a/chromium/net/http/http_auth_sspi_win_unittest.cc
+++ b/chromium/net/http/http_auth_sspi_win_unittest.cc
@@ -260,6 +260,18 @@ TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds_Logging) {
expected = base::JSONReader::Read(R"(
{
+ "flags": {
+ "delegated": false,
+ "mutual": false,
+ "value": "0x00000000"
+ },
+ "spn": "HTTP/intranet.google.com"
+ }
+ )");
+ EXPECT_EQ(expected, entries[0].params);
+
+ expected = base::JSONReader::Read(R"(
+ {
"context": {
"authority": "Dodgy Server",
"flags": {
diff --git a/chromium/net/http/http_auth_unittest.cc b/chromium/net/http/http_auth_unittest.cc
index 39e32e5dbf2..059385e9a6a 100644
--- a/chromium/net/http/http_auth_unittest.cc
+++ b/chromium/net/http/http_auth_unittest.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_filter.h"
@@ -41,9 +42,9 @@ std::unique_ptr<HttpAuthHandlerMock> CreateMockHandler(bool connection_based) {
challenge_text.end());
GURL origin("www.example.com");
SSLInfo null_ssl_info;
- EXPECT_TRUE(auth_handler->InitFromChallenge(&challenge, HttpAuth::AUTH_SERVER,
- null_ssl_info, origin,
- NetLogWithSource()));
+ EXPECT_TRUE(auth_handler->InitFromChallenge(
+ &challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ origin, NetLogWithSource()));
return auth_handler;
}
@@ -140,10 +141,10 @@ TEST(HttpAuthTest, ChooseBestChallenge) {
SSLInfo null_ssl_info;
std::unique_ptr<HttpAuthHandler> handler;
- HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(), *headers,
- null_ssl_info, HttpAuth::AUTH_SERVER, origin,
- disabled_schemes, NetLogWithSource(),
- host_resolver.get(), &handler);
+ HttpAuth::ChooseBestChallenge(
+ http_auth_handler_factory.get(), *headers, null_ssl_info,
+ NetworkIsolationKey(), HttpAuth::AUTH_SERVER, origin, disabled_schemes,
+ NetLogWithSource(), host_resolver.get(), &handler);
if (handler.get()) {
EXPECT_EQ(tests[i].challenge_scheme, handler->auth_scheme());
diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc
index b2bb7fd1958..085b1fe7fbf 100644
--- a/chromium/net/http/http_basic_stream.cc
+++ b/chromium/net/http/http_basic_stream.cc
@@ -138,6 +138,7 @@ bool HttpBasicStream::GetLoadTimingInfo(
}
load_timing_info->receive_headers_start = parser()->response_start_time();
+ load_timing_info->first_early_hints_time = parser()->first_early_hints_time();
return true;
}
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index ad6e626898d..a4afd4bc42a 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -2709,11 +2709,12 @@ ValidationType HttpCache::Transaction::RequiresValidation() {
if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION)
return VALIDATION_NONE;
+ TimeDelta response_time_in_cache =
+ cache_->clock_->Now() - response_.response_time;
if (response_.unused_since_prefetch &&
!(effective_load_flags_ & LOAD_PREFETCH) &&
- response_.headers->GetCurrentAge(
- response_.request_time, response_.response_time,
- cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) {
+ (response_time_in_cache < TimeDelta::FromMinutes(kPrefetchReuseMins)) &&
+ (response_time_in_cache >= TimeDelta())) {
// The first use of a resource after prefetch within a short window skips
// validation.
return VALIDATION_NONE;
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index d5283730314..bce0e10597c 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -209,9 +209,9 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
context.quic_context->params()->max_server_configs_stored_in_properties);
if (!params_.disable_idle_sockets_close_on_memory_pressure) {
- memory_pressure_listener_.reset(
- new base::MemoryPressureListener(base::BindRepeating(
- &HttpNetworkSession::OnMemoryPressure, base::Unretained(this))));
+ memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
+ FROM_HERE, base::BindRepeating(&HttpNetworkSession::OnMemoryPressure,
+ base::Unretained(this)));
}
}
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index 92530037564..c39cfddec9a 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -115,7 +115,7 @@ class NET_EXPORT HttpNetworkSession {
// logic from hiding broken servers.
spdy::SettingsMap http2_settings;
// If set, an HTTP/2 frame with a reserved frame type will be sent after
- // every HEADERS and SETTINGS frame. See
+ // every HTTP/2 SETTINGS frame and before every HTTP/2 DATA frame.
// https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
// The same frame will be sent out on all connections to prevent the retry
// logic from hiding broken servers.
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index 22a18a35871..64b249b6b72 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -1312,21 +1312,15 @@ void HttpNetworkTransaction::ProcessReportToHeader() {
return;
ReportingService* service = session_->reporting_service();
- if (!service) {
- ReportingHeaderParser::RecordHeaderDiscardedForNoReportingService();
+ if (!service)
return;
- }
// Only accept Report-To headers on HTTPS connections that have no
// certificate errors.
- if (!response_.ssl_info.is_valid()) {
- ReportingHeaderParser::RecordHeaderDiscardedForInvalidSSLInfo();
+ if (!response_.ssl_info.is_valid())
return;
- }
- if (IsCertStatusError(response_.ssl_info.cert_status)) {
- ReportingHeaderParser::RecordHeaderDiscardedForCertStatusError();
+ if (IsCertStatusError(response_.ssl_info.cert_status))
return;
- }
service->ProcessHeader(url_.GetOrigin(), value);
}
@@ -1340,11 +1334,8 @@ void HttpNetworkTransaction::ProcessNetworkErrorLoggingHeader() {
NetworkErrorLoggingService* service =
session_->network_error_logging_service();
- if (!service) {
- NetworkErrorLoggingService::
- RecordHeaderDiscardedForNoNetworkErrorLoggingService();
+ if (!service)
return;
- }
// Don't accept NEL headers received via a proxy, because the IP address of
// the destination server is not known.
@@ -1353,19 +1344,13 @@ void HttpNetworkTransaction::ProcessNetworkErrorLoggingHeader() {
// Only accept NEL headers on HTTPS connections that have no certificate
// errors.
- if (!response_.ssl_info.is_valid()) {
- NetworkErrorLoggingService::RecordHeaderDiscardedForInvalidSSLInfo();
- return;
- }
- if (IsCertStatusError(response_.ssl_info.cert_status)) {
- NetworkErrorLoggingService::RecordHeaderDiscardedForCertStatusError();
+ if (!response_.ssl_info.is_valid() ||
+ IsCertStatusError(response_.ssl_info.cert_status)) {
return;
}
- if (remote_endpoint_.address().empty()) {
- NetworkErrorLoggingService::RecordHeaderDiscardedForMissingRemoteEndpoint();
+ if (remote_endpoint_.address().empty())
return;
- }
service->OnHeader(url::Origin::Create(url_), remote_endpoint_.address(),
value);
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 86d5348164e..b01179e007e 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -15269,8 +15269,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
auth_challenge.end());
auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
- empty_ssl_info, origin,
- NetLogWithSource());
+ empty_ssl_info, NetworkIsolationKey(),
+ origin, NetLogWithSource());
auth_handler->SetGenerateExpectation(
test_config.proxy_auth_timing == AUTH_ASYNC,
n == 0 ? test_config.first_generate_proxy_token_rv : OK);
@@ -15284,8 +15284,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
auth_challenge.end());
auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
- empty_ssl_info, origin,
- NetLogWithSource());
+ empty_ssl_info, NetworkIsolationKey(),
+ origin, NetLogWithSource());
auth_handler->SetGenerateExpectation(
test_config.server_auth_timing == AUTH_ASYNC,
test_config.first_generate_server_token_rv);
@@ -15297,8 +15297,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
std::unique_ptr<HttpAuthHandlerMock> second_handler =
std::make_unique<HttpAuthHandlerMock>();
second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
- empty_ssl_info, origin,
- NetLogWithSource());
+ empty_ssl_info, NetworkIsolationKey(),
+ origin, NetLogWithSource());
second_handler->SetGenerateExpectation(true, OK);
auth_factory->AddMockHandler(second_handler.release(),
HttpAuth::AUTH_SERVER);
@@ -15413,7 +15413,8 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
auth_challenge.end());
SSLInfo empty_ssl_info;
auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
- empty_ssl_info, origin, NetLogWithSource());
+ empty_ssl_info, NetworkIsolationKey(), origin,
+ NetLogWithSource());
auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
int rv = OK;
@@ -19438,21 +19439,15 @@ class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
TEST_F(HttpNetworkTransactionReportingTest,
DontProcessReportToHeaderNoService) {
- base::HistogramTester histograms;
clear_reporting_service();
RequestPolicy();
- histograms.ExpectBucketCount(
- ReportingHeaderParser::kHeaderOutcomeHistogram,
- ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
+ // No crash.
}
TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
- base::HistogramTester histograms;
url_ = "http://www.example.org/";
RequestPolicy();
- histograms.ExpectBucketCount(
- ReportingHeaderParser::kHeaderOutcomeHistogram,
- ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
+ EXPECT_EQ(0u, reporting_context()->cache()->GetEndpointCount());
}
TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
@@ -19469,12 +19464,9 @@ TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
TEST_F(HttpNetworkTransactionReportingTest,
DontProcessReportToHeaderInvalidHttps) {
- base::HistogramTester histograms;
CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
RequestPolicy(cert_status);
- histograms.ExpectBucketCount(
- ReportingHeaderParser::kHeaderOutcomeHistogram,
- ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
+ EXPECT_EQ(0u, reporting_context()->cache()->GetEndpointCount());
}
#endif // BUILDFLAG(ENABLE_REPORTING)
@@ -19593,25 +19585,17 @@ class HttpNetworkTransactionNetworkErrorLoggingTest
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
DontProcessNelHeaderNoService) {
- base::HistogramTester histograms;
clear_network_error_logging_service();
RequestPolicy();
- histograms.ExpectBucketCount(
- NetworkErrorLoggingService::kHeaderOutcomeHistogram,
- NetworkErrorLoggingService::HeaderOutcome::
- DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
- 1);
+ // No crash.
}
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
DontProcessNelHeaderHttp) {
- base::HistogramTester histograms;
url_ = "http://www.example.org/";
request_.url = GURL(url_);
RequestPolicy();
- histograms.ExpectBucketCount(
- NetworkErrorLoggingService::kHeaderOutcomeHistogram,
- NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
+ EXPECT_EQ(0u, network_error_logging_service()->headers().size());
}
// Don't set NEL policies received on a proxied connection.
@@ -19690,13 +19674,9 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
DontProcessNelHeaderInvalidHttps) {
- base::HistogramTester histograms;
CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
RequestPolicy(cert_status);
- histograms.ExpectBucketCount(
- NetworkErrorLoggingService::kHeaderOutcomeHistogram,
- NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
- 1);
+ EXPECT_EQ(0u, network_error_logging_service()->headers().size());
}
TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
diff --git a/chromium/net/http/http_proxy_connect_job.h b/chromium/net/http/http_proxy_connect_job.h
index dac631fbe46..07b2627327a 100644
--- a/chromium/net/http/http_proxy_connect_job.h
+++ b/chromium/net/http/http_proxy_connect_job.h
@@ -40,8 +40,7 @@ class QuicStreamRequest;
// HttpProxySocketParams only needs the socket params for one of the proxy
// types. The other param must be NULL. When using an HTTP proxy,
// |transport_params| must be set. When using an HTTPS proxy or QUIC proxy,
-// |ssl_params| must be set. Also, if using a QUIC proxy, |quic_version| must
-// not be quic::QUIC_VERSION_UNSUPPORTED.
+// |ssl_params| must be set.
class NET_EXPORT_PRIVATE HttpProxySocketParams
: public base::RefCounted<HttpProxySocketParams> {
public:
diff --git a/chromium/net/http/http_request_headers.cc b/chromium/net/http/http_request_headers.cc
index d0aa57c2ba7..35ede841aa9 100644
--- a/chromium/net/http/http_request_headers.cc
+++ b/chromium/net/http/http_request_headers.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc
index 0c31a131cdf..f1adaf13ecd 100644
--- a/chromium/net/http/http_response_info.cc
+++ b/chromium/net/http/http_response_info.cc
@@ -162,6 +162,8 @@ HttpResponseInfo::ConnectionInfoCoarse HttpResponseInfo::ConnectionInfoToCoarse(
case CONNECTION_INFO_QUIC_999:
case CONNECTION_INFO_QUIC_DRAFT_25:
case CONNECTION_INFO_QUIC_DRAFT_27:
+ case CONNECTION_INFO_QUIC_DRAFT_28:
+ case CONNECTION_INFO_QUIC_DRAFT_29:
return CONNECTION_INFO_COARSE_QUIC;
case CONNECTION_INFO_UNKNOWN:
@@ -497,6 +499,8 @@ bool HttpResponseInfo::DidUseQuic() const {
case CONNECTION_INFO_QUIC_999:
case CONNECTION_INFO_QUIC_DRAFT_25:
case CONNECTION_INFO_QUIC_DRAFT_27:
+ case CONNECTION_INFO_QUIC_DRAFT_28:
+ case CONNECTION_INFO_QUIC_DRAFT_29:
return true;
case NUM_OF_CONNECTION_INFOS:
NOTREACHED();
@@ -579,6 +583,10 @@ std::string HttpResponseInfo::ConnectionInfoToString(
return "h3-25";
case CONNECTION_INFO_QUIC_DRAFT_27:
return "h3-27";
+ case CONNECTION_INFO_QUIC_DRAFT_28:
+ return "h3-28";
+ case CONNECTION_INFO_QUIC_DRAFT_29:
+ return "h3-29";
case CONNECTION_INFO_QUIC_T099:
return "h3-T099";
case CONNECTION_INFO_HTTP0_9:
diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h
index 445dd63b696..f878369a720 100644
--- a/chromium/net/http/http_response_info.h
+++ b/chromium/net/http/http_response_info.h
@@ -73,6 +73,8 @@ class NET_EXPORT HttpResponseInfo {
CONNECTION_INFO_QUIC_T099 = 34,
CONNECTION_INFO_QUIC_DRAFT_25 = 35,
CONNECTION_INFO_QUIC_DRAFT_27 = 36,
+ CONNECTION_INFO_QUIC_DRAFT_28 = 37,
+ CONNECTION_INFO_QUIC_DRAFT_29 = 38,
NUM_OF_CONNECTION_INFOS,
};
diff --git a/chromium/net/http/http_server_properties.cc b/chromium/net/http/http_server_properties.cc
index da1bf8335e9..cce79cafb0c 100644
--- a/chromium/net/http/http_server_properties.cc
+++ b/chromium/net/http/http_server_properties.cc
@@ -18,6 +18,7 @@
#include "base/time/default_tick_clock.h"
#include "base/values.h"
#include "net/base/features.h"
+#include "net/base/url_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties_manager.h"
#include "net/socket/ssl_client_socket.h"
@@ -871,7 +872,7 @@ void HttpServerProperties::SetAlternativeServicesInternal(
// before the first completes. In this case, only one of the jobs
// would reach this code, whereas all of them should should have.
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING,
- false);
+ false, IsGoogleHost(origin.host()));
}
// If this host ends with a canonical suffix, then set it as the
diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc
index fd30463050d..00fb6ee099b 100644
--- a/chromium/net/http/http_server_properties_manager.cc
+++ b/chromium/net/http/http_server_properties_manager.cc
@@ -529,7 +529,7 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceInfoDictOfServer(
}
// Advertised versions list is optional.
- // It is only used for PROTOCOL_QUIC_CRYPTO versions.
+ // It is only used for versions that use the legacy Google AltSvc format.
if (dict.HasKey(kAdvertisedVersionsKey)) {
const base::ListValue* versions_list = nullptr;
if (!dict.GetListWithoutPathExpansion(kAdvertisedVersionsKey,
@@ -546,15 +546,15 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceInfoDictOfServer(
<< server_str;
return false;
}
- if (!quic::ParsedQuicVersionIsValid(
- quic::PROTOCOL_QUIC_CRYPTO,
- quic::QuicTransportVersion(version))) {
- // This version is not valid, this can happen if we've deprecated
- // a version that used to be valid.
- continue;
+ for (const quic::ParsedQuicVersion& supported :
+ quic::AllSupportedVersions()) {
+ if (supported.UsesQuicCrypto() &&
+ supported.SupportsGoogleAltSvcFormat() &&
+ static_cast<int>(supported.transport_version) == version) {
+ advertised_versions.push_back(supported);
+ break;
+ }
}
- advertised_versions.push_back(quic::ParsedQuicVersion(
- quic::PROTOCOL_QUIC_CRYPTO, quic::QuicTransportVersion(version)));
}
alternative_service_info->set_advertised_versions(advertised_versions);
}
diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc
index ab1cd3a3c49..792231248ab 100644
--- a/chromium/net/http/http_server_properties_manager_unittest.cc
+++ b/chromium/net/http/http_server_properties_manager_unittest.cc
@@ -1481,10 +1481,7 @@ TEST_F(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) {
base::Time expiration1;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
quic::ParsedQuicVersionVector advertised_versions = {
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43)};
+ quic::ParsedQuicVersion::Q046(), quic::ParsedQuicVersion::Q043()};
alternative_service_info_vector.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions));
@@ -1543,7 +1540,7 @@ TEST_F(HttpServerPropertiesManagerTest, PersistAdvertisedVersionsToPref) {
"\"isolation\":[],"
"\"server\":\"https://www.google.com:80\"},"
"{\"alternative_service\":[{"
- "\"advertised_versions\":[46],\"expiration\":\"9223372036854775807\","
+ "\"advertised_versions\":[50],\"expiration\":\"9223372036854775807\","
"\"host\":\"foo.google.com\",\"port\":444,\"protocol_str\":\"quic\"}],"
"\"isolation\":[],"
"\"network_stats\":{\"srtt\":42},"
@@ -1606,12 +1603,8 @@ TEST_F(HttpServerPropertiesManagerTest, ReadAdvertisedVersionsFromPref) {
const quic::ParsedQuicVersionVector loaded_advertised_versions =
alternative_service_info_vector[1].advertised_versions();
EXPECT_EQ(2u, loaded_advertised_versions.size());
- EXPECT_EQ(quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43),
- loaded_advertised_versions[0]);
- EXPECT_EQ(quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- loaded_advertised_versions[1]);
+ EXPECT_EQ(quic::ParsedQuicVersion::Q043(), loaded_advertised_versions[0]);
+ EXPECT_EQ(quic::ParsedQuicVersion::Q046(), loaded_advertised_versions[1]);
// No other fields should have been populated.
server_info.alternative_services.reset();
@@ -1626,8 +1619,7 @@ TEST_F(HttpServerPropertiesManagerTest,
// #1: Set alternate protocol.
AlternativeServiceInfoVector alternative_service_info_vector;
- // Quic alternative service set with a single QUIC version:
- // quic::QUIC_VERSION_46.
+ // Quic alternative service set with a single QUIC version: Q046.
AlternativeService quic_alternative_service1(kProtoQUIC, "", 443);
base::Time expiration1;
ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
@@ -1660,7 +1652,7 @@ TEST_F(HttpServerPropertiesManagerTest,
"\"server_id\":\"https://mail.google.com:80\","
"\"server_info\":\"quic_server_info1\"}],"
"\"servers\":["
- "{\"alternative_service\":[{\"advertised_versions\":[46],"
+ "{\"alternative_service\":[{\"advertised_versions\":[50],"
"\"expiration\":\"13756212000000000\",\"port\":443,"
"\"protocol_str\":\"quic\"}],"
"\"isolation\":[],"
@@ -1680,10 +1672,7 @@ TEST_F(HttpServerPropertiesManagerTest,
AlternativeServiceInfoVector alternative_service_info_vector_2;
// Quic alternative service set with two advertised QUIC versions.
quic::ParsedQuicVersionVector advertised_versions = {
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43)};
+ quic::ParsedQuicVersion::Q046(), quic::ParsedQuicVersion::Q043()};
alternative_service_info_vector_2.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions));
@@ -1718,10 +1707,7 @@ TEST_F(HttpServerPropertiesManagerTest,
AlternativeServiceInfoVector alternative_service_info_vector_3;
// A same set of QUIC versions but listed in a different order.
quic::ParsedQuicVersionVector advertised_versions_2 = {
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43),
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46)};
+ quic::ParsedQuicVersion::Q043(), quic::ParsedQuicVersion::Q046()};
alternative_service_info_vector_3.push_back(
AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
quic_alternative_service1, expiration1, advertised_versions_2));
diff --git a/chromium/net/http/http_stream_factory_job.cc b/chromium/net/http/http_stream_factory_job.cc
index b2a42a4bdfa..10b862d5d47 100644
--- a/chromium/net/http/http_stream_factory_job.cc
+++ b/chromium/net/http/http_stream_factory_job.cc
@@ -175,7 +175,7 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
// The Job is forced to use QUIC without a designated version, try the
// preferred QUIC version that is supported by default.
- if (quic_version_ == quic::UnsupportedQuicVersion() &&
+ if (quic_version_ == quic::ParsedQuicVersion::Unsupported() &&
ShouldForceQuic(session, destination, origin_url, proxy_info,
using_ssl_)) {
quic_version_ =
@@ -183,7 +183,7 @@ HttpStreamFactory::Job::Job(Delegate* delegate,
}
if (using_quic_)
- DCHECK_NE(quic_version_, quic::UnsupportedQuicVersion());
+ DCHECK_NE(quic_version_, quic::ParsedQuicVersion::Unsupported());
DCHECK(session);
if (alternative_protocol != kProtoUnknown) {
@@ -1103,6 +1103,10 @@ int HttpStreamFactory::Job::DoCreateStream() {
->CreateBasicStream(std::move(connection_), using_proxy,
session_->websocket_endpoint_lock_manager());
} else {
+ if (request_info_.upload_data_stream &&
+ !request_info_.upload_data_stream->AllowHTTP1()) {
+ return ERR_H2_OR_QUIC_REQUIRED;
+ }
stream_ = std::make_unique<HttpBasicStream>(std::move(connection_),
using_proxy);
}
@@ -1292,7 +1296,7 @@ HttpStreamFactory::JobFactory::CreateMainJob(
return std::make_unique<HttpStreamFactory::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, destination, origin_url,
- kProtoUnknown, quic::UnsupportedQuicVersion(), ProxyServer(),
+ kProtoUnknown, quic::ParsedQuicVersion::Unsupported(), ProxyServer(),
is_websocket, enable_ip_based_pooling, net_log);
}
@@ -1339,8 +1343,8 @@ HttpStreamFactory::JobFactory::CreateAltProxyJob(
return std::make_unique<HttpStreamFactory::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, destination, origin_url,
- kProtoUnknown, quic::UnsupportedQuicVersion(), alternative_proxy_server,
- is_websocket, enable_ip_based_pooling, net_log);
+ kProtoUnknown, quic::ParsedQuicVersion::Unsupported(),
+ alternative_proxy_server, is_websocket, enable_ip_based_pooling, net_log);
}
bool HttpStreamFactory::Job::ShouldThrottleConnectForSpdy() const {
diff --git a/chromium/net/http/http_stream_factory_job.h b/chromium/net/http/http_stream_factory_job.h
index 7ab4e170b00..ee43e1eac99 100644
--- a/chromium/net/http/http_stream_factory_job.h
+++ b/chromium/net/http/http_stream_factory_job.h
@@ -193,6 +193,7 @@ class HttpStreamFactory::Job
void SetPriority(RequestPriority priority);
+ const GURL& origin_url() const { return origin_url_; }
RequestPriority priority() const { return priority_; }
bool was_alpn_negotiated() const;
NextProto negotiated_protocol() const;
diff --git a/chromium/net/http/http_stream_factory_job_controller.cc b/chromium/net/http/http_stream_factory_job_controller.cc
index b99d74823a0..9c0b0baea43 100644
--- a/chromium/net/http/http_stream_factory_job_controller.cc
+++ b/chromium/net/http/http_stream_factory_job_controller.cc
@@ -17,6 +17,7 @@
#include "base/values.h"
#include "net/base/host_mapping_rules.h"
#include "net/base/load_flags.h"
+#include "net/base/url_util.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
@@ -672,11 +673,11 @@ int HttpStreamFactory::JobController::DoCreateJobs() {
alternative_service_info_ =
GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_);
}
- quic::ParsedQuicVersion quic_version = quic::UnsupportedQuicVersion();
+ quic::ParsedQuicVersion quic_version = quic::ParsedQuicVersion::Unsupported();
if (alternative_service_info_.protocol() == kProtoQUIC) {
quic_version =
SelectQuicVersion(alternative_service_info_.advertised_versions());
- DCHECK_NE(quic_version, quic::UnsupportedQuicVersion());
+ DCHECK_NE(quic_version, quic::ParsedQuicVersion::Unsupported());
}
if (is_preconnect_) {
@@ -1014,7 +1015,8 @@ HttpStreamFactory::JobController::GetAlternativeServiceInfoInternal(
if (!is_any_broken) {
// Only log the broken alternative service once per request.
is_any_broken = true;
- HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false);
+ HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false,
+ HasGoogleHost(original_url));
}
continue;
}
@@ -1060,7 +1062,7 @@ HttpStreamFactory::JobController::GetAlternativeServiceInfoInternal(
// If there is no QUIC version in the advertised versions that is
// supported, ignore this entry.
if (SelectQuicVersion(alternative_service_info.advertised_versions()) ==
- quic::UnsupportedQuicVersion())
+ quic::ParsedQuicVersion::Unsupported())
continue;
// Check whether there is an existing QUIC session to use for this origin.
@@ -1106,13 +1108,13 @@ quic::ParsedQuicVersion HttpStreamFactory::JobController::SelectQuicVersion(
for (const quic::ParsedQuicVersion& advertised : advertised_versions) {
for (const quic::ParsedQuicVersion& supported : supported_versions) {
if (supported == advertised) {
- DCHECK_NE(quic::UnsupportedQuicVersion(), supported);
+ DCHECK_NE(quic::ParsedQuicVersion::Unsupported(), supported);
return supported;
}
}
}
- return quic::UnsupportedQuicVersion();
+ return quic::ParsedQuicVersion::Unsupported();
}
bool HttpStreamFactory::JobController::ShouldCreateAlternativeProxyServerJob(
@@ -1170,22 +1172,23 @@ void HttpStreamFactory::JobController::ReportAlternateProtocolUsage(
bool proxy_server_used =
alternative_job_->alternative_proxy_server().is_quic();
+ bool is_google_host = HasGoogleHost(job->origin_url());
if (job == main_job_.get()) {
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE,
- proxy_server_used);
+ proxy_server_used, is_google_host);
return;
}
DCHECK_EQ(alternative_job_.get(), job);
if (job->using_existing_quic_session()) {
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE,
- proxy_server_used);
+ proxy_server_used, is_google_host);
return;
}
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE,
- proxy_server_used);
+ proxy_server_used, is_google_host);
}
bool HttpStreamFactory::JobController::IsJobOrphaned(Job* job) const {
diff --git a/chromium/net/http/http_stream_factory_job_controller.h b/chromium/net/http/http_stream_factory_job_controller.h
index bad49ec4b4b..ee7bf05e525 100644
--- a/chromium/net/http/http_stream_factory_job_controller.h
+++ b/chromium/net/http/http_stream_factory_job_controller.h
@@ -253,7 +253,7 @@ class HttpStreamFactory::JobController
// Returns the first quic::ParsedQuicVersion that has been advertised in
// |advertised_versions| and is supported, following the order of
// |advertised_versions|. If no mutually supported version is found,
- // quic::UnsupportedQuicVersion() will be returned.
+ // quic::ParsedQuicVersion::Unsupported() will be returned.
quic::ParsedQuicVersion SelectQuicVersion(
const quic::ParsedQuicVersionVector& advertised_versions);
diff --git a/chromium/net/http/http_stream_factory_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_job_controller_unittest.cc
index 0c4ef067abd..c58ac8abdc3 100644
--- a/chromium/net/http/http_stream_factory_job_controller_unittest.cc
+++ b/chromium/net/http/http_stream_factory_job_controller_unittest.cc
@@ -873,7 +873,7 @@ TEST_F(HttpStreamFactoryJobControllerTest,
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
session_->http_server_properties()->SetQuicAlternativeService(
server, NetworkIsolationKey(), alternative_service, expiration,
- {quic::UnsupportedQuicVersion()});
+ {quic::ParsedQuicVersion::Unsupported()});
request_ =
job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
@@ -3286,14 +3286,14 @@ TEST_F(HttpStreamFactoryJobControllerTest, GetAlternativeServiceInfoFor) {
EXPECT_EQ(supported_versions, alt_svc_info.advertised_versions());
quic::ParsedQuicVersion unsupported_version_1 =
- quic::UnsupportedQuicVersion();
+ quic::ParsedQuicVersion::Unsupported();
quic::ParsedQuicVersion unsupported_version_2 =
- quic::UnsupportedQuicVersion();
+ quic::ParsedQuicVersion::Unsupported();
for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
if (std::find(supported_versions.begin(), supported_versions.end(),
version) != supported_versions.end())
continue;
- if (unsupported_version_1 == quic::UnsupportedQuicVersion()) {
+ if (unsupported_version_1 == quic::ParsedQuicVersion::Unsupported()) {
unsupported_version_1 = version;
continue;
}
@@ -3374,9 +3374,7 @@ TEST_F(HttpStreamFactoryJobControllerTest,
"h3-Q046=\":443\"; ma=2592000,"
"h3-Q043=\":443\"; ma=2592000,"
"h3-T050=\":443\"; ma=2592000",
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- quic::AllSupportedVersions());
+ quic::ParsedQuicVersion::Q046(), quic::AllSupportedVersions());
}
TEST_F(HttpStreamFactoryJobControllerTest,
@@ -3389,23 +3387,16 @@ TEST_F(HttpStreamFactoryJobControllerTest,
"h3-Q043=\":443\"; ma=2592000,"
"h3-T050=\":443\"; ma=2592000,"
"quic=\":443\"; ma=2592000; v=\"46,43\"",
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_50),
- quic::AllSupportedVersions());
+ quic::ParsedQuicVersion::Q050(), quic::AllSupportedVersions());
}
TEST_F(HttpStreamFactoryJobControllerTest,
AltSvcVersionSelectionWithInverseOrderingOldFormat) {
// Server prefers Q043 but client prefers Q046.
TestAltSvcVersionSelection(
- "quic=\":443\"; ma=2592000; v=\"43,46\"",
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43),
- quic::ParsedQuicVersionVector{
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43)});
+ "quic=\":443\"; ma=2592000; v=\"43,46\"", quic::ParsedQuicVersion::Q043(),
+ quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(),
+ quic::ParsedQuicVersion::Q043()});
}
TEST_F(HttpStreamFactoryJobControllerTest,
@@ -3414,13 +3405,19 @@ TEST_F(HttpStreamFactoryJobControllerTest,
TestAltSvcVersionSelection(
"h3-Q043=\":443\"; ma=2592000,"
"h3-Q046=\":443\"; ma=2592000",
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43),
- quic::ParsedQuicVersionVector{
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_46),
- quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO,
- quic::QUIC_VERSION_43)});
+ quic::ParsedQuicVersion::Q043(),
+ quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(),
+ quic::ParsedQuicVersion::Q043()});
+}
+
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltSvcVersionSelectionWithInvalidOldFormat) {
+ // Q043 can use the old format but Q050 cannot. Make sure the client ignores
+ // Q050 even though it is preferred.
+ TestAltSvcVersionSelection(
+ "quic=\":443\"; ma=2592000; v=\"50,43\"", quic::ParsedQuicVersion::Q043(),
+ quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q050(),
+ quic::ParsedQuicVersion::Q043()});
}
// Tests that if HttpNetworkSession has a non-empty QUIC host allowlist,
diff --git a/chromium/net/http/http_stream_factory_test_util.cc b/chromium/net/http/http_stream_factory_test_util.cc
index 1e898ceb5c2..e9ae6319cb8 100644
--- a/chromium/net/http/http_stream_factory_test_util.cc
+++ b/chromium/net/http/http_stream_factory_test_util.cc
@@ -80,7 +80,7 @@ std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateMainJob(
auto main_job = std::make_unique<MockHttpStreamFactoryJob>(
delegate, job_type, session, request_info, priority, proxy_info,
SSLConfig(), SSLConfig(), destination, origin_url, kProtoUnknown,
- quic::UnsupportedQuicVersion(), ProxyServer(), is_websocket,
+ quic::ParsedQuicVersion::Unsupported(), ProxyServer(), is_websocket,
enable_ip_based_pooling, net_log);
// Keep raw pointer to Job but pass ownership.
@@ -135,8 +135,8 @@ std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateAltProxyJob(
auto alternative_job = std::make_unique<MockHttpStreamFactoryJob>(
delegate, job_type, session, request_info, priority, proxy_info,
SSLConfig(), SSLConfig(), destination, origin_url, kProtoUnknown,
- quic::UnsupportedQuicVersion(), alternative_proxy_server, is_websocket,
- enable_ip_based_pooling, net_log);
+ quic::ParsedQuicVersion::Unsupported(), alternative_proxy_server,
+ is_websocket, enable_ip_based_pooling, net_log);
// Keep raw pointer to Job but pass ownership.
alternative_job_ = alternative_job.get();
diff --git a/chromium/net/http/http_stream_factory_unittest.cc b/chromium/net/http/http_stream_factory_unittest.cc
index 756599802f7..0ddf2a4aa70 100644
--- a/chromium/net/http/http_stream_factory_unittest.cc
+++ b/chromium/net/http/http_stream_factory_unittest.cc
@@ -2199,15 +2199,39 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) {
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
}
+struct TestParams {
+ quic::ParsedQuicVersion version;
+ bool client_headers_include_h2_stream_dependency;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParams& p) {
+ return quiche::QuicheStrCat(
+ ParsedQuicVersionToString(p.version), "_",
+ (p.client_headers_include_h2_stream_dependency ? "" : "No"),
+ "Dependency");
+}
+
+std::vector<TestParams> GetTestParams() {
+ std::vector<TestParams> params;
+ quic::ParsedQuicVersionVector all_supported_versions =
+ quic::AllSupportedVersions();
+ for (const auto& version : all_supported_versions) {
+ params.push_back(TestParams{version, false});
+ params.push_back(TestParams{version, true});
+ }
+ return params;
+}
+
class HttpStreamFactoryBidirectionalQuicTest
: public TestWithTaskEnvironment,
- public ::testing::WithParamInterface<
- std::tuple<quic::ParsedQuicVersion, bool>> {
+ public ::testing::WithParamInterface<TestParams> {
protected:
HttpStreamFactoryBidirectionalQuicTest()
: default_url_(kDefaultUrl),
- version_(std::get<0>(GetParam())),
- client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ version_(GetParam().version),
+ client_headers_include_h2_stream_dependency_(
+ GetParam().client_headers_include_h2_stream_dependency),
client_packet_maker_(version_,
quic::QuicUtils::CreateRandomConnectionId(
quic_context_.random_generator()),
@@ -2227,9 +2251,7 @@ class HttpStreamFactoryBidirectionalQuicTest
ssl_config_service_(new SSLConfigServiceDefaults) {
FLAGS_quic_enable_http3_grease_randomness = false;
quic_context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- quic::QuicEnableVersion(version_);
- }
+ quic::QuicEnableVersion(version_);
}
void TearDown() override { session_.reset(); }
@@ -2327,11 +2349,10 @@ class HttpStreamFactoryBidirectionalQuicTest
HttpNetworkSession::Params params_;
};
-INSTANTIATE_TEST_SUITE_P(
- VersionIncludeStreamDependencySequence,
- HttpStreamFactoryBidirectionalQuicTest,
- ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
- ::testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
+ HttpStreamFactoryBidirectionalQuicTest,
+ ::testing::ValuesIn(GetTestParams()),
+ ::testing::PrintToStringParamName());
TEST_P(HttpStreamFactoryBidirectionalQuicTest,
RequestBidirectionalStreamImplQuicAlternative) {
@@ -3452,10 +3473,10 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcClear) {
EXPECT_TRUE(alternatives.empty());
}
-TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuic) {
+TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicOldFormat) {
quic::ParsedQuicVersionVector versions_with_quic_handshake;
for (const auto& version : quic::AllSupportedVersions()) {
- if (version.handshake_protocol == quic::PROTOCOL_QUIC_CRYPTO) {
+ if (version.UsesQuicCrypto() && version.SupportsGoogleAltSvcFormat()) {
versions_with_quic_handshake.push_back(version);
}
}
@@ -3471,7 +3492,7 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuic) {
scoped_refptr<HttpResponseHeaders> headers(
base::MakeRefCounted<HttpResponseHeaders>(""));
- headers->AddHeader("alt-svc", "quic=\":443\"; v=\"99,50,49,48,47,46,43,39\"");
+ headers->AddHeader("alt-svc", "quic=\":443\"; v=\"46,43\"");
session_->http_stream_factory()->ProcessAlternativeServices(
session_.get(), network_isolation_key, headers.get(), origin);
@@ -3493,9 +3514,10 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuic) {
// Regression test for https://crbug.com/1044694.
TEST_F(ProcessAlternativeServicesTest, AltSvcQuicDoesNotSupportTLSHandshake) {
// In this example, QUIC v50 is only supported with TLS handshake.
+ // Note that this test only covers the Google-specific AltSvc format
+ // which is now deprecated.
quic_context_.params()->supported_versions = {
- {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_49},
- {quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_50}};
+ quic::ParsedQuicVersion::Q043(), quic::ParsedQuicVersion::T050()};
session_ =
std::make_unique<HttpNetworkSession>(session_params_, session_context_);
url::SchemeHostPort origin(url::kHttpsScheme, "example.com", 443);
@@ -3504,10 +3526,9 @@ TEST_F(ProcessAlternativeServicesTest, AltSvcQuicDoesNotSupportTLSHandshake) {
url::Origin::Create(GURL("https://example.com")),
url::Origin::Create(GURL("https://example.com")));
- // Alt-Svc header only refers to PROTOCOL_QUIC_CRYPTO handshake.
scoped_refptr<HttpResponseHeaders> headers(
base::MakeRefCounted<HttpResponseHeaders>(""));
- headers->AddHeader("alt-svc", "quic=\":443\"; v=\"50,49\"");
+ headers->AddHeader("alt-svc", "quic=\":443\"; v=\"50,43\"");
session_->http_stream_factory()->ProcessAlternativeServices(
session_.get(), network_isolation_key, headers.get(), origin);
@@ -3519,11 +3540,9 @@ TEST_F(ProcessAlternativeServicesTest, AltSvcQuicDoesNotSupportTLSHandshake) {
EXPECT_EQ(kProtoQUIC, alternatives[0].protocol());
EXPECT_EQ(HostPortPair("example.com", 443), alternatives[0].host_port_pair());
EXPECT_EQ(1u, alternatives[0].advertised_versions().size());
- // Q049 and T050 are supported. Q049 and Q050 are advertised in the Alt-Svc
- // header. Therefore only Q049 is parsed.
- quic::ParsedQuicVersion expected_advertised_version = {
- quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_49};
- EXPECT_EQ(expected_advertised_version,
+ // Q043 and T050 are supported. Q043 and Q050 are advertised in the Alt-Svc
+ // header. Therefore only Q043 is parsed.
+ EXPECT_EQ(quic::ParsedQuicVersion::Q043(),
alternatives[0].advertised_versions()[0]);
}
@@ -3541,24 +3560,16 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicIetf) {
base::MakeRefCounted<HttpResponseHeaders>(""));
headers->AddHeader("alt-svc",
"h3-27=\":443\","
- "h3-25=\":443\","
"h3-Q050=\":443\","
- "h3-Q049=\":443\","
- "h3-Q048=\":443\","
- "h3-Q047=\":443\","
- "h3-Q043=\":443\","
- "h3-Q039=\":443\"");
+ "h3-Q043=\":443\"");
session_->http_stream_factory()->ProcessAlternativeServices(
session_.get(), network_isolation_key, headers.get(), origin);
quic::ParsedQuicVersionVector versions = {
- {quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_IETF_DRAFT_27},
- {quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_IETF_DRAFT_25},
- {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_50},
- {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_49},
- {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_48},
- {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_43},
+ quic::ParsedQuicVersion::Draft27(),
+ quic::ParsedQuicVersion::Q050(),
+ quic::ParsedQuicVersion::Q043(),
};
AlternativeServiceInfoVector alternatives =
http_server_properties_.GetAlternativeServiceInfos(origin,
diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc
index c25ddf7029e..81b874031c0 100644
--- a/chromium/net/http/http_stream_parser.cc
+++ b/chromium/net/http/http_stream_parser.cc
@@ -922,6 +922,12 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
// tunnel.
response_header_start_offset_ = std::string::npos;
response_body_length_ = -1;
+ // Record the timing of the 103 Early Hints response for the experiment
+ // (https://crbug.com/1093693).
+ if (response_->headers->response_code() == 103 &&
+ first_early_hints_time_.is_null()) {
+ first_early_hints_time_ = response_start_time_;
+ }
// Now waiting for the second set of headers to be read.
} else {
// Only set keep-alive based on final set of headers.
diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h
index 2b5c2f0aeb7..0e773168272 100644
--- a/chromium/net/http/http_stream_parser.h
+++ b/chromium/net/http/http_stream_parser.h
@@ -95,6 +95,7 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
int64_t sent_bytes() const { return sent_bytes_; }
base::TimeTicks response_start_time() { return response_start_time_; }
+ base::TimeTicks first_early_hints_time() { return first_early_hints_time_; }
void GetSSLInfo(SSLInfo* ssl_info);
@@ -241,6 +242,9 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// parsed.
base::TimeTicks response_start_time_;
+ // Time at which the first 103 Early Hints response is received.
+ base::TimeTicks first_early_hints_time_;
+
// Indicates the content length. If this value is less than zero
// (and chunked_decoder_ is null), then we must read until the server
// closes the connection.
diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc
index 15c02611158..4dfad48917f 100644
--- a/chromium/net/http/http_stream_parser_unittest.cc
+++ b/chromium/net/http/http_stream_parser_unittest.cc
@@ -1680,6 +1680,39 @@ TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) {
EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
}
+// Test that "early hints" HTTP header is counted as "received_bytes".
+// 103 Early Hints hasn't been implemented yet and should be ignored, but we
+// collect timing information for the experiment (https://crbug.com/1093693).
+TEST(HttpStreamParser, EarlyHints) {
+ std::string status103 = "HTTP/1.1 103 Early Hints\r\n\r\n";
+ std::string headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 7\r\n\r\n";
+ int64_t headers_size = status103.size() + headers.size();
+ std::string body = "content";
+ std::string response = headers + body;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(status103);
+ get_runner.AddRead(response);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ EXPECT_EQ(103, get_runner.response_info()->headers->response_code());
+ int64_t status103_size = status103.size();
+ EXPECT_EQ(status103_size, get_runner.parser()->received_bytes());
+ get_runner.ReadHeaders();
+ EXPECT_EQ(200, get_runner.response_info()->headers->response_code());
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int64_t response_size = headers_size + body.size();
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+
+ // Make sure the timing of the Early Hints response is captured.
+ EXPECT_FALSE(get_runner.parser()->first_early_hints_time().is_null());
+}
+
// Test that an HttpStreamParser can be read from after it's received headers
// and data structures owned by its owner have been deleted. This happens
// when a ResponseBodyDrainer is used.
diff --git a/chromium/net/http/structured_headers.cc b/chromium/net/http/structured_headers.cc
index 7d5c9218bd6..ab37791e526 100644
--- a/chromium/net/http/structured_headers.cc
+++ b/chromium/net/http/structured_headers.cc
@@ -12,6 +12,7 @@
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
diff --git a/chromium/net/http/test_upload_data_stream_not_allow_http1.cc b/chromium/net/http/test_upload_data_stream_not_allow_http1.cc
new file mode 100644
index 00000000000..5fc9f8a00b6
--- /dev/null
+++ b/chromium/net/http/test_upload_data_stream_not_allow_http1.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include "net/http/test_upload_data_stream_not_allow_http1.h"
+
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+
+bool UploadDataStreamNotAllowHTTP1::AllowHTTP1() const {
+ return false;
+}
+
+int UploadDataStreamNotAllowHTTP1::InitInternal(const NetLogWithSource&) {
+ return net::OK;
+}
+
+int UploadDataStreamNotAllowHTTP1::ReadInternal(IOBuffer* buf, int buf_len) {
+ const size_t bytes_to_read =
+ std::min(content_.length(), static_cast<size_t>(buf_len));
+ memcpy(buf->data(), content_.c_str(), bytes_to_read);
+ content_ = content_.substr(bytes_to_read);
+ if (!content_.length())
+ SetIsFinalChunk();
+ return bytes_to_read;
+}
+
+void UploadDataStreamNotAllowHTTP1::ResetInternal() {}
+
+} // namespace net \ No newline at end of file
diff --git a/chromium/net/http/test_upload_data_stream_not_allow_http1.h b/chromium/net/http/test_upload_data_stream_not_allow_http1.h
new file mode 100644
index 00000000000..50d33f6c807
--- /dev/null
+++ b/chromium/net/http/test_upload_data_stream_not_allow_http1.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef NET_HTTP_TEST_UPLOAD_DATA_STREAM_NOT_ALLOW_HTTP1_H_
+#define NET_HTTP_TEST_UPLOAD_DATA_STREAM_NOT_ALLOW_HTTP1_H_
+
+#include "net/base/upload_data_stream.h"
+
+namespace net {
+
+// UploadDataStreamNotAllowHTTP1 simply disallows HTTP/1 and uploads content.
+class UploadDataStreamNotAllowHTTP1 : public UploadDataStream {
+ public:
+ explicit UploadDataStreamNotAllowHTTP1(const std::string& content)
+ : UploadDataStream(true, 0), content_(content) {}
+ UploadDataStreamNotAllowHTTP1(const UploadDataStreamNotAllowHTTP1&) = delete;
+ UploadDataStreamNotAllowHTTP1& operator=(
+ const UploadDataStreamNotAllowHTTP1&) = delete;
+
+ bool AllowHTTP1() const override;
+
+ private:
+ int InitInternal(const NetLogWithSource& net_log) override;
+ int ReadInternal(IOBuffer* buf, int buf_len) override;
+ void ResetInternal() override;
+
+ std::string content_;
+};
+
+} // namespace net
+
+#endif // NET_HTTP_TEST_UPLOAD_DATA_STREAM_NOT_ALLOW_HTTP1_H_ \ No newline at end of file
diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc
index ce625c788b1..137c09f5ff1 100644
--- a/chromium/net/http/transport_security_persister.cc
+++ b/chromium/net/http/transport_security_persister.cc
@@ -15,11 +15,14 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/location.h"
+#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "crypto/sha2.h"
+#include "net/base/features.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/x509_certificate.h"
#include "net/http/transport_security_state.h"
@@ -47,24 +50,50 @@ std::string ExternalStringToHashedDomain(const std::string& external) {
return out;
}
-const char kIncludeSubdomains[] = "include_subdomains";
+// Version 2 of the on-disk format consists of a single JSON object. The
+// top-level dictionary has "version", "sts", and "expect_ct" entries. The first
+// is an integer, the latter two are unordered lists of dictionaries, each
+// representing cached data for a single host.
+
+// Stored in serialized dictionary values to distinguish incompatible versions.
+// Version 1 is distinguished by the lack of an integer version value.
+const char kVersionKey[] = "version";
+const int kCurrentVersionValue = 2;
+
+// Keys in top level serialized dictionary, for lists of STS and Expect-CT
+// entries, respectively.
+const char kSTSKey[] = "sts";
+const char kExpectCTKey[] = "expect_ct";
+
+// Hostname entry, used in serialized STS and Expect-CT dictionaries. Value is
+// produced by passing hashed hostname strings to
+// HashedDomainToExternalString().
+const char kHostname[] = "host";
+
+// Key values in serialized STS entries.
const char kStsIncludeSubdomains[] = "sts_include_subdomains";
-const char kMode[] = "mode";
+const char kStsObserved[] = "sts_observed";
const char kExpiry[] = "expiry";
+const char kMode[] = "mode";
+
+// Values for "mode" used in serialized STS entries.
const char kForceHTTPS[] = "force-https";
-const char kStrict[] = "strict";
const char kDefault[] = "default";
-const char kPinningOnly[] = "pinning-only";
-const char kCreated[] = "created";
-const char kStsObserved[] = "sts_observed";
-// The keys below are contained in a subdictionary keyed as
-// |kExpectCTSubdictionary|.
-const char kExpectCTSubdictionary[] = "expect_ct";
-const char kExpectCTExpiry[] = "expect_ct_expiry";
+
+// Key names in serialized Expect-CT entries.
+const char kNetworkIsolationKey[] = "nik";
const char kExpectCTObserved[] = "expect_ct_observed";
+const char kExpectCTExpiry[] = "expect_ct_expiry";
const char kExpectCTEnforce[] = "expect_ct_enforce";
const char kExpectCTReportUri[] = "expect_ct_report_uri";
+// Obsolete values in older STS entries.
+const char kIncludeSubdomains[] = "include_subdomains";
+const char kStrict[] = "strict";
+const char kPinningOnly[] = "pinning-only";
+const char kCreated[] = "created";
+const char kExpectCTSubdictionary[] = "expect_ct";
+
std::string LoadState(const base::FilePath& path) {
std::string result;
if (!base::ReadFileToString(path, &result)) {
@@ -78,104 +107,201 @@ bool IsDynamicExpectCTEnabled() {
TransportSecurityState::kDynamicExpectCTFeature);
}
-// Populates |host| with default values for the STS states.
-// These default values represent "null" states and are only useful to keep
-// the entries in the resulting JSON consistent. The deserializer will ignore
-// "null" states.
-// TODO(davidben): This can be removed when the STS and Expect-CT states are
-// stored independently on disk. https://crbug.com/470295
-void PopulateEntryWithDefaults(base::DictionaryValue* host) {
- host->Clear();
-
- // STS default values.
- host->SetBoolean(kStsIncludeSubdomains, false);
- host->SetDouble(kStsObserved, 0.0);
- host->SetDouble(kExpiry, 0.0);
- host->SetString(kMode, kDefault);
-}
+// Serializes STS data from |state| to a Value.
+base::Value SerializeSTSData(const TransportSecurityState* state) {
+ base::Value sts_list(base::Value::Type::LIST);
-// Serializes STS data from |state| into |toplevel|. Any existing state in
-// |toplevel| for each item is overwritten.
-void SerializeSTSData(TransportSecurityState* state,
- base::DictionaryValue* toplevel) {
TransportSecurityState::STSStateIterator sts_iterator(*state);
for (; sts_iterator.HasNext(); sts_iterator.Advance()) {
- const std::string& hostname = sts_iterator.hostname();
const TransportSecurityState::STSState& sts_state =
sts_iterator.domain_state();
- const std::string key = HashedDomainToExternalString(hostname);
- std::unique_ptr<base::DictionaryValue> serialized(
- new base::DictionaryValue);
- PopulateEntryWithDefaults(serialized.get());
-
- serialized->SetBoolean(kStsIncludeSubdomains, sts_state.include_subdomains);
- serialized->SetDouble(kStsObserved, sts_state.last_observed.ToDoubleT());
- serialized->SetDouble(kExpiry, sts_state.expiry.ToDoubleT());
+ base::Value serialized(base::Value::Type::DICTIONARY);
+ serialized.SetStringKey(
+ kHostname, HashedDomainToExternalString(sts_iterator.hostname()));
+ serialized.SetBoolKey(kStsIncludeSubdomains, sts_state.include_subdomains);
+ serialized.SetDoubleKey(kStsObserved, sts_state.last_observed.ToDoubleT());
+ serialized.SetDoubleKey(kExpiry, sts_state.expiry.ToDoubleT());
switch (sts_state.upgrade_mode) {
case TransportSecurityState::STSState::MODE_FORCE_HTTPS:
- serialized->SetString(kMode, kForceHTTPS);
+ serialized.SetStringKey(kMode, kForceHTTPS);
break;
case TransportSecurityState::STSState::MODE_DEFAULT:
- serialized->SetString(kMode, kDefault);
+ serialized.SetStringKey(kMode, kDefault);
break;
- default:
- NOTREACHED() << "STSState with unknown mode";
- continue;
}
- toplevel->Set(key, std::move(serialized));
+ sts_list.Append(std::move(serialized));
}
+ return sts_list;
}
-// Serializes Expect-CT data from |state| into |toplevel|. For each Expect-CT
-// item in |state|, if |toplevel| already contains an item for that hostname,
-// the item is updated to include a subdictionary with key
-// |kExpectCTSubdictionary|; otherwise an item is created for that hostname with
-// a |kExpectCTSubdictionary| subdictionary.
-void SerializeExpectCTData(TransportSecurityState* state,
- base::DictionaryValue* toplevel) {
- if (!IsDynamicExpectCTEnabled())
+// Deserializes STS data from a Value created by the above method.
+void DeserializeSTSData(const base::Value& sts_list,
+ TransportSecurityState* state) {
+ if (!sts_list.is_list())
return;
+
+ base::Time current_time(base::Time::Now());
+
+ for (const base::Value& sts_entry : sts_list.GetList()) {
+ if (!sts_entry.is_dict())
+ continue;
+
+ const std::string* hostname = sts_entry.FindStringKey(kHostname);
+ base::Optional<bool> sts_include_subdomains =
+ sts_entry.FindBoolKey(kStsIncludeSubdomains);
+ base::Optional<double> sts_observed = sts_entry.FindDoubleKey(kStsObserved);
+ base::Optional<double> expiry = sts_entry.FindDoubleKey(kExpiry);
+ const std::string* mode = sts_entry.FindStringKey(kMode);
+
+ if (!hostname || !sts_include_subdomains.has_value() ||
+ !sts_observed.has_value() || !expiry.has_value() || !mode) {
+ continue;
+ }
+
+ TransportSecurityState::STSState sts_state;
+ sts_state.include_subdomains = *sts_include_subdomains;
+ sts_state.last_observed = base::Time::FromDoubleT(*sts_observed);
+ sts_state.expiry = base::Time::FromDoubleT(*expiry);
+
+ if (*mode == kForceHTTPS) {
+ sts_state.upgrade_mode =
+ TransportSecurityState::STSState::MODE_FORCE_HTTPS;
+ } else if (*mode == kDefault) {
+ sts_state.upgrade_mode = TransportSecurityState::STSState::MODE_DEFAULT;
+ } else {
+ continue;
+ }
+
+ if (sts_state.expiry < current_time || !sts_state.ShouldUpgradeToSSL())
+ continue;
+
+ std::string hashed = ExternalStringToHashedDomain(*hostname);
+ if (hashed.empty())
+ continue;
+
+ state->AddOrUpdateEnabledSTSHosts(hashed, sts_state);
+ }
+}
+
+// Serializes Expect-CT data from |state| to a Value.
+base::Value SerializeExpectCTData(TransportSecurityState* state) {
+ base::Value ct_list(base::Value::Type::LIST);
+
+ if (!IsDynamicExpectCTEnabled())
+ return ct_list;
+
TransportSecurityState::ExpectCTStateIterator expect_ct_iterator(*state);
for (; expect_ct_iterator.HasNext(); expect_ct_iterator.Advance()) {
- const std::string& hostname = expect_ct_iterator.hostname();
const TransportSecurityState::ExpectCTState& expect_ct_state =
expect_ct_iterator.domain_state();
- // See if the current |hostname| already has STS state and, if so,
- // update that entry.
- const std::string key = HashedDomainToExternalString(hostname);
- base::DictionaryValue* serialized = nullptr;
- if (!toplevel->GetDictionary(key, &serialized)) {
- std::unique_ptr<base::DictionaryValue> serialized_scoped(
- new base::DictionaryValue);
- serialized = serialized_scoped.get();
- PopulateEntryWithDefaults(serialized);
- toplevel->Set(key, std::move(serialized_scoped));
+ base::DictionaryValue ct_entry;
+
+ base::Value network_isolation_key_value;
+ // Don't serialize entries with transient NetworkIsolationKeys.
+ if (!expect_ct_iterator.network_isolation_key().ToValue(
+ &network_isolation_key_value)) {
+ continue;
+ }
+ ct_entry.SetKey(kNetworkIsolationKey,
+ std::move(network_isolation_key_value));
+
+ ct_entry.SetStringKey(
+ kHostname, HashedDomainToExternalString(expect_ct_iterator.hostname()));
+ ct_entry.SetDoubleKey(kExpectCTObserved,
+ expect_ct_state.last_observed.ToDoubleT());
+ ct_entry.SetDoubleKey(kExpectCTExpiry, expect_ct_state.expiry.ToDoubleT());
+ ct_entry.SetBoolKey(kExpectCTEnforce, expect_ct_state.enforce);
+ ct_entry.SetStringKey(kExpectCTReportUri,
+ expect_ct_state.report_uri.spec());
+
+ ct_list.Append(std::move(ct_entry));
+ }
+
+ return ct_list;
+}
+
+// Deserializes Expect-CT data from a Value created by the above method.
+void DeserializeExpectCTData(const base::Value& ct_list,
+ TransportSecurityState* state) {
+ if (!ct_list.is_list())
+ return;
+ bool partition_by_nik = base::FeatureList::IsEnabled(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+
+ const base::Time current_time(base::Time::Now());
+
+ for (const base::Value& ct_entry : ct_list.GetList()) {
+ if (!ct_entry.is_dict())
+ continue;
+
+ const std::string* hostname = ct_entry.FindStringKey(kHostname);
+ const base::Value* network_isolation_key_value =
+ ct_entry.FindKey(kNetworkIsolationKey);
+ base::Optional<double> expect_ct_last_observed =
+ ct_entry.FindDoubleKey(kExpectCTObserved);
+ base::Optional<double> expect_ct_expiry =
+ ct_entry.FindDoubleKey(kExpectCTExpiry);
+ base::Optional<bool> expect_ct_enforce =
+ ct_entry.FindBoolKey(kExpectCTEnforce);
+ const std::string* expect_ct_report_uri =
+ ct_entry.FindStringKey(kExpectCTReportUri);
+
+ if (!hostname || !network_isolation_key_value ||
+ !expect_ct_last_observed.has_value() || !expect_ct_expiry.has_value() ||
+ !expect_ct_enforce.has_value() || !expect_ct_report_uri) {
+ continue;
}
- std::unique_ptr<base::DictionaryValue> expect_ct_subdictionary(
- new base::DictionaryValue());
- expect_ct_subdictionary->SetDouble(
- kExpectCTObserved, expect_ct_state.last_observed.ToDoubleT());
- expect_ct_subdictionary->SetDouble(kExpectCTExpiry,
- expect_ct_state.expiry.ToDoubleT());
- expect_ct_subdictionary->SetBoolean(kExpectCTEnforce,
- expect_ct_state.enforce);
- expect_ct_subdictionary->SetString(kExpectCTReportUri,
- expect_ct_state.report_uri.spec());
- serialized->Set(kExpectCTSubdictionary, std::move(expect_ct_subdictionary));
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ expect_ct_state.last_observed =
+ base::Time::FromDoubleT(*expect_ct_last_observed);
+ expect_ct_state.expiry = base::Time::FromDoubleT(*expect_ct_expiry);
+ expect_ct_state.enforce = *expect_ct_enforce;
+
+ GURL report_uri(*expect_ct_report_uri);
+ if (report_uri.is_valid())
+ expect_ct_state.report_uri = report_uri;
+
+ if (expect_ct_state.expiry < current_time ||
+ (!expect_ct_state.enforce && expect_ct_state.report_uri.is_empty())) {
+ continue;
+ }
+
+ std::string hashed = ExternalStringToHashedDomain(*hostname);
+ if (hashed.empty())
+ continue;
+
+ NetworkIsolationKey network_isolation_key;
+ if (!NetworkIsolationKey::FromValue(*network_isolation_key_value,
+ &network_isolation_key)) {
+ continue;
+ }
+
+ // If Expect-CT is not being partitioned by NetworkIsolationKey, but
+ // |network_isolation_key| is not empty, drop the entry, to avoid ambiguity
+ // and favor entries that were saved with an empty NetworkIsolationKey.
+ if (!partition_by_nik && !network_isolation_key.IsEmpty())
+ continue;
+
+ state->AddOrUpdateEnabledExpectCTHosts(hashed, network_isolation_key,
+ expect_ct_state);
}
}
-// Populates |state| with the values in the |kExpectCTSubdictionary|
-// subdictionary in |parsed|. Returns false if |parsed| is malformed
-// (e.g. missing a required Expect-CT key) and true otherwise. Note that true
-// does not necessarily mean that Expect-CT state was present in |parsed|.
-bool DeserializeExpectCTState(const base::DictionaryValue* parsed,
- TransportSecurityState::ExpectCTState* state) {
+// Handles deserializing |kExpectCTSubdictionary| in dictionaries that use the
+// obsolete format. Populates |state| with the values from the Expect-CT
+// subdictionary in |parsed|. Returns false if |parsed| is malformed (e.g.
+// missing a required Expect-CT key) and true otherwise. Note that true does not
+// necessarily mean that Expect-CT state was present in |parsed|.
+//
+// TODO(mmenke): Remove once the obsolete format is no longer supported.
+bool DeserializeObsoleteExpectCTState(
+ const base::DictionaryValue* parsed,
+ TransportSecurityState::ExpectCTState* state) {
const base::DictionaryValue* expect_ct_subdictionary;
if (!parsed->GetDictionary(kExpectCTSubdictionary,
&expect_ct_subdictionary)) {
@@ -275,39 +401,75 @@ void TransportSecurityPersister::OnWriteFinished(base::OnceClosure callback) {
bool TransportSecurityPersister::SerializeData(std::string* output) {
DCHECK(foreground_runner_->RunsTasksInCurrentSequence());
- base::DictionaryValue toplevel;
-
- // TODO(davidben): Fix the serialization format by splitting the on-disk
- // representation of the STS and Expect-CT states. https://crbug.com/470295.
- SerializeSTSData(transport_security_state_, &toplevel);
- SerializeExpectCTData(transport_security_state_, &toplevel);
+ base::Value toplevel(base::Value::Type::DICTIONARY);
+ toplevel.SetIntKey(kVersionKey, kCurrentVersionValue);
+ toplevel.SetKey(kSTSKey, SerializeSTSData(transport_security_state_));
+ toplevel.SetKey(kExpectCTKey,
+ SerializeExpectCTData(transport_security_state_));
- base::JSONWriter::WriteWithOptions(
- toplevel, base::JSONWriter::OPTIONS_PRETTY_PRINT, output);
+ base::JSONWriter::Write(toplevel, output);
return true;
}
bool TransportSecurityPersister::LoadEntries(const std::string& serialized,
- bool* dirty) {
+ bool* data_in_old_format) {
DCHECK(foreground_runner_->RunsTasksInCurrentSequence());
transport_security_state_->ClearDynamicData();
- return Deserialize(serialized, dirty, transport_security_state_);
+ return Deserialize(serialized, data_in_old_format, transport_security_state_);
}
-// static
bool TransportSecurityPersister::Deserialize(const std::string& serialized,
- bool* dirty,
+ bool* data_in_old_format,
TransportSecurityState* state) {
- std::unique_ptr<base::Value> value =
- base::JSONReader::ReadDeprecated(serialized);
- base::DictionaryValue* dict_value = nullptr;
- if (!value.get() || !value->GetAsDictionary(&dict_value))
+ *data_in_old_format = false;
+ base::Optional<base::Value> value = base::JSONReader::Read(serialized);
+ if (!value || !value->is_dict())
return false;
+ // Old dictionaries don't have a version number, so try the obsolete format if
+ // there's no integer version number.
+ base::Optional<int> version = value->FindIntKey(kVersionKey);
+ if (!version) {
+ bool dirty_unused = false;
+ bool success = DeserializeObsoleteData(*value, &dirty_unused, state);
+ // If successfully loaded data from a file in the old format, need to
+ // overwrite the file with the newer format.
+ *data_in_old_format = success;
+ return success;
+ }
+
+ if (*version != kCurrentVersionValue)
+ return false;
+
+ base::Value* sts_value = value->FindKey(kSTSKey);
+ if (sts_value)
+ DeserializeSTSData(*sts_value, state);
+
+ base::Value* expect_ct_value = value->FindKey(kExpectCTKey);
+ if (expect_ct_value)
+ DeserializeExpectCTData(*expect_ct_value, state);
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ExpectCT.EntriesOnLoad",
+ state->num_expect_ct_entries(), 1 /* min */,
+ 2000 /* max */, 40 /* buckets */);
+ return true;
+}
+
+bool TransportSecurityPersister::DeserializeObsoleteData(
+ const base::Value& value,
+ bool* dirty,
+ TransportSecurityState* state) {
const base::Time current_time(base::Time::Now());
bool dirtied = false;
+ const base::DictionaryValue* dict_value = nullptr;
+ int rv = value.GetAsDictionary(&dict_value);
+ // The one caller ensures |value| is of Value::Type::DICTIONARY already,
+ // though it doesn't extract a DictionaryValue*, since that is the deprecated
+ // way to use dictionaries.
+ DCHECK(rv);
+
for (base::DictionaryValue::Iterator i(*dict_value);
!i.IsAtEnd(); i.Advance()) {
const base::DictionaryValue* parsed = nullptr;
@@ -367,7 +529,7 @@ bool TransportSecurityPersister::Deserialize(const std::string& serialized,
sts_state.last_observed = base::Time::Now();
}
- if (!DeserializeExpectCTState(parsed, &expect_ct_state)) {
+ if (!DeserializeObsoleteExpectCTState(parsed, &expect_ct_state)) {
continue;
}
@@ -394,8 +556,11 @@ bool TransportSecurityPersister::Deserialize(const std::string& serialized,
// We only register entries that have actual state.
if (has_sts)
state->AddOrUpdateEnabledSTSHosts(hashed, sts_state);
- if (has_expect_ct)
- state->AddOrUpdateEnabledExpectCTHosts(hashed, expect_ct_state);
+ if (has_expect_ct) {
+ // Use empty NetworkIsolationKeys for old data.
+ state->AddOrUpdateEnabledExpectCTHosts(hashed, NetworkIsolationKey(),
+ expect_ct_state);
+ }
}
*dirty = dirtied;
@@ -408,12 +573,10 @@ void TransportSecurityPersister::CompleteLoad(const std::string& state) {
if (state.empty())
return;
- bool dirty = false;
- if (!LoadEntries(state, &dirty)) {
- LOG(ERROR) << "Failed to deserialize state: " << state;
+ bool data_in_old_format = false;
+ if (!LoadEntries(state, &data_in_old_format))
return;
- }
- if (dirty)
+ if (data_in_old_format)
StateIsDirty(transport_security_state_);
}
diff --git a/chromium/net/http/transport_security_persister.h b/chromium/net/http/transport_security_persister.h
index a7a92839c32..9d6be48f3b6 100644
--- a/chromium/net/http/transport_security_persister.h
+++ b/chromium/net/http/transport_security_persister.h
@@ -45,6 +45,7 @@
namespace base {
class SequencedTaskRunner;
+class Value;
}
namespace net {
@@ -107,20 +108,27 @@ class NET_EXPORT TransportSecurityPersister
// Clears any existing non-static entries, and then re-populates
// |transport_security_state_|.
//
- // Sets |*dirty| to true if the new state differs from the persisted
- // state; false otherwise.
- bool LoadEntries(const std::string& serialized, bool* dirty);
+ // Sets |*data_in_old_format| to true if the loaded data is in an older format
+ // and should be overwritten with data in the newest format.
+ bool LoadEntries(const std::string& serialized, bool* data_in_old_format);
private:
// Populates |state| from the JSON string |serialized|. Returns true if
// all entries were parsed and deserialized correctly.
//
- // Sets |*dirty| to true if the new state differs from the persisted
- // state; false otherwise.
+ // Sets |*data_in_old_format| to true if the old data is in the old file
+ // format and needs to be overwritten with data in the newer format; false
+ // otherwise.
static bool Deserialize(const std::string& serialized,
- bool* dirty,
+ bool* data_in_old_format,
TransportSecurityState* state);
+ // Used internally by Deserialize() to handle older dictionaries.
+ // TODO(https://crbug.com/1086975): This should be removed in Chrome 88.
+ static bool DeserializeObsoleteData(const base::Value& value,
+ bool* dirty,
+ TransportSecurityState* state);
+
void CompleteLoad(const std::string& state);
void OnWriteFinished(base::OnceClosure callback);
diff --git a/chromium/net/http/transport_security_persister_unittest.cc b/chromium/net/http/transport_security_persister_unittest.cc
index db952591974..c9a893bcfe9 100644
--- a/chromium/net/http/transport_security_persister_unittest.cc
+++ b/chromium/net/http/transport_security_persister_unittest.cc
@@ -16,9 +16,13 @@
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "net/base/features.h"
+#include "net/base/network_isolation_key.h"
#include "net/http/transport_security_state.h"
#include "net/test/test_with_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
namespace net {
@@ -26,9 +30,19 @@ namespace {
const char kReportUri[] = "http://www.example.test/report";
-class TransportSecurityPersisterTest : public TestWithTaskEnvironment {
+// The bool indicates whether kPartitionExpectCTStateByNetworkIsolationKey
+// should be enabled.
+class TransportSecurityPersisterTest : public ::testing::TestWithParam<bool>,
+ public WithTaskEnvironment {
public:
- TransportSecurityPersisterTest() = default;
+ TransportSecurityPersisterTest()
+ : WithTaskEnvironment(
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+ // Mock out time so that entries with hard-coded json data can be
+ // successfully loaded. Use a large enough value that dynamically created
+ // entries have at least somewhat interesting expiration times.
+ FastForwardBy(base::TimeDelta::FromDays(3660));
+ }
~TransportSecurityPersisterTest() override {
EXPECT_TRUE(base::MessageLoopCurrentForIO::IsSet());
@@ -42,23 +56,36 @@ class TransportSecurityPersisterTest : public TestWithTaskEnvironment {
base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
+ // This feature is used in initializing |state_|.
+ if (partition_expect_ct_state()) {
+ feature_list_.InitAndEnableFeature(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+ } else {
+ feature_list_.InitAndDisableFeature(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+ }
+ state_ = std::make_unique<TransportSecurityState>();
persister_ = std::make_unique<TransportSecurityPersister>(
- &state_, temp_dir_.GetPath(), std::move(background_runner));
+ state_.get(), temp_dir_.GetPath(), std::move(background_runner));
}
+ bool partition_expect_ct_state() const { return GetParam(); }
+
protected:
base::ScopedTempDir temp_dir_;
- TransportSecurityState state_;
+ base::test::ScopedFeatureList feature_list_;
+ std::unique_ptr<TransportSecurityState> state_;
std::unique_ptr<TransportSecurityPersister> persister_;
};
+INSTANTIATE_TEST_SUITE_P(All, TransportSecurityPersisterTest, testing::Bool());
+
// Tests that LoadEntries() clears existing non-static entries.
-TEST_F(TransportSecurityPersisterTest, LoadEntriesClearsExistingState) {
+TEST_P(TransportSecurityPersisterTest, LoadEntriesClearsExistingState) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
- std::string output;
- bool dirty;
+ bool data_in_old_format;
TransportSecurityState::STSState sts_state;
TransportSecurityState::ExpectCTState expect_ct_state;
@@ -66,63 +93,65 @@ TEST_F(TransportSecurityPersisterTest, LoadEntriesClearsExistingState) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
static const char kYahooDomain[] = "yahoo.com";
- EXPECT_FALSE(state_.GetDynamicSTSState(kYahooDomain, &sts_state, nullptr));
+ EXPECT_FALSE(state_->GetDynamicSTSState(kYahooDomain, &sts_state));
- state_.AddHSTS(kYahooDomain, expiry, false /* include subdomains */);
- state_.AddExpectCT(kYahooDomain, expiry, true /* enforce */, GURL());
+ state_->AddHSTS(kYahooDomain, expiry, false /* include subdomains */);
+ state_->AddExpectCT(kYahooDomain, expiry, true /* enforce */, GURL(),
+ NetworkIsolationKey());
- EXPECT_TRUE(state_.GetDynamicSTSState(kYahooDomain, &sts_state, nullptr));
- EXPECT_TRUE(state_.GetDynamicExpectCTState(kYahooDomain, &expect_ct_state));
+ EXPECT_TRUE(state_->GetDynamicSTSState(kYahooDomain, &sts_state));
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kYahooDomain, NetworkIsolationKey(), &expect_ct_state));
- EXPECT_TRUE(persister_->LoadEntries("{}", &dirty));
- EXPECT_FALSE(dirty);
+ EXPECT_TRUE(persister_->LoadEntries("{\"version\":2}", &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
- EXPECT_FALSE(state_.GetDynamicSTSState(kYahooDomain, &sts_state, nullptr));
- EXPECT_FALSE(state_.GetDynamicExpectCTState(kYahooDomain, &expect_ct_state));
+ EXPECT_FALSE(state_->GetDynamicSTSState(kYahooDomain, &sts_state));
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kYahooDomain, NetworkIsolationKey(), &expect_ct_state));
}
-TEST_F(TransportSecurityPersisterTest, SerializeData1) {
+TEST_P(TransportSecurityPersisterTest, SerializeData1) {
std::string output;
- bool dirty;
+ bool data_in_old_format;
EXPECT_TRUE(persister_->SerializeData(&output));
- EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
- EXPECT_FALSE(dirty);
+ EXPECT_TRUE(persister_->LoadEntries(output, &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
}
-TEST_F(TransportSecurityPersisterTest, SerializeData2) {
+TEST_P(TransportSecurityPersisterTest, SerializeData2) {
TransportSecurityState::STSState sts_state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
static const char kYahooDomain[] = "yahoo.com";
- EXPECT_FALSE(state_.GetDynamicSTSState(kYahooDomain, &sts_state, nullptr));
+ EXPECT_FALSE(state_->GetDynamicSTSState(kYahooDomain, &sts_state));
bool include_subdomains = true;
- state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
+ state_->AddHSTS(kYahooDomain, expiry, include_subdomains);
std::string output;
- bool dirty;
+ bool data_in_old_format;
EXPECT_TRUE(persister_->SerializeData(&output));
- EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
+ EXPECT_TRUE(persister_->LoadEntries(output, &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
- EXPECT_TRUE(state_.GetDynamicSTSState(kYahooDomain, &sts_state, nullptr));
+ EXPECT_TRUE(state_->GetDynamicSTSState(kYahooDomain, &sts_state));
EXPECT_EQ(sts_state.upgrade_mode,
TransportSecurityState::STSState::MODE_FORCE_HTTPS);
- EXPECT_TRUE(state_.GetDynamicSTSState("foo.yahoo.com", &sts_state, nullptr));
+ EXPECT_TRUE(state_->GetDynamicSTSState("foo.yahoo.com", &sts_state));
EXPECT_EQ(sts_state.upgrade_mode,
TransportSecurityState::STSState::MODE_FORCE_HTTPS);
- EXPECT_TRUE(
- state_.GetDynamicSTSState("foo.bar.yahoo.com", &sts_state, nullptr));
+ EXPECT_TRUE(state_->GetDynamicSTSState("foo.bar.yahoo.com", &sts_state));
EXPECT_EQ(sts_state.upgrade_mode,
TransportSecurityState::STSState::MODE_FORCE_HTTPS);
- EXPECT_TRUE(
- state_.GetDynamicSTSState("foo.bar.baz.yahoo.com", &sts_state, nullptr));
+ EXPECT_TRUE(state_->GetDynamicSTSState("foo.bar.baz.yahoo.com", &sts_state));
EXPECT_EQ(sts_state.upgrade_mode,
TransportSecurityState::STSState::MODE_FORCE_HTTPS);
}
-TEST_F(TransportSecurityPersisterTest, SerializeData3) {
+TEST_P(TransportSecurityPersisterTest, SerializeData3) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
@@ -131,26 +160,27 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
base::Time expiry =
base::Time::Now() + base::TimeDelta::FromSeconds(1000);
bool include_subdomains = false;
- state_.AddHSTS("www.example.com", expiry, include_subdomains);
- state_.AddExpectCT("www.example.com", expiry, true /* enforce */, GURL());
+ state_->AddHSTS("www.example.com", expiry, include_subdomains);
+ state_->AddExpectCT("www.example.com", expiry, true /* enforce */, GURL(),
+ NetworkIsolationKey());
// Add another entry.
expiry =
base::Time::Now() + base::TimeDelta::FromSeconds(3000);
- state_.AddHSTS("www.example.net", expiry, include_subdomains);
- state_.AddExpectCT("www.example.net", expiry, false /* enforce */,
- report_uri);
+ state_->AddHSTS("www.example.net", expiry, include_subdomains);
+ state_->AddExpectCT("www.example.net", expiry, false /* enforce */,
+ report_uri, NetworkIsolationKey());
// Save a copy of everything.
std::set<std::string> sts_saved;
- TransportSecurityState::STSStateIterator sts_iter(state_);
+ TransportSecurityState::STSStateIterator sts_iter(*state_);
while (sts_iter.HasNext()) {
sts_saved.insert(sts_iter.hostname());
sts_iter.Advance();
}
std::set<std::string> expect_ct_saved;
- TransportSecurityState::ExpectCTStateIterator expect_ct_iter(state_);
+ TransportSecurityState::ExpectCTStateIterator expect_ct_iter(*state_);
while (expect_ct_iter.HasNext()) {
expect_ct_saved.insert(expect_ct_iter.hostname());
expect_ct_iter.Advance();
@@ -161,7 +191,7 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
// Persist the data to the file.
base::RunLoop run_loop;
- persister_->WriteNow(&state_, run_loop.QuitClosure());
+ persister_->WriteNow(state_.get(), run_loop.QuitClosure());
run_loop.Run();
// Read the data back.
@@ -169,13 +199,13 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
std::string persisted;
EXPECT_TRUE(base::ReadFileToString(path, &persisted));
EXPECT_EQ(persisted, serialized);
- bool dirty;
- EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
- EXPECT_FALSE(dirty);
+ bool data_in_old_format;
+ EXPECT_TRUE(persister_->LoadEntries(persisted, &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
// Check that states are the same as saved.
size_t count = 0;
- TransportSecurityState::STSStateIterator sts_iter2(state_);
+ TransportSecurityState::STSStateIterator sts_iter2(*state_);
while (sts_iter2.HasNext()) {
count++;
sts_iter2.Advance();
@@ -183,7 +213,7 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
EXPECT_EQ(count, sts_saved.size());
count = 0;
- TransportSecurityState::ExpectCTStateIterator expect_ct_iter2(state_);
+ TransportSecurityState::ExpectCTStateIterator expect_ct_iter2(*state_);
while (expect_ct_iter2.HasNext()) {
count++;
expect_ct_iter2.Advance();
@@ -191,24 +221,130 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
EXPECT_EQ(count, expect_ct_saved.size());
}
-TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
+TEST_P(TransportSecurityPersisterTest, DeserializeBadData) {
+ bool data_in_old_format;
+ EXPECT_FALSE(persister_->LoadEntries("", &data_in_old_format));
+ EXPECT_FALSE(persister_->LoadEntries("Foopy", &data_in_old_format));
+ EXPECT_FALSE(persister_->LoadEntries("15", &data_in_old_format));
+ EXPECT_FALSE(persister_->LoadEntries("[15]", &data_in_old_format));
+ EXPECT_FALSE(persister_->LoadEntries("{\"version\":1}", &data_in_old_format));
+}
+
+TEST_P(TransportSecurityPersisterTest, DeserializeDataOldWithoutCreationDate) {
+ const char kDomain[] = "example.test";
+
// This is an old-style piece of transport state JSON, which has no creation
// date.
- std::string output =
+ const std::string kInput =
"{ "
- "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
+ "\"G0EywIek2XnIhLrUjaK4TrHBT1+2TcixDVRXwM3/CCo=\": {"
"\"expiry\": 1266815027.983453, "
"\"include_subdomains\": false, "
"\"mode\": \"strict\" "
"}"
"}";
- bool dirty;
- EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
- EXPECT_TRUE(dirty);
+ bool data_in_old_format;
+ EXPECT_TRUE(persister_->LoadEntries(kInput, &data_in_old_format));
+ EXPECT_TRUE(data_in_old_format);
+
+ TransportSecurityState::STSState sts_state;
+ EXPECT_TRUE(state_->GetDynamicSTSState(kDomain, &sts_state));
+ EXPECT_EQ(kDomain, sts_state.domain);
+ EXPECT_FALSE(sts_state.include_subdomains);
+ EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
+ sts_state.upgrade_mode);
+}
+
+TEST_P(TransportSecurityPersisterTest, DeserializeDataOldMergedDictionary) {
+ const char kStsDomain[] = "sts.test";
+ const char kExpectCTDomain[] = "expect_ct.test";
+ const GURL kExpectCTReportUri = GURL("https://expect_ct.test/report_uri");
+ const char kBothDomain[] = "both.test";
+
+ // This is an old-style piece of transport state JSON, which uses a single
+ // unversioned host-keyed dictionary of merged ExpectCT and HSTS data.
+ const std::string kInput =
+ "{"
+ " \"CxLbri+JPdi5pZ8/a/2rjyzq+IYs07WJJ1yxjB4Lpw0=\": {"
+ " \"expect_ct\": {"
+ " \"expect_ct_enforce\": true,"
+ " \"expect_ct_expiry\": 1590512843.283966,"
+ " \"expect_ct_observed\": 1590511843.284064,"
+ " \"expect_ct_report_uri\": \"https://expect_ct.test/report_uri\""
+ " },"
+ " \"expiry\": 0.0,"
+ " \"mode\": \"default\","
+ " \"sts_include_subdomains\": false,"
+ " \"sts_observed\": 0.0"
+ " },"
+ " \"DkgjGShIBmYtgJcJf5lfX3rTr2S6dqyF+O8IAgjuleE=\": {"
+ " \"expiry\": 1590512843.283966,"
+ " \"mode\": \"force-https\","
+ " \"sts_include_subdomains\": false,"
+ " \"sts_observed\": 1590511843.284025"
+ " },"
+ " \"M5lkNV3JBeoPMlKrTOKRYT+mrUsZCS5eoQWsc9/r1MU=\": {"
+ " \"expect_ct\": {"
+ " \"expect_ct_enforce\": true,"
+ " \"expect_ct_expiry\": 1590512843.283966,"
+ " \"expect_ct_observed\": 1590511843.284098,"
+ " \"expect_ct_report_uri\": \"\""
+ " },"
+ " \"expiry\": 1590512843.283966,"
+ " \"mode\": \"force-https\","
+ " \"sts_include_subdomains\": true,"
+ " \"sts_observed\": 1590511843.284091"
+ " }"
+ "}";
+
+ bool data_in_old_format;
+ EXPECT_TRUE(persister_->LoadEntries(kInput, &data_in_old_format));
+ EXPECT_TRUE(data_in_old_format);
+
+ // kStsDomain should only have HSTS information.
+ TransportSecurityState::STSState sts_state;
+ EXPECT_TRUE(state_->GetDynamicSTSState(kStsDomain, &sts_state));
+ EXPECT_EQ(kStsDomain, sts_state.domain);
+ EXPECT_FALSE(sts_state.include_subdomains);
+ EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
+ sts_state.upgrade_mode);
+ EXPECT_LT(base::Time::Now(), sts_state.last_observed);
+ EXPECT_LT(sts_state.last_observed, sts_state.expiry);
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kStsDomain, NetworkIsolationKey(), &expect_ct_state));
+
+ // kExpectCTDomain should only have HSTS information.
+ sts_state = TransportSecurityState::STSState();
+ EXPECT_FALSE(state_->GetDynamicSTSState(kExpectCTDomain, &sts_state));
+ expect_ct_state = TransportSecurityState::ExpectCTState();
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kExpectCTDomain, NetworkIsolationKey(), &expect_ct_state));
+ EXPECT_EQ(kExpectCTReportUri, expect_ct_state.report_uri);
+ EXPECT_TRUE(expect_ct_state.enforce);
+ EXPECT_LT(base::Time::Now(), expect_ct_state.last_observed);
+ EXPECT_LT(expect_ct_state.last_observed, expect_ct_state.expiry);
+
+ // kBothDomain should have HSTS and ExpectCT information.
+ sts_state = TransportSecurityState::STSState();
+ EXPECT_TRUE(state_->GetDynamicSTSState(kBothDomain, &sts_state));
+ EXPECT_EQ(kBothDomain, sts_state.domain);
+ EXPECT_TRUE(sts_state.include_subdomains);
+ EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
+ sts_state.upgrade_mode);
+ EXPECT_LT(base::Time::Now(), sts_state.last_observed);
+ EXPECT_LT(sts_state.last_observed, sts_state.expiry);
+ expect_ct_state = TransportSecurityState::ExpectCTState();
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kBothDomain, NetworkIsolationKey(), &expect_ct_state));
+ EXPECT_TRUE(expect_ct_state.report_uri.is_empty());
+ EXPECT_TRUE(expect_ct_state.enforce);
+ EXPECT_LT(base::Time::Now(), expect_ct_state.last_observed);
+ EXPECT_LT(expect_ct_state.last_observed, expect_ct_state.expiry);
}
// Tests that dynamic Expect-CT state is serialized and deserialized correctly.
-TEST_F(TransportSecurityPersisterTest, ExpectCT) {
+TEST_P(TransportSecurityPersisterTest, ExpectCT) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
@@ -216,32 +352,35 @@ TEST_F(TransportSecurityPersisterTest, ExpectCT) {
TransportSecurityState::ExpectCTState expect_ct_state;
static const char kTestDomain[] = "example.test";
- EXPECT_FALSE(state_.GetDynamicExpectCTState(kTestDomain, &expect_ct_state));
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &expect_ct_state));
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- state_.AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL());
+ state_->AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL(),
+ NetworkIsolationKey());
std::string serialized;
EXPECT_TRUE(persister_->SerializeData(&serialized));
- bool dirty;
+ bool data_in_old_format;
// LoadEntries() clears existing dynamic data before loading entries from
// |serialized|.
- EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
TransportSecurityState::ExpectCTState new_expect_ct_state;
- EXPECT_TRUE(
- state_.GetDynamicExpectCTState(kTestDomain, &new_expect_ct_state));
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &new_expect_ct_state));
EXPECT_TRUE(new_expect_ct_state.enforce);
EXPECT_TRUE(new_expect_ct_state.report_uri.is_empty());
EXPECT_EQ(expiry, new_expect_ct_state.expiry);
// Update the state for the domain and check that it is
// serialized/deserialized correctly.
- state_.AddExpectCT(kTestDomain, expiry, false /* enforce */, report_uri);
+ state_->AddExpectCT(kTestDomain, expiry, false /* enforce */, report_uri,
+ NetworkIsolationKey());
EXPECT_TRUE(persister_->SerializeData(&serialized));
- EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
- EXPECT_TRUE(
- state_.GetDynamicExpectCTState(kTestDomain, &new_expect_ct_state));
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &new_expect_ct_state));
EXPECT_FALSE(new_expect_ct_state.enforce);
EXPECT_EQ(report_uri, new_expect_ct_state.report_uri);
EXPECT_EQ(expiry, new_expect_ct_state.expiry);
@@ -249,7 +388,7 @@ TEST_F(TransportSecurityPersisterTest, ExpectCT) {
// Tests that dynamic Expect-CT state is serialized and deserialized correctly
// when there is also STS data present.
-TEST_F(TransportSecurityPersisterTest, ExpectCTWithSTSDataPresent) {
+TEST_P(TransportSecurityPersisterTest, ExpectCTWithSTSDataPresent) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
@@ -257,36 +396,38 @@ TEST_F(TransportSecurityPersisterTest, ExpectCTWithSTSDataPresent) {
TransportSecurityState::ExpectCTState expect_ct_state;
static const char kTestDomain[] = "example.test";
- EXPECT_FALSE(state_.GetDynamicExpectCTState(kTestDomain, &expect_ct_state));
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &expect_ct_state));
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- state_.AddHSTS(kTestDomain, expiry, false /* include subdomains */);
- state_.AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL());
+ state_->AddHSTS(kTestDomain, expiry, false /* include subdomains */);
+ state_->AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL(),
+ NetworkIsolationKey());
std::string serialized;
EXPECT_TRUE(persister_->SerializeData(&serialized));
- bool dirty;
+ bool data_in_old_format;
// LoadEntries() clears existing dynamic data before loading entries from
// |serialized|.
- EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
TransportSecurityState::ExpectCTState new_expect_ct_state;
- EXPECT_TRUE(
- state_.GetDynamicExpectCTState(kTestDomain, &new_expect_ct_state));
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &new_expect_ct_state));
EXPECT_TRUE(new_expect_ct_state.enforce);
EXPECT_TRUE(new_expect_ct_state.report_uri.is_empty());
EXPECT_EQ(expiry, new_expect_ct_state.expiry);
// Check that STS state is loaded properly as well.
TransportSecurityState::STSState sts_state;
- EXPECT_TRUE(state_.GetDynamicSTSState(kTestDomain, &sts_state, nullptr));
+ EXPECT_TRUE(state_->GetDynamicSTSState(kTestDomain, &sts_state));
EXPECT_EQ(sts_state.upgrade_mode,
TransportSecurityState::STSState::MODE_FORCE_HTTPS);
}
// Tests that Expect-CT state is not serialized and persisted when the feature
// is disabled.
-TEST_F(TransportSecurityPersisterTest, ExpectCTDisabled) {
+TEST_P(TransportSecurityPersisterTest, ExpectCTDisabled) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndDisableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
@@ -294,19 +435,184 @@ TEST_F(TransportSecurityPersisterTest, ExpectCTDisabled) {
TransportSecurityState::ExpectCTState expect_ct_state;
static const char kTestDomain[] = "example.test";
- EXPECT_FALSE(state_.GetDynamicExpectCTState(kTestDomain, &expect_ct_state));
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &expect_ct_state));
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- state_.AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL());
+ state_->AddExpectCT(kTestDomain, expiry, true /* enforce */, GURL(),
+ NetworkIsolationKey());
std::string serialized;
EXPECT_TRUE(persister_->SerializeData(&serialized));
- bool dirty;
- EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
+ bool data_in_old_format;
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
TransportSecurityState::ExpectCTState new_expect_ct_state;
- EXPECT_FALSE(
- state_.GetDynamicExpectCTState(kTestDomain, &new_expect_ct_state));
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kTestDomain, NetworkIsolationKey(), &new_expect_ct_state));
+}
+
+// Save data with several NetworkIsolationKeys with
+// kPartitionExpectCTStateByNetworkIsolationKey enabled, and then load it with
+// the feature enabled or disabled, based on partition_expect_ct_state().
+TEST_P(TransportSecurityPersisterTest, ExpectCTWithNetworkIsolationKey) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ TransportSecurityState::kDynamicExpectCTFeature);
+
+ const GURL report_uri(kReportUri);
+ static const char kTestDomain[] = "example.test";
+ const url::Origin kOrigin =
+ url::Origin::Create(GURL("https://somewhere.else.test"));
+ const NetworkIsolationKey empty_network_isolation_key;
+ const NetworkIsolationKey network_isolation_key(kOrigin /* top_frame_origin*/,
+ kOrigin /* frame_origin*/);
+ const NetworkIsolationKey transient_network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
+
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000);
+ const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000);
+ const base::Time expiry3 = current_time + base::TimeDelta::FromSeconds(3000);
+
+ // Serialize data with kPartitionExpectCTStateByNetworkIsolationKey enabled,
+ // and then revert the feature to its previous value.
+ std::string serialized;
+ {
+ base::test::ScopedFeatureList feature_list2;
+ feature_list2.InitAndEnableFeature(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+ TransportSecurityState state2;
+ TransportSecurityPersister persister2(
+ &state2, temp_dir_.GetPath(),
+ std::move(base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN})));
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ state2.AddExpectCT(kTestDomain, expiry1, true /* enforce */, GURL(),
+ empty_network_isolation_key);
+ state2.AddExpectCT(kTestDomain, expiry2, true /* enforce */, GURL(),
+ network_isolation_key);
+ state2.AddExpectCT(kTestDomain, expiry3, true /* enforce */, GURL(),
+ transient_network_isolation_key);
+ EXPECT_TRUE(persister2.SerializeData(&serialized));
+
+ EXPECT_TRUE(state2.GetDynamicExpectCTState(
+ kTestDomain, empty_network_isolation_key, &expect_ct_state));
+ EXPECT_TRUE(state2.GetDynamicExpectCTState(
+ kTestDomain, network_isolation_key, &expect_ct_state));
+ EXPECT_TRUE(state2.GetDynamicExpectCTState(
+ kTestDomain, transient_network_isolation_key, &expect_ct_state));
+ }
+
+ bool data_in_old_format;
+ // Load entries into the other persister.
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
+
+ if (partition_expect_ct_state()) {
+ TransportSecurityState::ExpectCTState new_expect_ct_state;
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kTestDomain, empty_network_isolation_key, &new_expect_ct_state));
+ EXPECT_TRUE(new_expect_ct_state.enforce);
+ EXPECT_TRUE(new_expect_ct_state.report_uri.is_empty());
+ EXPECT_EQ(expiry1, new_expect_ct_state.expiry);
+
+ EXPECT_TRUE(state_->GetDynamicExpectCTState(
+ kTestDomain, network_isolation_key, &new_expect_ct_state));
+ EXPECT_TRUE(new_expect_ct_state.enforce);
+ EXPECT_TRUE(new_expect_ct_state.report_uri.is_empty());
+ EXPECT_EQ(expiry2, new_expect_ct_state.expiry);
+
+ // The data associated with the transient NetworkIsolationKey should not
+ // have been saved.
+ EXPECT_FALSE(state_->GetDynamicExpectCTState(
+ kTestDomain, transient_network_isolation_key, &new_expect_ct_state));
+ } else {
+ std::set<std::string> expect_ct_saved;
+ TransportSecurityState::ExpectCTStateIterator expect_ct_iter(*state_);
+ ASSERT_TRUE(expect_ct_iter.HasNext());
+ EXPECT_EQ(empty_network_isolation_key,
+ expect_ct_iter.network_isolation_key());
+ EXPECT_TRUE(expect_ct_iter.domain_state().enforce);
+ EXPECT_TRUE(expect_ct_iter.domain_state().report_uri.is_empty());
+ expect_ct_iter.Advance();
+ EXPECT_FALSE(expect_ct_iter.HasNext());
+ }
+}
+
+// Test the case when deserializing a NetworkIsolationKey fails. This happens
+// when data is persisted with kAppendFrameOriginToNetworkIsolationKey, but
+// loaded without it, or vice-versa.
+TEST_P(TransportSecurityPersisterTest,
+ ExpectCTNetworkIsolationKeyDeserializationFails) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ TransportSecurityState::kDynamicExpectCTFeature);
+
+ const GURL report_uri(kReportUri);
+ static const char kTestDomain[] = "example.test";
+ const url::Origin kOrigin =
+ url::Origin::Create(GURL("https://somewhere.else.test"));
+ const NetworkIsolationKey empty_network_isolation_key;
+ const NetworkIsolationKey network_isolation_key(kOrigin /* top_frame_origin*/,
+ kOrigin /* frame_origin*/);
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000);
+ const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000);
+
+ // Serialize data with kPartitionExpectCTStateByNetworkIsolationKey and
+ // kAppendFrameOriginToNetworkIsolationKey enabled, and then revert the
+ // features to their previous values.
+ std::string serialized;
+ {
+ base::test::ScopedFeatureList feature_list2;
+ feature_list2.InitWithFeatures(
+ // enabled_features
+ {features::kPartitionExpectCTStateByNetworkIsolationKey,
+ features::kAppendFrameOriginToNetworkIsolationKey},
+ // disabled_features
+ {});
+ TransportSecurityState state2;
+ TransportSecurityPersister persister2(
+ &state2, temp_dir_.GetPath(),
+ std::move(base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN})));
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ state2.AddExpectCT(kTestDomain, expiry1, true /* enforce */, GURL(),
+ empty_network_isolation_key);
+ state2.AddExpectCT(kTestDomain, expiry2, true /* enforce */, GURL(),
+ network_isolation_key);
+ EXPECT_TRUE(persister2.SerializeData(&serialized));
+
+ EXPECT_TRUE(state2.GetDynamicExpectCTState(
+ kTestDomain, empty_network_isolation_key, &expect_ct_state));
+ EXPECT_TRUE(state2.GetDynamicExpectCTState(
+ kTestDomain, network_isolation_key, &expect_ct_state));
+ }
+
+ base::test::ScopedFeatureList feature_list3;
+ feature_list3.InitAndDisableFeature(
+ features::kAppendFrameOriginToNetworkIsolationKey);
+
+ bool data_in_old_format;
+ // Load entries into the other persister.
+ EXPECT_TRUE(persister_->LoadEntries(serialized, &data_in_old_format));
+ EXPECT_FALSE(data_in_old_format);
+
+ // Regardless of whether kPartitionExpectCTStateByNetworkIsolationKey is
+ // enabled or not, the different kAppendFrameOriginToNetworkIsolationKey state
+ // will cause the entry with a non-empty NetworkIsolationKey to be dropped.
+ std::set<std::string> expect_ct_saved;
+ TransportSecurityState::ExpectCTStateIterator expect_ct_iter(*state_);
+ ASSERT_TRUE(expect_ct_iter.HasNext());
+ EXPECT_EQ(empty_network_isolation_key,
+ expect_ct_iter.network_isolation_key());
+ EXPECT_TRUE(expect_ct_iter.domain_state().enforce);
+ EXPECT_TRUE(expect_ct_iter.domain_state().report_uri.is_empty());
+ expect_ct_iter.Advance();
+ EXPECT_FALSE(expect_ct_iter.HasNext());
}
} // namespace
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index 29ee1e2ffa0..f7b7de2f277 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -4,7 +4,9 @@
#include "net/http/transport_security_state.h"
+#include <algorithm>
#include <memory>
+#include <tuple>
#include <utility>
#include <vector>
@@ -12,6 +14,7 @@
#include "base/bind.h"
#include "base/build_time.h"
#include "base/containers/span.h"
+#include "base/feature_list.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
@@ -28,6 +31,7 @@
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "crypto/sha2.h"
+#include "net/base/features.h"
#include "net/base/hash_value.h"
#include "net/base/host_port_pair.h"
#include "net/cert/ct_policy_status.h"
@@ -207,7 +211,7 @@ std::string HashesToBase64String(const HashValueVector& hashes) {
return str;
}
-std::string HashHost(const std::string& canonicalized_host) {
+std::string HashHost(base::StringPiece canonicalized_host) {
char hashed[crypto::kSHA256Length];
crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
return std::string(hashed, sizeof(hashed));
@@ -392,29 +396,6 @@ bool DecodeHSTSPreload(const std::string& search_hostname, PreloadResult* out) {
return found;
}
-// Records a histogram for details on the HSTS status of a host. |enabled| is
-// true if the host had HSTS enabled when considering both the preload list and
-// the current dynamic implementation and false otherwise. |should_be_dynamic|
-// is true if the current dynamic implementation reported host did not have HSTS
-// enabled, but a spec-compliant implementation would have reported it enabled.
-// Note both parameters may be true, in which case the spec non-compliance was
-// masked by the HSTS preload list.
-//
-// See https://crbug.com/821811.
-void RecordHstsInfo(bool enabled, bool should_be_dynamic) {
- HstsInfo info;
- if (enabled) {
- info = should_be_dynamic
- ? HstsInfo::kDynamicIncorrectlyMaskedButMatchedStatic
- : HstsInfo::kEnabled;
- } else {
- info = should_be_dynamic ? HstsInfo::kDynamicIncorrectlyMasked
- : HstsInfo::kDisabled;
- }
-
- UMA_HISTOGRAM_ENUMERATION("Net.HstsInfo", info);
-}
-
} // namespace
// static
@@ -435,7 +416,9 @@ TransportSecurityState::TransportSecurityState(
enable_static_expect_ct_(true),
enable_pkp_bypass_for_local_trust_anchors_(true),
sent_hpkp_reports_cache_(kMaxReportCacheEntries),
- sent_expect_ct_reports_cache_(kMaxReportCacheEntries) {
+ sent_expect_ct_reports_cache_(kMaxReportCacheEntries),
+ key_expect_ct_by_nik_(base::FeatureList::IsEnabled(
+ features::kPartitionExpectCTStateByNetworkIsolationKey)) {
// Static pinning is only enabled for official builds to make sure that
// others don't end up with pins that cannot be easily updated.
#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || defined(OS_ANDROID) || defined(OS_IOS)
@@ -455,13 +438,9 @@ TransportSecurityState::TransportSecurityState(
bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) {
STSState unused_sts;
PKPState unused_pkp;
- // Query GetDynamicSTSState() first to set |sts_should_be_dynamic|.
- bool sts_should_be_dynamic = false;
- bool ret = GetDynamicSTSState(host, &unused_sts, &sts_should_be_dynamic) ||
- GetDynamicPKPState(host, &unused_pkp) ||
- GetStaticDomainState(host, &unused_sts, &unused_pkp);
- RecordHstsInfo(ret, sts_should_be_dynamic);
- return ret;
+ return GetDynamicSTSState(host, &unused_sts) ||
+ GetDynamicPKPState(host, &unused_pkp) ||
+ GetStaticDomainState(host, &unused_sts, &unused_pkp);
}
bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) {
@@ -512,7 +491,8 @@ TransportSecurityState::CheckCTRequirements(
const SignedCertificateTimestampAndStatusList&
signed_certificate_timestamps,
const ExpectCTReportStatus report_status,
- ct::CTPolicyCompliance policy_compliance) {
+ ct::CTPolicyCompliance policy_compliance,
+ const NetworkIsolationKey& network_isolation_key) {
using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
std::string hostname = host_port_pair.host();
@@ -535,16 +515,17 @@ TransportSecurityState::CheckCTRequirements(
// Expect-CT reports from being sent.
bool required_via_expect_ct = false;
ExpectCTState state;
- if (IsDynamicExpectCTEnabled() && GetDynamicExpectCTState(hostname, &state)) {
+ if (IsDynamicExpectCTEnabled() &&
+ GetDynamicExpectCTState(hostname, network_isolation_key, &state)) {
UMA_HISTOGRAM_ENUMERATION(
"Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup",
policy_compliance, ct::CTPolicyCompliance::CT_POLICY_COUNT);
if (!complies && expect_ct_reporter_ && !state.report_uri.is_empty() &&
report_status == ENABLE_EXPECT_CT_REPORTS) {
- MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri, state.expiry,
- validated_certificate_chain,
- served_certificate_chain,
- signed_certificate_timestamps);
+ MaybeNotifyExpectCTFailed(
+ host_port_pair, state.report_uri, state.expiry,
+ validated_certificate_chain, served_certificate_chain,
+ signed_certificate_timestamps, network_isolation_key);
}
required_via_expect_ct = state.enforce;
}
@@ -658,14 +639,28 @@ void TransportSecurityState::AddHSTSInternal(
const base::Time& expiry,
bool include_subdomains) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ if (canonicalized_host.empty())
+ return;
STSState sts_state;
+ // No need to store |sts_state.domain| since it is redundant.
+ // (|canonicalized_host| is the map key.)
sts_state.last_observed = base::Time::Now();
sts_state.include_subdomains = include_subdomains;
sts_state.expiry = expiry;
sts_state.upgrade_mode = upgrade_mode;
- EnableSTSHost(host, sts_state);
+ // Only store new state when HSTS is explicitly enabled. If it is
+ // disabled, remove the state from the enabled hosts.
+ if (sts_state.ShouldUpgradeToSSL()) {
+ enabled_sts_hosts_[HashHost(canonicalized_host)] = sts_state;
+ } else {
+ const std::string hashed_host = HashHost(canonicalized_host);
+ enabled_sts_hosts_.erase(hashed_host);
+ }
+
+ DirtyNotify();
}
void TransportSecurityState::AddHPKPInternal(const std::string& host,
@@ -675,80 +670,22 @@ void TransportSecurityState::AddHPKPInternal(const std::string& host,
const HashValueVector& hashes,
const GURL& report_uri) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ const std::string canonicalized_host = CanonicalizeHost(host);
+ if (canonicalized_host.empty())
+ return;
PKPState pkp_state;
+ // No need to store |pkp_state.domain| since it is redundant.
+ // (|canonicalized_host| is the map key.)
pkp_state.last_observed = last_observed;
pkp_state.expiry = expiry;
pkp_state.include_subdomains = include_subdomains;
pkp_state.spki_hashes = hashes;
pkp_state.report_uri = report_uri;
- EnablePKPHost(host, pkp_state);
-}
-
-void TransportSecurityState::AddExpectCTInternal(
- const std::string& host,
- const base::Time& last_observed,
- const base::Time& expiry,
- bool enforce,
- const GURL& report_uri) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- ExpectCTState expect_ct_state;
- expect_ct_state.last_observed = last_observed;
- expect_ct_state.expiry = expiry;
- expect_ct_state.enforce = enforce;
- expect_ct_state.report_uri = report_uri;
-
- EnableExpectCTHost(host, expect_ct_state);
-}
-
-void TransportSecurityState::
- SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) {
- enable_pkp_bypass_for_local_trust_anchors_ = value;
-}
-
-void TransportSecurityState::EnableSTSHost(const std::string& host,
- const STSState& state) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- const std::string canonicalized_host = CanonicalizeHost(host);
- if (canonicalized_host.empty())
- return;
-
- // Only store new state when HSTS is explicitly enabled. If it is
- // disabled, remove the state from the enabled hosts.
- if (state.ShouldUpgradeToSSL()) {
- STSState sts_state(state);
- // No need to store this value since it is redundant. (|canonicalized_host|
- // is the map key.)
- sts_state.domain.clear();
-
- enabled_sts_hosts_[HashHost(canonicalized_host)] = sts_state;
- } else {
- const std::string hashed_host = HashHost(canonicalized_host);
- enabled_sts_hosts_.erase(hashed_host);
- }
-
- DirtyNotify();
-}
-
-void TransportSecurityState::EnablePKPHost(const std::string& host,
- const PKPState& state) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- const std::string canonicalized_host = CanonicalizeHost(host);
- if (canonicalized_host.empty())
- return;
-
// Only store new state when HPKP is explicitly enabled. If it is
// disabled, remove the state from the enabled hosts.
- if (state.HasPublicKeyPins()) {
- PKPState pkp_state(state);
- // No need to store this value since it is redundant. (|canonicalized_host|
- // is the map key.)
- pkp_state.domain.clear();
-
+ if (pkp_state.HasPublicKeyPins()) {
enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state;
} else {
const std::string hashed_host = HashHost(canonicalized_host);
@@ -758,8 +695,13 @@ void TransportSecurityState::EnablePKPHost(const std::string& host,
DirtyNotify();
}
-void TransportSecurityState::EnableExpectCTHost(const std::string& host,
- const ExpectCTState& state) {
+void TransportSecurityState::AddExpectCTInternal(
+ const std::string& host,
+ const base::Time& last_observed,
+ const base::Time& expiry,
+ bool enforce,
+ const GURL& report_uri,
+ const NetworkIsolationKey& network_isolation_key) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!IsDynamicExpectCTEnabled())
return;
@@ -768,23 +710,33 @@ void TransportSecurityState::EnableExpectCTHost(const std::string& host,
if (canonicalized_host.empty())
return;
+ ExpectCTState expect_ct_state;
+ // No need to store |expect_ct_state.domain| since it is redundant.
+ // (|canonicalized_host| is the map key.)
+ expect_ct_state.last_observed = last_observed;
+ expect_ct_state.expiry = expiry;
+ expect_ct_state.enforce = enforce;
+ expect_ct_state.report_uri = report_uri;
+
// Only store new state when Expect-CT is explicitly enabled. If it is
// disabled, remove the state from the enabled hosts.
- if (state.enforce || !state.report_uri.is_empty()) {
- ExpectCTState expect_ct_state(state);
- // No need to store this value since it is redundant. (|canonicalized_host|
- // is the map key.)
- expect_ct_state.domain.clear();
-
- enabled_expect_ct_hosts_[HashHost(canonicalized_host)] = expect_ct_state;
+ ExpectCTStateIndex index = CreateExpectCTStateIndex(
+ HashHost(canonicalized_host), network_isolation_key);
+ if (expect_ct_state.enforce || !expect_ct_state.report_uri.is_empty()) {
+ enabled_expect_ct_hosts_[index] = expect_ct_state;
+ MaybePruneExpectCTState();
} else {
- const std::string hashed_host = HashHost(canonicalized_host);
- enabled_expect_ct_hosts_.erase(hashed_host);
+ enabled_expect_ct_hosts_.erase(index);
}
DirtyNotify();
}
+void TransportSecurityState::
+ SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) {
+ enable_pkp_bypass_for_local_trust_anchors_ = value;
+}
+
TransportSecurityState::PKPStatus
TransportSecurityState::CheckPinsAndMaybeSendReport(
const HostPortPair& host_port_pair,
@@ -855,7 +807,6 @@ bool TransportSecurityState::GetStaticExpectCTState(
if (!enable_static_expect_ct_ || !result.expect_ct)
return false;
- expect_ct_state->domain = host.substr(result.hostname_offset);
expect_ct_state->report_uri = GURL(
g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]);
return true;
@@ -868,7 +819,8 @@ void TransportSecurityState::MaybeNotifyExpectCTFailed(
const X509Certificate* validated_certificate_chain,
const X509Certificate* served_certificate_chain,
const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps) {
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) {
// Do not send repeated reports to the same host/port pair within
// |kTimeToRememberReportsMins|. Theoretically, there could be scenarios in
// which the same host/port generates different reports and it would be useful
@@ -886,7 +838,8 @@ void TransportSecurityState::MaybeNotifyExpectCTFailed(
expect_ct_reporter_->OnExpectCTFailed(
host_port_pair, report_uri, expiration, validated_certificate_chain,
- served_certificate_chain, signed_certificate_timestamps);
+ served_certificate_chain, signed_certificate_timestamps,
+ network_isolation_key);
}
bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
@@ -910,9 +863,16 @@ bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
deleted = true;
}
- auto expect_ct_iterator = enabled_expect_ct_hosts_.find(hashed_host);
- if (expect_ct_iterator != enabled_expect_ct_hosts_.end()) {
- enabled_expect_ct_hosts_.erase(expect_ct_iterator);
+ // Delete matching entries for all NetworkIsolationKeys. Performance isn't
+ // important here, since this is only called when directly initiated by the
+ // user, so a linear search is fine.
+ for (auto it = enabled_expect_ct_hosts_.begin();
+ it != enabled_expect_ct_hosts_.end();) {
+ auto current = it;
+ ++it;
+ if (current->first.hashed_host != hashed_host)
+ continue;
+ enabled_expect_ct_hosts_.erase(current);
deleted = true;
}
@@ -1024,18 +984,22 @@ void TransportSecurityState::AddHPKP(const std::string& host,
report_uri);
}
-void TransportSecurityState::AddExpectCT(const std::string& host,
- const base::Time& expiry,
- bool enforce,
- const GURL& report_uri) {
+void TransportSecurityState::AddExpectCT(
+ const std::string& host,
+ const base::Time& expiry,
+ bool enforce,
+ const GURL& report_uri,
+ const NetworkIsolationKey& network_isolation_key) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- AddExpectCTInternal(host, base::Time::Now(), expiry, enforce, report_uri);
+ AddExpectCTInternal(host, base::Time::Now(), expiry, enforce, report_uri,
+ network_isolation_key);
}
void TransportSecurityState::ProcessExpectCTHeader(
const std::string& value,
const HostPortPair& host_port_pair,
- const SSLInfo& ssl_info) {
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// If a site sends `Expect-CT: preload` and appears on the preload list, they
@@ -1057,10 +1021,10 @@ void TransportSecurityState::ProcessExpectCTHeader(
}
ExpectCTState state;
if (GetStaticExpectCTState(host_port_pair.host(), &state)) {
- MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri, base::Time(),
- ssl_info.cert.get(),
- ssl_info.unverified_cert.get(),
- ssl_info.signed_certificate_timestamps);
+ MaybeNotifyExpectCTFailed(
+ host_port_pair, state.report_uri, base::Time(), ssl_info.cert.get(),
+ ssl_info.unverified_cert.get(),
+ ssl_info.signed_certificate_timestamps, network_isolation_key);
}
return;
}
@@ -1104,16 +1068,17 @@ void TransportSecurityState::ProcessExpectCTHeader(
}
ExpectCTState state;
if (expect_ct_reporter_ && !report_uri.is_empty() &&
- !GetDynamicExpectCTState(host_port_pair.host(), &state)) {
- MaybeNotifyExpectCTFailed(host_port_pair, report_uri, base::Time(),
- ssl_info.cert.get(),
- ssl_info.unverified_cert.get(),
- ssl_info.signed_certificate_timestamps);
+ !GetDynamicExpectCTState(host_port_pair.host(), network_isolation_key,
+ &state)) {
+ MaybeNotifyExpectCTFailed(
+ host_port_pair, report_uri, base::Time(), ssl_info.cert.get(),
+ ssl_info.unverified_cert.get(),
+ ssl_info.signed_certificate_timestamps, network_isolation_key);
}
return;
}
AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce,
- report_uri);
+ report_uri, network_isolation_key);
}
// static
@@ -1126,6 +1091,10 @@ void TransportSecurityState::ClearReportCachesForTesting() {
sent_expect_ct_reports_cache_.Clear();
}
+size_t TransportSecurityState::num_expect_ct_entries() const {
+ return enabled_expect_ct_hosts_.size();
+}
+
// static
bool TransportSecurityState::IsBuildTimely() {
const base::Time build_time = base::GetBuildTime();
@@ -1209,11 +1178,8 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
bool TransportSecurityState::GetSTSState(const std::string& host,
STSState* result) {
PKPState unused;
- bool should_be_dynamic = false;
- bool ret = GetDynamicSTSState(host, result, &should_be_dynamic) ||
- GetStaticDomainState(host, result, &unused);
- RecordHstsInfo(ret, should_be_dynamic);
- return ret;
+ return GetDynamicSTSState(host, result) ||
+ GetStaticDomainState(host, result, &unused);
}
bool TransportSecurityState::GetPKPState(const std::string& host,
@@ -1224,22 +1190,18 @@ bool TransportSecurityState::GetPKPState(const std::string& host,
}
bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
- STSState* result,
- bool* should_be_dynamic) {
+ STSState* result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (should_be_dynamic)
- *should_be_dynamic = false;
const std::string canonicalized_host = CanonicalizeHost(host);
if (canonicalized_host.empty())
return false;
base::Time current_time(base::Time::Now());
- bool first_match = true;
for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
- std::string host_sub_chunk(&canonicalized_host[i],
- canonicalized_host.size() - i);
+ base::StringPiece host_sub_chunk =
+ base::StringPiece(canonicalized_host).substr(i);
auto j = enabled_sts_hosts_.find(HashHost(host_sub_chunk));
if (j == enabled_sts_hosts_.end())
continue;
@@ -1251,27 +1213,13 @@ bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
continue;
}
- // If this is the most specific STS match, add it to the result. Note: a STS
- // entry at a more specific domain overrides a less specific domain whether
- // or not |include_subdomains| is set.
+ // An entry matches if it is either an exact match, or if it is a prefix
+ // match and the includeSubDomains directive was included.
if (i == 0 || j->second.include_subdomains) {
- // TransportSecurityState considers a more specific non-includeSubDomains
- // entry to override a less specific includeSubDomain entry. This does not
- // match the specification and results in confusing behavior, so evaluate
- // both versions for histogramming purposes.
- if (!first_match) {
- if (should_be_dynamic)
- *should_be_dynamic = true;
- // No need to continue iterating.
- break;
- }
-
*result = j->second;
result->domain = DNSDomainToString(host_sub_chunk);
return true;
}
-
- first_match = false;
}
return false;
@@ -1288,8 +1236,8 @@ bool TransportSecurityState::GetDynamicPKPState(const std::string& host,
base::Time current_time(base::Time::Now());
for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
- std::string host_sub_chunk(&canonicalized_host[i],
- canonicalized_host.size() - i);
+ base::StringPiece host_sub_chunk =
+ base::StringPiece(canonicalized_host).substr(i);
auto j = enabled_pkp_hosts_.find(HashHost(host_sub_chunk));
if (j == enabled_pkp_hosts_.end())
continue;
@@ -1304,6 +1252,10 @@ bool TransportSecurityState::GetDynamicPKPState(const std::string& host,
// If this is the most specific PKP match, add it to the result. Note: a PKP
// entry at a more specific domain overrides a less specific domain whether
// or not |include_subdomains| is set.
+ //
+ // TODO(davidben): This does not match the HSTS behavior. We no longer
+ // implement HPKP, so this logic is only used via AddHPKP(), reachable from
+ // Cronet.
if (i == 0 || j->second.include_subdomains) {
*result = j->second;
result->domain = DNSDomainToString(host_sub_chunk);
@@ -1316,8 +1268,10 @@ bool TransportSecurityState::GetDynamicPKPState(const std::string& host,
return false;
}
-bool TransportSecurityState::GetDynamicExpectCTState(const std::string& host,
- ExpectCTState* result) {
+bool TransportSecurityState::GetDynamicExpectCTState(
+ const std::string& host,
+ const NetworkIsolationKey& network_isolation_key,
+ ExpectCTState* result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
const std::string canonicalized_host = CanonicalizeHost(host);
@@ -1325,7 +1279,8 @@ bool TransportSecurityState::GetDynamicExpectCTState(const std::string& host,
return false;
base::Time current_time(base::Time::Now());
- auto j = enabled_expect_ct_hosts_.find(HashHost(canonicalized_host));
+ auto j = enabled_expect_ct_hosts_.find(CreateExpectCTStateIndex(
+ HashHost(canonicalized_host), network_isolation_key));
if (j == enabled_expect_ct_hosts_.end())
return false;
// If the entry is invalid, drop it.
@@ -1349,10 +1304,12 @@ void TransportSecurityState::AddOrUpdateEnabledSTSHosts(
void TransportSecurityState::AddOrUpdateEnabledExpectCTHosts(
const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key,
const ExpectCTState& state) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(state.enforce || !state.report_uri.is_empty());
- enabled_expect_ct_hosts_[hashed_host] = state;
+ enabled_expect_ct_hosts_[CreateExpectCTStateIndex(
+ hashed_host, network_isolation_key)] = state;
}
TransportSecurityState::STSState::STSState()
@@ -1384,6 +1341,15 @@ TransportSecurityState::ExpectCTState::ExpectCTState() : enforce(false) {}
TransportSecurityState::ExpectCTState::~ExpectCTState() = default;
+TransportSecurityState::ExpectCTStateIndex::ExpectCTStateIndex(
+ const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key,
+ bool respect_network_isolation_keyn_key)
+ : hashed_host(hashed_host),
+ network_isolation_key(respect_network_isolation_keyn_key
+ ? network_isolation_key
+ : NetworkIsolationKey()) {}
+
TransportSecurityState::ExpectCTStateIterator::ExpectCTStateIterator(
const TransportSecurityState& state)
: iterator_(state.enabled_expect_ct_hosts_.begin()),
@@ -1433,4 +1399,140 @@ bool TransportSecurityState::PKPState::HasPublicKeyPins() const {
return spki_hashes.size() > 0 || bad_spki_hashes.size() > 0;
}
+TransportSecurityState::ExpectCTStateIndex
+TransportSecurityState::CreateExpectCTStateIndex(
+ const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key) {
+ return ExpectCTStateIndex(hashed_host, network_isolation_key,
+ key_expect_ct_by_nik_);
+}
+
+void TransportSecurityState::MaybePruneExpectCTState() {
+ if (!base::FeatureList::IsEnabled(features::kExpectCTPruning) ||
+ enabled_expect_ct_hosts_.size() <
+ static_cast<size_t>(features::kExpectCTPruneMax.Get())) {
+ return;
+ }
+
+ base::Time now = base::Time::Now();
+ if (now < earliest_next_prune_expect_ct_time_)
+ return;
+
+ earliest_next_prune_expect_ct_time_ =
+ now +
+ base::TimeDelta::FromSeconds(features::kExpectCTPruneDelaySecs.Get());
+
+ base::Time last_prunable_observation_time =
+ now -
+ base::TimeDelta::FromDays(features::kExpectCTSafeFromPruneDays.Get());
+
+ // Cache this locally, so don't have to repeatedly query the value.
+ size_t expect_ct_prune_min = features::kExpectCTPruneMin.Get();
+
+ // Entries that are eligible to be pruned based on the global (not per-NIK)
+ // entry limit.
+ std::vector<ExpectCTStateMap::iterator> prunable_expect_ct_entries;
+
+ // Clear expired entries first. If that's enough, maybe no valid entries have
+ // to be removed. Also populate |prunable_expect_ct_entries|.
+ for (auto expect_ct_iterator = enabled_expect_ct_hosts_.begin();
+ expect_ct_iterator != enabled_expect_ct_hosts_.end();) {
+ if (expect_ct_iterator->second.expiry < now) {
+ enabled_expect_ct_hosts_.erase(expect_ct_iterator++);
+ continue;
+ }
+
+ // If there are fewer than |expect_ct_prune_min| entries remaining, no need
+ // to delete anything else.
+ if (enabled_expect_ct_hosts_.size() <= expect_ct_prune_min)
+ return;
+
+ // Entries that are older than the prunable time window, are report-only, or
+ // have a transient NetworkIsolationKey, are considered prunable.
+ //
+ // If |key_expect_ct_by_nik_| is false, all entries have an empty NIK.
+ // IsTransient() returns true for the empty NIK, despite entries being saved
+ // to disk, so don't want to delete entries with empty NIKs.
+ if (expect_ct_iterator->second.last_observed <
+ last_prunable_observation_time ||
+ !expect_ct_iterator->second.enforce ||
+ (key_expect_ct_by_nik_ &&
+ expect_ct_iterator->first.network_isolation_key.IsTransient())) {
+ prunable_expect_ct_entries.push_back(expect_ct_iterator);
+ }
+ ++expect_ct_iterator;
+ }
+
+ // Number of entries that need to be removed to reach |expect_ct_prune_min|.
+ size_t num_entries_to_prune =
+ enabled_expect_ct_hosts_.size() - expect_ct_prune_min;
+ if (num_entries_to_prune < prunable_expect_ct_entries.size()) {
+ // There are more than enough prunable entries to reach kExpectCTPruneMin.
+ // Find the |num_entries_to_prune| most prunable entries, according to
+ // ExpectCTPruningSorter.
+ auto expect_ct_prune_end =
+ prunable_expect_ct_entries.begin() + num_entries_to_prune;
+ std::partial_sort(prunable_expect_ct_entries.begin(), expect_ct_prune_end,
+ prunable_expect_ct_entries.end(), ExpectCTPruningSorter);
+ } else {
+ // Otherwise, delete all prunable entries.
+ num_entries_to_prune = prunable_expect_ct_entries.size();
+ }
+ DCHECK_LE(num_entries_to_prune, prunable_expect_ct_entries.size());
+
+ for (size_t i = 0; i < num_entries_to_prune; ++i) {
+ enabled_expect_ct_hosts_.erase(prunable_expect_ct_entries[i]);
+ }
+
+ // If there are fewer than |kExpectCTPruneMin| entries remaining, or entries
+ // are not being keyed by NetworkIsolationKey, nothing left to do.
+ if (enabled_expect_ct_hosts_.size() <= expect_ct_prune_min ||
+ !key_expect_ct_by_nik_) {
+ return;
+ }
+
+ // Otherwise, cap the number of entries per NetworkIsolationKey to
+ // |kMaxEntriesPerNik|.
+
+ // Create a vector of all the ExpectCT entries for each NIK.
+ std::map<net::NetworkIsolationKey, std::vector<ExpectCTStateMap::iterator>>
+ nik_map;
+ for (auto expect_ct_iterator = enabled_expect_ct_hosts_.begin();
+ expect_ct_iterator != enabled_expect_ct_hosts_.end();
+ ++expect_ct_iterator) {
+ nik_map[expect_ct_iterator->first.network_isolation_key].push_back(
+ expect_ct_iterator);
+ }
+
+ // For each NIK with more than the maximum number of entries, remove the most
+ // prunable entries until it has exactly |kExpectCTMaxEntriesPerNik| entries.
+ size_t max_entries_per_nik = features::kExpectCTMaxEntriesPerNik.Get();
+ for (auto& nik_entries : nik_map) {
+ if (nik_entries.second.size() < max_entries_per_nik)
+ continue;
+ auto top_frame_origin_prune_end = nik_entries.second.begin() +
+ nik_entries.second.size() -
+ max_entries_per_nik;
+ std::partial_sort(nik_entries.second.begin(), top_frame_origin_prune_end,
+ nik_entries.second.end(), ExpectCTPruningSorter);
+ for (auto entry_to_prune = nik_entries.second.begin();
+ entry_to_prune != top_frame_origin_prune_end; ++entry_to_prune) {
+ enabled_expect_ct_hosts_.erase(*entry_to_prune);
+ }
+ }
+}
+
+bool TransportSecurityState::ExpectCTPruningSorter(
+ const ExpectCTStateMap::iterator& it1,
+ const ExpectCTStateMap::iterator& it2) {
+ // std::tie requires r-values, so have to put these on the stack to use
+ // std::tie.
+ bool is_not_transient1 = !it1->first.network_isolation_key.IsTransient();
+ bool is_not_transient2 = !it2->first.network_isolation_key.IsTransient();
+ return std::tie(is_not_transient1, it1->second.enforce,
+ it1->second.last_observed) <
+ std::tie(is_not_transient2, it2->second.enforce,
+ it2->second.last_observed);
+}
+
} // namespace net
diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h
index b54581d4a2e..ba863bd6bae 100644
--- a/chromium/net/http/transport_security_state.h
+++ b/chromium/net/http/transport_security_state.h
@@ -20,6 +20,7 @@
#include "net/base/expiring_cache.h"
#include "net/base/hash_value.h"
#include "net/base/net_export.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/http/transport_security_state_source.h"
#include "url/gurl.h"
@@ -31,6 +32,7 @@ enum class CTPolicyCompliance;
}
class HostPortPair;
+class NetworkIsolationKey;
class SSLInfo;
class X509Certificate;
@@ -232,8 +234,6 @@ class NET_EXPORT TransportSecurityState {
ExpectCTState();
~ExpectCTState();
- // The domain which matched during a search for this DomainState entry.
- std::string domain;
// The URI to which reports should be sent if valid CT info is not
// provided.
GURL report_uri;
@@ -247,6 +247,30 @@ class NET_EXPORT TransportSecurityState {
base::Time expiry;
};
+ // Unlike other data, Expect-CT information is indexed by NetworkIsolationKey
+ // in addition to domain hash, to prevent leaking user IDs across different
+ // first party contexts. Public only because ExpectCTStateIterator is public
+ // and depends on it.
+ struct ExpectCTStateIndex {
+ // Creates an ExpectCTStateIndex. Uses an empty NetworkIsolationKey instead
+ // of the passed in one, depending on |respect_network_isolation_key|.
+ // The value of features::kPartitionExpectCTStateByNetworkIsolationKey is
+ // cached on creation of the TransportSecurityState, and then passed in to
+ // this method whenever an ExpectCTStateIndex() is created, to avoid
+ // constantly querying the field trial.
+ ExpectCTStateIndex(const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key,
+ bool respect_network_isolation_key);
+
+ bool operator<(const ExpectCTStateIndex& other) const {
+ return std::tie(hashed_host, network_isolation_key) <
+ std::tie(other.hashed_host, other.network_isolation_key);
+ }
+
+ std::string hashed_host;
+ NetworkIsolationKey network_isolation_key;
+ };
+
class NET_EXPORT ExpectCTStateIterator {
public:
explicit ExpectCTStateIterator(const TransportSecurityState& state);
@@ -254,12 +278,15 @@ class NET_EXPORT TransportSecurityState {
bool HasNext() const { return iterator_ != end_; }
void Advance() { ++iterator_; }
- const std::string& hostname() const { return iterator_->first; }
+ const std::string& hostname() const { return iterator_->first.hashed_host; }
+ const NetworkIsolationKey& network_isolation_key() const {
+ return iterator_->first.network_isolation_key;
+ }
const ExpectCTState& domain_state() const { return iterator_->second; }
private:
- std::map<std::string, ExpectCTState>::const_iterator iterator_;
- std::map<std::string, ExpectCTState>::const_iterator end_;
+ std::map<ExpectCTStateIndex, ExpectCTState>::const_iterator iterator_;
+ std::map<ExpectCTStateIndex, ExpectCTState>::const_iterator end_;
};
// An interface for asynchronously sending HPKP violation reports.
@@ -301,7 +328,8 @@ class NET_EXPORT TransportSecurityState {
const X509Certificate* validated_certificate_chain,
const X509Certificate* served_certificate_chain,
const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps) = 0;
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) = 0;
protected:
virtual ~ExpectCTReporter() {}
@@ -383,7 +411,8 @@ class NET_EXPORT TransportSecurityState {
const SignedCertificateTimestampAndStatusList&
signed_certificate_timestamps,
const ExpectCTReportStatus report_status,
- ct::CTPolicyCompliance policy_compliance);
+ ct::CTPolicyCompliance policy_compliance,
+ const NetworkIsolationKey& network_isolation_key);
// Assign a |Delegate| for persisting the transport security state. If
// |NULL|, state will not be persisted. The caller retains
@@ -425,8 +454,10 @@ class NET_EXPORT TransportSecurityState {
// |hashed_host|. |hashed_host| is already in the internal representation.
// Note: This is only used for serializing/deserializing the
// TransportSecurityState.
- void AddOrUpdateEnabledExpectCTHosts(const std::string& hashed_host,
- const ExpectCTState& state);
+ void AddOrUpdateEnabledExpectCTHosts(
+ const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key,
+ const ExpectCTState& state);
// Deletes all dynamic data (e.g. HSTS or HPKP data) created since a given
// time.
@@ -465,19 +496,15 @@ class NET_EXPORT TransportSecurityState {
// Returns true and updates |*result| iff |host| has dynamic
// HSTS/HPKP/Expect-CT (respectively) state. If multiple entries match |host|,
- // the most specific match determines the return value. |*should_be_dynamic|
- // is set to true if |host| has no dynamic HSTS state based on the current
- // implementation but would have it based on a spec-compliant implementation.
- // See https://crbug.com/821811. |should_be_dynamic| may be nullptr to ignore
- // the output.
+ // the most specific match determines the return value.
//
// Note that these methods are not const because they opportunistically remove
// entries that have expired.
- bool GetDynamicSTSState(const std::string& host,
- STSState* result,
- bool* should_be_dynamic);
+ bool GetDynamicSTSState(const std::string& host, STSState* result);
bool GetDynamicPKPState(const std::string& host, PKPState* result);
- bool GetDynamicExpectCTState(const std::string& host, ExpectCTState* result);
+ bool GetDynamicExpectCTState(const std::string& host,
+ const NetworkIsolationKey& network_isolation_key,
+ ExpectCTState* result);
// Processes an HSTS header value from the host, adding entries to
// dynamic state if necessary.
@@ -505,7 +532,8 @@ class NET_EXPORT TransportSecurityState {
void AddExpectCT(const std::string& host,
const base::Time& expiry,
bool enforce,
- const GURL& report_uri);
+ const GURL& report_uri,
+ const NetworkIsolationKey& network_isolation_key);
// Enables or disables public key pinning bypass for local trust anchors.
// Disabling the bypass for local trust anchors is highly discouraged.
@@ -527,7 +555,8 @@ class NET_EXPORT TransportSecurityState {
// connection is not CT-compliant, then a report will be sent.
void ProcessExpectCTHeader(const std::string& value,
const HostPortPair& host_port_pair,
- const SSLInfo& ssl_info);
+ const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key);
void AssertCalledOnValidThread() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -545,6 +574,9 @@ class NET_EXPORT TransportSecurityState {
void EnableStaticPinsForTesting() { enable_static_pins_ = true; }
bool has_dynamic_pkp_state() const { return !enabled_pkp_hosts_.empty(); }
+ // The number of cached ExpectCTState entries.
+ size_t num_expect_ct_entries() const;
+
private:
friend class TransportSecurityStateTest;
friend class TransportSecurityStateStaticFuzzer;
@@ -553,7 +585,7 @@ class NET_EXPORT TransportSecurityState {
typedef std::map<std::string, STSState> STSStateMap;
typedef std::map<std::string, PKPState> PKPStateMap;
- typedef std::map<std::string, ExpectCTState> ExpectCTStateMap;
+ typedef std::map<ExpectCTStateIndex, ExpectCTState> ExpectCTStateMap;
typedef ExpiringCache<std::string,
bool,
base::TimeTicks,
@@ -579,34 +611,26 @@ class NET_EXPORT TransportSecurityState {
// changed.
void DirtyNotify();
- // Adds HSTS state to |host|.
+ // Adds HSTS, HPKP, and Expect-CT state for |host|. The new state supercedes
+ // any previous state for the |host|, including static entries.
+ //
+ // The new state for |host| is persisted using the Delegate (if any).
void AddHSTSInternal(const std::string& host,
STSState::UpgradeMode upgrade_mode,
const base::Time& expiry,
bool include_subdomains);
-
- // Adds HPKP state to |host|.
void AddHPKPInternal(const std::string& host,
const base::Time& last_observed,
const base::Time& expiry,
bool include_subdomains,
const HashValueVector& hashes,
const GURL& report_uri);
-
- // Adds Expect-CT state to |host|.
void AddExpectCTInternal(const std::string& host,
const base::Time& last_observed,
const base::Time& expiry,
bool enforce,
- const GURL& report_uri);
-
- // Enable TransportSecurity for |host|. |state| supercedes any previous
- // state for the |host|, including static entries.
- //
- // The new state for |host| is persisted using the Delegate (if any).
- void EnableSTSHost(const std::string& host, const STSState& state);
- void EnablePKPHost(const std::string& host, const PKPState& state);
- void EnableExpectCTHost(const std::string& host, const ExpectCTState& state);
+ const GURL& report_uri,
+ const NetworkIsolationKey& network_isolation_key);
// Returns true if a request to |host_port_pair| with the given
// SubjectPublicKeyInfo |hashes| satisfies the pins in |pkp_state|,
@@ -637,7 +661,24 @@ class NET_EXPORT TransportSecurityState {
const X509Certificate* validated_certificate_chain,
const X509Certificate* served_certificate_chain,
const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps);
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key);
+
+ // Convenience method to create ExpectCTStateIndex, taking into account
+ // |key_expect_ct_by_nik_|.
+ ExpectCTStateIndex CreateExpectCTStateIndex(
+ const std::string& hashed_host,
+ const NetworkIsolationKey& network_isolation_key);
+
+ // Checks if Expect-CT entries should be pruned, based on number of them and
+ // when entries were last pruned, and then performs pruning if necessary.
+ void MaybePruneExpectCTState();
+
+ // Sort ExpectCTState based on retention priority, with earlier entries to be
+ // removed first. Transient entries put in the front, then report-only
+ // entries, then entries are sorted by age, oldest first.
+ static bool ExpectCTPruningSorter(const ExpectCTStateMap::iterator& it1,
+ const ExpectCTStateMap::iterator& it2);
// The sets of hosts that have enabled TransportSecurity. |domain| will always
// be empty for a STSState, PKPState, or ExpectCTState in these maps; the
@@ -670,6 +711,16 @@ class NET_EXPORT TransportSecurityState {
ReportCache sent_hpkp_reports_cache_;
ReportCache sent_expect_ct_reports_cache_;
+ // Whether Expect-CT data should keyed by a NetworkIsolationKey. When false,
+ // ExpectCTStateIndex is always created with an empty NetworkIsolationKey.
+ // Populated based on features::kPartitionExpectCTStateByNetworkIsolationKey
+ // on construction of the TransportSecurityStateObject to avoid repeatedly
+ // querying the feature.
+ bool key_expect_ct_by_nik_;
+
+ // The earliest possible time for the next pruning of Expect-CT state.
+ base::Time earliest_next_prune_expect_ct_time_;
+
std::set<std::string> hsts_host_bypass_list_;
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 6f54b439db4..8f4ba4124c4 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -31,8 +31,11 @@
// - bulk-legacy: bulk entries preloaded before Chrome 50.
// - bulk-18-weeks: bulk entries with max-age >= 18 weeks (Chrome 50-63).
// - bulk-1-year: bulk entries with max-age >= 1 year (after Chrome 63).
-// - public-suffix-requested: public suffixes preloaded at the owners
-// request (manual).
+// - public-suffix: public suffixes (e.g. TLDs or other public suffix
+// list entries) preloaded at the owner's request.
+// - public-suffix-requested: domains under a public suffix that have
+// been preloaded at the request of the the public suffix owner (e.g.
+// the registry for the TLD).
// include_subdomains: (optional boolean) For backwards compatibility, this
// means:
// - If mode == "force-https", then apply force-https to subdomains.
@@ -263,6 +266,7 @@
{ "name": "bmoattachments.org", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "now.sh", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "cnpy.gdn", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentapps.com", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
// Google domains using Expect-CT.
{
@@ -1237,7 +1241,6 @@
{ "name": "datenkeks.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "derhil.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "energy-drink-magazin.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ferienhaus-polchow-ruegen.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "freeshell.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "greensolid.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hasilocke.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -1573,7 +1576,6 @@
{ "name": "onedot.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "powerplannerapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ru-sprachstudio.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "slattery.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "slidebatch.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "smartship.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "southside-crew.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -1582,7 +1584,6 @@
{ "name": "fleximus.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "animurecs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "arendburgers.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "big-andy.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bitgo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "buttercoin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "chainmonitor.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -1647,7 +1648,6 @@
{ "name": "ethack.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fabianfischer.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fastcomcorp.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gizzo.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "itshost.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jmedved.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "keepclean.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -1800,7 +1800,6 @@
{ "name": "atlassian.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "atte.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bizon.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "broeselei.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cordial-restaurant.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "curiosity-driven.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "egfl.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2061,7 +2060,6 @@
{ "name": "mailmag.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mevs.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "miconcinemas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mister.hosting", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mtau.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "myprintcard.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nationalpriorities.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2141,7 +2139,6 @@
{ "name": "imgg.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ipmimagazine.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "isogram.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "j0s.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jbn.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jeremyness.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jkb.pics", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2196,7 +2193,6 @@
{ "name": "securedrop.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sigterm.sh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sleio.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "souki.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "speedcounter.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stesti.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stevegrav.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2242,7 +2238,6 @@
{ "name": "fa-works.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "getmango.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gokmenguresci.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "goodwin43.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gotspot.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gra2.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hledejpravnika.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2302,7 +2297,6 @@
{ "name": "ge3k.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hboeck.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "indovinabank.com.vn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ipsec.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jamesdoylephoto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jpbike.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kaneo-gmbh.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2768,7 +2762,6 @@
{ "name": "sarahlicity.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "schreibnacht.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "screenlight.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "search-one.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shanewadleigh.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shasso.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shoprose.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3337,7 +3330,6 @@
{ "name": "iqboxy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ivk.website", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jacekowski.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kermadec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "latrine.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lmddgtfy.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lmsptfy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3715,7 +3707,6 @@
{ "name": "billninja.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bionicspirit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "blackburn.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "blazor.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "blechschmidt.saarland", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bugginslab.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bwcscorecard.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3917,7 +3908,6 @@
{ "name": "elimdengelen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "entersynapse.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "epay.bg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "escalate.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "espci.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ev-zertifikate.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "evdenevenakliyatankara.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3980,7 +3970,6 @@
{ "name": "nikolasbradshaw.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nomial.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "npmcdn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "nutritionculture.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "oasis.mobi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "opsbears.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "otchecker.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4021,7 +4010,6 @@
{ "name": "teampaddymurphy.ie", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "teampoint.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "therewill.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "thomspooren.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "threelions.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tm-solutions.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tomasjacik.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4051,7 +4039,6 @@
{ "name": "binaryevolved.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bitcoinhk.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "blackdragoninc.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "c16t.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cabarave.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cannyfoxx.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "clmde.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4356,7 +4343,6 @@
{ "name": "kleppe.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "konijntjes.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kraft.im", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kredietpaspoort.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kurtmclester.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "labs.directory", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lambda-complex.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4431,7 +4417,6 @@
{ "name": "profundr.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "proxybay.al", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "purplemoon.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "qiliang.wang", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "quotehex.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "redshield.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "responsibledisclosure.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4458,7 +4443,6 @@
{ "name": "sslpoint.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stalkerhispano.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "star-citizen.wiki", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "staticisnoise.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "statuscode.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "storycollective.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stricted.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4494,7 +4478,6 @@
{ "name": "unitel2000.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "unixadm.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "unoccupyabq.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "unterschicht.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "unwiredbrain.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uvarov.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "valentin-sundermann.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4503,8 +4486,6 @@
{ "name": "vissanum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vsund.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "walkeryoung.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "wangqiliang.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "wangqiliang.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wartorngalaxy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wealthprojector.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wealthprojector.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5089,7 +5070,6 @@
{ "name": "alexvetter.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "alkami.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "alkamitech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "andrewbroekman.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "angristan.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "annabellaw.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "approlys.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5272,7 +5252,6 @@
{ "name": "eligible.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "englishclub.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "esclear.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fearsomegaming.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "firevap.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gintenreiter-photography.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "graphire.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5312,7 +5291,6 @@
{ "name": "netsystems.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neuralgic.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nolberg.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "onefour.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "openxmpp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "optenhoefel.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "oversight.garden", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5361,7 +5339,6 @@
{ "name": "adams.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "anderslind.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "chiru.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "consul.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dealpass.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "driving-lessons.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "elbetech.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5387,7 +5364,6 @@
{ "name": "lyx.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "martinp.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "minpingvin.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mt.me.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "omniti.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "open-bs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "perfect.in.th", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5407,7 +5383,6 @@
{ "name": "tresorsecurity.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "urphp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "v0tti.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vagrantup.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wegner.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wilddog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wlzhiyin.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5456,7 +5431,6 @@
{ "name": "alexn.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "allbenjoy.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "am3.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "amavis.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ambiente.one", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ancientkarma.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "andreaboero.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5724,7 +5698,6 @@
{ "name": "fiksel.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fikt.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "finfev.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "firebird.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fischers.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flamingkeys.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flocktofedora.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5772,7 +5745,6 @@
{ "name": "gravitechthai.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "greedbutt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "greenpeace.berlin", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gresak.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "griesser2.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grog.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gropp.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5838,7 +5810,6 @@
{ "name": "infosenior.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "inios.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "insane.zone", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "interference.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "internetcasinos.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "inton.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "investorforms.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5898,7 +5869,6 @@
{ "name": "ke7tlf.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "keaysmillwork.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kekku.li", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kermadec.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ketosecology.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kevinapease.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kevinbusse.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5951,7 +5921,6 @@
{ "name": "logicsale.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "loginseite.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "loli.bz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "lonal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "loopstart.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lpm-uk.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lubot.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6081,7 +6050,6 @@
{ "name": "ozvolvo.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "p1984.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "p1c.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "pagerate.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paginapolitica.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pakke.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paneu.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6127,7 +6095,6 @@
{ "name": "qingpei.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "qinxi1992.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "qop.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "qorm.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "qtl.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "quantoras.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "quranserver.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6156,7 +6123,6 @@
{ "name": "richardhering.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ringingliberty.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rix.ninja", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rkmantpur.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "robertkrueger.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rodehutskors.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rodney.id.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6223,7 +6189,6 @@
{ "name": "someshit.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "soph.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sortaweird.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sourcelair.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sown.dyndns.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "spacedust.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sparsa.army", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6762,7 +6727,6 @@
{ "name": "newportpropertygroup.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ninchat.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nobly.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "nocit.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nodelia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "noop.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "noxlogic.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6794,7 +6758,6 @@
{ "name": "palatin.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pamplona.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "panaceallc.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "panmetro.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "panni.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paradoxdesigns.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "parithy.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6840,7 +6803,6 @@
{ "name": "reprolife.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "richsiciliano.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ring0.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rop.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rossen.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rous.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rozalisbengal.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6965,7 +6927,6 @@
{ "name": "viciousviscosity.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "videomuz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "visiontree-beta.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "visiontree.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vmem.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vogt.tech", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vonedelmann.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -7256,7 +7217,6 @@
{ "name": "glasschmuck-millefiori.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "goge.site", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "graavaapi.elasticbeanstalk.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gyz.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gz-architekten.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "httpsecurityreport.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ibron.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -7421,7 +7381,6 @@
{ "name": "datacalle.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "datacandy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "datortipsen.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "deer.team", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "detutorial.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "developmentaid.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "digminecraft.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8126,7 +8085,6 @@
{ "name": "appreciationkards.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "appsdash.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aprovpn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "aquapoint.kiev.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aramido.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aran.me.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "arlen.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8185,7 +8143,6 @@
{ "name": "bcbsmagentprofile.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bcmlu.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bcweightlifting.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "beavers.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bebef.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "beeznest.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "befundonline.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8249,7 +8206,6 @@
{ "name": "bluepoint.foundation", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bluepoint.institute", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "blusmurf.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bngsecure.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "boensou.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "boernecancerfonden.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bonfi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8372,7 +8328,6 @@
{ "name": "cmahy.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cni-certing.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "coachingconsultancy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "coam.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cocolovesdaddy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "codeferm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "coderhangout.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8631,7 +8586,6 @@
{ "name": "evi.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "evin.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "evites.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "evowl.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "exchangeworks.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "exemples-de-stands.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "exoscale.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8993,7 +8947,6 @@
{ "name": "janosh.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "japan4you.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "japlex.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "jaredeberle.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jaredfernandez.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jartza.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "javelinsms.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9344,7 +9297,6 @@
{ "name": "nako.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nalifornia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nargileh.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "natalia.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "natalt.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "natanaelys.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "natenom.name", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9538,7 +9490,6 @@
{ "name": "pieq.eu.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pieterjangeeroms.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "piliszek.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "pinnaclelife.co.nz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pinnaclelife.nz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pirateproxy.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pisupp.ly", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9798,7 +9749,6 @@
{ "name": "simonsreich.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "simplepractice.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "simplixos.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "simplymozzo.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "singleuse.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "singlu10.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sinosky.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9961,7 +9911,6 @@
{ "name": "tempcraft.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tenenz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tennisadmin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "teos.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "teoskanta.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tepid.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "terracloud.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9979,7 +9928,6 @@
{ "name": "theendofzion.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thefarbeyond.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thefootballanalyst.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "thefox.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thegcccoin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thegvoffice.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thehiddenbay.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10065,7 +10013,6 @@
{ "name": "tsgbit.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tsrstore.gq", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tubepro.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tunai.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "turnik-67.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "turtle.ai", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "turtlementors.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10389,7 +10336,6 @@
{ "name": "azino777.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "badoo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ballmerpeak.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bandb.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bangzafran.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "barrett.ag", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "baffinlee.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10474,7 +10420,6 @@
{ "name": "cheapestgamecards.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cheapestgamecards.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cjcaron.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "chloeallison.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cheapgoa.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "christina-quast.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "classicsandexotics.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10569,7 +10514,6 @@
{ "name": "droomhuis-in-friesland-kopen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dredgepress.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "duernberg.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "dustri.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-lifetechnology.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eames-clayton.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dvotx.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10660,7 +10604,6 @@
{ "name": "geneau.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gameparade.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "getflorence.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gilgaz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gasnews.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "giant-powerfit.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ginzadelunch.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10687,7 +10630,6 @@
{ "name": "grozip.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hallelujahsoftware.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hakugin.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "happygastro.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gold24.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hdrboundless.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hatcherlawgroupnm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10998,7 +10940,6 @@
{ "name": "oxynux.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "papa-webzeit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pastenib.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "penguinclientsystem.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "percolate.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pdevio.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "oyste.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11007,7 +10948,6 @@
{ "name": "phantasie.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "perroud.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "perthdevicelab.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "peterfolta.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pfolta.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "performancesantafe.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pirateproxy.pe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11085,7 +11025,6 @@
{ "name": "riscascape.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rithm.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rhapsodhy.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rochman.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rointe.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "royalhop.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rokort.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11102,7 +11041,6 @@
{ "name": "ruh-veit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saleslift.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saba-piserver.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sangwon.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saml-gateway.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sbirecruitment.co.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sansemea.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11275,7 +11213,6 @@
{ "name": "trondelan.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ueu.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "twelve.today", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tuxflow.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tumelum.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tyrelius.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "unblocked.win", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11344,7 +11281,6 @@
{ "name": "web-hotel.gr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "webdev.mobi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "webmedpharmacy.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "weme.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "werktor.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wheeler.kiwi.nz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "whiterabbitcakery.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11702,7 +11638,6 @@
{ "name": "justinho.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "justupdate.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jxm.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kaizenreporting.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "karmaflux.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kayon.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "keepcoalintheground.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11710,7 +11645,6 @@
{ "name": "kialo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kiapps.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kielderweather.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kilometertje.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kinomoto.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kircp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kitk.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12109,7 +12043,6 @@
{ "name": "4vf.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "540.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "7thcircledesigns.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "88.to", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "8mpay.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "922.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "9906753.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12260,7 +12193,6 @@
{ "name": "bownty.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bownty.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bownty.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "brandspray.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "brashear.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "brasilmorar.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bratislava-airport-taxi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12656,7 +12588,6 @@
{ "name": "hartmancpa.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hasdf.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hatethe.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "haxoff.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hcs-company.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hdrtranscon.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "healthjoy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12816,7 +12747,6 @@
{ "name": "kadmec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kanar.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kartec.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kasadara.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kashmirobserver.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kateduggan.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kati-raumplaner.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12938,7 +12868,6 @@
{ "name": "manageall.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "manageforall.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "manageforall.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "manesht.ir", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "maniadeprazer.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mansion-note.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "marble.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12983,7 +12912,6 @@
{ "name": "mind.sh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "minux.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mipla.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "miragrow.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "missoy.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mivcon.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mixtape.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -13121,7 +13049,6 @@
{ "name": "petrasestakova.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pexieapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pgnetwork.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "phcnetworks.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "phenomeno-porto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "phenomeno.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "phenomenoporto.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -14602,7 +14529,6 @@
{ "name": "mazda-mps.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "marc-schlagenhauf.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mechmk1.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "marketio.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "microlog.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mobio.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "map4erfurt.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15114,7 +15040,6 @@
{ "name": "sw-servers.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stair.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tcby45.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "suksit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "testadron.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "supersonnig-festival.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sweep-me.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15122,7 +15047,6 @@
{ "name": "studybay.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tetrarch.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "studio-panic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "teamtrack.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "solariiknight.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "suckmyan.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "talun.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15159,7 +15083,6 @@
{ "name": "timnash.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thues.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ti-pla.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "timdebruijn.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tolboe.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tomandshirley.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tinyssh.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15183,7 +15106,6 @@
{ "name": "tracetracker.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "todoescine.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "topaxi.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tradinews.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "trafficquality.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thomasvochten.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thedarkartsandcrafts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15253,7 +15175,6 @@
{ "name": "vocab.guru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vinner.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "v4veedu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "webstellung.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uberwald.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "w7k.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wawak.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15270,7 +15191,6 @@
{ "name": "wowjs.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "webthings.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wait.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "wemakemenus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "waits.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "whoownsmyavailability.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wachtwoordencheck.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15615,7 +15535,6 @@
{ "name": "curveprotect.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "devafterdark.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "customfilmworks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "cyberpeace.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cytadel.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "crossborderreturns.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cybersins.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15731,7 +15650,6 @@
{ "name": "esample.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "europapier.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "europapier.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fastograph.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "etheria-software.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fastconfirm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "exactlyinfinite.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16114,7 +16032,6 @@
{ "name": "momentumdash.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "minitruckin.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "meincloudspeicher.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "migrator.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mimemo.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "medialab.nrw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "miguelmoura.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16473,7 +16390,6 @@
{ "name": "theflowerbasketonline.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "team-pancake.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stilmobil.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "teambeoplay.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thesaturdaypaper.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "telling.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "telefoonabonnement.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16504,7 +16420,6 @@
{ "name": "syt3.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "timewasters.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "studentrightsadvocate.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tomharris.tech", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "triadwars.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uhm.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thewebsitemarketingagency.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16514,7 +16429,6 @@
{ "name": "trynowrinkleseyeserum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tragmi.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thijsvanderveen.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tradinews.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "transcricentro.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tobi-mayer.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "theschool.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16635,7 +16549,6 @@
{ "name": "xat.re", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yotilabs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wundtherapie-schulung.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "zupago.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yuki.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yukiminami.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--mentaltraining-fr-musiker-uwc.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16977,7 +16890,6 @@
{ "name": "aoku3d.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "biospeak.solutions", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "camperlist.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "cctld.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bundespolizei-forum.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "carbon12.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cesipagano.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -17240,7 +17152,6 @@
{ "name": "ecomlane.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "duncanwinfrey.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "droni.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "eddyn.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "egbert.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "droomhuis-in-de-friese-meren-kopen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "droomhuisophetplattelandverkopen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -17294,7 +17205,6 @@
{ "name": "et180.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "especificosba.com.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eengezinswoningverkopen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "eastmanbusinessinstitute.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "enginepit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "buildingclouds.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "erick.blog", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -17614,7 +17524,6 @@
{ "name": "inima.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "indusap.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "infinity-freedom.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "hydra.zone", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ihrhost.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "inme.ga", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "interhosts.co.za", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -17906,7 +17815,6 @@
{ "name": "matthias-muenzner.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lorenadumitrascu.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lovelyblogacademy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mentalhealth.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "laurelblack.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "melhorproduto.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "metsasta.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18102,7 +18010,6 @@
{ "name": "nordwaldzendo.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neofelhz.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nurses.dating", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "oktoberfeststore.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "osburn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "olswangtrainees.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "new.travel.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18231,7 +18138,6 @@
{ "name": "r-rickroll-u.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rally-base.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "novurania.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "qqj.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rasagiline.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "questsocial.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rathorian.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18338,7 +18244,6 @@
{ "name": "selegiline.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "semianalog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "safelist.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sensebridge.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "schauer.so", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sendthisfile.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "safeex.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18672,7 +18577,6 @@
{ "name": "unblocked.works", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "upmchealthsecurity.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tumagiri.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "usability.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uctarna.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "utilitarianism.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "twee-onder-een-kap-woning-in-leeuwarden-kopen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19061,7 +18965,6 @@
{ "name": "ballbusting-cbt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "b422edu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avdagic.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "automotivemechanic.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "auerbach-verlag.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "axem.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ave.zone", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19332,7 +19235,6 @@
{ "name": "co-yutaka.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "coding.lv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "channellife.asia", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "clovissantos.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "codelitmus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "craigwfox.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cnbs.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19492,7 +19394,6 @@
{ "name": "dohanews.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dorfbaeck.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dreamaholic.club", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "domaine-aigoual-cevennes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dopravni-modely.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "drabbin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "duckbase.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19708,7 +19609,6 @@
{ "name": "garageenginuity.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ftang.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fuchsy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fx24.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "freelo.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fegans.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gayforgenji.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19809,7 +19709,6 @@
{ "name": "hackbubble.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hawk-la.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grieg.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "heavyequipments.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hearttruth.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "heisenberg.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "friendship-quotes.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20225,7 +20124,6 @@
{ "name": "main-street-seo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "macht-elektro.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "matlss.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "maquinariaspesadas.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "manitasicily.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "marcelmarnitz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "masty.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20245,7 +20143,6 @@
{ "name": "matthew-carson.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "matillat.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kinderopvangengeltjes.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mecanicoautomotriz.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mi80.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mediumraw.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "maurus-automation.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20324,7 +20221,6 @@
{ "name": "muwatenraqamy.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "morpheusxaut.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "morpheusx.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mannford.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mrd.ninja", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mygrotto.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mode-marine.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20510,7 +20406,6 @@
{ "name": "payfazz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "panama-gbs.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "open-sauce-recipes.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "padovani.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pbytes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "olightstore.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "otellio.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20637,7 +20532,6 @@
{ "name": "radiomodem.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "progressivecfo.co.nz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pianetaottica.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "prepaid-voip.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "readingandmath.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ravengergaming.ga", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rbti.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20704,7 +20598,6 @@
{ "name": "rehabthailand.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rockpesado.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "robertattfield.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "reussirsavie.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ripa.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rough.nu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rockbankland.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20724,7 +20617,6 @@
{ "name": "reto.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reality.news", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rolroer.co.za", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rulu.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saferedirect.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rpasafrica.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "portaluniversalista.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20805,7 +20697,6 @@
{ "name": "sebastianhampl.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shanekoster.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shareoffice.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "schroettle.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sergeyreznikov.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "seriousclimbing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shareeri.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21030,7 +20921,6 @@
{ "name": "theyear199x.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "throttlerz.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thejobauction.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "startuppeople.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "techday.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thairehabassociation.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sportchirp-internal.azurewebsites.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21052,7 +20942,6 @@
{ "name": "tomiler.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tobiassachs.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "teulon.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "theobromos.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tolud.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tlcdn.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thesignalco.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21193,7 +21082,6 @@
{ "name": "vsestiralnie.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vasileruscior.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vitaminler.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "westtulsa.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "webpublica.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "web404.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "whereiszakir.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21284,7 +21172,6 @@
{ "name": "xn--90accgba6bldkcbb7a.xn--p1acf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xninja.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "youdungoofd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "xn--d1acj9c.xn--90ais", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yukonrefugees.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zeds-official.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wildcard.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21707,7 +21594,6 @@
{ "name": "gelb-computer.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gfk-kunststoff-luebben.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ghislainphu.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gianlucapartengo.photography", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "giduv.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "giochi-online.ws", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "girlan.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22202,7 +22088,6 @@
{ "name": "theavenuegallery.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thecodeninja.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thehoopsarchive.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "thelefthand.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thelinuxtree.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "themoneyconverter.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thepcweb.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22443,7 +22328,6 @@
{ "name": "abasky.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "abi-fvs.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "abigisp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "aboderenovation.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "abolicionistas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "abolition.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "abolition.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22482,7 +22366,6 @@
{ "name": "active-escape.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "addicional.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "adlerweb.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "administratorserwera.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "admongo.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "adrafinil.wiki", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "adriancohea.ninja", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22640,7 +22523,6 @@
{ "name": "astenretail.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "astronomie-fulda.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "at-one.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "at1.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "athena-bartholdi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "atkdesign.pt", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "atlantareroof.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22788,7 +22670,6 @@
{ "name": "bltc.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bluefrag.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "blues-and-pictures.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bluteklab.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bnty.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bobep.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "boboates.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -23116,7 +22997,6 @@
{ "name": "cvninja.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cwrcoding.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cyber-computer.club", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "cyber.cafe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cybercecurity.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cyberwars.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cyoda.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -23284,7 +23164,6 @@
{ "name": "dzomo.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-migration.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-newshub.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "e-pokupki.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-tune-mt.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-vau.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "e-wishlist.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -23419,7 +23298,6 @@
{ "name": "falkus.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fame-agency.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "familyreal.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fanflow.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fantasticgardenersmelbourne.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fantastichandymanmelbourne.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fantasticpestcontrolmelbourne.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24062,8 +23940,6 @@
{ "name": "kirainmoe.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kisallatorvos.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kisstube.tv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kitchen-profi.com.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kitchen-profi.kz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kittyhacker101.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kjg-bachrain.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kjoglum.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24410,7 +24286,6 @@
{ "name": "mister-cooks.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mk-dizajn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mkaciuba.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mkakh.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mkakh.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mlcambiental.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mlpchan.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24526,7 +24401,6 @@
{ "name": "neeerd.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neemzy.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neet-investor.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "nemcd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nemez.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neobits.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neokobe.city", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24608,7 +24482,6 @@
{ "name": "obyvateleceska.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ocelot.help", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ocsigroup.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "odzyskaniedomeny.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ofcss.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "off-the-clock.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "offroadeq.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24799,7 +24672,6 @@
{ "name": "popmagz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "poppetsphere.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "population-ethics.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "poquvi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "porg.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pork.org.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "porn77.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25001,7 +24873,6 @@
{ "name": "robin.co.kr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "robu.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rocketnet.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rockfax.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rodichi.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rodomonte.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rogagym.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25580,7 +25451,6 @@
{ "name": "uex.im", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ufo.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ufplanets.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ukclimbing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ukhillwalking.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ukkeyholdingcompany.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ukrnet.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25668,7 +25538,6 @@
{ "name": "vorlicek.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vpc-display.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vpsboard.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vsc-don-stocksport.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vsesrazu-raiffeisen.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vstehn.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vuakhuyenmai.vn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26197,7 +26066,6 @@
{ "name": "beckerantiques.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "belfastlocks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "benburwell.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "benfairclough.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aurora-multimedia.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "balidesignshop.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "around-the-blog.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26332,7 +26200,6 @@
{ "name": "c2o-library.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "burckardtnet.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bronetb2b.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bm-i.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "by1898.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "boyan.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "buttercupstraining.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26387,7 +26254,6 @@
{ "name": "celigo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ccv-deutschland.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cc-brantomois.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "catburton.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "chaurocks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "charmingsaul.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "chatbots.email", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26479,7 +26345,6 @@
{ "name": "coolbutbroken.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "collard.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cloud2go.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "capachitos.cl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "continuation.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "comyuno.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cloud.bugatti", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26515,7 +26380,6 @@
{ "name": "crossfunctional.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "curiouscat.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cosmiatria.pe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "conkret.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "conkret.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "colarelli.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "conformist.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26589,7 +26453,6 @@
{ "name": "ddocu.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "deflumeri.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "davie3.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "dai.top", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "delahrzolder.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cutelariafiveladeouro.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dcw.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26754,7 +26617,6 @@
{ "name": "eidolons.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "egeozcan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "encouragemarketing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ecirtam.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "electragirl.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "elosrah.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dtx.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26775,7 +26637,6 @@
{ "name": "elliff.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dovenzorgmalawi.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "efa-football.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "emil.click", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "elektro-roth.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eolme.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "drlazarina.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26929,7 +26790,6 @@
{ "name": "flagshop.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fonseguin.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fidelis-it.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "flanga.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fidelis-it.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fiodental.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "frankyan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27033,7 +26893,6 @@
{ "name": "gnosticjade.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gidea.nu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gevaulug.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ghaglund.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "geld-im-blick.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "glahcks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "goemail.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27114,7 +26973,6 @@
{ "name": "gugert.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "harveyauzorst.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hammer-schnaps.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "hanfox.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "handyglas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gynaecology.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "haruue.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27576,7 +27434,6 @@
{ "name": "linearaudio.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lipex.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "local360.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "lotuscloud.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lolibrary.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "livingforreal.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "llvm.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27650,7 +27507,6 @@
{ "name": "madbin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mastichor.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "markus-ullmann.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mainston.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "maroc-bivouac.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "markllego.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "marqueswines.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27840,7 +27696,6 @@
{ "name": "netki.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "napcae.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "myrig.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "nebul.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nakanishi-paint.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nedwave.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "newbownerton.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27859,7 +27714,6 @@
{ "name": "neostralis.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nella.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nickcraver.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "nbur.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "newaccess.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nicolasiung.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "night2stay.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -28340,7 +28194,6 @@
{ "name": "rumoterra.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "s4tips.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rummel-platz.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "savingbytes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "salonestella.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sbobetfun.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sanatrans.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29050,7 +28903,6 @@
{ "name": "woomu.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vysko.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wvw698.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "xiaoniaoyou.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wangkezun.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--w22a.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--tigreray-i1a.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29318,7 +29170,6 @@
{ "name": "alroniks.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "anttitenhunen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aevpn.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "b8a.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "aqua-fitness-nacht.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "asmdz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ammoulianiapartments.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29644,7 +29495,6 @@
{ "name": "downtimerobot.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "downtimerobot.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dualascent.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "dev-bluep.pantheonsite.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "drogoz.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dosomeworks.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "droidgyan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29871,7 +29721,6 @@
{ "name": "gogleapis.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ghkim.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "glencarbide.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gamebrott.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "givesunlight.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gtopala.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "giveme.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29933,7 +29782,6 @@
{ "name": "hostworkz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fire-wolf.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hiteco.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gencmedya.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "heverhagen.rocks", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "horkel.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hfu.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30098,7 +29946,6 @@
{ "name": "kremalicious.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kabashop.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "keycenter.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kitchen-profi.by", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kobofarm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kostecki.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kevinroebert.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30111,9 +29958,7 @@
{ "name": "koryfi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jacobsenarquitetura.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kitatec.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "konoe.studio", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lannainnovation.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "knep.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lazulu.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "leadgenie.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "laraveldirectory.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30163,7 +30008,6 @@
{ "name": "littlefairy.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lockyourcomputer.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "linux-vme.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "lavolte.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "linkage.ph", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "logimagine.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kswcosmetics.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30359,7 +30203,6 @@
{ "name": "nba2k.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nba2k.live", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nba2k.download", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "myliveupdates.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "microbiote-insectes-vecteurs.group", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nba2k.tw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nba.vg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30390,7 +30233,6 @@
{ "name": "nbaspot.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nbalivex.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nbask.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mundoadulto.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mvnet.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mundtec.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "multibomasm.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30434,7 +30276,6 @@
{ "name": "notablog.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "nyphox.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "numwave.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mrksk.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "neurocny.cloud", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "netscaler.expert", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "opposer.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30790,7 +30631,6 @@
{ "name": "snovey.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "softrobot.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "slo-net.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sorinmuntean.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "speedracer.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "snakafya.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "snowraven.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -30926,7 +30766,6 @@
{ "name": "tomticket.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "timbishopartist.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thuisverpleging-meerdael.be", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "the.ie", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "transcriptionwave.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tomwassenberg.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "toptec.net.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31400,7 +31239,6 @@
{ "name": "jungleculture.co.za", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "www-8522.am", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "savecrypto.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rickmartensen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vigoxatelier.tech", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sproing.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "webveloper.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31471,7 +31309,6 @@
{ "name": "corporatecomputingsolutions.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cosmeticosdelivery.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "creativeapple.ltd", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "d.nf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "d.nr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dbq.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "deliver.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31871,7 +31708,6 @@
{ "name": "enamae.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "enlazaresbueno.cl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "entaurus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "eoitek.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "equinox.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "esb111.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "espacio-cultural.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32327,7 +32163,6 @@
{ "name": "complexsystems.fail", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cranforddental.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "crea.bg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "cusfit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cyberlightapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dado.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dado.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32601,7 +32436,6 @@
{ "name": "bewerbungsfoto-deinfoto.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bewertet.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bezemkast.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bhost.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "biaoqingfuhao.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "biaoqingfuhao.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bidorbuy.co.ke", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32900,7 +32734,6 @@
{ "name": "failover.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "failover.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fakerli.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fakti.bg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "familie-leu.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "familletouret.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fantasyescortsbirmingham.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32934,7 +32767,6 @@
{ "name": "firstq.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fiuxy.bz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fl0222.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "flehm.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flets-ms.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fliacuello.com.ar", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flightzero.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33069,7 +32901,6 @@
{ "name": "holidaysportugal.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "homatism.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "homeodynamics.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "homeownersinsurancenevada.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "homeownersinsurancenv.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hoplongtech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "horrendous-servers.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33135,7 +32966,6 @@
{ "name": "itzap.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ivanbenito.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "iwell.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "j-elliott.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "janssen.fm", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "japaneseemoticons.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "japanesenames.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33333,7 +33163,6 @@
{ "name": "melakaltenegger.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "melaniebernhardt.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "melbourneapartments.website", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "melikoff.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "melina-schefczyk.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "memetrash.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "memorygame.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33398,7 +33227,6 @@
{ "name": "myaggic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mybloggedlife.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "myclinicalstudybuddy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mydmdi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "myforfaitmobile.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mygaysitges.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mygoldennetwork.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33813,7 +33641,6 @@
{ "name": "tijo.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tik.edu.ee", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tik.help", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "timeatlas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "timer.fit", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tkn.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tlca.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -33840,7 +33667,6 @@
{ "name": "tridimage.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "trymegadrol.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tsuki.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ttbonline.gov", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ttdsevaonline.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "turigum.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tutanota.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34047,7 +33873,6 @@
{ "name": "unblocked.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "upd.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uscp8.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vida.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "viepixel.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wochennummern.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wplatin.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34170,8 +33995,6 @@
{ "name": "dellipaoli.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "depotsquarekerrville.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "depthe.gr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "di2pra.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "di2pra.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "diamondyze.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dice.tokyo", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "digilicious.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34275,7 +34098,6 @@
{ "name": "helpantiaging.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hevertonfreitas.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hfcbank.com.gh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "hh-medic.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hiddenmalta.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hiltonarubabeachservices.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "himens.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34292,7 +34114,6 @@
{ "name": "hotelsinformer.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "house-of-japan.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hp42.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "hrjfeedstock.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hustlehope.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hyakumachi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "i-hakul.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34843,7 +34664,6 @@
{ "name": "bolivarfm.com.ve", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "boogiebouncecastles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "boosinflatablegames.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bopp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "born2bounce.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bounce-a-mania.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bounce-a-roo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -35755,7 +35575,6 @@
{ "name": "primalinea.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pristineevents.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "projectcastle.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "promarketer.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "provokator.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "psc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ptmarquees.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -35914,7 +35733,6 @@
{ "name": "supercastlessouthsydney.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "supercastlessunshinecoast.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "supercastlessydney.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "supersole.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "supersteosbouncycastles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sushi.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "suttonbouncycastles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -35973,7 +35791,6 @@
{ "name": "tokobungadilampung.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tokobungadipadangflorist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tokyo-onkyo.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "topbounce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topbouncycastles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topclassfun.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topdogsinflatables.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -36002,7 +35819,6 @@
{ "name": "tuppenceworth.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "turtles.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tuthowto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tuvangoicuoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tverdohleb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tvs-virtual.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "twizzkidzinflatables.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -36174,7 +35990,6 @@
{ "name": "rogerdat.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "roomongo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securi-tay.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "simontaite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "skks.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stackunderflow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stedb.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -36256,7 +36071,6 @@
{ "name": "bikehistory.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bizstarter.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "blackmonday.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "blarg.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "blogexpert.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bloodyexcellent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bluesecure.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -36284,7 +36098,6 @@
{ "name": "carolynjoyce.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carteirasedistintivos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cartelcircuit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cartertonscouts.org.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "catveteran.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "centrolavoro.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "centurionunderground.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37082,11 +36895,9 @@
{ "name": "iczc.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iea-annex61.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "illsley.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "imageination.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ims-sargans.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inixal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inkvisual.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "isfriday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isotope.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isz.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "it-jobbank.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37134,7 +36945,6 @@
{ "name": "larondinedisinfestazione.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lasuzefc.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laviedalex.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lbc.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "legumefederation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "legumeinfo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lemni.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37194,7 +37004,6 @@
{ "name": "ntx360grad-fallakte.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "numarasorgulama.tel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "o-loska.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "oaksbloom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ocenovani-inspekce.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "okib.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "omegahosting.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37202,7 +37011,6 @@
{ "name": "onepopstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "opencircuit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "optimal-e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "optimisedlabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pabloarteaga.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pabloarteaga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pabloarteaga.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37339,7 +37147,6 @@
{ "name": "waltellis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "waterleeftinbeek.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "waterschaplimburg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "wdodelta.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wearedisneyland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "webartex.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "websiterent.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37779,7 +37586,6 @@
{ "name": "robotattack.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rockthebabybump.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rubenkruisselbrink.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "rybox.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "safeinfra.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "safesecret.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sana-store.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37933,7 +37739,6 @@
{ "name": "abstractbarista.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aceanswering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "acroso.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "actom.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "adhd-inattentive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "admin-forms.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "adminwerk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -37962,7 +37767,6 @@
{ "name": "alpinechaletrental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "altaplana.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alwaysonssl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "amaderelectronics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amalficoastchauffeur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amalfitabula.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amauf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -38072,7 +37876,6 @@
{ "name": "baptistedeleris.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "barabrume.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "barryswebdesign.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bayz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bbnbb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bbswin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bcdonadio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -38315,7 +38118,6 @@
{ "name": "deltaonlineguards.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "deparis.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "depedtayo.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "desuperheroes.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "devagency.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dewaard.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dicio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -38449,7 +38251,6 @@
{ "name": "euvo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eva-select.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evailoil.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "evamira.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "event64.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "everydaywp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evilsite.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -38744,7 +38545,6 @@
{ "name": "klseet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kocherev.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kochereva.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kochhar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kogcoder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "koka-shop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "koninkrijk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -38961,7 +38761,6 @@
{ "name": "neoeliteconsulting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "neonataleducationalresources.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "neonatalgoldenhours.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nepageeks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nepremicninar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nepremicnine.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nepremicnine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -39256,7 +39055,6 @@
{ "name": "sorenam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "soruly.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "spaconnection.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "spaldingwall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "spanyolul.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sparendirekt.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sparprofi.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -39690,7 +39488,6 @@
{ "name": "campamentos.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cangelloplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cardboard.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "casinobonuscodes.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "catchers.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "catfooddispensersreviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "catherinesarasin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -39828,7 +39625,6 @@
{ "name": "euro-servers.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eurofrank.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "europeanpreppers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "evamachkova.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evenementenhoekvanholland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "examsmate.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "expoort.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -39949,7 +39745,6 @@
{ "name": "ip-tanz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isakssons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itaiferber.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jak-na-les.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jalogisch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jamberry.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jazzfeet.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40135,7 +39930,6 @@
{ "name": "pirateproxy.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "planetromeo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "planformation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "plotbubble.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "plural.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pm.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pn.id.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40293,13 +40087,11 @@
{ "name": "suisui.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "suitesapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "supernaut.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sxistolithos.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "symfora-meander.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "syncflare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "syslogic.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tabarnak.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tabitatsu.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "talenthub.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tamersunion.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tangerine.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tanyanama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40307,7 +40099,6 @@
{ "name": "technicalbrothers.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techwithcromulent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tecnicoelettrodomestici.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tecnogazzetta.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "temnacepel.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ten-cafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "terabyte.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40351,7 +40142,6 @@
{ "name": "tycom.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ugx-mods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uiberlay.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "unapolegetic.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unblocked.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "underfloorheating-uk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unitedkingdoms-guild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40761,7 +40551,6 @@
{ "name": "imyz.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "indiraactive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "infosec-handbook.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "injapan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inlabo.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "insureon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inup.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40987,7 +40776,6 @@
{ "name": "programlama.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "projektarbeit-projektplanung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "proprietairesmaisons.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "pxio.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pycrc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quantolytic.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quizl.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41361,7 +41149,6 @@
{ "name": "cldfile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clicandfioul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cliniquecomplementaire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cloaked.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cloudfiles.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cmftech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cna-aiic.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -42328,7 +42115,6 @@
{ "name": "aisi316l.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "albanboye.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alco-united.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "aldred.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "allontanamentovolatili.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "allstakesupply.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alphaetomega3d.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -42415,8 +42201,6 @@
{ "name": "elnoorandelmohanad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "emaging-productions.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "escort-fashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ethantskinner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "etskinner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eurotravelstar.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evidentiasoftware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evodia-spirits.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -42636,7 +42420,6 @@
{ "name": "touhouwiki.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "transbike.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "transfers.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tsukeawase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tulenceria.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uclip.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uktw.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -42655,7 +42438,6 @@
{ "name": "voidcore.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "votesandymurman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wealthformyhealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "webstijlen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "welovecatsandkittens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wentu.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wesoco.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -42820,7 +42602,6 @@
{ "name": "buildmorebuslanes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "c12discountonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "c3.pm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "calluna.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "camshowhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "captainsinn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cartouche-deal.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43014,7 +42795,6 @@
{ "name": "inquant.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "intasky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "intasky.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "invitacionesytarjetas.gratis", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ionote.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iphonekaitori.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ipo-times.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43070,7 +42850,6 @@
{ "name": "learning-id.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leastsignificantbit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "legaillart.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lelambiental.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lemondenumerique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lequerceagriturismo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "linext.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43615,7 +43394,6 @@
{ "name": "ewaipiotr.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ewtl.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "exceptionalbits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "exocen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "extintormadrid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "faraonplay7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "faraonplay8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -44080,7 +43858,6 @@
{ "name": "webwinkelexploitatie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weekendinitaly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weitergedacht.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "wepay.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "westcoastaggregate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wft-portfolio.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "whateveraspidercan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -44197,7 +43974,6 @@
{ "name": "dinocarrozzeria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "disinfestazioni.treviso.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "disinfestazionivespe.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dolt.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dsuinnovation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ecobergerie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ecos.srl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -44518,7 +44294,6 @@
{ "name": "kobejet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kooliveeb.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kovehitus.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ladraiglaan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lalajj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lederer-it.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "libricks.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -44715,7 +44490,6 @@
{ "name": "barpodsosnami.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "basementfinishingohio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "batch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "betterweb.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bezr.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "biehlsoft.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bifrost.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -44870,7 +44644,6 @@
{ "name": "falling.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ferienhausprovence.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ferm-rotterdam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ffh.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fileon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "filmesonline.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fiskestang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -46229,7 +46002,6 @@
{ "name": "boattrader.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bonami.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bordadoenpedreria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "brand-foo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brand-foo.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brand-foo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bsee.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -46612,7 +46384,6 @@
{ "name": "mekesh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mekesh.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mekesh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "melissameuwszen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "messagevortex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "messagevortex.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meta-word.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -46820,7 +46591,6 @@
{ "name": "safaritenten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "samhuri.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "samwrigley.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sandrocorapi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "satoshinumbers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scaarus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scalacollege.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -46895,7 +46665,6 @@
{ "name": "thalia.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thebonerking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "theimagefile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thetree.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thewaxhouse.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thuybich.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tiantangbt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -46961,7 +46730,6 @@
{ "name": "wijzijnwolf.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "winddan.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "windowslatest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "winepress.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wingify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wonderfuleducation.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -47635,7 +47403,6 @@
{ "name": "retronet.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "returnpath.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "reussir-ma-fete.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "revirt.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rmm-i.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "root.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "royalasianescorts.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -47714,7 +47481,6 @@
{ "name": "tdpblog.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "technicalsystemsprocessing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techsys.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "teknolit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "terranova-nutrition.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "testdomain.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "texasparkinglotstriping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48006,7 +47772,6 @@
{ "name": "kockanakocko.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "la-kaz-a-velo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lacaserita.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lacoquette.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lamikvah.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "landchecker.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lanforalla.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48064,7 +47829,6 @@
{ "name": "nshipster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "numerologist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nuwaterglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "oanalista.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ocdadmin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oirealtor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "onepointsafeband.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48305,7 +48069,6 @@
{ "name": "bitfence.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "blackhat.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "blending.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "blockchainwhiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bobaly.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bowdens.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brettw.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48331,7 +48094,6 @@
{ "name": "casadellecose.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cbd.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cbdmarket.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "centralmarket.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cherry-green.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "childrens-room.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "christec.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48363,13 +48125,11 @@
{ "name": "csu.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ctl.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "customfitbymj.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cutimbo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cwinfo.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cyberpubonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danielpeukert.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danmassarano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "darinjohnson.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "davidundetiwan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dccommunity.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ddholdingservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "debarrasantony.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48492,7 +48252,6 @@
{ "name": "grozter.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gruppoipl.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hackettrecipes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hackzogtum-coburg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "harekaze.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "harry-baker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "havenstrategies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48595,7 +48354,6 @@
{ "name": "l33te.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lachlan-harris.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lancashirecca.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "latiendauno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laufers.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lauraenvoyage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lawyerkf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48670,7 +48428,6 @@
{ "name": "mobiproj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "moderncoinmart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "modosaude.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "momjoyas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "monlabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mono.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "morgner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48711,9 +48468,7 @@
{ "name": "nansa.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "narardetval.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nature-shots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "natureword.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ncdc.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "neocoding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nerdbox.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "net-share.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netfuture.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -48933,7 +48688,6 @@
{ "name": "uniojeda.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "upsettunnel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "usadba.net.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "user-re.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vagrantbits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "valiant.finance", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "valleyautoloan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -49094,7 +48848,6 @@
{ "name": "cyberexplained.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "damghaem.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danielgorr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "danielt.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danslan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "degosoft.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "digital1world.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -49991,8 +49744,6 @@
{ "name": "loigiai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "loihay.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "loli.tube", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "loyaltyondemand.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "loyaltyondemand.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lsmpx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lucasbergen.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "luke6887.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50091,7 +49842,6 @@
{ "name": "nechiactua.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "neffat.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "neos.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "neotist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netsec.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "network-midlands.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "network-midlands.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50428,7 +50178,6 @@
{ "name": "theworldexchange.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thisisgrey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thisisthefinalact.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thomasduerlund.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thomasmerritt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thoroughbreddiesel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "threit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50613,7 +50362,6 @@
{ "name": "amati.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amend-friseur-schwabing.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "americandetour.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "amitabhsirkiclasses.org.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amiu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "animeinsights.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "antiekboerderijgraafland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50641,7 +50389,6 @@
{ "name": "bcs.adv.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "beacham.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "beeming.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "beerly.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bemindly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ben-jarvis.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "benedikt-tuchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50801,7 +50548,6 @@
{ "name": "huonit.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hyperstack.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iaf.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "iam.lc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ibodyiq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "idealimplant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "idratherbequilting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50820,7 +50566,6 @@
{ "name": "integratedintegrations.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iposm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "irandp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "isitpatchtuesday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "it-seems-to.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itruth.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iuyos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -50854,7 +50599,6 @@
{ "name": "krazyboi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krey.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krishnenduayur.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kuro.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kvantel.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kwiknews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lappari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -51086,7 +50830,6 @@
{ "name": "stromzivota.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "studiobergaminloja.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "suited21.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sunset.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sunsong.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "surasak.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "surefit-oms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -51317,7 +51060,6 @@
{ "name": "dota2huds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dowell.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dreamersgiftshopec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dressify.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dressify.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "drgdrp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "druckerei-huesgen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -51860,7 +51602,6 @@
{ "name": "evilbunnyfufu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "exitooutdoor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "expertviolinteacher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "facepainting.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "faelix.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fahnen-fanwelt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fameus.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -51938,7 +51679,6 @@
{ "name": "hirakatakoyou.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hirevo.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hisgifts.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hlin.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "home-insurance-quotes.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hotelpostaorvieto.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "howtoteachviolin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -51960,7 +51700,6 @@
{ "name": "ihakkitekin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ilookz.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "industriafranchini.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "infinitomaisum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "infomir.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "infuzeit.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inglebycakes.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -52428,7 +52167,6 @@
{ "name": "tannerwilliamson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tar-mag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tccmb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "techamigo.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tellyourtale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "teriyakisecret.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "terminsrakning.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -52466,7 +52204,6 @@
{ "name": "trendus.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "trilliumvacationrentals.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "trouble-free-employees.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "trueproxy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tsgkc1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tuasaude.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "turf-experts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -52823,7 +52560,6 @@
{ "name": "dorpshuis-dwarsgracht.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dr-it.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "drump-truck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "drwang.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dschwarzachtaler.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dsgnet.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dubious-website.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53054,7 +52790,6 @@
{ "name": "lng-17.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lohl1kohl.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "looseleafsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lord.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "louisemisellinteriors.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "loveamber.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lovevape.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53168,7 +52903,6 @@
{ "name": "openroademail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oriondynamic.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "orocojuco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "otmo7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "otoblok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "otokiralama.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "out-of-scope.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53282,8 +53016,6 @@
{ "name": "savingsoftheyear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "schgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "schoeller.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scholar.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scholar.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scholledev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seachef.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "secpoc.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53573,7 +53305,6 @@
{ "name": "cpe-colleg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cplala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "craftsmany.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "createcos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "creditta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cstrong.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cxadd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53897,7 +53628,6 @@
{ "name": "thevenueofhollywood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thrillernyc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tiekoetter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tilman.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "toontown.team", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topdroneusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topgshop.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -53930,7 +53660,6 @@
{ "name": "vlakem.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vos-systems.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vtuber.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "webutils.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weems.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "whirlpool.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "whiskygentle.men", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54484,7 +54213,6 @@
{ "name": "annunciationbvmchurch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "anoncrypto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "apkmod.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "appelaprojets.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aranchhomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "architectureandgovernance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arizonahomeownerinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54510,7 +54238,6 @@
{ "name": "awningcanopyus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "baazee.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ball-bizarr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bangridho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "banjostringiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "barbarabowersrealty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "barbiere.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54570,7 +54297,6 @@
{ "name": "calenfil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "canal-onanismo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "candguchocolat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "candidaturedunprix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "capitalfps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "capsulesubs.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carburetorcycleoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54603,7 +54329,6 @@
{ "name": "cl0ud.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clayprints.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cleanfiles.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "click4web.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clippings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cloudchart.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cmgacheatcontrol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54799,7 +54524,6 @@
{ "name": "form3w.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "formsbyair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fossforward.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "francescopandolfibalbi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "francoisbelangerboisclair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "frasesconemocion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "freemanlogistics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -54980,7 +54704,6 @@
{ "name": "libre.cr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lifeenrichmentnc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lifelenz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lifereset.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "linchpin-it.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lincolnpedsgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lindaolsson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -55126,7 +54849,6 @@
{ "name": "phpower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pierrickdeniel.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pinetopazrealestate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "plateformecandidature.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "playcollect.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "poc88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pogetback.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -55135,7 +54857,6 @@
{ "name": "pooltools.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "poorclarepa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pornovk.xxx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "poterepersonale.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "precisionventures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "presentationmedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "preserveourhillcountry.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -55368,7 +55089,6 @@
{ "name": "thestandingroomrestaurant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thetinylife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thevalueofarchitecture.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "think-pink.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "this-server-will-be-the-death-of-me.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thomas-schmittner.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "timewk.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -55506,7 +55226,6 @@
{ "name": "zydronium.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "10414.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1527web.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "159cp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1cswd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1way.faith", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "222001.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -55650,7 +55369,6 @@
{ "name": "avtomarket.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "awarify.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "awarify.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "axon-toumpa.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "axre.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "azane.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "azarus.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -56024,8 +55742,6 @@
{ "name": "findyourtrainer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fionafuchs.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fisinfomanagerdr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "fj.je", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "fjdekermadec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fjzone.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fleesty.dynv6.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "floify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -56264,7 +55980,6 @@
{ "name": "kermadec.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kevin-ta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kgv-schlauroth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kiisu.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kinderpneumologie.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kinerd.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kinesiomed-cryosauna.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -56764,7 +56479,6 @@
{ "name": "section77.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securist.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "secvault.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sedomicilier.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seedcoworking.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "segnidisegni.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sekikawa.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57016,7 +56730,6 @@
{ "name": "videojuegos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "videosparatodos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vikaviktoria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "viktorbarzin.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vim.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vinigas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vitalium-therme.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57318,7 +57031,6 @@
{ "name": "mrhookupsd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mteleport.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mullerimoveisrj.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "musikholics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myduffyfamily.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nakladki.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "natureclaim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57667,7 +57379,6 @@
{ "name": "ctr.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cyberlegal.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dailyroverr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "danieln.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danielparker.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "darkestproductions.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "datahive360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57698,7 +57409,6 @@
{ "name": "dodomu.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "donnajeanbooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "doorswest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dophys.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dox-box.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dragon.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "draintechnorthwest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57764,7 +57474,6 @@
{ "name": "gekosoft.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "georgiatransport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gettodoing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "giftya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "glamouria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goldenmonrepos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gomel.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57873,7 +57582,6 @@
{ "name": "klemkow.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "klemkow.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "klinik-fuer-aesthetische-zahnheilkunde.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "knowyourday.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kongsecuritydata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kos4all.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kosherjava.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -57890,7 +57598,6 @@
{ "name": "lancelhoff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lancemanion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "latinmusicrecords.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "leaf-consulting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lehmitz-weinstuben.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leibniz-gymnasium-altdorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lequest.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58015,7 +57722,6 @@
{ "name": "preme.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pretor.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pretor.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "pretor.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pretorcup.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "primananda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "proformer.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58402,7 +58108,6 @@
{ "name": "adtelligent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "advaithbot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "advenacs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "aegis.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aenterprise.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aeonct.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aff.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58508,7 +58213,6 @@
{ "name": "bootsschule-weiss.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "boreo.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "boysontech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bps.vc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "breakwall.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brightside.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "britanniacateringyeovil.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58765,7 +58469,6 @@
{ "name": "flibusta.appspot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fmstr.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "followmystaff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "fono.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "forbidden-mods.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ford.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ford.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58801,7 +58504,6 @@
{ "name": "gehrke.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "general-plast.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "geniofinanciero.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gesnex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gfedating.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ghost-legion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "givingtools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -58817,7 +58519,6 @@
{ "name": "gostargazing.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goufaan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graandco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "grenlandkiropraktor.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "grupodatco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gtn-pravda.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gyakori.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59095,13 +58796,11 @@
{ "name": "meuble-house.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mexicodental.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mgiljum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mi92.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mibh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "micelius.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "michaell.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "michaell.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "michaelloveys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "micromookie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "micsell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mihgroup.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mihgroup.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59175,7 +58874,6 @@
{ "name": "nosuch.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nosuch.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nosuch.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "noteshare.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nourishandnestle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nowitzki.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "npbeta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59361,7 +59059,6 @@
{ "name": "selectionengine.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "send4x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seomik.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "seotools.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seowebexpert.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seriousaboutsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "servicerequesthub.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59516,7 +59213,6 @@
{ "name": "ufo-blogger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ultramookie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "umzuege-berlin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "umzug-berlin24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unik.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "united-german-commander.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uoone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59802,7 +59498,6 @@
{ "name": "inoxmavang.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isaropiping.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jabba.homelinux.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "joeseago.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jonas.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jxkangyifu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jz585.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59863,7 +59558,6 @@
{ "name": "nyoliveoil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oaktonhouseandgardens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "omenprinting.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "orangesquash.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ordekho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "organicskincare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oximo.lviv.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -59901,7 +59595,6 @@
{ "name": "scottmay.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "secure-computing.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securefiletransfer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "securemy.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securityrussia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seminariruumid.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "server92.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -60115,7 +59808,6 @@
{ "name": "hyyen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ifreetion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ingridbai.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "injurylawyer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inspiredlife.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "instant-clearance-sale.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "interessengemeinschaft-pregelstrasse.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -60134,7 +59826,6 @@
{ "name": "kinkyhookup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kirkwoodfence.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kooxdiving.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kopplin.family", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kosinc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kozawa.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kscarlett.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -60421,7 +60112,6 @@
{ "name": "dickord.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dictionarypro.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "directoriostelefonicos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "donetsk24.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dotesports.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dpsg-hohenlinden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "drros.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -60606,7 +60296,6 @@
{ "name": "rvsuitlaatdelen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sabbottlabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "safungerar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scevity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "searchpartners.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securevideo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seemomclick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -60818,7 +60507,6 @@
{ "name": "ekpj.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "elitepaintingsa.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "elon-musk.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "emergeandsee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "energysolutionstech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "esu.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "etnoria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -61092,7 +60780,6 @@
{ "name": "achat-volets-roulants.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "addistribution.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "agenciamseo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ak47-miyamoto.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alabordage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alfredapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "altijdleroy.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -61101,7 +60788,6 @@
{ "name": "anarajaoui.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aoe9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aptumseguros.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "arabhardware.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arcobalabs.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artacadia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asemanhotel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -61243,7 +60929,6 @@
{ "name": "ibericarcuzcomini.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ijinus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imaginationpathway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "impossible.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "impossible.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "impossiblefitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "impossiblehq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -61422,7 +61107,6 @@
{ "name": "traha.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tulsaworkshop.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tupass.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tw-hosting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tyroremotes.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uberactivist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ultimatepaleoguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -61977,7 +61661,6 @@
{ "name": "euroroad17.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "expertpanel.gc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "exvs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "eythorsson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "facesdr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "faggut.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fanzhencha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62300,7 +61983,6 @@
{ "name": "africankitchen.gallery", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "akrep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "albareport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "alexlambertz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "algebra-quiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "allesovertech.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alloutsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62424,7 +62106,6 @@
{ "name": "gunz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gyoza.beer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "haju.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hamikala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hatcher.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hikawa.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hillier-swift.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62466,7 +62147,6 @@
{ "name": "kulinaristi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kysil.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "l0v0l.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lambertz.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lapatio.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laurineprice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lawabidingcactus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62557,7 +62237,6 @@
{ "name": "realgear.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rebelko.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "redgravity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "rentaways.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "residentialmortgageholdings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ribtours.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rizonrice.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62776,7 +62455,6 @@
{ "name": "iondrey.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itpanda.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ix.mk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jackflet.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jackfletcher.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jerseyplantsdirect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jesusvazquez.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62804,7 +62482,6 @@
{ "name": "llandudnochristmasfayre.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "locksmith--sanantoniotx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lohmeyer-it.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "losmedicamentos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lowcost.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lrumeq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lsh1688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -62939,7 +62616,6 @@
{ "name": "videoseriesbiblicas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vikramkulkarni.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vqcymsa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vuldb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vvild.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wasteman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "whitevpn.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -63032,7 +62708,6 @@
{ "name": "clite.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clubmarina.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "codemahrt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "colantonio.homelinux.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "colectivos.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "commercia.srl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "communitychurchafrica.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -63057,7 +62732,6 @@
{ "name": "determapp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dhelixnet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "die-pleners.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "direct.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "directscripts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "distraction.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dmoj.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -63528,7 +63202,6 @@
{ "name": "hq77.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "huoyankan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ibb.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ieji.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "img.com.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "impactplumbingdrainage.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "indiapur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -63637,7 +63310,6 @@
{ "name": "powerwashingproslosangeles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "premsarswat.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "privc.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "quieroserdoula.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quieroserdoula.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quranliveonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ramsdensforcash.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -64256,7 +63928,6 @@
{ "name": "ip-address.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ireviewi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "irvingramo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "is-rocket.science", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isaaccomputerscience.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "isovideo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "israel-in-color.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -64396,7 +64067,6 @@
{ "name": "mimavision.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "minandolacorrupcion.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mio-ip.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "miroctum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mmprojects.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mobizma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "moduloseltaladro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -64480,7 +64150,6 @@
{ "name": "orgyporngroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "osteendiner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ota365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "otomobilforumu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "outfunnel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "outinjersey.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ouxiang.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -65090,7 +64759,6 @@
{ "name": "icetravellers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iglosujemy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ihearmedical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ihempz.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "impresa-di-pulizie.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "infohub.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "infrafile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -65170,7 +64838,6 @@
{ "name": "nivelul2.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "noiglosujemy.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "noiglosujemy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "novema.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "noxx.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "olitham.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oneearthapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -66287,7 +65954,6 @@
{ "name": "aromachat.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arttel-media.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "as8423.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "asfaleianet.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "attendanceondemand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "auvidos.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "awesomenamegenerator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -66342,7 +66008,6 @@
{ "name": "d9397.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "d9721.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "d9728.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "datelah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dd5197.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dd9297.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dd9397.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -66463,7 +66128,6 @@
{ "name": "ibavaro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ibi.mt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "icloud.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "igarage.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ii5197.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ii9297.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ii9397.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -66544,7 +66208,6 @@
{ "name": "mazepa.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "medcorfu.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "medicinasaludvida.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "meeplegamers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mehmetdursun.av.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meinewolke.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "memmertusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -66873,7 +66536,6 @@
{ "name": "z9397.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "z9721.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "z9728.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "zacco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zebranolemagicien.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zhaotongjun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zz5197.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -67167,7 +66829,6 @@
{ "name": "linkk9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lndrive.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "londonindustry.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lorenzocompeticion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lsiq.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "luckystorevn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "madsstorm.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68318,7 +67979,6 @@
{ "name": "n6957.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "n6957.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "n8ta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nattiam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netexpat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "networg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "networg.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68449,7 +68109,6 @@
{ "name": "tda602-secure-login.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tentech.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "termoidraulica.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thealchemistatelier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "theantarticx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "theaviationagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thecr3ative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68457,7 +68116,6 @@
{ "name": "thedailyshirts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "themenmedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thetipo01.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thewoosh.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tielecingenieria.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tipo01.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tldtattoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68503,7 +68161,6 @@
{ "name": "werkenbijsherpa.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wervingenselectieamsterdam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wikibuy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "workingon.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wowin58.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wowin88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ww6729.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68605,7 +68262,6 @@
{ "name": "918sa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "a1post.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "a6729.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "adamlee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ag-2.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ag-3.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ag-55.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -68731,7 +68387,6 @@
{ "name": "eons.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eqassociates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "erfolgsmaschine.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "eshterry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "especialistagoogleadwords.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "espyder.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "euc.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69009,7 +68664,6 @@
{ "name": "2222k8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "222k8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2264707.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "2isk.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "3333k8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "36594.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "518k8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69074,9 +68728,7 @@
{ "name": "brettpostin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "broadyexpress.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bsimyanmar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt269g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "butterflycare.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bytheglass.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "campaignlake.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "canine-mobility.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carefulcolor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69312,7 +68964,6 @@
{ "name": "lysbed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magnumwallet.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mailbro.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "maximind.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "md19lc8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "md21lc8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "md24lc8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69327,7 +68978,6 @@
{ "name": "mklenterprises.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mklenterprisesacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mklenterprisescoaching.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mmpaymentsystem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "momobako.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "moosmaus.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "motorzone.od.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69441,7 +69091,6 @@
{ "name": "we9988.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "webcaptive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "webhostingspace.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "werd.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "win365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xboxachievements.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--90adahrqfmec.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69743,7 +69392,6 @@
{ "name": "osterlensyd.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pandiora.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pcr24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "pixelabs.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "planet.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "popitsnack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "proctorauth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69864,7 +69512,6 @@
{ "name": "aktca.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alchemy.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "allcarespecialty.pharmacy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "allied.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alpharail.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amsfoodhk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "anora.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69901,7 +69548,6 @@
{ "name": "byraje.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "caetanoflotas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cafedelahalle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "carbonating.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casino-cash-flow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casino-cash-flow.com.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casino-cash-flow.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -69910,7 +69556,6 @@
{ "name": "casinocashflow.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casinocashflow.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casinocashflow.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cdireland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "centumail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chataberan.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chaturbate.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70027,7 +69672,6 @@
{ "name": "kk575757.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "konfekcjonowanie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "koreanrandom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kusadasiforum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "labworks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lelux.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leminhduong.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70042,7 +69686,6 @@
{ "name": "londontaxipr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "luctam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lueersen.homedns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "luu.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lxx77.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "m23cal.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magestionfinanciere.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70111,8 +69754,6 @@
{ "name": "photolessya.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pirateproxy.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "piucellulare.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "planetofwoman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "planetofwomen.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "plu-pro.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "plusmobile.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pointclickcare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70184,7 +69825,6 @@
{ "name": "toolshero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "top2servers.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topreit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "trianglebruins.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "trutopoffer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "twin-tails.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tytod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70438,11 +70078,9 @@
{ "name": "kennethandersen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "khohangmadeinvietnam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kiomara.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kirklandtriallawyer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kleinhelena.dynv6.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kmnsk.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kotonozaka.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks0816.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "labavn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "labibikids.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "landassessmentservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70522,11 +70160,9 @@
{ "name": "ocnjapartment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "okasurfbali.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oliverah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "orebolt.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "orged.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ostechnix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "otoma.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "oxygenit.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pactandoconlamoda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "panoramichq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "patriciaandpaul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70587,7 +70223,6 @@
{ "name": "sagenesykkel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sainikbiswas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "salesblackbelt.coach", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "saluddecalidad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sam-cousins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sampleappservice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sduconnect.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70641,7 +70276,6 @@
{ "name": "testmx.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "testmx.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "testmx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tetr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "textonly.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thailandlongtime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thaqfni.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70842,7 +70476,6 @@
{ "name": "588e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "58w66.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "62222.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "8102d88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "88btt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "91milk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "a2os.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -70900,8 +70533,6 @@
{ "name": "cadastroloteamento.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "calendriergn.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "careerdirectionsltd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cheapsharedhost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cheapsharedhost.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chicourologist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "childrensfurniture.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chrisseoguy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -71193,7 +70824,6 @@
{ "name": "tytocare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uboratz.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uix.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ultrasdesign.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "un-instantpoursoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unicorndesign.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "universal-village.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -71212,12 +70842,10 @@
{ "name": "vinmmo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "voevm.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "volvoconnect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "w4040w.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wallisch.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wearefrantic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "websiteboost.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "websitesmiths.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "webx5.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weecarepreschool.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weightlossoutcome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wormhol.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -71350,7 +70978,6 @@
{ "name": "9k686.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9k689.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9k692.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "9k698.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9k823.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9k826.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9k833.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -71425,7 +71052,6 @@
{ "name": "ccriderlosangeles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "centrederessourcement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chifumi.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "clubapk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "coachapp-ipass.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "coachsystem.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "combigo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -72395,11 +72021,6 @@
{ "name": "906vv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "90920.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "90n13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "918aav.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "918aff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "918bip.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "918bis.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "918bit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "918nn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "91d91.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "940365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -72756,15 +72377,6 @@
{ "name": "brusselsexpoloft.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brusselsexpostudio.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bryanarmijomd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt0101.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt0505.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt0606.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt11.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt583g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt7878.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt829.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt830g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt889g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "btta16.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buddy-acceptance-authentication-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buddy-acceptance-profiles-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -72952,7 +72564,6 @@
{ "name": "deionized.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "delcan.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "delcan.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dellacasapizzasemassas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dementieva-pennetta.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "demicrofonos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "demirdokum.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -73378,9 +72989,7 @@
{ "name": "jose-latino.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "joseenriquegonzalez.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "josefernandomorilloardila.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "journeyfitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jovenescontraelaburrimiento.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jqk918.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jsidefox.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "julia-clarete.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jungyonghwa.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -73438,8 +73047,6 @@
{ "name": "kresimir-blazevic.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kryptologie.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ks023.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks0566.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks0668.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ks257.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ks318.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ks641.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -73728,7 +73335,6 @@
{ "name": "olivejs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ollo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "omretreats.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "one-news.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "onlineautodealered.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ooo-santal.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "operanavigation.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -74050,7 +73656,6 @@
{ "name": "skante.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "skateswagger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "skirts.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sky-live.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "slipknot-site.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "smartcover.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "smartleads.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -74182,7 +73787,6 @@
{ "name": "thaihotmodels.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thaiportal.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "the51news.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "theandroidsoul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thebacteriafight.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thebestlaos.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thecarpenters.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -74577,7 +74181,6 @@
{ "name": "1lc22.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1lc55.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1vpns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "2000meter.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2018j95.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2019j95.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2020j95.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -75199,7 +74802,6 @@
{ "name": "justquoteme.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jvlfinance.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jwimps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jysk-kornteknik.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kadvi.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kalamos.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kaliboairport.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -76709,7 +76311,6 @@
{ "name": "maneql.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "maneql.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "marcus.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "martin-renze.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "masarn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mbadika.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mdihi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -76857,7 +76458,6 @@
{ "name": "undeadpirates.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unitedmatrix.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "universal-tutorial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "unlocktechs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unternehmensbewertung.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "upgradedpoints.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "v800d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77087,7 +76687,6 @@
{ "name": "instawierszyki.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "internetloansdirect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iqskinclinics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "irgendeine.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "issaias.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "it-journal.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "j81818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77141,7 +76740,6 @@
{ "name": "mitratech.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mjniessen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mkpdeepclean.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mlxysf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mokhan.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "monkatos.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "monodejuegos.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77268,7 +76866,6 @@
{ "name": "t5880.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "t81818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "temperandtantrum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "termbackti.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "terra-24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thealonas.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thealonas.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77335,7 +76932,6 @@
{ "name": "yourpocketbook.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yspa.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zeilenwind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "zenideen.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zeta.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zgndh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zhendre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77629,7 +77225,6 @@
{ "name": "sam88.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sanketsu.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scapdoors.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scheinerhaus.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seaborn.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "securelogin.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seminariosvip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77679,7 +77274,6 @@
{ "name": "tube8.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "twobitbusker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tyc001.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "unifestal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uppercap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vaisselle-nature.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vandijkmaatwerk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -77907,7 +77501,6 @@
{ "name": "lonelypawn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "loverngifts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lz898.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "m6pub.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "machinerysafety101.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magicnethosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magicvps.md", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78013,7 +77606,6 @@
{ "name": "spectrum-markets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "srfloki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "srkb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "stainhaufen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "summusglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "suniru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sunnistan.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78074,7 +77666,6 @@
{ "name": "wirkungs-forschung.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wjg.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wordops.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "woxter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wsv-pfeffingen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ww8989.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wwin818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78087,7 +77678,6 @@
{ "name": "xn--nidar-tib.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--prfontaine-c7a.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xuehao.net.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yaseminuzumcu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yesh.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yesildiyetisyen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yuleyule88game.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78104,7 +77694,6 @@
{ "name": "1lc44.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "220control.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "33weishang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "369018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "50milli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "5eki.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "690938.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78233,7 +77822,6 @@
{ "name": "goodfor.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "granli.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gregmarziomedia-dev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "griswoldwellwaterct.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gujun-sky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "haitou.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "harley-davidson-live.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78249,8 +77837,6 @@
{ "name": "highclasseducation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "holacannx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "holacbdoils.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "holenergies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "holenergies.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hongbomiao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "howmanypeoplearethereinthe.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "howmanypeoplearethereintheworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78380,7 +77966,6 @@
{ "name": "s2i.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "salvameuba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "salvandoalocombia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sanix.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "secureenduserconnection.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sevipro.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "shakthifacility.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78793,7 +78378,6 @@
{ "name": "z6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "znn.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0x15.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "131ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "162229.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22i.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "27is.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78804,7 +78388,6 @@
{ "name": "52062n.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "52062o.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "52062s.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "8869ks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "88djl.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9118inc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aanwp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78813,8 +78396,6 @@
{ "name": "acneintelligence.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "acunetix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "agencyalacarte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "agks89.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "agks998.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "airconrandburg.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aljaspod.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alpharoofga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78848,7 +78429,6 @@
{ "name": "brojagraphics.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bumble.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "campo-salado.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "carbonvision.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "caycehouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cbnainital.org.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ccli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78923,7 +78503,6 @@
{ "name": "honeymaze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ictindia.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "incomeproshoutr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "irequi.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itsallaboutplumbing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itschromeos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jakse.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -78942,9 +78521,6 @@
{ "name": "knowledgebuilds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kroyclothing.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krupacars.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks0558.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks0660.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks597.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ks89.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kstr.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lacochinacounselor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79072,7 +78648,6 @@
{ "name": "unblocked.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "unitedfitness.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "upliving.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "urb-budex.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vangore.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ventadecolchones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "veryswing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79082,7 +78657,6 @@
{ "name": "vuelacaruru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "walkingandcycling.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "warthog.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "wegiel24.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wellandslim.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weloveliving.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wemajin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79104,7 +78678,6 @@
{ "name": "ywyz.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zd739.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zone-de-confiance.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "zorgenvoorandrea.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zoubaa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0cd.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "123666365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79185,7 +78758,6 @@
{ "name": "callmewhatever.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cameramark.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "canhas.report", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cardozovargas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cardozovargas.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "casashmodel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ceramiche.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79211,7 +78783,6 @@
{ "name": "cubesugar.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cuckoo.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cursosgratuitos.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cybertrash.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "d1qvlbepn0kduz.cloudfront.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dal.net.sa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dating.wedding", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79303,7 +78874,6 @@
{ "name": "johannfritsche.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jyk.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "karawanken-tunnel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "karolak.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "katapult.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "keestalkstech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kingfast.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79584,7 +79154,6 @@
{ "name": "beeksnetwork.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "beeremovalspretoria.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "beestation13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "berndklaus.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bestcivilattorneys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bestroofbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "betmobilenigeria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79671,7 +79240,6 @@
{ "name": "flightright.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "flightright.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "flightright.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "foair.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fojing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fraufries.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "freedomtoolkit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79707,7 +79275,6 @@
{ "name": "harrisonm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hendranicholas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hl8id.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hl8th.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hosteons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hotelmonal.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hvenetworks.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -79842,7 +79409,6 @@
{ "name": "odesenvolvedor.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ohmy.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ohoreviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ojojz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "on9.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ondeapostar.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "one6688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -80298,7 +79864,6 @@
{ "name": "b67803.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b67804.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b67805.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "b70881.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b70883.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b70884.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b70885.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -80410,7 +79975,6 @@
{ "name": "creaintel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "crownsterling.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "curanderosantiago.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cvdc.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danskefilm.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dartydiscount.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dc-acupuncture.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -80550,7 +80114,6 @@
{ "name": "linuxhilux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "livelondon.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "livingspace.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "liz-fry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lohr.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lowestpriceremovals.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lsmarketing.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -80578,7 +80141,6 @@
{ "name": "mountbatten.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "msoll.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "msoll.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "msopopop.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "murmu.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myinjuryattorney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mythoughtmachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -81119,7 +80681,6 @@
{ "name": "latinoramarecords.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "le-fumoir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lesptitstutos.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lg2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "liborburda.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lightyear.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "liypoi.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -81443,7 +81004,6 @@
{ "name": "background-checks.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "backgroundchecks.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bairuo.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bandolino-bewind.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bandolino.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "baypromoteam.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "beautyandfashionadvice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -81495,7 +81055,6 @@
{ "name": "dandan101.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "datacommissioner.gov.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "defendtheweb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dekel.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "delhitalkie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "deltafinanceiro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "deltaloja.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -81581,7 +81140,6 @@
{ "name": "illange.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inspiresurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "intrixgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "intrixlifestyle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "inyr.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ipinfo.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "irenkuhn.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -81858,7 +81416,6 @@
{ "name": "22lc8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "234lc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "3002712.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "365yuwen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "3dnovedades.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "4233070.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "455328.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82076,7 +81633,6 @@
{ "name": "fonamperu.org.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "forfeiture.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "forthewin.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "forumstandaardisatie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "foselectro.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fozzie.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "frankieistanbul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82159,10 +81715,7 @@
{ "name": "k852.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k860.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k865.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k865.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k86690.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k867.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k867.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k869.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k87071.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k87072.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82238,7 +81791,6 @@
{ "name": "kimkyzcrs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kingstake.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kneli.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "koladeogunleye.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kritikahotels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "larsson-ornmark.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc0188.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82255,18 +81807,14 @@
{ "name": "lc3746.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3747.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3748.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc3757.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3759.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3760.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc3772.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3774.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc3776.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3778.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3779.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3780.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3781.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3782.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc3783.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3793.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3794.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3795.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82353,7 +81901,6 @@
{ "name": "lc8md77.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc90000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc9108.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc9256.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc9862.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc9899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc9900.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82399,7 +81946,6 @@
{ "name": "mochilerostailandia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mojizuri.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "moninformaticien.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "moninformaticien.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "movahoteis.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myebony.cam", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myintimtoys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82514,7 +82060,6 @@
{ "name": "tiendadolca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "timeforcoffe.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tishopsv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "toldositajuba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "travelassist.us.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "trechosemilhas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "trezor.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -82894,7 +82439,6 @@
{ "name": "openbayes.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "osano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "paardenpro.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "pacificintegration.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "packetoverflow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "panthi.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "parfum-selbermachen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83153,7 +82697,6 @@
{ "name": "boundaryvets.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bracknellvets.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brainboxai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "breakingtech.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brindice.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "broadwayvets.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bszoft.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83338,8 +82881,6 @@
{ "name": "josealonsodds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "josephquinaucho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jourdain.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k88398.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k88399.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k88601.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k88602.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k88603.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83421,7 +82962,6 @@
{ "name": "myqservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nachovni.pp.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "naiaokami.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nategreen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ndx.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netferie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netferie.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83466,7 +83006,6 @@
{ "name": "nic.youtube", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nic.zip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nihaarpstars.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ningrui.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nocommentsallowed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nordvestkysten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nordvestkysten.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83486,7 +83025,6 @@
{ "name": "opp.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ordevanoranjenassau.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ortopedistamarcelocosta.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "osteolaclusaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "otocenterfelix.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oxidemusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "p-damda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83553,7 +83091,6 @@
{ "name": "seedboite.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "selltous.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "senshot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "seriesdatv.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "servermaster.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "setuplog.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sevilinux.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83585,7 +83122,6 @@
{ "name": "spellic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sportchirp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "spotworld.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ssfbank.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ssmut.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stage-recuperation-points-bordeaux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stage-recuperation-points-lille.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -83790,7 +83326,6 @@
{ "name": "brendansbits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brookes.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brutecloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "burotec-sarl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buster.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buycurious.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bxegypt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84064,7 +83599,6 @@
{ "name": "on-targettrainingcourses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "on-this.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "onlineltctraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "op3y.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "openstakes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "opstory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ornsyn.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84339,7 +83873,6 @@
{ "name": "aarwer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aarwer.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "abacross.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "abelrubio.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "abona24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aboutasia-trade.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aboutasia.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84368,7 +83901,6 @@
{ "name": "am8028.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "am8866m.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "am8895.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "amalficoastransfers.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amazighlove.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amb8.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amjinc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84385,7 +83917,6 @@
{ "name": "arhitekti.hr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artikel9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artisan-emmanuel.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "artsacademics.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aseth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "askexpert.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asmrbuluo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84762,7 +84293,6 @@
{ "name": "gainins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gantt-chart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "garagedoorrepaircedarhilltx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gentapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gentlemens-life.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gentlentapis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "germfr.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -84874,7 +84404,6 @@
{ "name": "kyivstar-internet.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "labs.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ladeboks.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lambda.dance", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lamchannang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lamnhom.com.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laprensadelasagradafamilia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -85087,7 +84616,6 @@
{ "name": "tapasnandi.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tarba-schluesseldienst-duesseldorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tateishi-ip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tathanhson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tauerperfumes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tche.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techfishnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -85653,7 +85181,6 @@
{ "name": "metrolaut.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "miacordeonstereo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mightybit.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mijam.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mijnkantoor.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mikedhoore.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "minibaggerverleih-aulendorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86389,7 +85916,6 @@
{ "name": "maxiglobal.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meekhak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meldpuntemma.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "melento.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "metadedi.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "microcyber.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mijnkwadraad.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86466,7 +85992,6 @@
{ "name": "q81365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "q82365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "qpaypro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "qualiacomputers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "r81365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "r82365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rainbowswingers.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86573,7 +86098,6 @@
{ "name": "valutienda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vectordtg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vegner.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "verymetal.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vibgyorhigh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "viceversa2013.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "videograb.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86681,7 +86205,6 @@
{ "name": "ahlstrom-filters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alibamu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alphabet-z.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "alvaiazere.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "amanduscommunication.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ambra.net.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ameeventos.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86693,7 +86216,6 @@
{ "name": "apexfacades.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "apsscientific.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arablovepet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "arcismant.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arktalentsolutions.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arooshi.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asiaflash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86803,14 +86325,12 @@
{ "name": "dubyou.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "durastill-distiller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dustpla.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dwword.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ebooklib.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "echoesfromantiquity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "edisongroup.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "edisonprint.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "edisontent.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eikerposten.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "eladvardi.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "elgenero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eliezermarcano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "elmarchive.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86859,8 +86379,6 @@
{ "name": "gevme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "giancarlomarino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "go-indochine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "go6.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "go6lab.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goftava.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "golvlyftarna.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goolnk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -86890,7 +86408,6 @@
{ "name": "ian678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ian678.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ibadboy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ibexrepair.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imagevillage.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imaxinaria.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imgbu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87112,7 +86629,6 @@
{ "name": "shtaketnik-metall.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sindlerova.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sindlerova.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sinog.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sloanestreetdeli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sologoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sotaytienganh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87132,7 +86648,6 @@
{ "name": "techday.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techday.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techvrse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "techzhou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tehranlittmann.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "telegram-sms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "teleportweb.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87177,7 +86692,6 @@
{ "name": "vl-grafikdesign.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vrgamecritic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vrgametrailers.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vveactiefbeheer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wa7sh-seo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "waaifu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wbcasaverde.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87474,7 +86988,6 @@
{ "name": "chinesemedicine.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "christianbsl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "christianhamacher.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cimala5bta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "circlepluscircle.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "circumstances.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ckenel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87652,7 +87165,6 @@
{ "name": "globalizationpedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "glpepper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goddard.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "godknowsclothing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gokhana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gordon-reid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gorlani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87691,7 +87203,6 @@
{ "name": "hoorig.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hostwinds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hotdates18.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hotrowordpress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "houselovin.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hsimrall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hyundaisrilanka.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87723,7 +87234,6 @@
{ "name": "integrityoklahoma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "interallied.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "interconlarp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "internettradie.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "intracdf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "introverted.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ionutnechita.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87744,7 +87254,6 @@
{ "name": "jchn.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jed.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jedcg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jellypepper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jeremywinn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jeremywinn.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jeretec.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87808,7 +87317,6 @@
{ "name": "legion.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lerefugedujambon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lesacredescouleurs.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "leventmebel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "levidromelist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "libertytereconoce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "libertywines.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -87865,7 +87373,6 @@
{ "name": "minhng99.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "minimalmx.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mipasevip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mitsubishi-club.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mix-recruit.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mkgraves.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mlstav.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88003,7 +87510,6 @@
{ "name": "promax.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "promocjedladzieci.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "promotech.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "propertysold.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "prosperfit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "prostoporno.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ptk-svarka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88023,7 +87529,6 @@
{ "name": "rama.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rassadacvetov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rasset.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ratul.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rayfalling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "recordmeeting.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "recreatieftotaal.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88064,7 +87569,6 @@
{ "name": "sanctum.geek.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sandra-perlbach.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "saorsat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "sarahjanecreates.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "saronikos.guide", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scatterscasino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "schafzwitschern.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88716,7 +88220,6 @@
{ "name": "zolotoy-standart.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "01.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "038899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "0verl0rd.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1248.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "1eanda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2fr3.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88830,8 +88333,6 @@
{ "name": "dfc52.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "diamondyacca.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "diesicheremail.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "digipolis.gent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dominionedge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "douzer.earth", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dreamingwolf.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "drtis.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -88965,7 +88466,6 @@
{ "name": "nutritionalsupplement.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "obliviate.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "officevibe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "onlinecasinolisboa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "opendoorcounselingpa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "opnaarsalto.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "opticasocialvision.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89031,7 +88531,6 @@
{ "name": "sardinianvillas.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sardinianvillas.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "saxis.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scarabcoder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "schiau.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "schoolofequineshiatsu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "servermacher.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89083,7 +88582,6 @@
{ "name": "vlqnc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vnetboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "voedselbankmoerwijk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vontainment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vvtv.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "warmsquirrel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "warupu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89117,37 +88615,12 @@
{ "name": "x59788.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "x59888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "x59988.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98h.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98i.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98k.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98l.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98m.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98n.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98o.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98p.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98q.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98r.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98s.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98w.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98y.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x98z.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x993.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xamax.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xemcloud.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xiaoneijun.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xiaoneimao.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--lti-3qa.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpj000444.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpj000555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpj000666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpj678678.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xpj909.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpjbeting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xpjcs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yellsy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yourbusinesscommunity.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yourpalmbeachcountyrealtor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89218,7 +88691,6 @@
{ "name": "asm.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asps.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "audioblackmagic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "audiovoodoo.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b89bb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b89cc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b89dd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89269,7 +88741,6 @@
{ "name": "bet7234.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "betza.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bicicletassym.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "bidadari.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "biotecommunity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bizeasesupport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "blixtv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89362,7 +88833,6 @@
{ "name": "elijahzawesome.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "emergencycommand.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "empreinte.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "energy.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eoy.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "epsi.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "espacioprofundo.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89379,7 +88849,6 @@
{ "name": "fauxcams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fenriragic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fetishblend.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "fieldelite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "finprison.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fish-n-chips.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fitrecepty.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -89389,7 +88858,6 @@
{ "name": "foxycredit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fracturedperspective.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "free-sex-sites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "freecodezilla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "freedomdujour.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "freetext.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fsd.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90169,7 +89637,6 @@
{ "name": "palessit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pcf-frankfurt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pipscprd.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "poirierlavoie.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pojdnafp.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pomdoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "poquiloco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90407,7 +89874,6 @@
{ "name": "autopeople.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "averste.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aviannahelise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "aviationweather.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "awinninghabit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "axearrow.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "azl-app.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90420,7 +89886,6 @@
{ "name": "b67883.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b67884.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b67885.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "b9l8tt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bachomp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "backspace.dev", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "backspace.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90477,12 +89942,6 @@
{ "name": "brisbaneflamenco.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brooklyntheborough.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brunoamaral.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt1313.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt1515.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt185.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt494g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt949g.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "btt9595.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buffalowdown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "burdine-andersoninc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "businessgram.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90520,10 +89979,8 @@
{ "name": "chanderson.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chaoscommunication.camp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chaturbate.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "chaussmomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "checkmedia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "christoph-gadow.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cimaflash.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cleankey.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clearlakechildrenscenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clientesal100.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90583,12 +90040,6 @@
{ "name": "cybersecurity.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cyprus-company-for.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "d-vision-create.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d868.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d881.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d882.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d885.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d889.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d898.app", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dailyblocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dailyngn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "daltcore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90782,7 +90233,6 @@
{ "name": "gobiernousa.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gocdn.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "godofredo.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gomelagromashplus.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gometa.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gomods.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goontu.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -90856,7 +90306,6 @@
{ "name": "iemsamex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ifashionable.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "iganesh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ikhwanto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ilawgix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ilovehoney.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imoasis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91022,13 +90471,9 @@
{ "name": "mcsteve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "medibasket.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "megamov.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "megamov.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "megamov.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "megamov.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "megazine3.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meinforum.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meldwekker.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mentorbuk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "menurutparaahli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mettin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "meziblog.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91038,9 +90483,7 @@
{ "name": "milanvit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "milehighmaniac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mileyweasel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "millim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "minicampingshalom.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "minilov.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mississippigenealogy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mitchkalf.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mmxx-distribution.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91048,7 +90491,6 @@
{ "name": "mobileinternetbanking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mobilmobil.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mobincube.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mobinstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "modelbase.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mohamedhamuda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "montsearias.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91073,7 +90515,6 @@
{ "name": "myersking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myforum.community", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mygate.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "mymartinbeckeropenhab.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mypharmjar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nachovni.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nasehyar.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91203,7 +90644,6 @@
{ "name": "pornokran.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "postman.com.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pouchdog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "poupee.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "powertoolsrater.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ppissis.com.cy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "preciodolarhoymexico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91459,7 +90899,6 @@
{ "name": "tloschinski.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tobdesignfirm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "toepferwerk.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tommyphotographie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "toolsense.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "toperadigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "totalwebboost.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91500,7 +90939,6 @@
{ "name": "unpause.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "upgradeguru.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uponsel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "uptime.fm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uptownbabe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "uropenn.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "usa.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91571,7 +91009,6 @@
{ "name": "xtom.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xtom.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xtom.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xuexi.icu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xxxuno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yahav.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yasic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91593,14 +91030,9 @@
{ "name": "00228vip5.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228vip6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228vip8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "00228vv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228w.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "00228ww.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "00228x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228xx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228y.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "00228yy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "00228z.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "00228zz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "01zemi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0cdn.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91615,7 +91047,6 @@
{ "name": "22884.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22884a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22884b.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "22884c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22884d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22884e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "22884f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91673,7 +91104,6 @@
{ "name": "9968love.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "9968xpj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "a00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "a77018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aa00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aarsunwoods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "abelordbalagtas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91730,7 +91160,6 @@
{ "name": "archim.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arest.web.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arganwinkel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "artchic.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aryankhera.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asgardiamc.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "assessortrainingonline.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91752,7 +91181,6 @@
{ "name": "avionschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "axisins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "azadcyber.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "b00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b77018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "baixarvideosgratis.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bajarvideosinstagram.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91785,7 +91213,6 @@
{ "name": "beus.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bihaberkalma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bijou.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "billchen.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "billiebone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bim0s.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "binarypuzzle.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -91887,14 +91314,12 @@
{ "name": "cr1coffee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "creati.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "crossconnected.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "crowdfundingwaterresearch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cs-kurnik.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cube-filing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cumulus.photo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "curl.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "customerfocus.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "d00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "d88.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dada.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "daimonikos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dalvik.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92085,7 +91510,6 @@
{ "name": "gressnet.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gridky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gryphonnetworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gsaadvantage.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gugcstudentguild.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "guochang.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "guyuy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92607,7 +92031,6 @@
{ "name": "stopsscam.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "strategic9.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "strategiczni.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "strenght.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stress-mess-punkte.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "stuccorepaircontractors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "subafoto.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92619,12 +92042,10 @@
{ "name": "symbolic.software", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "synergenxhealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "synth.style", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "t00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "t4gh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tadzkitchen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tamboa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tanahtinggi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tandoanh.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tapple.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "taxi-meridian.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tcspartner.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92667,7 +92088,6 @@
{ "name": "tomiubezpiecz.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topbdnews.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topdomainsandhosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tophatpuffin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topofmind.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "torisamaahirusama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "totalmdplan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92785,7 +92205,6 @@
{ "name": "www00228d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "www00228e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wwwn888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "x00228.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xavio-design.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xbblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xbots.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -92810,11 +92229,9 @@
{ "name": "yannyann.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yellowtrace.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yj4p.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yjav.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjav11.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjav8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjav9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yjsp.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjsp07.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjsp17.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yjsp333.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -93892,7 +93309,6 @@
{ "name": "63wq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "663365i.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "663365j.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "663365j.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "663365k.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "663365k.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "663365l.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94306,9 +93722,7 @@
{ "name": "b131000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b2222.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b789.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "b979555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "b979666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "b979999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "badnjar.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "banajanitorialservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bassment.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94401,7 +93815,6 @@
{ "name": "elsenzhafen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "employmentlawworldview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "empregopraontem.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "eproceedings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "equinenow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "equityelevate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eremnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94431,7 +93844,6 @@
{ "name": "flowdise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "fnckfashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "foochia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "fortressis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "francoise-angelini.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "frederickbourget.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "funtransport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94498,7 +93910,6 @@
{ "name": "itabi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itajvi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "itsapps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "j51365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jackwarren.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jakartacloudhosting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jamiehansonyoga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94585,7 +93996,6 @@
{ "name": "neosys.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "netrilo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "newgle.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nextsociety.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nexustraducoes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ngawa-avocat-paris.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "niemandmussirgendwas.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94605,21 +94015,6 @@
{ "name": "outrider.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "owmobility.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "p7jl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88813.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88814.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88816.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88817.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88823.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88825.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88827.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88829.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88835.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88836.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88845.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88848.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88856.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p88867.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "p888a.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pablosaraiva.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "panelesyperfiles.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "papascave.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94790,7 +94185,6 @@
{ "name": "vichama.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "victorique.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "visse-if.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vns6654.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vosges-tourisme.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "w123.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "warmteshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94818,7 +94212,6 @@
{ "name": "zamor.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zeglujemy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zhoujianghan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "zieler.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zivver.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0x12.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0x22.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -94881,7 +94274,6 @@
{ "name": "brisbanecashforcars.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "buyiptv.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "calibreapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "camwoodbats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carbuzz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cardiaccane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cartale.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -95176,7 +94568,6 @@
{ "name": "urbanon.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "v.ps", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "v8abc.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vaioswolke.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vetapp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "viaura.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "victoria-legis.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -95229,7 +94620,6 @@
{ "name": "bugfender.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "burgerbites.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "candytip.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cerecup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ceyhanmolla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cheapfarestouk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "chowchowugo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -95403,7 +94793,6 @@
{ "name": "pechibani.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "penisenlargementpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pixelshape.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "placenet.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "platform.ltd.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pragatiparasguesthouse.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "prod-simplesend-api.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -95421,7 +94810,6 @@
{ "name": "sharingiscaring.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "shaunallen.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "shiulungkungfu.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "signal34.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "simplesend.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "skidzun.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sorocabacopos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -95511,7 +94899,6 @@
{ "name": "xz0.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ymy.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "you-livetv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yuweetek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zakbk.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0km.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "0x2a.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -96179,7 +95566,6 @@
{ "name": "gutterguardcharlotte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "guttershutter.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "habibitravels.com.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hae.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "haizrulamrie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hby.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "heckmann.photos", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -96233,7 +95619,6 @@
{ "name": "jettenbommelaer.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jettenjachtbouw.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "joico.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "jonaskruckenberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "josephrichard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jrfortune.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "julianporras.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -96309,7 +95694,6 @@
{ "name": "luxplay.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lvee.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lvfc.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "machkovi.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "madeincana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magazineflex.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mailsupport.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -99015,7 +98399,6 @@
{ "name": "e-umbrellas.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "e-zine.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "earth-quake.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "eas.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eastdream.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eastendonline.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eastheaven.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -99790,7 +99173,6 @@
{ "name": "getinfoleads.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "getme.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "getreadyforever.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "getrealutah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gettwo.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "getvalidate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "getyoureuro.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -99931,7 +99313,6 @@
{ "name": "gpl25.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gppro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graberbooks.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "grabtech.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gracia-club.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graciasmarvin.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graduados.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -100368,7 +99749,6 @@
{ "name": "imeria.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imgo.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "imgo.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "imiku.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "immoraldoctors.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "immortal-it.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "immune.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -100702,26 +100082,6 @@
{ "name": "justpdf.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "justrighthsc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "jwompa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866088.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866089.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866090.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866091.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866092.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866093.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866094.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866095.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866096.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866097.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866098.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866099.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866100.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866101.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866102.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866103.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866104.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866105.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866106.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "k8866107.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k9lady.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "k9life.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ka4ka-ru.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -101130,7 +100490,6 @@
{ "name": "lean-consulting.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leandromarcolino.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "learn-this.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "learolstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leatherstreet.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lebensinselparaguay.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lechenietravami.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -102066,7 +101425,6 @@
{ "name": "mywebserver.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myweightlosstips.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "myzarabot.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "n-mail.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "n3rd0rama.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nabeer.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nabiev.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -102280,7 +101638,6 @@
{ "name": "no-terrorism.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "no-war-on-iraq.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "noart.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nocoffeetech.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nocturnos.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nodde.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nonemail.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -102573,7 +101930,6 @@
{ "name": "overtunes.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ovez.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ovodakadarkut.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "owall.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oxaliz.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oxbridge.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oxigenoinformatica.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -104204,8 +103560,6 @@
{ "name": "start-knighki.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "startbetter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "startgeophysical.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "startnowmakingmoneyonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "startpa.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "startplats.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "startupyourmind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "statcenter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -104591,7 +103945,6 @@
{ "name": "textcounter.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "textil-kyoto.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "textsite.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tfrei.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thailandpropertylisting.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thailandvariety.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thais.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106127,7 +105480,6 @@
{ "name": "claudia-halfter.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "claudiahalfter.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "clean.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "clouditme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cm-valenca.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "codefive.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "colah.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106166,7 +105518,6 @@
{ "name": "ebooksa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eccologic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ecn.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "elartedelaweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "electricianboksburg24-7.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "elona-wvw.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "emarketingprince.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106176,7 +105527,6 @@
{ "name": "epicsoft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "escobpb.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "esea.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "esj.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "esperanto.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eudireto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "evga.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106347,7 +105697,6 @@
{ "name": "kitagawa-internal-medicine-clinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "klankenkast.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "klausbijou.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kngkng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "knowledze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kod13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "koehn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106355,13 +105704,11 @@
{ "name": "konzepttreu.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kood13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "koood13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kouroshnet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krishnakalisaha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kurenivka.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kurniasihmandiri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lakewylietax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lapulgaflamenco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lazyw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ledcross.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "legion.hosting", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lendingmate.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106386,7 +105733,6 @@
{ "name": "macc.org.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "madebythijmen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "magicorama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "maleylabapplications.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mansys.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "maratondeclics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "matjarkom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106488,7 +105834,6 @@
{ "name": "roethelheim.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "romatours.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rosaserra.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "rot256.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "running.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rx-safety.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sabrinajoiasvarejo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106512,8 +105857,6 @@
{ "name": "seditious.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "segdomedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "seniorhomexchange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "seocompany1.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "seowebstat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sertaobom.eco.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "serverfix.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sextop1.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106537,7 +105880,6 @@
{ "name": "stove-server.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sultangroup.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "supedium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "swj.red", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tandemwise.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tannextcloud.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tarahancenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106546,11 +105888,9 @@
{ "name": "tcmk-tomsk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "techsna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "theatrepremol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thequalitycleaning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thesemperfibeard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tomasdrtina.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tomphenix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "top10antivirus.review", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "torohandyman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tsaama2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tsproesasac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106577,7 +105917,6 @@
{ "name": "vulnerabilityscans.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wars.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "waseetalnokhba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "wealthsuccess.edu.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "webparallevar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "weddingwire.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wedooper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106595,7 +105934,6 @@
{ "name": "wuifan.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wuifan.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wuifan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xialingshi.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xkeyc.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn----7sbbhzfbdo6dnf.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--xwqa8512b.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106619,7 +105957,6 @@
{ "name": "557bbb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "722sss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "795sss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "840.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "991ccc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aaflalo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "abeshultz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106676,7 +106013,6 @@
{ "name": "boundless-designs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "brazilhealth.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "breteuilcommerceartisanat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "brexitmart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "bride.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "butlerdisposal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "camshowhive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106934,7 +106270,6 @@
{ "name": "mdsconcept.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "medicano.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "medicoway.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "meer-der-ideen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mendrala.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mendrala.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mendrala.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -106966,7 +106301,6 @@
{ "name": "nbsgames.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nectere.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "nejrecept.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "networkprosecurity.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "newikis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "newshour.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ngservers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107007,7 +106341,6 @@
{ "name": "philippehannes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "philpatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "piezus.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "pjdigitalmarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "platform-med.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "playorigin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "playstationplus.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107020,7 +106353,6 @@
{ "name": "pro-dog.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "proficiodigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "proficiodigital.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "proitsecurity.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "protection-plexi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "protection-plexi.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "psicologomogidascruzes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107035,7 +106367,6 @@
{ "name": "rabec.com.sa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "refansta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "renedekoeijer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "reseau-protestant.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ricor.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "riley.love", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rinton.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107149,7 +106480,6 @@
{ "name": "zook.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "016910804.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "123start.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "2002000.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "2makeu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "4driver.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "4hypo.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107187,7 +106517,6 @@
{ "name": "apuraytravel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arabwomen.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "archaeology.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "aromaimportado.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artlinestix.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artofclouds.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asdf.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107232,7 +106561,6 @@
{ "name": "campus-competences.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "candalgic.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "canopy.garden", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "captainkids.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cardoneshop.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "careify.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cateromarket.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107274,7 +106602,6 @@
{ "name": "covidmodel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cpad.org.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "crea.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "creatapeak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "credee.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cricoff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "crohnszone.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107297,7 +106624,6 @@
{ "name": "digino.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "digino.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "digino.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "digitalmarketerconsultant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dioxido.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dnddobbelstenen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dossierweb.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107412,31 +106738,10 @@
{ "name": "korkortonline.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krome.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "krpaforum.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks178.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks187.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks500.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks700.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ks800.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "l2l.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lablic-beta.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "langages-programmation.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "latronicenergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80803.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80804.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80805.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80806.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80807.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80808.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80809.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80810.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80811.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80812.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80813.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80815.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80817.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80819.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80820.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lejade.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "letterzaken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leyendaluzrenacer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107572,7 +106877,6 @@
{ "name": "ragnarokhpg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rallyekrumlov.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rapidxray.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ravihotel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ravijuhend.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rcsscontractors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rebelsewerservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107742,7 +107046,6 @@
{ "name": "yanwo.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yg-crew.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yobda.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yojanahub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "youbehero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ywyz.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zagainov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107836,7 +107139,6 @@
{ "name": "cafminiapp.ac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "callumgroeger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "camslagz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "capradip.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "car-clean-nord.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carcleannord.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "carinaklijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -107971,10 +107273,8 @@
{ "name": "georgewilsonvsgatsbyjs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gestalte-deinen-balkon.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "getsmartlife.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gilar2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goenea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "goldenworldec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "goover.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "grapheneengine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graphicapps.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "graphicwallet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108036,7 +107336,6 @@
{ "name": "kibazen.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kinklist.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kinkyheretics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "kitajagakawasan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kmzs123.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kocovi.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "kokily.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108048,10 +107347,6 @@
{ "name": "layers.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lazoscollection.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lc3755.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80801.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80802.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80814.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc80816.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "learnpine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lebozec.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lidl.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108200,7 +107495,6 @@
{ "name": "sharonsplace.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "shouohkai-dental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sipln.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "skrealtyplus.co.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "smaden.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "smikom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "snitch.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108221,7 +107515,6 @@
{ "name": "survivalfitnessplan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "svatba.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sylencegsm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "synology.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "systemplust.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "taguiginfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "takeshi.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108386,7 +107679,6 @@
{ "name": "casalor.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cccp-o.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ccnexus.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "cdxmaster.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cecilgreens.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ceifx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "certified-cpr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108422,7 +107714,6 @@
{ "name": "daniel-san.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "danielives.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "darkovepredmety.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "datashenas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "davusito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dayman.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dccomputerrepair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108454,7 +107745,6 @@
{ "name": "ecomoov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eggzr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eklavyacs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "elbassira.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eleonoramazzola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "emeraldshield.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "empty.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108607,7 +107897,6 @@
{ "name": "mandospersonalizados.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "marketingseo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "marklehane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "marshallpeak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "marta.uz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mask4all.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mastercareplus-demo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108780,7 +108069,6 @@
{ "name": "storebusy.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "storeinstallieren.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "strafe-muss-sein.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "supercima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "suritylabs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sylvain.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "synapseretailing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108904,7 +108192,6 @@
{ "name": "aprenderjuntos.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "aptekaref.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arcanehardware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "area51-project.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "argon2.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "armilex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "arobaz-informatique.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -108914,7 +108201,6 @@
{ "name": "artesaniaselmagodeoz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artisansofsleep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "artizlibranza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "artworksthatlookgood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asabharwal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "asalearn.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "assignmentshelp.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109161,7 +108447,6 @@
{ "name": "htsm.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hunhee.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hushbabysleep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "hutuishangmeng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hypertensionexplained.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hypno-thera.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "hysupchile.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109344,7 +108629,6 @@
{ "name": "pueblanmilksnake.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "purepowercycle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pygmyleafchameleon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "qnixon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quietapple.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "quoteee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ratsmicedormice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109425,14 +108709,10 @@
{ "name": "theartofe.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thebookiejoint.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thefireflygrill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "thepainapple.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thrivebymitchelle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "timecaptis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tirion.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tirion.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tirion.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "todocruces.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "topnotchsociety.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "topvision.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tra-tra.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tradesrenovations.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109461,7 +108741,6 @@
{ "name": "virus.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vlaser.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "volreinsistemas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vondenstein.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "voxengo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "waf.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wallamigos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109469,7 +108748,6 @@
{ "name": "warszawa-pranie-dywanow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "webslate.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wheyteck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "why7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "willobyhomes.realestate", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wineforhelp.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "wmbey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109524,7 +108802,6 @@
{ "name": "airtrolinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "alfransiacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "allitschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "alnavedic.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "altecgmbh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "altrasoluzione.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ambulanceplus.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109532,7 +108809,6 @@
{ "name": "amroofingelpaso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "andrewsandford.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "androtiyas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "anitahebe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "anthonywesbrook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "antivirus.directory", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "anzahcraft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109612,7 +108888,6 @@
{ "name": "computingaustralia.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "coniectoinvestments.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "continuumm-tech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "coopemep.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cooperativaminka.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cravecraftonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "cuscocontable.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109650,7 +108925,6 @@
{ "name": "dy.express", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dynamicsdays.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "e30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "easynotes4u.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ecozona.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "eda.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "edok.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109781,7 +109055,6 @@
{ "name": "laptopnewbie.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laudlab.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "laudworks.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lc9915.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "leales.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lecoquelicot.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "legterm.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109794,7 +109067,6 @@
{ "name": "localcryptos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lojasmary.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "longoconsulting.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "los-hoppers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lost-illusions.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lostserial.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lourencolar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109865,7 +109137,6 @@
{ "name": "oblitsov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ofasoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ofcac.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ohitsviral.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "olegchursin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "olimpikfit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "olimpikfit.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -109929,7 +109200,6 @@
{ "name": "pornogo.sex", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "portfreezone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "portusidades.com.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "postfree.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "pp30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ppapogey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ppapogey.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -110064,7 +109334,6 @@
{ "name": "taskseller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "teacuppersiancats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "teacupyorkiespets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "tecnikan.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tendoryu-aikido.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "tfok.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "thaserv.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -110115,7 +109384,6 @@
{ "name": "velorail01.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "very-stylish.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vestakassa-online.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "veterinariaelcrack.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vihotar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vinaygarg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "visionmedicale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -110153,7 +109421,6 @@
{ "name": "yewtu.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yuina.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yukinarita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "yvcr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yvonne-stingel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "yy30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "z30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -110162,6 +109429,3268 @@
{ "name": "zorox.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zporno.porn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zz30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flynnhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0x5f3759df.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "112q.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123hpcom.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1337ersprime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "205920.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3niu10.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "573sss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "797sss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7qlm.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "941618.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aaex.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abram-lab.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "absurdopedia.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aciclinical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adaiacorporation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "admin-gator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "admin-gator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "admingator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "admingator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aechelon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "afive.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "africanchildrenschoir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aiken.golf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aim.org.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aion-beritra.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akoya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aktarma.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexgsites.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alghadpowersolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alinol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alpineitltd.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amatya.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ameri.capital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "americanhoneyproducers.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anblife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antidopamine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anuncioacompanhantes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arc.run", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "argovpn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "askingmonkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asocedune.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aspenrealestate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aspire-irb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "astellaria.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atheatac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aube.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autumn.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avgeeksunited.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awtogid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "babaganousha.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bahai-rdc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bahiastudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baixtaxi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balosport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bazhan.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beijing30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bellezademujeres.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "berichandcreamy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "berjou.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "big4mas.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blueparrotpainting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bookworld.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "borsodsakk.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bothive.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bricmon.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "britishcountrymusicfestival.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buerliag.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "builtinsf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buycompanyname.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buynowbol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c19explorer.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c4safety.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cachacagaboardi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cangku.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "capitalism.rip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cariadcymru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carolinelanthier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casaruralcincoleyendas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casasincreibles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "catpic.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cccanna.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celebrate-creativity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celebritypictures.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cerberusecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cgirb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cgplumbing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ch-y.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "charitocracy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "charlie-liveshow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chatx.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chkserv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chongqing30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciplerli.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "classificar.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clintraxglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clixa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudlfront.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudsys.dnsalias.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coinsconnect.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conceptground.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "concern.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "confortiaperu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consultahn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "core.md", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cortho.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "covidfreeathome.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "covidlive.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "covidpppstore.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creacode.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cri-cloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crm911.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptocentral.africa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptotaxonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csgostash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyptechost.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dagyirivera.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dailyw88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "damebe.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dan124.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danielnaaman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dawlya-19089.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daxrunbase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "denoroulette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devandy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devincave.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devopt.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dexign.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diabhalstaff.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diaspordc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dickp.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "didakeanimaciones.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dietaparaadelgazar1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digit2go.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalgeekspro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diplomatcruises.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "django-lessons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dnspropagation.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dodolle.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dokutech.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domainsetup.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "douglasrumbaugh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dripindustries.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drjungspine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dunangel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e5xbps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebcfx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebuyon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecohousejapan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecologiahoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eg7.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eladalfassa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elimidrol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elphnt.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emarch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enstructo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epharmasolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esale.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esprit.tn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etbtoursegypt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eteachbd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "europeanbizhealthcare.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exbasi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extrasauber.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extrasauber.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extrasauber.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f88vip1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f88vip101.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f88vip113.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facileway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fazz.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "felixgerschau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fenyks.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fidemlenceria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finalgambit.band", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "firstbaptistchurchofchrist.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fitmybike.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fl0w.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowbuk.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowcrypt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fluenciamodas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fogonrustico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fors.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fortcommunity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freecam-sex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freedailygifts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freehdporn.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freehqporno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freshmusicsheets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frog.industries", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frown.town", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fujian30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fynbo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "g2price.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaboardi.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gansu30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaonadigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garage.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gatehub.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gbhem.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekcreations.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gergoladi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghostruler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "giannifoti.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "girassolacessorios.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glaccessonline.icu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glserviciosweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gold-iptv.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gregbonner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grsstore.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gsoluzioniweb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guadaluperoses.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guangdong30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gudbrand.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guiadev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guizhou30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guruminode.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gzhzg.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "h5q.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hack-bang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hainan30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hakiminvestment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "handsaccounting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hebei30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heilongjiang30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heixiongwl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hejazultra.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "henan30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hidraulic.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hitpt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hostingdiario.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "houlang.ac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "houseepropiedadraiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hqmovies.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hqmovies.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hrlab.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hu2ty.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hubei30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hunan30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iflipy.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ihct.sch.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imaginativo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imanageproducts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imf-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imfacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "implantologiadentalgt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "impressionusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "incnjp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "interchangeillawarra.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "internetstones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invicti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inweb.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iprash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "irwinvalera.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isinolsun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "islide-powerpoint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iszy.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iszy.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itaro.bot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iurisnovagestion.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamereviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jiangsu30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jiangxi30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jilin30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jonathan.us.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jpdineroasi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jpmultimedia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "js-webcoding.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "js889.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jswc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juraganilmu.web.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kamery.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanker.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kap-kirche.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "karwish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kcpromi.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kescher.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kihi.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kingsol.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kizuki1749.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "klinikum-oldenburg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "klofteam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kloftowel.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kloftowel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "knowledge-base.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koko.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kor.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kosturanov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kpop.events", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuestensiegel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kutalek.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuzmik.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuzmik.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuzmiks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lagrotta.pizza", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lanthanum.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lawncorner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ld-duesseldorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "learnblue.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lepallec.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lgerman.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liaoning30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lidservicessac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "limportemps.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linux.monster", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lkotlarenko.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "localdmcs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loxdonmarkets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lundlist.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mackungfu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "macupdate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madadmin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mail.ac", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "makocontrols.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mamapatrzy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marinelife.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "markocloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marturet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mascarillas.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matega.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mclanedirect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mclanexpress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meetsummer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "merkleforest.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mgmpic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "microbird.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "microsolenergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikkel.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minapan.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "miraclesformya.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "misterd.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "misterorion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlada-moda.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlirb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlpvcdn.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moblkar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modacruz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mods.fm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monveilleuretmoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morwynna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrsourabh.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "msoida.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mueblescuerolorca.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mui.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mujeresfemeninas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muskokadanceconnection.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mutsumikai8989.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myerscreekcascades.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mypdns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mypdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysites.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nanomap.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natuwa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naxoprojects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neimenggu30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neirb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nestorgaleanomegamariachi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netweaver.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "newyorkhipknee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ningxia30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ninpang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nixcp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noawildschut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nodi.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notaryassistant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "novaway.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nycstyleboutique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oecdpisaforschools.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offtherayles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ohiowebtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orbitgoods.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osdnc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "otrainfans.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "overlandirelandtours.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "p-vegas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "packservice.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagbitcoin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagexl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pakarrumah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pakcha.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paleblue.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paranoid.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parkviewcity.com.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paysensei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paysitesreviews.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perfumerh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phygitalentrepreneur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planisware.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planisware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planiswareusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pley.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pocketcraft.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "policymakr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "popotomodem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "porkbun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "portaledelira.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "portalpower.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "press-presse.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "procode.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proconspain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "procore.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "progressivepurchasing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proiceresurfacer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "projectalias.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "propertea.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "puntacanavapor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qinghai30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qrlab.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quellenwiese.ski", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quesecelebra.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radiosimba.ug", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raycon.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reaff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realwinner.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rebajasoferta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rebeccakirk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reck.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redecloud.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reducealcoholism.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reiff-schlauchkonfigurator.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remediohalkiparaladiabetes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renaudmuller.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "restaurantbetriebe.schwarz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riseofthewildwoman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roge.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "routerchart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safiosolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sairus.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salkield.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saludparatodos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "santehnik-home.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saudiglasses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scanmy.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schleifenbaum.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "screenzy.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "secureover.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "segmentify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seincojavea.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seo-en-barcelona.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seoargentina.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seospecialist.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servi-tek.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ses-egy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shandong30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shanghai30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shanxi30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharingcolombia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shipbuddies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shutterstreetblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sichuang30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skilift-quellenwiese.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smartriotour.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sme-gmbh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snatertlc.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "socialabstracto.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soroush-barber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starborne.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stoneoakgs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stoom-stichting.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "subastasnacionales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suger.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "t90official.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taibachicken.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taibafarms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taskman.london", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taxisantandreudelabarca.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tch-forum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tecnologia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tecnomagazine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teknologiia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tempoprimo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teplo-russia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "termodej.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tescomobile.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teslasuit.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tevi.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theboltway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thefoxtalk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thehomemademasks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theocoffee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thepalateportfolio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "therra.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thevirtualdetective.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tianjin30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timqueen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tobacco-shop.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "today.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tokoword.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomacino.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "totkamassage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tourfunnels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "traintowin.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "travelwithlocalspecialists.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trespedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trifence.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "troyjanda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trypt.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "turismogdl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tvtorcedor.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uffserver.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ukvoipforums.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ultifreehosting.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "urge55.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "utaowan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vader.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valvulasvaneo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "variadoresindustriales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vdlegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vennprime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verdi.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verzi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villu.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "virtool.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vivo.cam", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "voltajedigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wallabywallaroo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waranistudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "washingmachinesguide.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wasithard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webcontentserver.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "websitedown.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weimaranerdogcare.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weirdware.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "westlab.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wicca-witchcraft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wjtje.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wolrdwidessl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wordwidessl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldwidessl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpboys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wxw.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xanzhu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xgys.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xinjiang30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xizang30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xoxo.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xyz.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yaay.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yasikish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yingshu.hopto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yorkiepooexpert.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yorkshireterrieraspets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yunnan30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zbuilderz-lb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zeitgitter.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhejiang30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ziron.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zombie-apocalypse-survival.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123-d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "138.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1pieces.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3ecpa.com.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3ecpa.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3ecpa.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4245pay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "42usd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4huawei.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4meizu.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4nokia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4xiaomi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "889vip1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aaablindfactory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "addedesign.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adventistai.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "africanbushcamps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agroturismoenpanama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aihub.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "airit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alamanceconstruction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alastalonmailla.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "albourne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allpvrtours.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altrei.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amanandalens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "americapitalfunding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amlakzibakenar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andradealbuquerque.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "angelesverdes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anhui30019.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "annuitycommunity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anzalikala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apfm.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arc-relight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arcsar.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "armourroofinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arnamur.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asteq.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "athorcis.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avalontechsv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avtorlab.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aykonet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "azimech.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b88vip1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "babyshopsupport.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "babystudio.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bags-ua.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balkanturist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "barbaleonecuador.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "barriotoboardroom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bbqs-algarve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beecreative.company", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "behtarin10.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bereelcorporation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "besox.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigpresentes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcoinsv.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackhealthwealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blightnight.games", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blightnight.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blightnight.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bocciatitanium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bollymarket.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brasilmedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brianleemarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bridge-to-knowledge.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brigantinebeachguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bringfido.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brndtfy.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brskt.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bss-systems.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bss.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bss.net.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bss.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "btcshower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bubsngrubs.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "burz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buurtkeukens.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyer.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buzzkuri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bv-driver.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "byll.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "californiahempin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calzaturesira.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canakkalebasin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cannamaca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casamentos.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbvoucher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celulares.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centralex.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centrosocialferrel.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chambermeansbusiness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "charles-brian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cherokee.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christinaaguilera.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christophergowerjohnson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chufftex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chuongle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cindydudley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cirasync.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "citacitaku.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clevyr.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmnc.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codectron.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coloradoseodesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "completecareair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "configwizard.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corpomotriztokio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coviddrawings.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "createcode.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cubex.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "curseus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cushytushiediapers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberallegiance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danielleskosky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dbradley771.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dekasseguiempregos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delta11.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "demaison.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "demapachesweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "denisalmeida.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "denizuydur.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "denverilluminations.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devin.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dicoeste.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dievozodis.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitale-oekonomie.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disenoyarquitectura.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "displayrd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "djmcadam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "djmoremusic.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dogwoodceramics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dominicself.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dominicself.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doranobi-fansub.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "draughts64.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "draughts64.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-facture.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "earthpoints.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eightyfour.pictures", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ejcabinets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elbiaadmin.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elielsanchez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enerity.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enginytech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epsamsg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erkankavas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etics.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extrafrei.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fahadbook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "familychiropracticcolumbus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "famouschilirecipes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fapality.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fastrack.co.mz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fdm.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "felipesuri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "filmphotograph.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fipackaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flanderslaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flog.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flytrap.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foguest.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forex-opinie.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forexplay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forwardemail.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fotohunter.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fourseasonsgrower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "free8.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freehotline.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freepornomovies.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freesexvidz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freeths.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frilima.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fromsalttopepper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fsinsight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furzone.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fussy.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "galodasa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gayryder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gbusercontent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "georgiaparks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getfithtx.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getthegoat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getveer.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gfmomcertified.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghanabusiness.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gitesprestige.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glk.academy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gobytedesign.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goingawesomeplaces.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goudsbloemonline.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gplah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gradedblue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grafik.org.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gravitydrawn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grupoenelcolombia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gvaa.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "h10s.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "habboz.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hackathontwjr.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hamiltonsalestraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hangmychanhhieu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hard.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hardmc.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hawa-adam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "henrybrown0.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heritagemachining.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hesanlang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hireteen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hqteas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hrxkauppa.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "htxnet.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hx-sun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyllie.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i-3c.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i2i.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ibliss.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ibtba.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idehvector.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iexpats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "illumepgh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imperialism.rip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infantry.org.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infomalin.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inmucrom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inmucrom.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "insideevs.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "insightfully.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "institutosparroquiales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "instrumentodepaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "internalfb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "international-genealogy-services.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intruder.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iosme.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iowxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ipadshowroom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iphonesoft.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "islaminbremen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itapuapotynoticias.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itraincalisthenic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itrezzo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ivan1874.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jasper.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jasperpatterson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jasperpatterson.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jesuschrist.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jian.spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jmbelloteau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobkeus.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobs.schwarz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobsjets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johncunningham.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "julioteixeira.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justforsunn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jwala.diamonds", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kadeshfoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaijo-physics-club.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kalafard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kccargo.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kenoschwalb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kevinbauer.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "khazarvila.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kickassblogger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kievantico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinderevents-sehnde.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kingdomcoffee.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiplelive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kmrgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kojiishikawa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koredia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kosterenpartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "krilotek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kswork.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "labelledigital.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lagaleria-ag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lanasomething.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "landofoz.dynu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laparoscopic-urology.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "latestmata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "layar.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "learnspace.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lecafedugeek.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lefarsankids.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "legadosindumentaria.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lellek.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leonardoneiva.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lespepinspunk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lidl.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifeismmo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lineaesse5.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linulex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lizteacher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "locoxlasmascotas.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojaonlineshop.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loopcore.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lost-in-place.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maianhtravel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maiotik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maison-coutin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maksimyugai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "malaysiabrands.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "malenachzahlen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maracarlinicourses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcyacademiademusica.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "markellos-olive.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marthus.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mastercheat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "masterpizzaiolo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mathieuescos.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mayesoley.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mazayaashop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcplat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediabrandgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediacritik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megacity.com.ng", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meine-stirnlampe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mes-courriers.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikeborowskigroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mips.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "missinicial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mjgroup.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mmaker.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mnemonicninja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moddedphones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modsrigs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mojezegarki.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morgan.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moviles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrpanipiales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrunang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mvwr.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mydaxio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mydigicard.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mydigicard.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mynaturalhairstyles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mywoodbridgedentist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nanosealcreto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naplestotalgarage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neniu.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neophotonics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nesheims.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netmarvic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nfmovies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nibbler.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nick-black.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nikhilnimiya.love", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nikz.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nodegalaxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noggalito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nordcheckout.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nordesttrasporti.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nordpass.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notcurses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nrmc.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "o5.vc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ob-salon.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oceane.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "odabilocal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "odensc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ok.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onsitemower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orlandooutdoor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orquestaataulfoargenta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osborneprice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oscaroverton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ouderamstelbridge.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ozcreatives.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "padena.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pancakesfromscratch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pblandscapesolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pcverge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pdpa.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pfeifferszilard.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phoenix-cms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "photographymof.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "piekblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plahtan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "playblightnight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plcclosets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "politicaprivacidade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "preferidaseguros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prefolio.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proitsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "promotionnissanauto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "protech.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ptcdogpark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "punjabitube.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pureindoorair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qclean.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qr0.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radechefonne.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radio-valois-multien.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rburz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redcross.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redtrig.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redtrig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "revisionvillage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ritoner.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rockymountaininsurancecenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rvmfm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ryzen.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saadat.in.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saltyproshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sanisafepro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sardoche.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sarkarinaukriworld.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sb-webdev.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scan.computer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schwb.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scphotography.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seestersmexicancantina.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "semillainfinita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "semiotical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "serverportugal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seve7.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sgsmart.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shodanian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shopexo.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "siika.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "singaporebrand.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sisbensantarosa.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sjlegacy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skf-arts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smallsites.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smart-ket.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smtchahal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snapsh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "softsite.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soji.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soon.lk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soulplay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spfl.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sprayontv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssshh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starseersprophecy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "statefundca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "statefunddirect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stealth.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stg-0-con.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stiltnerelectric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sukker-oaxaca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supercursosonline.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supershrooms.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "superstone.diamonds", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sveikas.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swoop-qa.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "syncgal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tagaytayhighlands.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taksa-club.org.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tarahi-seo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tavoseimai.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tavsiyeforumu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tcckonsult.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teawithmum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "technetutrecht.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tema.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "temporaris.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenshokudo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenshokufair.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teogramm.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terminalserver.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teronia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terraneesens.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "testadministrators.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theangelgivingtree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theangelgivingtree.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theangelgivingtree.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theatheistbook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thebookietrials.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thedoc.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thefitcareerist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themodernalchemist.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "therenderingmachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theselfcarenook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesimarchitect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "threadtrails.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiendashuacho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "time4writing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toledotrainday.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tookiweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topbrunchspots.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toph.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "training-eca.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tricountyheatingcooling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trypenspinning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tsacareer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tsakalian.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tuherbalife.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "turnosinscripcionchascomus.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tutima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "twocatsinacaravan.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ucabinet.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ultimatepatrol.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "universdejeff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unleashyouridentity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "updoze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uu939.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vagabond.film", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vanessailustracoes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "veracruzti.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "viatvperu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoria.associates", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vincexpertconsulting.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipenvia.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visionwow.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vokzalkursk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vokzalperm.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vuohijarvisoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vuoto.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vzzjoias.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wapplerbrewing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webmediaclick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webusage.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weddingwire.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wideweb.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wirbsinglereview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wisehome.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wokfilms.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldspirituality.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wwads.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xbros.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xcafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xerbisworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaobai.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn----7sbq4auch5b4b.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--6n2ao17b.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--c1aapkosapc.xn--80asehdb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--dy-via.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xpertsunlimited.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xps-auto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xps3dp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xpsauto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xpsautomation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xvaldezendocrino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xyz.blue", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yamanami.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yerbamatero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yourcrypto.tax", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zamtech.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zenspace.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zoopix.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1001reasonstolearnspanish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "11traders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "186526.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3degreedesign.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3niu668.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3niu99.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4hw.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8bitsafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "92ganb.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "99casinos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9ss6.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a05webapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abatex.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abellanillos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aceofdiamondspainting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acephalafashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adhyayanclasses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aepx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agilecyber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ainouno.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "airdropkings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aksuplast.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexandbonnie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexkushner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alojamientos-cuba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ambicorpenergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "animestreamingfr.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthonys-landscaping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aprizalputra.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "articole.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artworks.gd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "as41405.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atk-huolto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aunto.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autohit.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autotras.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "auxessenceselfiques.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awoau.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bakerbasements.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bamheroes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bcome.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beauty92.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beautyest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beestitching.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benmedia.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bentcreekvineyards.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestvpnservice.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betrimus.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bgjargon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bicicletassym.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigeasygrille.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bithugo.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bka.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blc.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "block-planet.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blossomsflowerboutique.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluerabbit.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bobbleheads.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boizeau.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "borza.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bowlidex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "breffa.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brickland.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bricksandmotor.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bryantluk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buchangroupinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bunnyworld.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "burmeister-gmbh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bylivetrp.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c01webapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c01webappv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cailoli.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caiqueparrot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camarguinho.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camarguinhokids.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camilafloresrp.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carcare.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casa-familia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbtl-see.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdseditora.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chamonixcamera.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciel.coffee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciph.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "civilcorner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clinicadentalayomunoz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clinicortinascali.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cod-ggw.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cody.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coffeeciel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coffeeciel.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "compare-energie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "compustore.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "computerscience.guide", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "condormobile.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "construademadeira.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coomer.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corectim.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coronavirus-19.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "correoscorporativos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "couchidiomas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "covid-games.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptsus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csgo.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "curtispope.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "curts-showcars.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "custombobbleheads.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cybeautiful.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyklistika24.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d-solutions.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d-va.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "damacosmeticos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dancesafe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dannys.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "davidskinnerantiques.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dealershipdrop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delta-wings.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deltaworkssecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deltaworkssecurity.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dennis-aumiller.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detailingsp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diamondanzali.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalitglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalsearchlab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "docket.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "documentnode.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dodotek.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dominobreaker.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dookhtaniha.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "downloadbestapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drinkvhemp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eazydokan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebino.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "economyroofingco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edgelogs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edibleforest.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "egh.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ehmkala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ejit.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elhacedordemarcas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "empleosdorita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enactusteesside.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "envirotecstructures.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erogen.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esgfoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "everythingcovid-19.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evolucionhoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evonet.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evoprint.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "famlefeber.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fantasiasaitian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "farb-tabelle.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fasmaritime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fgeiger.dnshome.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fggpay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fixedpricemovers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flashcardsmobile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flsbanners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flucover.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flurecover.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flystar.immo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "followboost.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fourfivecbd.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fourmaq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freelyplaygames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freerun.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ftx.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gabnotes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gamesics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geblitzt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geenoo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gefeuert.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "genesisgrade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "github.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "good-time-to-be.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gopress.web.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gpereira.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "graffitinetwerk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grappes.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gregbonner.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grimms-schuhe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gruaskmsa.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grupo-zoom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gsa-online.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gsaauctions.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "habana.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hdevent.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hearted.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hekoro.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heliumbrno.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herbamedicine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hertzhz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hesaplat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heyitgirl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hibiscuscoastfinancialservices.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hockeycircles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hostingtipps.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hx36.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ian-barker.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iblog.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iceberg.ddns.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iclg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ideagen-ops-sandbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igry-onlayn.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iitala.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imiku.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imransarwar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infcloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ingeniotic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "innovatech.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inshared.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "instantsystems.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intedot.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ioanamateas.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iskariot.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "it-xperts.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itguru7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itreboot.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itsoft.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iuspenal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamieb.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jasalokal.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jav.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jhtrades.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joomlaclub.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joshua.mn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kabuki-inc.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaffeepflanze-pflege.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanivatonga.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kardjali.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kedero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kevinperrow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keyserve.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kochcommunity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kopieid.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kreidl.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kristall.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kushfest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kushfest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kwieben.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laguiadelpapa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lansilesia.tf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lazzzy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ldtborovina.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lefcoaching.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leilaelu.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemkinlaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leontic.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letschat.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lhuilerie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liisauusitaloarola.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lirelesgens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojadosirmaos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lokjagruktafoundation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lopezmanzano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lsv-tech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lucacastelnuovo.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luxembourgapartment.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lwis.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lynamhomeloans.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magenta-health.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "main1.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "makesenseofdata.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mantalak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "markentier.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketingdigitalefisiente.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maskmondelez.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maslife365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxiutov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mbrjun.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megawhat.energy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "menufree.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.uy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercadopago.com.ve", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mibeneficio.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "misbalances.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mksport.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ml-academy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mnml.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobidesigns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moderntrailers.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "montagetravel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morz.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mostfamousbirthdays.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mouracloset.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrmn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muellerurology.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muntajati-om.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myfxbook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nadacnifondacr.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nakazato-shika.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nalipapelaria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "namiejscu.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nangluongxanhbinhphuoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncksrv.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ndev.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "necd.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nemplex.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neo1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netdisk.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netzwerk-sozialliberal.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neurosurgeryinmexico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nfluence.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "niinaratsula.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nikitacartes.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nillarayeshi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nksmart.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nlivestream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nostoautomaatti.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notizienelmondooggi.altervista.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nslacandelaria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nunoprospero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "odsylvie.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "officecode.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ofo.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onedollar.fund", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onemac.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "openid.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opil.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "optimumcoffeesv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orenohatake.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ormanetrading.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ottoduarte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oursiteupdates.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "outerface.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ozudogru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pachinstyle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pasclassic.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pazzmodernist.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pensan.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peoplesrights.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perroon.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phony.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phv-bw.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pincodehome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "piszmak.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pixelmonworld.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plan.in.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planeta-tierra.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pravlife.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "presgrp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "presgrp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "private-relay.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "privatepilot.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prospect1838.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "putchiconsultorias.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rahulgupta.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ranters.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rdmc.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "readlight.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "readydedis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realtechreviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "recipekensaku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "recursoscristianosleinad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regionaalenergieloket.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "relations-business.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remotish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "repairtly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rexeroofing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rezni.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rhymesofreason.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rivals.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rko.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rogue.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roguecoder.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "romantica90.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "royal939.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rsrv.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rszm.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rueckert-gymnasium-blog.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s-mall.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samskaar.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sapporo-asaichi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "satoshibattles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sauve-tes-euros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "savonsuuntaporaus.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "says.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scoutbee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "secretzone.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "semtinde.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "serviciosparaconsorcio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servimecabrasil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "share2act-dev.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "share2act-test.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sheepymeh.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shenming.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shevelev.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shirro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shopcceputnam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "silverfalcon.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skyarch.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skywalkersa.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slowhttp.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smartit.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smileback.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smkn5smg.sch.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snacdata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snohomishdragons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sodermans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "some.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "somosdefensores.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sosou.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "specificenergy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "staging-covid-games.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stampingoriginal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stars24.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stategov.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "staygold.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stlpoolattendants.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strappazzon.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strobel.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suceveanca.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sugarondemand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sugaropencloud.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sugaropencloud.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suicide.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "super11.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "talenthubmpi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teleyal.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "temporalmotivation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terryburton.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "the-burtons.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thenova.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theunleashedpet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thevitpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thierrymazue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thinxtream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tianbo1088.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tianbo1998.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiktokoff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiny777.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tinychen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tommycarrauto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topspani.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trackingencomendas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transportcomparator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "triballi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "triploqal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tsekhovik-agro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ttr-home.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uhuc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "umlt.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "universiteplatformu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vapezone.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vapocial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vcz.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vendaonlinebr.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venomxsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verzekerdbijhema.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "viilup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villekautto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vinicius.sl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visiondigitalpe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visionseal.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vital-pack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vkr2020.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vooxia.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vros.co.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wakuwakustudyworld.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "war-requiem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wcloud.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weboperater.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weboperater.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wegivetlc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whattheactual.nyc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wikalin.ski", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wobblyibiza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--s1r71tg0o30bxm52odlvspdop4b.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yangmaopubu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuanandyuan.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zehka.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhouzhi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zuhausejobs.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzcc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00000000-0000-0000-0000-000000000000.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0x3a.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0x6470.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2.ag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "22.ag", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2makeu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3654.vip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3pif.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "533sss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "761.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abellagranitecountertops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abogadamediadora.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abrightsolution.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acidoascorbico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acuvate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adeloveshipping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adenopatia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adesachatbottecnicowab01.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "afoch.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aguilarsoluciones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aimanance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aimmail.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aksot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alanbleiweiss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alanina.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexandraschmidt.coach", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alianet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alng.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altokep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amdrumors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aminovega.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andreamonicahug.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "angelzapien.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antihistaminico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antikeo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antoni.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aptctg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asana.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asana.plus", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asesoramientosolay.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ashevillemenshealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asian-rugby-exchange-fest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asitanc.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asm802.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asm802.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asoziales-netzwerk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "astrolab.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asylinfo.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atrakcjenaeventy.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "babylurve.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "backlotgaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bajarjuegos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bandaumnikov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "belzlongroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benjaminleupold.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "besiconstruct.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestsiteporn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betalgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betterbusiness.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bfkkutu.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bharatology.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biologo.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitbroker.exchange", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biuromowcow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bjecard.buzz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackhat.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blardiblah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blogtechnologiczny.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bnb.direct", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bodas.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boehm.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "booked.md", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bremermaschinenbau.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brewit.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brighterimagelab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsmsl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsmsoluciones.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bss.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsurfcr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "budofjoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bugfuzz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buscalotodo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buzzword24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c2athletics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c3stream.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cancersintomas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carlingforddental.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carnetdeconducir.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "catartofsweden.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centrmrt.spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "checkrz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chesstempo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chnroute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christianyleny.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciclodekrebs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciclodelcarbono.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ciclohidrologico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cinematictouch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clarkhowell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudomation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudplan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmrconstructions.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cms-world.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cnpkg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coderslight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coenzima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coindica.com.ve", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "collegium-musicum-bocholt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comprar.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comviodemo.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "condictor.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conphungtourist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conpulpademanzana.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consolebros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consumercouncil.je", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "contralegem.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "correo.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cosmic-relations.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cottage.direct", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "covid19.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cozzack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cpucheu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crashbolsa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "criscond.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csaerotherm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cuties.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cv-developpeur-web.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberskyline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d-taube.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daoplatthanhhoa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daycubrem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dealbeathn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deathcult.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "debattinnlegg.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dela.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deltav.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dendi-staging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dendisoftware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedtambayan.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedtambayan.net.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deportes.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dienmattroichonthanh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "directmailctr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "discordextremelist.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "docedic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "docedic.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "docsrev-aws.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doterrashop.ec", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drawjar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dreamytheatre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dupuis.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dutchpentathlon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dyregrave.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "earthsocialism.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eisei-iinkai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eldiariodemof.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elektroruoff.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emvitals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eod-dissemination-uat.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eod-dissemination.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eosinofilos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "est-tatsujin.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etf2l.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eurocom.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "execupharm.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exentio.sexy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "expand.technology", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exyusubs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ezhub.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ezone57.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feastofplants.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "federaljob.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "femiwiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ferad.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fernandezvilar.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fibune.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findcheap.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fleeb.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowlytics.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fn-0.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foundationrepairpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fprinnovaciones.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freefinancialhelp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freegaypornhd.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "futbito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "futbolcba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garrow.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekynutritionist.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "georgiebailey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getscif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gillettechampions.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "golovabol.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goodseed.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gordonbeeming.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gosiberia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gpsmith.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grahamsmith.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "growthlab.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gruveo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gryphzia.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guythomasevans.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gzfc.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "harumi-cl.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "headfullofdynamite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heavymetalonline.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heimdall-home.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hellopowerserg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestegrovvaren.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "higleyarts.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hiranosayuri-piano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "histhist.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hobbslanddevelopment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "home-page.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hourai.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "huesers.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ideagenpentana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idowp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "illuminaterecovery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "immijobs.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "immobilier-swiss.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "immoe.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inoreader.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "instaart.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invisitone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iox.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itaro.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itaro.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jandj.yachts", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jefcorlabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jloh.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jmeno.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johnmac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joomladeveloper.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jrulka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justpractice.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jwala.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kadooonline.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "katerinastudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kathrin-maren-enders.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kgky.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kidan.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kimino-school.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinetikos.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiseki.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kitaplus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kreuzbergflieger.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kstasinos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "labels.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laby.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lacarna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lagloriadehuampani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lajas.com.ve", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laoudit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "larenas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ldbeauty.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "legowerewolf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leo.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letriolet-tignes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lightquantum.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "link.sb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "listazakupow.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "littlefingersindia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livetv.tube", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "llredac.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lolifamily.js.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovesquirting.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lukaskollmer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lumien.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luxeblades.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "m-a-i-l.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "macabacus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "machinerysource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magetsi.co.zw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mahmalci.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcillacetfils.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mariages.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marinasmad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marleenjacobi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "martinschulze.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "massdesigners.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mathiasheise.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matrimonio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattmorrissound.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mayacoa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medsanuk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medstatix-dev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megatorrenthd.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mf58.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mhcouncil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "middle.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "midl.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "millennium-thisiswhoweare.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "millersprolandscape.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "miriamgamburd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "missbitcoin.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mitchkiah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlsvallarta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modax.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monmiel.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moonbyte.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "motolinesupply.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "movihut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "msngr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mtran.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multimediosmonti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "museodefutbol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musicwind.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muydelgada.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "my.urown.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mybokx.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myheartlaundry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myload.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysouschef.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mytransmissionexperts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myzoograd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natuurlijkmooi-meppel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nekochan.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neoseo.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netzabfragen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ngo-online.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nistorvictor.software", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nmcep.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nobitex.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noktaradyo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notteit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "novi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nuclea.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nya.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oboivam.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "obs.plus", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ocastrowork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "office.urown.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offsetservices.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onpaws.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "open-fixture-library.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "operationtulip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oralb-prestazioni-odontoiatriche.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oralbregalaoralb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "organicseo4u.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osaka-hero-project.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osteopathe-voisine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "outervision.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oversightboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pachamamaproduct.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paketverfolgung.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paviformas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peelawayyourpain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perved.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petitsfreresdespauvres.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petya.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pfarrhaus-mon.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phw.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "picomedia.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pnp.ac.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pockets.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "polaxtor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pornfreesites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pornmad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "porthos.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powerscif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powerserg.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powersergfeds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powersergisrc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powersergsecure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pozitone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poziworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pradmin.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prestatyn-scala.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prestatynflowershow.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prijmeni.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "printwasteminimizer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "problemysholkama.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "producciondealimentos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "productive-garden.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "project-scarlett.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "projectarmy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "promospg.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proservices-informatique.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "protrainerbrasil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psc.gov.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pujasharma.associates", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pv-golf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pvao.gov.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qigehl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quentindestombes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raderamig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radiation-oncologist.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raniwan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rasc.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rbn.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "readyscif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "readysetscif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regalador.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reinheft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remigius-michael.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reviewpipe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "richfieldsean.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "road-safety.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rodnik-pansionat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roishopper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rosewebdesignstudio.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roveridx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rpcinmobiliaria.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rpj.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "russell-tech.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s2.coach", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safefreepornsites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safescif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safetydrivessuccess.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samuelcoles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sanitix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "santandertrade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sarahjaneredmond.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saxobroko.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schoffelcountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scifplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scifsafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scorb.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scroll-to-top-button.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sentralshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shakalaka.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shincastella.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shoppingjin.pk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sieliakus.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simplylocalhosting.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sincromyl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sitinjau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slabstage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slavblog.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smithandellis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smltour.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sns.med.sa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snsdomain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solaxfaq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solviq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soykaf.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spicystove.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportify-design.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportspassbremen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "squarepocketdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starthubs.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stilus-patent.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stla.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stomwhite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "storage-base.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuartparsons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sugarsalted.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "svse.global", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "svseglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swiffertirimborsa.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sypreformas.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tangochoang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taroe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "team957.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techgarage.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenken1010.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thekokuin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thelaurelchiropractor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themenucard.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themusicalsafari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thewaytoyourself.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thoplam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiendamaquillajes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tilcra.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tinmarin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tradeshift.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trains.sexy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transdev.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transdev.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tridnice.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trpl.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tryfrontline.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "twilo-host.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "txyz.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "typesofdogs.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ubsolutions.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unblockedgames.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "up.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uradvd.best", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "urby.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "url.kg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "useworkshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valsorey.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vapourtown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verso.money", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vibetribe.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "videoclases.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vietnamhairs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vinyl-digital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visabuddy.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vision-painting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vpnstreamer.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vrallart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "walla.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wallatienda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "warrenhousevets.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wass.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "watchtolearn.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wdesk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weitweg.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskey.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskey.money", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskey.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whisky.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whisky.money", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskymy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskyshop.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskyshop.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whmcs.xn--9dbq2a", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "winkli.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "winnersaffiliate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wis.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wivcfinancialservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wivenhoeforum.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wngs-creative.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "womywomwoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "woodwicker.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldfinancenews.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpspeedking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--avocai-timioara-kmf1a.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--hsers-kva.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xunmengdu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yarowork.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yellowsource.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yescool.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yozakura.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuth.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zegarkidlakazdego.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zotan.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zotan.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zotan.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "17avolemsaberlaveritat.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2q.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2vp-an.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "360kuvia.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "360prokuvat.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9to5linux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a3sys.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aanlynskool.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abhijitvalluri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "academy.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acaseta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "action1st.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "addendum.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adkup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agviet88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajvco.com.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alemorbel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexandrepedrosa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aliamex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alltape.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alphabytes.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amicusmed.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amordetelas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anabolic.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anasibrahim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andigraf.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andsecure.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anitalk.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthro.icu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthro.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aothuntees.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apiora.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "armodobrasil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "as41073.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asa.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asamoe.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "astrology.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atakac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "audiomedica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autoverhuur-tilburg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awe130.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awedience.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bait55.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bangim.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banyaktutorial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bargest.su", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "barronmartins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bdsmcontrol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "belic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bellaireroofinginc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benepla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestbudget.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betterboards.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bhemcasa.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bighorn.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigmama.travel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bilicdn.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bintube.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biocbdolio.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blogsnote.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brainstorm.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brnrx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bruniano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buckanddoe.farm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buckdoeand.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bydik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c7n.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cabazon-tu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cajaica.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "californiakingsnakepet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camaraslima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camposcasares.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canekeiros.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canonisti.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carbonholic.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cardsbymaria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cardschat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carevo.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carsonkoziol.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caumont-normandie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbcf.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbd-oil.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ccaguavivadonaciones.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cctf-m.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chacoonline.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chacraexperimental.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "charlyclearsky.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christiangaro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chronikdanceclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chshuju.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cities.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clapbacks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clarity-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cleangreen.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cleverdarts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clevyrhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudeffects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "code.golf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "colchesterglobal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conexionok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "connecto.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "connecto.marketing", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cons.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consejociudadanomx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consens.us.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cooltrades.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coop.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coronasafe.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cosmetology.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creatapeak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crrapi.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ctendoscopy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cuhawaii.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberwritersink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daniweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "datadorf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "david-osipov.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dbnext.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deemasfashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deiamodas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delicatewonders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedcommons.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedcommons.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedcommons.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "depedcommons.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deremedioss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "derguns.town", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dethoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detroitlocksmiths.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devenv.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "devxify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diennobi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diff-speed.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digiaika.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digiaika.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digichurch.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digikerk.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "discrete-passion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dlagoss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donewhen.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donewhen.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donewhen.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donewhen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donewhen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donwhen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dosimabag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dropsite.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "duysondang.name.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "echoteam.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecostarcleaning.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ectpro.co.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elad.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elahuehuete.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricbeast.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elimperiolatino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elisabeth-raendel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emptyarcade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emxvn.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "encontro.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "entropyofdelicatewonders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epitafija.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erpollo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erysonhandel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eslove.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evadi.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "everydaypower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exarcheia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eye-move.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fairwaynow.mortgage", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fannietremblay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feehla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fernheim.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ferozes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fightsupplies.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findeth.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finestinfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flashlightchart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fleischkaes.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flinny.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fnpodinajpur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foreverbreak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forevertoday.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fortsecure.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freegovernmentcellphoneguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freenome.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frigochaco.com.py", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fundaekhaya.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwg.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwt99.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwt999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwtapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwtewm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwtpic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaming-lenkrad-experten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gba.ge", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekymansion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "genghan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.help", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlentgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ggld.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gharbala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghyvelde.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gloryhere.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glpreparation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gms-records.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goldsteingloves.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gomezhvac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "govorenefekt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gralhaazulcondominio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gti.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "happytestings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hashi.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hassmelden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hbomaxaustralia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hemopet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hemp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hemsfoods.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hifiaudio.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hindigalaxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hiracar.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hope21.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hopkinsmediation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hotelfloridachaco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "howarh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "howtohomeschool.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hypertesto.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hypr.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i-can.center", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iamattila.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ifederalland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloopreview.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloosandbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imhotx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "index-of.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infohas.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inmadesarrollos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inoder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inscribeusercontent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inszu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itexpress.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ivelop.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ivixor.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaiyen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "javocean.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jcelectronics.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jel-tech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobsoid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jocata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jsg.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jsjfact.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jtg-inc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "junshinkai.ed.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kadimperium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kadmirra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaleylocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kalpavriksh.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "karting-normandie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kennedy.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kennedy.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinderosteopathie-osteopathie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kindredcode.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kindredcode.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kjs73.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kkc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kojima-life.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "konflikte-als-chance.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "konflikthaus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "korofilms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kosto.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kotaartsklan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kra2laiz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kratom-k.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kryptoforce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuraga.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "la-vraie-histoire.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laby.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lacatta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lamaturitadidaniele.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lambda-calculus.church", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leidegoncalves.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lesultandalep.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lgam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lit.foundation", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liveteachers.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logopaedie-sandkrug.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "looop.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loukkos.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovegpl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovemoon.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lowcarbspark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lpasteur.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lucidea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lumi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "machin.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maciej.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madurasfollando.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magaliff.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magikbyte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maisonmere.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maksatmoda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "malcathatochen.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maniadicane.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manulife.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mapuut.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marblenexus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "margherita.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marijuanamed420.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketfeed.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "martelus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maschine.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maschinen.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "masconil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mastercareplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matrichelp.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matriekhulp.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxwellcody.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mchollet.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediamonitors.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megafide.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "memola.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mentorbuk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "metropole.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "michaelmckenney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "michaelstoffer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikaknuutila.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikaknuutila.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikaknuutila.photography", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "milenkojovanov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mineralnibani.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minetrack.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modulkuhni.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mon-dolibarr.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monidenum.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moustream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muellercustombuild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "museodefutbol.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "museumofautism.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musicbow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musttest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musttest.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musttest.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musttest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musttest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mylever.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mymartinbeckeropenhab.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysteriousbeans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mzyxsl.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n-a-railways.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n-metz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nachbar.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nalits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nanamovies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nanxin.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natalia-shablo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natwest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nautile.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ndaal.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nei.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netpreneur.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "newburymobility.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nextcloud-server.spdns.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nieuwebroek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nieuwebroek.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nihon-mozartaikoukai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nocoffeetech.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nonuplebroken.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notrero13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "npc-ts.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offgridbound.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "office-dolmetscher-scharnagl.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "okmaybe.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "olajcbd.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oofishing.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oops.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opcod3.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "organic-cbdoil.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oromolido.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oroygrana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ortanatech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pamiers-citoyenne.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pasnyburiat.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "payalts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pekcazip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pentruprieteni.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peterlajos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pioneersenior.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plexverzoek.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plum.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poezja.art", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "positivefocus.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "postex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pqd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "principalstest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "problempaws.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "processout.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "profitimages.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "propertyupdate.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prospa.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prostoporno.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pwgenerator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pygb.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qnixon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quantatec.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qwrk.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "railsideworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rainbowbrains.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "recycledinorsett.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "recycledinorsett.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "release.monster", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remoteroom.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "repairgeniuses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reviewsonlineguide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riku.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riosoil.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riosoil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riosoils.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riosoils.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rivalsa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rncc.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roodfruit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roodfruit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rubdiavila.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "russiancms.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s-4.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sabinespielberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saghekin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saigonland24h.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sakakun.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sarv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sawiday.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sawiday.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sccoaching.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schambereich.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scholarships.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scott.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scouting-westenenk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "security-systems.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seeker.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seoz.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shahidfakih.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shanteo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shopazmoon.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shopforeverproducts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shore.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shotgunstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldtest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldtest.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldtest.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldtest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldtest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simpelkoken.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simpelkoken.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simpelkoken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skartecedu.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skyblond.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skylightipv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sl41.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sodelicious.recipes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soeasy.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sogo.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solostocks.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solutionmotsfleches.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soml.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "somosti.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sopenguin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spjaet.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportllux.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "squarewave.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "standoffdrop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steinmetz.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strandypink.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suerteloteria.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "surgerylifeenhancement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tagat.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taki.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taki.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taqeemi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taytaytiangge.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telemedi.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teodw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teodw.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terranovadesignbuild.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terryoconnor.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tf2pickup.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tfsound.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thecolourcloset.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thecubepsych.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theentropyofdelicatewonders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thefarleys.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theparklane-sukhumvitbearing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thetransformingchurch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thevoltageteam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tifile.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tisec.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topb.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "totalintegratedtherapy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toyotasp.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transformatutrading.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tribeoftomorrow.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "triedandtruebytrista.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trussgenius.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tryin.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ts3.ink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tschang.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ubetoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unblockit.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "understandmaths.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unfoldbeauty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uniteforrecovery.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unitefortherecovery.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "untamedprints.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "us-igloopreview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valkyriecloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vanillacoder.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venbraca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verstaanwiskunde.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verygoodwebsite.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vidaxp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vincentwolsink.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vincie.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipturismo-europa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "virtualx.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visionacademy.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vivi.fyi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vkgpakketkorting.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vojtechpetrasek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vokabl.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wallinvogue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wangyp.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wbookcompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wbsogids.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdesign-kall.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdesignzarin.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "websiteproxy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whattyre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiskersandtails.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whiteglovemoving.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "willenberg.family", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wisemen.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wisersp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "withgentlent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wordpress-szakerto.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "work-shift.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldstyling.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpg-verwaltungen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "writtenandrecorded.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wuchoamoveis.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "www-fwt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaodingyi.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yangrq.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yinyang.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yjdevtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "youran.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yukino.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaimitut.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ziad87.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zlatograd.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zubr.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzops.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzops.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzops.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzops.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3sixtydutyfree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "604windswell.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "70mpg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8800.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8885asknick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "99laptops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "achat-de-lead.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adaptationplatform.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "addresstobe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adilgraphics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adutoras.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aflam4you.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "afrique.buzz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agence-initiale.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agrecosolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ahstrem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ai.mr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aklagare.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aldyputra.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alex-weigle.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alterlinks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alterlinks.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alterlinks.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alterlinks.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altinopoliscervejaria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alvastonauto.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "americanpop.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amoraparavoce.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ancroma.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apartema.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apartema.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apfhaiti.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apkmody.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apsb.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arabakiralama.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "argo.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arina.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arlenitas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artchic.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artigoagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artsautomotive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ats-autohandel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "attcleaning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel-company.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogel.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avogelusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awesomeness.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bacahorror.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banhphongtomquangtran.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banmapvn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bartholf.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bb-ek.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bb-moisel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bent-nails.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "besate.ec", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bgm.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bieville-beuville.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigcountry.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biocbdolej.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biocbdolja.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcoinlatestnewstoday.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcoinnewsupdates.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bjarno.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockexplorer.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockfi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boostplm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bouville.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brownwrapper.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buggiano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bunbun.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bunniesoflasvegas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyupstorepremium.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ca-saintdie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cadeirasparaescritorio.ind.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cafefacil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camisetas4fun.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camisetasbichopreguica.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caribeeficiente.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casanovafishtacos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casavlas.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cattsgym.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbd181.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbd2050.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbdeighty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbdnews.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbdtelegram.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ccnadesdecero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheekboss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chick-goo-ewe-farm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christiamguerra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chronocarpe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cjr.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cjw.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clearcomm.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmtportal.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cntraveller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cobbm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocomelody.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocomelody.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocomelody.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocomelody.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "collateral360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "colorfulcloud.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "columbiaproemergencymovers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comerciaonline.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conoceme.bio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conservationfreedivers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "contractstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cosmosmkt.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cougar-bordeaux.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "couplesapp.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cpgiiaragon.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "craftyproducts.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cresserons.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cristaleslitios.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cronjob.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptoeighty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptohinge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptoleed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptowhile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csis.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csisgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ctyrisinkneri.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cultrixdigital.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "currentbitcoin.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "currentcryptocurrency.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "currentcryptocurrencynews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cursointeractivo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dallaswebsite.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dangeredwolf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danielaeichberger.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dannys.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "date-hijri.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deadspin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dealsfromheaven.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "decorarei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deemasfashion.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deemasfashion.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deemasfashion.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dentystabirmingham.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "desanctispro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dharma-clinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dice-strategy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digimoncard.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digivet.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "direcore.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dispemec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dnratthee.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donacarlota.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "draft.cards", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drivehub.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drrenointerior.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dymovskiy.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecocleanpower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eggbay.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eldiedesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elecpromo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elfatih-markting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elmnt.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emporiopurochile.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emprendimientoweb.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enequilibreflocoach.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epirk.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erotycznehistorie.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "espaceroseauteinturiers.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "espectrocrom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "essentialoils.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "estampascriativas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etaldelune.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etdonline.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evolucionestudios.com.bo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ezinternet.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f3b.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fabfrugals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facebook-program.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "factsvision.sr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faktury.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fapobyte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fatvalley.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fbthirdpartypixel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fbwat.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feecreativity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feedthefuture.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feitam.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fetish-x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "filokiralama.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finanzasydinero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finapi.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fivetecnologia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fixverkaufen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "floline.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flooddoctorva.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flow-serv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foodling.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forecastapp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forexnews.world", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forexnewslive.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forklift.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forthenrycustomknives.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freehomerisk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frikandellenmoord.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frikandelmoord.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxaltas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxperk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxpunch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxwrite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gabe.watch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ganaderosdeceres.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaytubec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "genlack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gentlent.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghgkhalsaschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "giddyhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gil.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gizmodo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glamourmagazine.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gncsuplementos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gopass-dev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gopass.health", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gougeul.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gq-magazine.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grabtech.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gradecube.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grasengroenkunstgras.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gumbointro.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gutterbus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "h2cclipboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hacktivitycon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "half-dead.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hardies.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hathai.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "havebetterconversations.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hazardhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthbrochures.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hementaze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herbarex.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herreriamauricio.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hesabcenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hexapk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "highaltitudearchery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hob.bi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hobbypow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hometechmtl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homeysnack.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hookahshop.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hostelxaxid.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hotsoft.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hrsa.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hydroxide.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyy.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyychat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyyperchat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icid.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idlemon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloocommunities.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloodigitalworkplace.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloodigitalworkplace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloodigitalworkplaces.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igloopartnerportal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "illumis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ilusionphoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imageessentialsweightloss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imawasn-consulting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imexmed.com.gt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "impresadipulizia.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infernal.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infotectsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "insidetheigloo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "internet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intiveo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "investors.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ireta.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iritual.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "irmo.hr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ironbarnyc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isharryworking.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "istramaster.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "istramoda.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "istratehnik.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itvia.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itvia.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itvia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itvia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iuup.menu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "izdaher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ja-tay.sr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jalopnik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "japaneseacupuncture.london", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "japatacado.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jarno.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "javanie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaylee.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jcbfshr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeevanpaul.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jellebuitenhuis.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeneratorkiralama.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jezebel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jichi.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jkuu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobinbennykutty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johngreatwood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joshmoulin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joshu.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juguetron.com.ec", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kabataanpartylist.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kahane.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kazumi-clinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keithwillcock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keramikaopava.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keyspanish.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kientrucnamcuong.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kissmateszabolcs.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kit.watch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kleincliche.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "knovator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koe.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kostenlosepornos.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kotaku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "la-meute.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ladrilleraeldiamante.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lagalaxiagrafica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lampiaoluz.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "larsi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "las.so", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "latestbitcoinnews.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "latestbitcoinnews.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laughingloon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laveriebyk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lawyersofmissouri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lawzava.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leclicbazar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemans.com.gt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letrissimas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letssolarize.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "levico.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifehacker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "listing-here.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "littlesk.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lloydrogerspencer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logay.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojacorbuccieats.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojamultplick.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lucasuwadi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lysel.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "macawos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mag-led.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magneticarrow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magneticarrowdev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "malek3d.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manchestertechservices.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marthus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "masterminer.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "materasocial.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattdrew.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maynails.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mchughisle.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meatfoods.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "metrourgentcarestl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mindspace.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "miscursosdebelleza.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "misterboddy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mit.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mkws.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mngfam.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mns.llc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moderndeck.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moneytamer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moscow-xiaomi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrtprioritet.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrtskidkispb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mumbairoleplay.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mundialpresentes.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "musicradar.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mustardwallet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myjosephine.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mypinasale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n8solutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naif.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nakliye.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nathanphoenix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natsar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "near.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nemberone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nerdnet.goip.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nesez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "newlight.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nextalefieldrecording.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nicklazarov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nihon-rosoku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nilpointer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nobasico.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nukleovisual.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nullbox.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nvlifeinsurance.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyangasm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyangasm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyangasm.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ocdhub.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onechronos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oomuj.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "optimale.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oraclecode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oriya-hrs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "padena.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parroquiaelcarmen.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "partsbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "partsbox.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "payrollhr.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peerpressurecreative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pijamasbichopreguica.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pirateproxy.voto", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planned-cities.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "polifisio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poppylala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pornbot.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "precisionstocks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "privatefiles.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proxybay.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qinh.ren", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qlulife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rad2share.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rase.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ravron.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rc21x.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "readable.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realcanada.com.gt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realestatesales.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redraven.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rentacar.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "replyua.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "resolvo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rgl.support", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rhysre.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rioinbox.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "riverdale.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rurian-gyohen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saint-aubin-sur-scie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saint-leonard.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sakiborislam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samanexports.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sechssiwwe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "security.golf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seexw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "segurancaresidencialbh.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "semiweb.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "senditvia.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "senior2senior.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sentitvia.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shinice.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shoarq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shoppingdascapinhas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sintraunipricol.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "siongseafood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sitestudio.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skedo.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skovbosburgerblog.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slimmarkets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smokkelenken.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smyleo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "so-buff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "so-commerce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "song.ski", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sound-recording.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sozialistische-gruppe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spb-xiaomi.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "speedsvip.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stabilization-in.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stamurai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starlabs.bio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starsub.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "staydryohio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stemgirls.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "surgerylifeenhancement.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "switchinitiatives.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "switchinitiatives.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "switchinitiatives.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "syazli7.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taiwan-kitchen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taleintwo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tasintrip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tcdn.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teammojo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "technopost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thapduoc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thebusinessmasterminds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theinventory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themurrayfamily.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theonion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theroot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thetakeout.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thetipo01.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thinkconsultores.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toolip.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "touchandpark.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trabajarytrabajar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tractor-pulling.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tradedigital.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trakid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transferwise.jobs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trappeer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trollbox.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trophyshopinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tscomputers.net.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tukaraokeonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ubereatsprinters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ultravendas.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ulyamuhendislik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uniforcele.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unitedsapiens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usecamisetas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ut-jobs.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vaclavkocum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vedshastradata.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "velocitycu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venturebum.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "veules-les-roses.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vfxstudy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "viera.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "viewpointsfromfacebook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villers-ecalles.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vinc.name.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "voetbalquizkopen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vogue.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "voyancedanslenord.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vpsce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vrimcas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vuldb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wabbel.sa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wbbauth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wcfauth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdevoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webforce.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webformula.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webpressbuilder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "websiteurl.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wemediate.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wexfly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whaleapp.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whaller.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wigwam.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "willmage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "windrich-werkzeugmaschinen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "winebrasil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wired.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "woltauth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wptrigone.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wscauth.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wurzelkanal.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wykop.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--d1acalaltdk2d.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xosh.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ysoft.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zappy.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zero-skill.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zigao.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
// END OF 1-YEAR BULK HSTS ENTRIES
// Only eTLD+1 domains can be submitted automatically to hstspreload.org,
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index f68e798ccf2..8131e687c03 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -17,6 +17,7 @@
#include "base/metrics/field_trial_param_associator.h"
#include "base/rand_util.h"
#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
@@ -24,8 +25,10 @@
#include "build/build_config.h"
#include "crypto/openssl_util.h"
#include "crypto/sha2.h"
+#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_verifier.h"
@@ -35,13 +38,13 @@
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "net/extras/preload_data/decoder.h"
-#include "net/http/hsts_info.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/net_buildflags.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
+#include "net/test/test_with_task_environment.h"
#include "net/tools/huffman_trie/bit_writer.h"
#include "net/tools/huffman_trie/trie/trie_bit_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -171,13 +174,15 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
MockExpectCTReporter() : num_failures_(0) {}
~MockExpectCTReporter() override = default;
- void OnExpectCTFailed(const HostPortPair& host_port_pair,
- const GURL& report_uri,
- base::Time expiration,
- const X509Certificate* validated_certificate_chain,
- const X509Certificate* served_certificate_chain,
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps) override {
+ void OnExpectCTFailed(
+ const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ base::Time expiration,
+ const X509Certificate* validated_certificate_chain,
+ const X509Certificate* served_certificate_chain,
+ const SignedCertificateTimestampAndStatusList&
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) override {
num_failures_++;
host_port_pair_ = host_port_pair;
report_uri_ = report_uri;
@@ -185,22 +190,26 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
served_certificate_chain_ = served_certificate_chain;
validated_certificate_chain_ = validated_certificate_chain;
signed_certificate_timestamps_ = signed_certificate_timestamps;
+ network_isolation_key_ = network_isolation_key;
}
- const HostPortPair& host_port_pair() { return host_port_pair_; }
- const GURL& report_uri() { return report_uri_; }
- const base::Time& expiration() { return expiration_; }
- uint32_t num_failures() { return num_failures_; }
- const X509Certificate* served_certificate_chain() {
+ const HostPortPair& host_port_pair() const { return host_port_pair_; }
+ const GURL& report_uri() const { return report_uri_; }
+ const base::Time& expiration() const { return expiration_; }
+ uint32_t num_failures() const { return num_failures_; }
+ const X509Certificate* served_certificate_chain() const {
return served_certificate_chain_;
}
- const X509Certificate* validated_certificate_chain() {
+ const X509Certificate* validated_certificate_chain() const {
return validated_certificate_chain_;
}
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps() {
+ const SignedCertificateTimestampAndStatusList& signed_certificate_timestamps()
+ const {
return signed_certificate_timestamps_;
}
+ const NetworkIsolationKey& network_isolation_key() const {
+ return network_isolation_key_;
+ }
private:
HostPortPair host_port_pair_;
@@ -210,6 +219,7 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
const X509Certificate* served_certificate_chain_;
const X509Certificate* validated_certificate_chain_;
SignedCertificateTimestampAndStatusList signed_certificate_timestamps_;
+ NetworkIsolationKey network_isolation_key_;
};
class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
@@ -307,12 +317,38 @@ bool operator==(const TransportSecurityState::PKPState& lhs,
lhs.domain == rhs.domain && lhs.report_uri == rhs.report_uri;
}
+// Creates a unique new host name every time it's called. Tests should not
+// depend on the exact domain names, as they may vary depending on what other
+// tests have been run by the same process. Intended for Expect-CT pruning
+// tests, which add a lot of domains.
+std::string CreateUniqueHostName() {
+ static int count = 0;
+ return base::StringPrintf("%i.test", ++count);
+}
+
+// As with CreateUniqueHostName(), returns a unique NetworkIsolationKey for use
+// with Expect-CT prunung tests.
+NetworkIsolationKey CreateUniqueNetworkIsolationKey(bool is_transient) {
+ if (is_transient)
+ return NetworkIsolationKey::CreateTransient();
+ url::Origin origin = url::Origin::CreateFromNormalizedTuple(
+ "https", CreateUniqueHostName(), 443);
+ return NetworkIsolationKey(origin /* top_frame_origin */,
+ origin /* frame_origin */);
+}
+
} // namespace
-class TransportSecurityStateTest : public testing::Test {
+class TransportSecurityStateTest : public ::testing::Test,
+ public WithTaskEnvironment {
public:
- TransportSecurityStateTest() {
+ TransportSecurityStateTest()
+ : WithTaskEnvironment(
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource);
+ // Need mocked out time for pruning tests. Don't start with a
+ // time of 0, as code doesn't generally expect it.
+ FastForwardBy(base::TimeDelta::FromDays(1));
}
~TransportSecurityStateTest() override {
@@ -480,51 +516,65 @@ TEST_F(TransportSecurityStateTest, SubdomainMatches) {
EXPECT_FALSE(state.ShouldUpgradeToSSL("notexample.test"));
}
-// Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule
-// with it, regardless of the includeSubDomains bit. This is a regression test
-// for https://crbug.com/469957. Note this behavior does not match the spec.
-// See https://crbug.com/821811.
-TEST_F(TransportSecurityStateTest, SubdomainCarveout) {
+// Tests that a more-specific HSTS rule without the includeSubDomains bit does
+// not override a less-specific rule with includeSubDomains. Applicability is
+// checked before specificity. See https://crbug.com/821811.
+TEST_F(TransportSecurityStateTest, STSSubdomainNoOverride) {
const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
- state.AddHSTS("example1.test", expiry, true);
- state.AddHSTS("foo.example1.test", expiry, false);
+ state.AddHSTS("example.test", expiry, true);
+ state.AddHSTS("foo.example.test", expiry, false);
- state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(),
- report_uri);
- state.AddHPKP("foo.example2.test", expiry, false, GetSampleSPKIHashes(),
- report_uri);
+ // The example.test rule applies to the entire domain, including subdomains of
+ // foo.example.test.
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("example.test"));
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example.test"));
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example.test"));
+ EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example.test"));
- EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test"));
- EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test"));
+ // Expire the foo.example.test rule.
+ state.AddHSTS("foo.example.test", older, false);
+
+ // The example.test rule still applies.
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("example.test"));
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example.test"));
+ EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example.test"));
+ EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example.test"));
+}
- // The foo.example1.test rule overrides the example1.test rule, so
- // bar.foo.example1.test has no HSTS state.
- EXPECT_FALSE(state.ShouldUpgradeToSSL("bar.foo.example1.test"));
- EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
+// Tests that a more-specific HPKP rule overrides a less-specific rule
+// with it, regardless of the includeSubDomains bit. Note this behavior does not
+// match HSTS. See https://crbug.com/821811.
+TEST_F(TransportSecurityStateTest, PKPSubdomainCarveout) {
+ const GURL report_uri(kReportUri);
+ TransportSecurityState state;
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
- EXPECT_TRUE(state.HasPublicKeyPins("example2.test"));
- EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test"));
+ state.AddHPKP("example.test", expiry, true, GetSampleSPKIHashes(),
+ report_uri);
+ state.AddHPKP("foo.example.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
+ EXPECT_TRUE(state.HasPublicKeyPins("example.test"));
+ EXPECT_TRUE(state.HasPublicKeyPins("foo.example.test"));
- // The foo.example2.test rule overrides the example1.test rule, so
- // bar.foo.example2.test has no HPKP state.
- EXPECT_FALSE(state.HasPublicKeyPins("bar.foo.example2.test"));
- EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
+ // The foo.example.test rule overrides the example1.test rule, so
+ // bar.foo.example.test has no HPKP state.
+ EXPECT_FALSE(state.HasPublicKeyPins("bar.foo.example.test"));
+ EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example.test"));
- // Expire the foo.example*.test rules.
- state.AddHSTS("foo.example1.test", older, false);
- state.AddHPKP("foo.example2.test", older, false, GetSampleSPKIHashes(),
+ // Expire the foo.example.test rule.
+ state.AddHPKP("foo.example.test", older, false, GetSampleSPKIHashes(),
report_uri);
- // Now the base example*.test rules apply to bar.foo.example*.test.
- EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example1.test"));
- EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
- EXPECT_TRUE(state.HasPublicKeyPins("bar.foo.example2.test"));
- EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
+ // Now the base example.test rule applies to bar.foo.example.test.
+ EXPECT_TRUE(state.HasPublicKeyPins("bar.foo.example.test"));
+ EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example.test"));
}
TEST_F(TransportSecurityStateTest, FatalSSLErrors) {
@@ -667,7 +717,7 @@ TEST_F(TransportSecurityStateTest, DynamicDomainState) {
TransportSecurityState::STSState sts_state;
TransportSecurityState::PKPState pkp_state;
- ASSERT_TRUE(state.GetDynamicSTSState("foo.example.com", &sts_state, nullptr));
+ ASSERT_TRUE(state.GetDynamicSTSState("foo.example.com", &sts_state));
ASSERT_TRUE(state.GetDynamicPKPState("foo.example.com", &pkp_state));
EXPECT_TRUE(sts_state.ShouldUpgradeToSSL());
EXPECT_TRUE(pkp_state.HasPublicKeyPins());
@@ -729,21 +779,24 @@ TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
EXPECT_FALSE(state.ShouldUpgradeToSSL("example.com"));
EXPECT_FALSE(state.HasPublicKeyPins("example.com"));
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.com", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.com", NetworkIsolationKey(), &expect_ct_state));
bool include_subdomains = false;
state.AddHSTS("example.com", expiry, include_subdomains);
state.AddHPKP("example.com", expiry, include_subdomains,
GetSampleSPKIHashes(), GURL());
- state.AddExpectCT("example.com", expiry, true, GURL());
+ state.AddExpectCT("example.com", expiry, true, GURL(), NetworkIsolationKey());
state.DeleteAllDynamicDataSince(expiry, base::DoNothing());
EXPECT_TRUE(state.ShouldUpgradeToSSL("example.com"));
EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
- EXPECT_TRUE(state.GetDynamicExpectCTState("example.com", &expect_ct_state));
+ EXPECT_TRUE(state.GetDynamicExpectCTState(
+ "example.com", NetworkIsolationKey(), &expect_ct_state));
state.DeleteAllDynamicDataSince(older, base::DoNothing());
EXPECT_FALSE(state.ShouldUpgradeToSSL("example.com"));
EXPECT_FALSE(state.HasPublicKeyPins("example.com"));
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.com", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.com", NetworkIsolationKey(), &expect_ct_state));
// Dynamic data in |state| should be empty now.
EXPECT_FALSE(TransportSecurityState::STSStateIterator(state).HasNext());
@@ -753,32 +806,48 @@ TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
TEST_F(TransportSecurityStateTest, DeleteDynamicDataForHost) {
base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- TransportSecurityState::kDynamicExpectCTFeature);
+ feature_list.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey},
+ /* disabled_features */
+ {});
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
bool include_subdomains = false;
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
state.AddHSTS("example1.test", expiry, include_subdomains);
state.AddHPKP("example1.test", expiry, include_subdomains,
GetSampleSPKIHashes(), GURL());
- state.AddExpectCT("example1.test", expiry, true, GURL());
+ state.AddExpectCT("example1.test", expiry, true, GURL(),
+ NetworkIsolationKey());
EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test"));
EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.test"));
EXPECT_TRUE(state.HasPublicKeyPins("example1.test"));
EXPECT_FALSE(state.HasPublicKeyPins("example2.test"));
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_TRUE(state.GetDynamicExpectCTState("example1.test", &expect_ct_state));
- EXPECT_FALSE(
- state.GetDynamicExpectCTState("example2.test", &expect_ct_state));
+ EXPECT_TRUE(state.GetDynamicExpectCTState(
+ "example1.test", NetworkIsolationKey(), &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example2.test", NetworkIsolationKey(), &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example1.test", network_isolation_key, &expect_ct_state));
+ state.AddExpectCT("example1.test", expiry, true, GURL(),
+ network_isolation_key);
+ EXPECT_TRUE(state.GetDynamicExpectCTState(
+ "example1.test", network_isolation_key, &expect_ct_state));
EXPECT_TRUE(state.DeleteDynamicDataForHost("example1.test"));
EXPECT_FALSE(state.ShouldUpgradeToSSL("example1.test"));
EXPECT_FALSE(state.HasPublicKeyPins("example1.test"));
- EXPECT_FALSE(
- state.GetDynamicExpectCTState("example1.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example1.test", NetworkIsolationKey(), &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example1.test", network_isolation_key, &expect_ct_state));
}
TEST_F(TransportSecurityStateTest, LongNames) {
@@ -790,7 +859,7 @@ TEST_F(TransportSecurityStateTest, LongNames) {
TransportSecurityState::PKPState pkp_state;
// Just checks that we don't hit a NOTREACHED.
EXPECT_FALSE(state.GetStaticDomainState(kLongName, &sts_state, &pkp_state));
- EXPECT_FALSE(state.GetDynamicSTSState(kLongName, &sts_state, nullptr));
+ EXPECT_FALSE(state.GetDynamicSTSState(kLongName, &sts_state));
EXPECT_FALSE(state.GetDynamicPKPState(kLongName, &pkp_state));
}
@@ -940,7 +1009,6 @@ TEST_F(TransportSecurityStateTest, PreloadedExpectCT) {
TransportSecurityState::ExpectCTState expect_ct_state;
EXPECT_TRUE(
GetExpectCTState(&state, kExpectCTStaticHostname, &expect_ct_state));
- EXPECT_EQ(kExpectCTStaticHostname, expect_ct_state.domain);
EXPECT_EQ(GURL(kExpectCTStaticReportURI), expect_ct_state.report_uri);
EXPECT_FALSE(
GetExpectCTState(&state, "hsts-preloaded.test", &expect_ct_state));
@@ -967,13 +1035,15 @@ TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("", host_port, ssl_info);
+ state.ProcessExpectCTHeader("", host_port, ssl_info, NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
- state.ProcessExpectCTHeader("blah blah", host_port, ssl_info);
+ state.ProcessExpectCTHeader("blah blah", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -998,11 +1068,13 @@ TEST_F(TransportSecurityStateTest, ExpectCTNonPublicRoot) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
ssl_info.is_issued_by_known_root = true;
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1027,12 +1099,14 @@ TEST_F(TransportSecurityStateTest, ExpectCTComplianceNotAvailable) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1057,12 +1131,14 @@ TEST_F(TransportSecurityStateTest, ExpectCTCompliantCert) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1087,14 +1163,16 @@ TEST_F(TransportSecurityStateTest, PreloadedExpectCTBuildNotTimely) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
// Sanity-check that the reporter is notified if the build is timely and the
// connection is not compliant.
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1119,18 +1197,21 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTBuildNotTimely) {
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
const char kHeader[] = "max-age=10, report-uri=http://report.test";
- state.ProcessExpectCTHeader(kHeader, host_port, ssl_info);
+ state.ProcessExpectCTHeader(kHeader, host_port, ssl_info,
+ NetworkIsolationKey());
// No report should have been sent and the state should not have been saved.
EXPECT_EQ(0u, reporter.num_failures());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
// Sanity-check that the reporter is notified if the build is timely and the
// connection is not compliant.
ssl_info.ct_policy_compliance =
ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
- state.ProcessExpectCTHeader(kHeader, host_port, ssl_info);
+ state.ProcessExpectCTHeader(kHeader, host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1155,11 +1236,13 @@ TEST_F(TransportSecurityStateTest, ExpectCTNotPreloaded) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(0u, reporter.num_failures());
host_port.set_host(kExpectCTStaticHostname);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1183,12 +1266,15 @@ TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
std::string(), std::string(), base::Time::Now(),
ct::SCT_STATUS_INVALID_SIGNATURE,
&ssl_info.signed_certificate_timestamps);
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
TransportSecurityState state;
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ network_isolation_key);
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ(host_port.host(), reporter.host_port_pair().host());
EXPECT_EQ(host_port.port(), reporter.host_port_pair().port());
@@ -1202,6 +1288,7 @@ TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(ssl_info.signed_certificate_timestamps[0].sct,
reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
}
// Tests that the Expect CT reporter is not notified for repeated noncompliant
@@ -1229,11 +1316,13 @@ TEST_F(TransportSecurityStateTest, RepeatedExpectCTReportsForStaticExpectCT) {
TransportSecurityStateTest::EnableStaticExpectCT(&state);
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
// After processing a second header, the report should not be sent again.
- state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+ state.ProcessExpectCTHeader("preload", host_port, ssl_info,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -1467,7 +1556,7 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
using CTRequirementLevel =
TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
- // Dummy cert to use as the validate chain. The contents do not matter.
+ // Dummy cert to use as the validation chain. The contents do not matter.
scoped_refptr<X509Certificate> cert =
ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
ASSERT_TRUE(cert);
@@ -1486,7 +1575,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey());
MockRequireCTDelegate always_require_delegate;
EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_, _, _))
@@ -1498,28 +1588,32 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
state.SetRequireCTDelegate(nullptr);
EXPECT_EQ(
@@ -1528,7 +1622,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
}
// If CT is not required, then regardless of the CT state for the host,
@@ -1540,7 +1635,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey());
MockRequireCTDelegate never_require_delegate;
EXPECT_CALL(never_require_delegate, IsCTRequiredForHost(_, _, _))
@@ -1552,14 +1648,16 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_NOT_REQUIRED,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ NetworkIsolationKey()));
state.SetRequireCTDelegate(nullptr);
EXPECT_EQ(
@@ -1568,7 +1666,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
}
// If the Delegate is in the default state, then it should return the same
@@ -1580,7 +1679,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey());
MockRequireCTDelegate default_require_ct_delegate;
EXPECT_CALL(default_require_ct_delegate, IsCTRequiredForHost(_, _, _))
@@ -1592,7 +1692,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
state.SetRequireCTDelegate(nullptr);
EXPECT_EQ(
@@ -1601,7 +1702,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
}
}
@@ -1639,7 +1741,8 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
// ... but certificates issued after 1 June 2016 are required to be...
EXPECT_EQ(
@@ -1648,28 +1751,32 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
// ... unless they were issued by an excluded intermediate.
hashes.push_back(HashValue(google_hash_value));
@@ -1679,14 +1786,16 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_NOT_REQUIRED,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
// And other certificates should remain unaffected.
SHA256HashValue unrelated_hash_value = {{0x01, 0x02}};
@@ -1699,14 +1808,16 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
before_cert.get(), before_cert.get(),
SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, unrelated_hashes,
after_cert.get(), after_cert.get(),
SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
}
// Tests that CAs can enable CT for testing their issuance practices, prior
@@ -1733,7 +1844,8 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
// However, simulating a Field Trial in which CT is required for certificates
// after 2017-12-01 should cause CT to be required for this certificate, as
@@ -1753,7 +1865,8 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
// It should succeed if it does comply with policy.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
@@ -1761,7 +1874,8 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
// It should succeed if the build is outdated.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
@@ -1769,7 +1883,8 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
// It should succeed if it was a locally-trusted CA.
EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
@@ -1777,7 +1892,8 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
HostPortPair("www.example.com", 443), false, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
}
// Tests that Certificate Transparency is required for all of the Symantec
@@ -1810,28 +1926,32 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantecManagedCAs) {
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, before_cert.get(),
before_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
scoped_refptr<X509Certificate> after_cert =
ImportCertFromFile(GetTestCertsDirectory(), "post_june_2016.pem");
@@ -1843,28 +1963,32 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantecManagedCAs) {
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ NetworkIsolationKey()));
EXPECT_EQ(
TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, after_cert.get(),
after_cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
}
// Tests that dynamic Expect-CT state is cleared from ClearDynamicData().
@@ -1878,14 +2002,16 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTStateCleared) {
const base::Time current_time = base::Time::Now();
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- state.AddExpectCT(host, expiry, true, GURL());
- EXPECT_TRUE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ state.AddExpectCT(host, expiry, true, GURL(), NetworkIsolationKey());
+ EXPECT_TRUE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
EXPECT_TRUE(expect_ct_state.enforce);
EXPECT_TRUE(expect_ct_state.report_uri.is_empty());
EXPECT_EQ(expiry, expect_ct_state.expiry);
state.ClearDynamicData();
- EXPECT_FALSE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
}
// Tests that dynamic Expect-CT state can be added and retrieved.
@@ -1900,8 +2026,9 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTState) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
// Test that Expect-CT state can be added and retrieved.
- state.AddExpectCT(host, expiry, true, GURL());
- EXPECT_TRUE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ state.AddExpectCT(host, expiry, true, GURL(), NetworkIsolationKey());
+ EXPECT_TRUE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
EXPECT_TRUE(expect_ct_state.enforce);
EXPECT_TRUE(expect_ct_state.report_uri.is_empty());
EXPECT_EQ(expiry, expect_ct_state.expiry);
@@ -1909,16 +2036,18 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTState) {
// Test that Expect-CT can be updated (e.g. by changing |enforce| to false and
// adding a report-uri).
const GURL report_uri("https://example-report.test");
- state.AddExpectCT(host, expiry, false, report_uri);
- EXPECT_TRUE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ state.AddExpectCT(host, expiry, false, report_uri, NetworkIsolationKey());
+ EXPECT_TRUE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
EXPECT_FALSE(expect_ct_state.enforce);
EXPECT_EQ(report_uri, expect_ct_state.report_uri);
EXPECT_EQ(expiry, expect_ct_state.expiry);
// Test that Expect-CT state is discarded when expired.
state.AddExpectCT(host, current_time - base::TimeDelta::FromSeconds(1000),
- true, report_uri);
- EXPECT_FALSE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ true, report_uri, NetworkIsolationKey());
+ EXPECT_FALSE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
}
// Tests that the Expect-CT reporter is not notified for repeated dynamic
@@ -1946,9 +2075,11 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTDeduping) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_TRUE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_TRUE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
EXPECT_EQ(GURL("http://foo.test"), expect_ct_state.report_uri);
EXPECT_TRUE(expect_ct_state.enforce);
EXPECT_LT(now, expect_ct_state.expiry);
@@ -1963,7 +2094,8 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTDeduping) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(1u, reporter.num_failures());
// The second time it fails to meet CT requirements, a report should not be
@@ -1973,7 +2105,8 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTDeduping) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -2002,7 +2135,8 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTCompliantConnection) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
// No report should be sent when the header was processed over a connection
// that complied with CT policy.
@@ -2011,7 +2145,8 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTCompliantConnection) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ NetworkIsolationKey()));
EXPECT_EQ(0u, reporter.num_failures());
}
@@ -2029,15 +2164,18 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTHeaderProcessingDeduping) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
// The first time the header was received over a connection that failed to
// meet CT requirements, a report should be sent.
EXPECT_EQ(1u, reporter.num_failures());
// The second time the header was received, no report should be sent.
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
EXPECT_EQ(1u, reporter.num_failures());
}
@@ -2053,8 +2191,9 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTStateDisabled) {
const base::Time current_time = base::Time::Now();
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- state.AddExpectCT(host, expiry, true, GURL());
- EXPECT_FALSE(state.GetDynamicExpectCTState(host, &expect_ct_state));
+ state.AddExpectCT(host, expiry, true, GURL(), NetworkIsolationKey());
+ EXPECT_FALSE(state.GetDynamicExpectCTState(host, NetworkIsolationKey(),
+ &expect_ct_state));
}
// Tests that dynamic Expect-CT opt-ins are processed correctly (when the
@@ -2072,11 +2211,11 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCT) {
feature_list.InitAndDisableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
TransportSecurityState state;
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443),
- ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(
- state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
}
// Now test that the header is processed when the feature is enabled.
@@ -2088,11 +2227,11 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCT) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443),
- ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_TRUE(
- state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_TRUE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
EXPECT_EQ(GURL("http://foo.test"), expect_ct_state.report_uri);
EXPECT_TRUE(expect_ct_state.enforce);
EXPECT_LT(now, expect_ct_state.expiry);
@@ -2115,9 +2254,11 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTPrivateRoot) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
EXPECT_EQ(0u, reporter.num_failures());
}
@@ -2145,9 +2286,11 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTNoComplianceDetails) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
EXPECT_EQ(0u, reporter.num_failures());
}
@@ -2174,15 +2317,19 @@ TEST_F(TransportSecurityStateTest,
ct::SCT_STATUS_INVALID_SIGNATURE,
&ssl.signed_certificate_timestamps);
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ network_isolation_key);
TransportSecurityState::ExpectCTState expect_ct_state;
- EXPECT_FALSE(state.GetDynamicExpectCTState("example.test", &expect_ct_state));
+ EXPECT_FALSE(state.GetDynamicExpectCTState(
+ "example.test", NetworkIsolationKey(), &expect_ct_state));
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ("example.test", reporter.host_port_pair().host());
EXPECT_TRUE(reporter.expiration().is_null());
@@ -2194,6 +2341,7 @@ TEST_F(TransportSecurityStateTest,
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(ssl.signed_certificate_timestamps[0].sct,
reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
}
// Tests that CheckCTRequirements() returns the correct response if a connection
@@ -2212,6 +2360,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
std::string(), std::string(), base::Time::Now(),
ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
TransportSecurityState::kDynamicExpectCTFeature);
@@ -2220,11 +2370,11 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
state.AddExpectCT("example.test", expiry, true /* enforce */,
- GURL("https://example-report.test"));
+ GURL("https://example-report.test"), network_isolation_key);
state.AddExpectCT("example-report-only.test", expiry, false /* enforce */,
- GURL("https://example-report.test"));
+ GURL("https://example-report.test"), network_isolation_key);
state.AddExpectCT("example-enforce-only.test", expiry, true /* enforce */,
- GURL());
+ GURL(), network_isolation_key);
// Test that a connection to an unrelated host is not affected.
EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
@@ -2232,13 +2382,15 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example2.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
state.CheckCTRequirements(
HostPortPair("example2.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ network_isolation_key));
EXPECT_EQ(0u, reporter.num_failures());
// A connection to an Expect-CT host should be closed and reported.
@@ -2247,7 +2399,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ("example.test", reporter.host_port_pair().host());
EXPECT_EQ(443, reporter.host_port_pair().port());
@@ -2258,6 +2411,7 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
EXPECT_EQ(sct_list[0].status,
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
// A compliant connection to an Expect-CT host should not be closed or
// reported.
@@ -2266,14 +2420,16 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ network_isolation_key));
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY,
+ network_isolation_key));
EXPECT_EQ(1u, reporter.num_failures());
// A connection to a report-only host should be reported only.
@@ -2282,7 +2438,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example-report-only.test", 443), true,
HashValueVector(), cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ network_isolation_key));
EXPECT_EQ(2u, reporter.num_failures());
EXPECT_EQ("example-report-only.test", reporter.host_port_pair().host());
EXPECT_EQ(443, reporter.host_port_pair().port());
@@ -2292,6 +2449,7 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
EXPECT_EQ(sct_list[0].status,
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
// A connection to an enforce-only host should be closed but not reported.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
@@ -2299,7 +2457,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example-enforce-only.test", 443), true,
HashValueVector(), cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS,
+ network_isolation_key));
EXPECT_EQ(2u, reporter.num_failures());
// A connection with a private root should be neither enforced nor reported.
@@ -2308,7 +2467,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example.test", 443), false, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(2u, reporter.num_failures());
// A connection with DISABLE_EXPECT_CT_REPORTS should not send a report.
@@ -2317,7 +2477,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCT) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(2u, reporter.num_failures());
}
@@ -2341,6 +2502,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
std::string(), std::string(), base::Time::Now(),
ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
@@ -2350,7 +2513,7 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
state.AddExpectCT("example.test", expiry, false /* enforce */,
- GURL("https://example-report.test"));
+ GURL("https://example-report.test"), network_isolation_key);
// A connection to an Expect-CT host, which also requires CT by the delegate,
// should be closed and reported.
@@ -2363,7 +2526,8 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ("example.test", reporter.host_port_pair().host());
EXPECT_EQ(443, reporter.host_port_pair().port());
@@ -2374,6 +2538,7 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
EXPECT_EQ(sct_list[0].status,
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
}
// Tests that for a host that explicitly disabled CT by delegate and is also
@@ -2397,6 +2562,8 @@ TEST_F(TransportSecurityStateTest,
MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
std::string(), std::string(), base::Time::Now(),
ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
@@ -2406,7 +2573,7 @@ TEST_F(TransportSecurityStateTest,
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
state.AddExpectCT("example.test", expiry, false /* enforce */,
- GURL("https://example-report.test"));
+ GURL("https://example-report.test"), network_isolation_key);
// A connection to an Expect-CT host, which is exempted from the CT
// requirements by the delegate, should be reported but not closed.
@@ -2419,7 +2586,8 @@ TEST_F(TransportSecurityStateTest,
HostPortPair("example.test", 443), true, HashValueVector(),
cert1.get(), cert2.get(), sct_list,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key));
EXPECT_EQ(1u, reporter.num_failures());
EXPECT_EQ("example.test", reporter.host_port_pair().host());
EXPECT_EQ(443, reporter.host_port_pair().port());
@@ -2430,6 +2598,7 @@ TEST_F(TransportSecurityStateTest,
EXPECT_EQ(sct_list[0].status,
reporter.signed_certificate_timestamps()[0].status);
EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
}
// Tests that the dynamic Expect-CT UMA histogram is recorded correctly.
@@ -2452,8 +2621,8 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTUMA) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443),
- ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
histograms.ExpectTotalCount(kHistogramName, 1);
histograms.ExpectBucketCount(kHistogramName, true, 1);
}
@@ -2466,67 +2635,13 @@ TEST_F(TransportSecurityStateTest, DynamicExpectCTUMA) {
TransportSecurityState state;
MockExpectCTReporter reporter;
state.SetExpectCTReporter(&reporter);
- state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443),
- ssl);
+ state.ProcessExpectCTHeader(kHeader, HostPortPair("example.test", 443), ssl,
+ NetworkIsolationKey());
histograms.ExpectTotalCount(kHistogramName, 1);
histograms.ExpectBucketCount(kHistogramName, false, 1);
}
}
-// Tests the Net.HstsInfo histogram is recorded correctly. See
-// https://crbug.com/821811.
-TEST_F(TransportSecurityStateTest, HstsInfoHistogram) {
- const base::Time current_time(base::Time::Now());
- const base::Time expiry = current_time + base::TimeDelta::FromDays(1000);
-
- TransportSecurityState state;
- // a.test is not on the static list, so the dynamic set applies.
- state.AddHSTS("a.test", expiry, /*include_subdomains=*/true);
- state.AddHSTS("a.a.test", expiry, /*include_subdomains=*/false);
- // Also test the interaction with the HSTS preload list.
- state.AddHSTS("a.include-subdomains-hsts-preloaded.test", expiry,
- /*include_subdomains=*/true);
- state.AddHSTS("a.a.include-subdomains-hsts-preloaded.test", expiry,
- /*include_subdomains=*/false);
-
- const struct {
- const char* host;
- HstsInfo expected;
- } kTests[] = {
- // HSTS was not enabled.
- {"b.test", HstsInfo::kDisabled},
- // HSTS was enabled via the header.
- {"a.test", HstsInfo::kEnabled},
- {"a.a.test", HstsInfo::kEnabled},
- // HSTS was enabled via the preload list.
- {"b.include-subdomains-hsts-preloaded.test", HstsInfo::kEnabled},
- // HSTS should have been enabled but was not due to spec non-compliance.
- {"a.a.a.test", HstsInfo::kDynamicIncorrectlyMasked},
- // Spec non-compliance was masked by the preload list.
- {"a.a.a.include-subdomains-hsts-preloaded.test",
- HstsInfo::kDynamicIncorrectlyMaskedButMatchedStatic},
- };
-
- for (const auto& test : kTests) {
- SCOPED_TRACE(test.host);
- bool enabled =
- test.expected == HstsInfo::kEnabled ||
- test.expected == HstsInfo::kDynamicIncorrectlyMaskedButMatchedStatic;
- {
- base::HistogramTester histograms;
- EXPECT_EQ(enabled, state.ShouldUpgradeToSSL(test.host));
- histograms.ExpectTotalCount("Net.HstsInfo", 1);
- histograms.ExpectBucketCount("Net.HstsInfo", test.expected, 1);
- }
- {
- base::HistogramTester histograms;
- EXPECT_EQ(enabled, state.ShouldSSLErrorsBeFatal(test.host));
- histograms.ExpectTotalCount("Net.HstsInfo", 1);
- histograms.ExpectBucketCount("Net.HstsInfo", test.expected, 1);
- }
- }
-}
-
#if BUILDFLAG(INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST)
const char kSubdomain[] = "foo.example.test";
@@ -3274,4 +3389,506 @@ TEST_F(TransportSecurityStateTest, DecodeSizeFour) {
#endif // BUILDFLAG(INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST)
+TEST_F(TransportSecurityStateTest,
+ PartitionExpectCTStateByNetworkIsolationKey) {
+ const char kDomain[] = "example.test";
+ HostPortPair host_port_pair(kDomain, 443);
+
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ TransportSecurityState::kDynamicExpectCTFeature);
+
+ const base::Time expiry =
+ base::Time::Now() + base::TimeDelta::FromSeconds(1000);
+
+ // Dummy cert to use as the validation chain. The contents do not matter.
+ scoped_refptr<X509Certificate> cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert);
+ HashValueVector hashes;
+ hashes.push_back(
+ HashValue(X509Certificate::CalculateFingerprint256(cert->cert_buffer())));
+
+ // An ExpectCT entry is set using network_isolation_key1, and then accessed
+ // using both keys. It should only be accessible using the other key when
+ // kPartitionExpectCTStateByNetworkIsolationKey is disabled.
+ NetworkIsolationKey network_isolation_key1 =
+ NetworkIsolationKey::CreateTransient();
+ NetworkIsolationKey network_isolation_key2 =
+ NetworkIsolationKey::CreateTransient();
+
+ for (bool partition_expect_ct_state : {false, true}) {
+ base::test::ScopedFeatureList feature_list2;
+ if (partition_expect_ct_state) {
+ feature_list2.InitAndEnableFeature(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+ } else {
+ feature_list2.InitAndDisableFeature(
+ features::kPartitionExpectCTStateByNetworkIsolationKey);
+ }
+
+ // Add Expect-CT entry.
+ TransportSecurityState state;
+ state.AddExpectCT(kDomain, expiry, true, GURL(), network_isolation_key1);
+ TransportSecurityState::ExpectCTState expect_ct_state;
+ EXPECT_TRUE(state.GetDynamicExpectCTState(kDomain, network_isolation_key1,
+ &expect_ct_state));
+
+ // The Expect-CT entry should only be respected with
+ // |network_isolation_key2| when
+ // kPartitionExpectCTStateByNetworkIsolationKey is disabled.
+ EXPECT_EQ(!partition_expect_ct_state,
+ state.GetDynamicExpectCTState(kDomain, network_isolation_key2,
+ &expect_ct_state));
+ EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
+ state.CheckCTRequirements(
+ host_port_pair, true, hashes, cert.get(), cert.get(),
+ SignedCertificateTimestampAndStatusList(),
+ TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key1));
+ EXPECT_EQ(!partition_expect_ct_state,
+ TransportSecurityState::CT_REQUIREMENTS_NOT_MET ==
+ state.CheckCTRequirements(
+ host_port_pair, true, hashes, cert.get(), cert.get(),
+ SignedCertificateTimestampAndStatusList(),
+ TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ network_isolation_key2));
+
+ // An Expect-CT header with |network_isolation_key2| should only overwrite
+ // the entry when |partition_expect_ct_state| is false.
+ SSLInfo ssl_info;
+ ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
+ ssl_info.is_issued_by_known_root = true;
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ const char kHeader[] = "max-age=0";
+ state.ProcessExpectCTHeader(kHeader, host_port_pair, ssl_info,
+ network_isolation_key2);
+ EXPECT_EQ(partition_expect_ct_state,
+ state.GetDynamicExpectCTState(kDomain, network_isolation_key1,
+ &expect_ct_state));
+
+ // An Expect-CT header with |network_isolation_key1| should always overwrite
+ // the added entry.
+ state.ProcessExpectCTHeader(kHeader, host_port_pair, ssl_info,
+ network_isolation_key1);
+ EXPECT_FALSE(state.GetDynamicExpectCTState(kDomain, network_isolation_key1,
+ &expect_ct_state));
+ }
+}
+
+// Tests the eviction logic and priority of pruning resources, before applying
+// the per-NetworkIsolationKey limit.
+TEST_F(TransportSecurityStateTest, PruneExpectCTPriority) {
+ const GURL report_uri(kReportUri);
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ // enabled_features
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey},
+ // disabled_features
+ {});
+
+ // Each iteration adds two groups of |kGroupSize| entries, with specified
+ // parameters, and then enough entries are added for a third group to trigger
+ // pruning. |kGroupSize| is chosen so that exactly all the entries in the
+ // first group or the second will typically be pruned. Note that group 1 is
+ // always added before group 2.
+ const size_t kGroupSize =
+ features::kExpectCTPruneMax.Get() - features::kExpectCTPruneMin.Get();
+ // This test requires |2 * kGroupSize| to be less than |kExpectCTPruneMax|.
+ ASSERT_LT(2 * kGroupSize,
+ static_cast<size_t>(features::kExpectCTPruneMax.Get()));
+ const size_t kThirdGroupSize =
+ features::kExpectCTPruneMax.Get() - 2 * kGroupSize;
+
+ // Specifies where the entries of no groups or of only the first group are old
+ // enough to be pruned.
+ enum class GroupsOldEnoughToBePruned {
+ kNone,
+ kFirstGroupOnly,
+ kFirstAndSecondGroups,
+ };
+
+ const struct TestCase {
+ bool first_group_has_transient_nik;
+ bool second_group_has_transient_nik;
+ bool first_group_has_enforce;
+ bool second_group_has_enforce;
+ bool first_group_is_expired;
+ bool second_group_is_expired;
+ GroupsOldEnoughToBePruned groups_old_enough_to_be_pruned;
+ bool expect_first_group_retained;
+ bool expect_second_group_retained;
+ } kTestCases[] = {
+ // No entries are prunable, so will exceed features::kExpectCTPruneMax.
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ true /* expect_first_group_retained */,
+ true /* expect_second_group_retained */
+ },
+
+ // Only second group is prunable, so it should end up empty.
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ false /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ true /* expect_first_group_retained */,
+ false /* expect_second_group_retained */
+ },
+ {
+ false /* first_group_has_transient_nik */,
+ true /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ true /* expect_first_group_retained */,
+ false /* expect_second_group_retained */
+ },
+
+ // Only first group is prunable, so only it should be evicted.
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ false /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ false /* expect_first_group_retained */,
+ true /* expect_second_group_retained */
+ },
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */,
+ GroupsOldEnoughToBePruned::kFirstGroupOnly,
+ false /* expect_first_group_retained */,
+ true /* expect_second_group_retained */
+ },
+
+ // Both groups are prunable for the same reason, but group 1 is older
+ // (since group 1 is added first).
+ {
+ true /* first_group_has_transient_nik */,
+ true /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ false /* expect_first_group_retained */,
+ true /* expect_second_group_retained */
+ },
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */,
+ GroupsOldEnoughToBePruned::kFirstAndSecondGroups,
+ false /* expect_first_group_retained */,
+ true /* expect_second_group_retained */
+ },
+
+ // First group has enforce not set, second uses a transient NIK. First
+ // should take priority.
+ {
+ false /* first_group_has_transient_nik */,
+ true /* second_group_has_transient_nik */,
+ false /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */, GroupsOldEnoughToBePruned::kNone,
+ true /* expect_first_group_retained */,
+ false /* expect_second_group_retained */
+ },
+
+ // First group outside the non-prunable window, second has enforce set.
+ // not set. First should take priority.
+ {
+ false /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ true /* bool first_group_has_enforce */,
+ false /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ false /* second_group_is_expired */,
+ GroupsOldEnoughToBePruned::kFirstGroupOnly,
+ true /* expect_first_group_retained */,
+ false /* expect_second_group_retained */
+ },
+
+ // Second group is expired, so it is evicted, even though the first group
+ // would otherwise be prunable and the second would not.
+ {
+ true /* first_group_has_transient_nik */,
+ false /* second_group_has_transient_nik */,
+ false /* bool first_group_has_enforce */,
+ true /* bool second_group_has_enforce */,
+ false /* first_group_is_expired */,
+ true /* second_group_is_expired */,
+ GroupsOldEnoughToBePruned::kFirstGroupOnly,
+ true /* expect_first_group_retained */,
+ false /* expect_second_group_retained */
+ },
+ };
+
+ for (const auto& test_case : kTestCases) {
+ // Each test case simulates up to |features::kExpectCTSafeFromPruneDays
+ // + 1| days passing, so if an entry added for a test case should not expire
+ // over the course of running the test, its expiry date must be farther into
+ // the future than that.
+ base::Time unexpired_expiry_time =
+ base::Time::Now() +
+ base::TimeDelta::FromDays(
+ 2 * features::kExpectCTSafeFromPruneDays.Get() + 1);
+
+ // Always add entries unexpired.
+ base::Time first_group_expiry =
+ test_case.first_group_is_expired
+ ? base::Time::Now() + base::TimeDelta::FromMilliseconds(1)
+ : unexpired_expiry_time;
+
+ TransportSecurityState state;
+ base::Time first_group_observation_time = base::Time::Now();
+ for (size_t i = 0; i < kGroupSize; ++i) {
+ // All entries use a unique NetworkIsolationKey, so
+ // NetworkIsolationKey-based pruning will do nothing.
+ state.AddExpectCT(CreateUniqueHostName(), first_group_expiry,
+ test_case.first_group_has_enforce, report_uri,
+ CreateUniqueNetworkIsolationKey(
+ test_case.first_group_has_transient_nik));
+ }
+
+ // Skip forward in time slightly, so the first group is always older than
+ // the first.
+ FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+ // If only the first group should be old enough to be pruned, wait until
+ // enough time for the group to be prunable has passed.
+ if (test_case.groups_old_enough_to_be_pruned ==
+ GroupsOldEnoughToBePruned::kFirstGroupOnly) {
+ FastForwardBy(base::TimeDelta::FromDays(
+ features::kExpectCTSafeFromPruneDays.Get() + 1));
+ }
+
+ // Always add entries unexpired.
+ base::Time second_group_expiry =
+ test_case.second_group_is_expired
+ ? base::Time::Now() + base::TimeDelta::FromMilliseconds(1)
+ : unexpired_expiry_time;
+
+ base::Time second_group_observation_time = base::Time::Now();
+ ASSERT_NE(first_group_observation_time, second_group_observation_time);
+ for (size_t i = 0; i < kGroupSize; ++i) {
+ state.AddExpectCT(CreateUniqueHostName(), second_group_expiry,
+ test_case.second_group_has_enforce, report_uri,
+ CreateUniqueNetworkIsolationKey(
+ test_case.second_group_has_transient_nik));
+ }
+
+ // Skip forward in time slightly, so the first group is always older than
+ // the first. This needs to be long enough so that if
+ // |second_group_is_expired| is true, the entry will expire.
+ FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+ // If both the first and second groups should be old enough to be pruned,
+ // wait until enough time has passed for both groups to prunable.
+ if (test_case.groups_old_enough_to_be_pruned ==
+ GroupsOldEnoughToBePruned::kFirstAndSecondGroups) {
+ FastForwardBy(base::TimeDelta::FromDays(
+ features::kExpectCTSafeFromPruneDays.Get() + 1));
+ }
+
+ for (size_t i = 0; i < kThirdGroupSize; ++i) {
+ state.AddExpectCT(
+ CreateUniqueHostName(),
+ base::Time::Now() + base::TimeDelta::FromSeconds(1),
+ true /* enforce */, report_uri,
+ CreateUniqueNetworkIsolationKey(false /* is_transient */));
+ }
+
+ size_t first_group_size = 0;
+ size_t second_group_size = 0;
+ size_t third_group_size = 0;
+ for (TransportSecurityState::ExpectCTStateIterator iterator(state);
+ iterator.HasNext(); iterator.Advance()) {
+ if (iterator.domain_state().last_observed ==
+ first_group_observation_time) {
+ ++first_group_size;
+ } else if (iterator.domain_state().last_observed ==
+ second_group_observation_time) {
+ ++second_group_size;
+ } else {
+ ++third_group_size;
+ }
+ }
+
+ EXPECT_EQ(test_case.expect_first_group_retained ? kGroupSize : 0,
+ first_group_size);
+ EXPECT_EQ(test_case.expect_second_group_retained ? kGroupSize : 0,
+ second_group_size);
+ EXPECT_EQ(kThirdGroupSize, third_group_size);
+
+ // Make sure that |unexpired_expiry_time| was set correctly - if this fails,
+ // it will need to be increased to avoid unexpected entry expirations.
+ ASSERT_LT(base::Time::Now(), unexpired_expiry_time);
+ }
+}
+
+// Test the delay between pruning Expect-CT entries.
+TEST_F(TransportSecurityStateTest, PruneExpectCTDelay) {
+ const GURL report_uri(kReportUri);
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ TransportSecurityState::kDynamicExpectCTFeature);
+
+ TransportSecurityState state;
+ base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(10);
+ // Add prunable entries until pruning is triggered.
+ for (int i = 0; i < features::kExpectCTPruneMax.Get(); ++i) {
+ state.AddExpectCT(CreateUniqueHostName(), expiry, false /* enforce */,
+ report_uri,
+ CreateUniqueNetworkIsolationKey(true /* is_transient */));
+ }
+ // Should have removed enough entries to get down to kExpectCTPruneMin
+ // entries.
+ EXPECT_EQ(features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // Add more prunable entries, but pruning should not be triggered, due to the
+ // delay between subsequent pruning tasks.
+ for (int i = 0; i < features::kExpectCTPruneMax.Get(); ++i) {
+ state.AddExpectCT(CreateUniqueHostName(), expiry, false /* enforce */,
+ report_uri,
+ CreateUniqueNetworkIsolationKey(true /* is_transient */));
+ }
+ EXPECT_EQ(
+ features::kExpectCTPruneMax.Get() + features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // Time passes, which does not trigger pruning.
+ FastForwardBy(
+ base::TimeDelta::FromSeconds(features::kExpectCTPruneDelaySecs.Get()));
+ EXPECT_EQ(
+ features::kExpectCTPruneMax.Get() + features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // Another entry is added, which triggers pruning, now that enough time has
+ // passed.
+ state.AddExpectCT(CreateUniqueHostName(), expiry, false /* enforce */,
+ report_uri,
+ CreateUniqueNetworkIsolationKey(true /* is_transient */));
+ EXPECT_EQ(features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // More time passes.
+ FastForwardBy(base::TimeDelta::FromSeconds(
+ 10 * features::kExpectCTPruneDelaySecs.Get()));
+ EXPECT_EQ(features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // When enough entries are added to trigger pruning, it runs immediately,
+ // since enough time has passed.
+ for (int i = 0; i < features::kExpectCTPruneMax.Get() -
+ features::kExpectCTPruneMin.Get();
+ ++i) {
+ state.AddExpectCT(CreateUniqueHostName(), expiry, false /* enforce */,
+ report_uri,
+ CreateUniqueNetworkIsolationKey(true /* is_transient */));
+ }
+ EXPECT_EQ(features::kExpectCTPruneMin.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+}
+
+// Test that Expect-CT pruning respects kExpectCTMaxEntriesPerNik, which is only
+// applied if there are more than kExpectCTPruneMin entries after global
+// pruning.
+TEST_F(TransportSecurityStateTest, PruneExpectCTNetworkIsolationKeyLimit) {
+ const GURL report_uri(kReportUri);
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ // enabled_features
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey},
+ // disabled_features
+ {});
+
+ TransportSecurityState state;
+
+ // Three different expiration times, which are used to distinguish entries
+ // added by each loop. No entries actually expire in this test.
+ base::Time expiry1 = base::Time::Now() + base::TimeDelta::FromDays(10);
+ base::Time expiry2 = expiry1 + base::TimeDelta::FromDays(10);
+ base::Time expiry3 = expiry2 + base::TimeDelta::FromDays(10);
+
+ // Add non-prunable entries using different non-transient NIKs. They should
+ // not be pruned because they are recently-observed enforce entries.
+ for (int i = 0; i < features::kExpectCTPruneMax.Get(); ++i) {
+ state.AddExpectCT(
+ CreateUniqueHostName(), expiry1, true /* enforce */, report_uri,
+ CreateUniqueNetworkIsolationKey(false /* is_transient */));
+ }
+ EXPECT_EQ(features::kExpectCTPruneMax.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // Add kExpectCTMaxEntriesPerNik non-prunable entries with a single NIK,
+ // allowing pruning to run each time. No entries should be deleted.
+ NetworkIsolationKey network_isolation_key =
+ CreateUniqueNetworkIsolationKey(false /* is_transient */);
+ for (int i = 0; i < features::kExpectCTMaxEntriesPerNik.Get(); ++i) {
+ FastForwardBy(
+ base::TimeDelta::FromSeconds(features::kExpectCTPruneDelaySecs.Get()));
+ state.AddExpectCT(CreateUniqueHostName(), expiry2, true /* enforce */,
+ report_uri, network_isolation_key);
+ EXPECT_EQ(features::kExpectCTPruneMax.Get() + i + 1,
+ static_cast<int>(state.num_expect_ct_entries()));
+ }
+
+ // Add kExpectCTMaxEntriesPerNik non-prunable entries with the same NIK as
+ // before, allowing pruning to run each time. Each time, a single entry should
+ // be removed, resulting in the same total number of entries as before.
+ for (int i = 0; i < features::kExpectCTMaxEntriesPerNik.Get(); ++i) {
+ FastForwardBy(
+ base::TimeDelta::FromSeconds(features::kExpectCTPruneDelaySecs.Get()));
+ state.AddExpectCT(CreateUniqueHostName(), expiry3, true /* enforce */,
+ report_uri, network_isolation_key);
+ EXPECT_EQ(features::kExpectCTPruneMax.Get() +
+ features::kExpectCTMaxEntriesPerNik.Get(),
+ static_cast<int>(state.num_expect_ct_entries()));
+
+ // Count entries with |expiry2| and |expiry3|. For each loop iteration, an
+ // entry with |expiry2| should be replaced by one with |expiry3|.
+ int num_expiry2_entries = 0;
+ int num_expiry3_entries = 0;
+ for (TransportSecurityState::ExpectCTStateIterator iterator(state);
+ iterator.HasNext(); iterator.Advance()) {
+ if (iterator.domain_state().expiry == expiry2) {
+ EXPECT_EQ(network_isolation_key, iterator.network_isolation_key());
+ ++num_expiry2_entries;
+ } else if (iterator.domain_state().expiry == expiry3) {
+ EXPECT_EQ(network_isolation_key, iterator.network_isolation_key());
+ ++num_expiry3_entries;
+ }
+ }
+ EXPECT_EQ(features::kExpectCTMaxEntriesPerNik.Get() - i - 1,
+ num_expiry2_entries);
+ EXPECT_EQ(i + 1, num_expiry3_entries);
+ }
+}
+
} // namespace net
diff --git a/chromium/net/http/url_security_manager_win.cc b/chromium/net/http/url_security_manager_win.cc
index 33ab56efe09..4286ba72840 100644
--- a/chromium/net/http/url_security_manager_win.cc
+++ b/chromium/net/http/url_security_manager_win.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/http/http_auth_filter.h"
diff --git a/chromium/net/http2/platform/impl/http2_logging_impl.h b/chromium/net/http2/platform/impl/http2_logging_impl.h
index 92f1a33b7df..804d6a7b3ca 100644
--- a/chromium/net/http2/platform/impl/http2_logging_impl.h
+++ b/chromium/net/http2/platform/impl/http2_logging_impl.h
@@ -5,7 +5,9 @@
#ifndef NET_HTTP2_PLATFORM_IMPL_HTTP2_LOGGING_IMPL_H_
#define NET_HTTP2_PLATFORM_IMPL_HTTP2_LOGGING_IMPL_H_
+#include "base/check_op.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/http2/platform/impl/http2_macros_impl.h b/chromium/net/http2/platform/impl/http2_macros_impl.h
index 17628d338f3..c1029a26020 100644
--- a/chromium/net/http2/platform/impl/http2_macros_impl.h
+++ b/chromium/net/http2/platform/impl/http2_macros_impl.h
@@ -5,8 +5,8 @@
#ifndef NET_HTTP2_PLATFORM_IMPL_HTTP2_MACROS_IMPL_H_
#define NET_HTTP2_PLATFORM_IMPL_HTTP2_MACROS_IMPL_H_
+#include "base/check.h"
#include "base/compiler_specific.h"
-#include "base/logging.h"
#define HTTP2_FALLTHROUGH_IMPL FALLTHROUGH
#define HTTP2_UNREACHABLE_IMPL() DCHECK(false)
diff --git a/chromium/net/log/file_net_log_observer.cc b/chromium/net/log/file_net_log_observer.cc
index 722f95afaa2..1374fecc44c 100644
--- a/chromium/net/log/file_net_log_observer.cc
+++ b/chromium/net/log/file_net_log_observer.cc
@@ -481,7 +481,8 @@ FileNetLogObserver::FileNetLogObserver(
write_queue_(std::move(write_queue)),
file_writer_(std::move(file_writer)) {
if (!constants)
- constants = GetNetConstants();
+ constants = base::DictionaryValue::From(
+ base::Value::ToUniquePtrValue(GetNetConstants()));
file_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&FileNetLogObserver::FileWriter::Initialize,
base::Unretained(file_writer_.get()),
diff --git a/chromium/net/log/file_net_log_observer_unittest.cc b/chromium/net/log/file_net_log_observer_unittest.cc
index 860a98defe9..7de5d885a55 100644
--- a/chromium/net/log/file_net_log_observer_unittest.cc
+++ b/chromium/net/log/file_net_log_observer_unittest.cc
@@ -123,12 +123,12 @@ struct ParsedNetLog {
return ::testing::AssertionFailure() << "input is empty";
}
- base::JSONReader reader;
- base::Optional<base::Value> container_optional = reader.Read(input);
- if (!container_optional) {
- return ::testing::AssertionFailure() << reader.GetErrorMessage();
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(input);
+ if (!parsed_json.value) {
+ return ::testing::AssertionFailure() << parsed_json.error_message;
}
- container = std::move(*container_optional);
+ container = std::move(*parsed_json.value);
if (!container.GetAsDictionary(&root)) {
return ::testing::AssertionFailure() << "Not a dictionary";
diff --git a/chromium/net/log/net_log.cc b/chromium/net/log/net_log.cc
index 6d10b0791c8..c648e76c2e5 100644
--- a/chromium/net/log/net_log.cc
+++ b/chromium/net/log/net_log.cc
@@ -198,11 +198,11 @@ const char* NetLog::EventTypeToString(NetLogEventType event) {
// static
base::Value NetLog::GetEventTypesAsValue() {
- base::DictionaryValue dict;
+ base::Value dict(base::Value::Type::DICTIONARY);
for (int i = 0; i < static_cast<int>(NetLogEventType::COUNT); ++i) {
- dict.SetInteger(EventTypeToString(static_cast<NetLogEventType>(i)), i);
+ dict.SetIntKey(EventTypeToString(static_cast<NetLogEventType>(i)), i);
}
- return std::move(dict);
+ return dict;
}
// static
@@ -221,11 +221,11 @@ const char* NetLog::SourceTypeToString(NetLogSourceType source) {
// static
base::Value NetLog::GetSourceTypesAsValue() {
- base::DictionaryValue dict;
+ base::Value dict(base::Value::Type::DICTIONARY);
for (int i = 0; i < static_cast<int>(NetLogSourceType::COUNT); ++i) {
- dict.SetInteger(SourceTypeToString(static_cast<NetLogSourceType>(i)), i);
+ dict.SetIntKey(SourceTypeToString(static_cast<NetLogSourceType>(i)), i);
}
- return std::move(dict);
+ return dict;
}
// static
diff --git a/chromium/net/log/net_log_entry.cc b/chromium/net/log/net_log_entry.cc
index d889aed4140..40fe04da449 100644
--- a/chromium/net/log/net_log_entry.cc
+++ b/chromium/net/log/net_log_entry.cc
@@ -25,27 +25,27 @@ NetLogEntry::NetLogEntry(NetLogEntry&& entry) = default;
NetLogEntry& NetLogEntry::operator=(NetLogEntry&& entry) = default;
base::Value NetLogEntry::ToValue() const {
- base::DictionaryValue entry_dict;
+ base::Value entry_dict(base::Value::Type::DICTIONARY);
- entry_dict.SetString("time", NetLog::TickCountToString(time));
+ entry_dict.SetStringKey("time", NetLog::TickCountToString(time));
// Set the entry source.
- base::DictionaryValue source_dict;
- source_dict.SetInteger("id", source.id);
- source_dict.SetInteger("type", static_cast<int>(source.type));
- source_dict.SetString("start_time",
- NetLog::TickCountToString(source.start_time));
+ base::Value source_dict(base::Value::Type::DICTIONARY);
+ source_dict.SetIntKey("id", source.id);
+ source_dict.SetIntKey("type", static_cast<int>(source.type));
+ source_dict.SetStringKey("start_time",
+ NetLog::TickCountToString(source.start_time));
entry_dict.SetKey("source", std::move(source_dict));
// Set the event info.
- entry_dict.SetInteger("type", static_cast<int>(type));
- entry_dict.SetInteger("phase", static_cast<int>(phase));
+ entry_dict.SetIntKey("type", static_cast<int>(type));
+ entry_dict.SetIntKey("phase", static_cast<int>(phase));
// Set the event-specific parameters.
if (!params.is_none())
entry_dict.SetKey("params", params.Clone());
- return std::move(entry_dict);
+ return entry_dict;
}
NetLogEntry NetLogEntry::Clone() const {
diff --git a/chromium/net/log/net_log_event_type_list.h b/chromium/net/log/net_log_event_type_list.h
index 12553338d45..36b24fb87a1 100644
--- a/chromium/net/log/net_log_event_type_list.h
+++ b/chromium/net/log/net_log_event_type_list.h
@@ -831,7 +831,7 @@ EVENT_TYPE(SOCKET_POOL_CLOSING_SOCKET)
// "initiator": <Initiator origin of the request, if any, or else "not an
// origin">,
// "load_flags": <Numeric value of the combined load flags>,
-// "privacy_mode": <True if privacy mode is enabled for the request>,
+// "privacy_mode": <Privacy mode associated with the request>,
// "network_isolation_key": <NIK associated with the request>,
// "priority": <Numeric priority of the request>,
// "site_for_cookies": <SiteForCookies associated with the request>,
@@ -2004,6 +2004,20 @@ EVENT_TYPE(QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_RECEIVED)
// }
EVENT_TYPE(QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT)
+// A QUIC connection received transport parameters.
+// {
+// "quic_transport_parameters": <Human readable view of the transport
+// parameters>
+// }
+EVENT_TYPE(QUIC_SESSION_TRANSPORT_PARAMETERS_RECEIVED)
+
+// A QUIC connection sent transport parameters.
+// {
+// "quic_transport_parameters": <Human readable view of the transport
+// parameters>
+// }
+EVENT_TYPE(QUIC_SESSION_TRANSPORT_PARAMETERS_SENT)
+
// A QUIC connection received a PUSH_PROMISE frame. The following
// parameters are attached:
// {
@@ -2284,6 +2298,13 @@ EVENT_TYPE(QUIC_CONNECTION_MIGRATION_TRIGGERED)
// }
EVENT_TYPE(QUIC_CONNECTION_MIGRATION_FAILURE)
+// This event is emitted whenenver a platform notification is received that
+// could possibly trigger connection migration.
+// {
+// "signal": <Type of the platform notification>
+// }
+EVENT_TYPE(QUIC_CONNECTION_MIGRATION_PLATFORM_NOTIFICATION)
+
// Records a successful QUIC connection migration attempt of the session
// identified by connection_id.
// {
@@ -2357,6 +2378,15 @@ EVENT_TYPE(QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_SENT)
// }
EVENT_TYPE(QUIC_CONNECTIVITY_PROBING_MANAGER_PROBE_RECEIVED)
+// Records that QUIC connectivity probing manager receives STATLESS_RESET on the
+// following path:
+// {
+// "network": <ID of the network being probed>
+// "self_address": <Self address on the probed path>
+// "peer_address": <Peer address on the probed path>
+// }
+EVENT_TYPE(QUIC_CONNECTIVITY_PROBING_MANAGER_STATELESS_RESET_RECEIVED)
+
// ------------------------------------------------------------------------
// QuicPortMigration
// ------------------------------------------------------------------------
@@ -2628,13 +2658,21 @@ EVENT_TYPE(AUTH_LIBRARY_ACQUIRE_CREDS)
// This operation involves invoking an external library which may perform disk,
// IPC, and network IO as a part of its work.
//
-// On Posix platforms, the END phase has the following parameters.
+// On Windows, the BEGIN phase has the following parameters:
+// {
+// "spn": <Service Principle Name>,
+// "context_flags": <Integer with bitfield value>
+// }
+//
+// The END phase has the following parameters.
+//
+// On Posix platforms:
// {
// "context": <GSSAPI Context Description>,
// "status" : <GSSAPI Status if the operation failed>
// }
//
-// On Windows, the END phase has the following parameters.
+// On Windows:
// {
// "context": <SSPI Context Description>
// "status" : <SSPI SECURITY_STATUS>
diff --git a/chromium/net/log/net_log_source.cc b/chromium/net/log/net_log_source.cc
index 8386d63f338..a6c3eefdf0e 100644
--- a/chromium/net/log/net_log_source.cc
+++ b/chromium/net/log/net_log_source.cc
@@ -20,9 +20,9 @@ namespace {
base::Value SourceEventParametersCallback(const NetLogSource source) {
if (!source.IsValid())
return base::Value();
- base::DictionaryValue event_params;
+ base::Value event_params(base::Value::Type::DICTIONARY);
source.AddToEventParameters(&event_params);
- return std::move(event_params);
+ return event_params;
}
} // namespace
diff --git a/chromium/net/log/net_log_source.h b/chromium/net/log/net_log_source.h
index 01b091bd4b9..046f371c9f1 100644
--- a/chromium/net/log/net_log_source.h
+++ b/chromium/net/log/net_log_source.h
@@ -12,7 +12,6 @@
#include "net/log/net_log_source_type.h"
namespace base {
-class DictionaryValue;
class Value;
}
@@ -29,7 +28,7 @@ struct NET_EXPORT NetLogSource {
NetLogSource(NetLogSourceType type, uint32_t id, base::TimeTicks start_time);
bool IsValid() const;
- // Adds the source to a DictionaryValue containing event parameters,
+ // Adds the source to a dictionary containing event parameters,
// using the name "source_dependency".
void AddToEventParameters(base::Value* event_params) const;
diff --git a/chromium/net/log/net_log_source_type_list.h b/chromium/net/log/net_log_source_type_list.h
index ccde5695c03..15f1cdd6eb4 100644
--- a/chromium/net/log/net_log_source_type_list.h
+++ b/chromium/net/log/net_log_source_type_list.h
@@ -21,9 +21,8 @@ SOURCE_TYPE(TRANSPORT_CONNECT_JOB)
SOURCE_TYPE(WEB_SOCKET_TRANSPORT_CONNECT_JOB)
SOURCE_TYPE(SOCKET)
SOURCE_TYPE(HTTP2_SESSION)
-SOURCE_TYPE(QUIC_SESSION)
SOURCE_TYPE(QUIC_CONNECTION_MIGRATION)
-SOURCE_TYPE(QUIC_PORT_MIGRATION)
+SOURCE_TYPE(QUIC_SESSION)
SOURCE_TYPE(HOST_RESOLVER_IMPL_JOB)
SOURCE_TYPE(DISK_CACHE_ENTRY)
SOURCE_TYPE(MEMORY_CACHE_ENTRY)
diff --git a/chromium/net/log/net_log_util.cc b/chromium/net/log/net_log_util.cc
index b00221ea87d..91c57cc7da5 100644
--- a/chromium/net/log/net_log_util.cc
+++ b/chromium/net/log/net_log_util.cc
@@ -136,49 +136,48 @@ const char* NetInfoSourceToString(NetInfoSource source) {
return "?";
}
-std::unique_ptr<base::DictionaryValue> GetNetConstants() {
- std::unique_ptr<base::DictionaryValue> constants_dict(
- new base::DictionaryValue());
+base::Value GetNetConstants() {
+ base::Value constants_dict(base::Value::Type::DICTIONARY);
// Version of the file format.
- constants_dict->SetInteger("logFormatVersion", kLogFormatVersion);
+ constants_dict.SetIntKey("logFormatVersion", kLogFormatVersion);
// Add a dictionary with information on the relationship between event type
// enums and their symbolic names.
- constants_dict->SetKey("logEventTypes", NetLog::GetEventTypesAsValue());
+ constants_dict.SetKey("logEventTypes", NetLog::GetEventTypesAsValue());
// Add a dictionary with information about the relationship between CertStatus
// flags and their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (const auto& flag : kCertStatusFlags)
- dict->SetInteger(flag.name, flag.constant);
+ dict.SetIntKey(flag.name, flag.constant);
- constants_dict->Set("certStatusFlag", std::move(dict));
+ constants_dict.SetKey("certStatusFlag", std::move(dict));
}
// Add a dictionary with information about the relationship between
// CertVerifier::VerifyFlags and their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
- dict->SetInteger("VERIFY_DISABLE_NETWORK_FETCHES",
- CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES);
+ dict.SetIntKey("VERIFY_DISABLE_NETWORK_FETCHES",
+ CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES);
static_assert(CertVerifier::VERIFY_FLAGS_LAST == (1 << 0),
"Update with new flags");
- constants_dict->Set("certVerifierFlags", std::move(dict));
+ constants_dict.SetKey("certVerifierFlags", std::move(dict));
}
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
- dict->SetInteger(
+ dict.SetIntKey(
"kStrong",
static_cast<int>(SimplePathBuilderDelegate::DigestPolicy::kStrong));
- dict->SetInteger(
+ dict.SetIntKey(
"kWeakAllowSha1",
static_cast<int>(
SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1));
@@ -187,127 +186,126 @@ std::unique_ptr<base::DictionaryValue> GetNetConstants() {
SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1,
"Update with new flags");
- constants_dict->Set("certPathBuilderDigestPolicy", std::move(dict));
+ constants_dict.SetKey("certPathBuilderDigestPolicy", std::move(dict));
}
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-
- dict->SetInteger("DISTRUSTED",
- static_cast<int>(CertificateTrustType::DISTRUSTED));
- dict->SetInteger("UNSPECIFIED",
- static_cast<int>(CertificateTrustType::UNSPECIFIED));
- dict->SetInteger("TRUSTED_ANCHOR",
- static_cast<int>(CertificateTrustType::TRUSTED_ANCHOR));
- dict->SetInteger(
- "TRUSTED_ANCHOR_WITH_CONSTRAINTS",
- static_cast<int>(
- CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS));
+ base::Value dict(base::Value::Type::DICTIONARY);
+
+ dict.SetIntKey("DISTRUSTED",
+ static_cast<int>(CertificateTrustType::DISTRUSTED));
+ dict.SetIntKey("UNSPECIFIED",
+ static_cast<int>(CertificateTrustType::UNSPECIFIED));
+ dict.SetIntKey("TRUSTED_ANCHOR",
+ static_cast<int>(CertificateTrustType::TRUSTED_ANCHOR));
+ dict.SetIntKey("TRUSTED_ANCHOR_WITH_CONSTRAINTS",
+ static_cast<int>(
+ CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS));
static_assert(CertificateTrustType::LAST ==
CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS,
"Update with new flags");
- constants_dict->Set("certificateTrustType", std::move(dict));
+ constants_dict.SetKey("certificateTrustType", std::move(dict));
}
// Add a dictionary with information about the relationship between load flag
// enums and their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (const auto& flag : kLoadFlags)
- dict->SetInteger(flag.name, flag.constant);
+ dict.SetIntKey(flag.name, flag.constant);
- constants_dict->Set("loadFlag", std::move(dict));
+ constants_dict.SetKey("loadFlag", std::move(dict));
}
// Add a dictionary with information about the relationship between load state
// enums and their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (const auto& state : kLoadStateTable)
- dict->SetInteger(state.name, state.constant);
+ dict.SetIntKey(state.name, state.constant);
- constants_dict->Set("loadState", std::move(dict));
+ constants_dict.SetKey("loadState", std::move(dict));
}
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
#define NET_INFO_SOURCE(label, string, value) \
- dict->SetInteger(string, NET_INFO_##label);
+ dict.SetIntKey(string, NET_INFO_##label);
#include "net/base/net_info_source_list.h"
#undef NET_INFO_SOURCE
- constants_dict->Set("netInfoSources", std::move(dict));
+ constants_dict.SetKey("netInfoSources", std::move(dict));
}
// Add information on the relationship between net error codes and their
// symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (const auto& error : kNetErrors)
- dict->SetInteger(ErrorToShortString(error), error);
+ dict.SetIntKey(ErrorToShortString(error), error);
- constants_dict->Set("netError", std::move(dict));
+ constants_dict.SetKey("netError", std::move(dict));
}
// Add information on the relationship between QUIC error codes and their
// symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (quic::QuicErrorCode error = quic::QUIC_NO_ERROR;
error < quic::QUIC_LAST_ERROR;
error = static_cast<quic::QuicErrorCode>(error + 1)) {
- dict->SetInteger(QuicErrorCodeToString(error), static_cast<int>(error));
+ dict.SetIntKey(QuicErrorCodeToString(error), static_cast<int>(error));
}
- constants_dict->Set("quicError", std::move(dict));
+ constants_dict.SetKey("quicError", std::move(dict));
}
// Add information on the relationship between QUIC RST_STREAM error codes
// and their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
for (quic::QuicRstStreamErrorCode error = quic::QUIC_STREAM_NO_ERROR;
error < quic::QUIC_STREAM_LAST_ERROR;
error = static_cast<quic::QuicRstStreamErrorCode>(error + 1)) {
- dict->SetInteger(QuicRstStreamErrorCodeToString(error),
- static_cast<int>(error));
+ dict.SetIntKey(QuicRstStreamErrorCodeToString(error),
+ static_cast<int>(error));
}
- constants_dict->Set("quicRstStreamError", std::move(dict));
+ constants_dict.SetKey("quicRstStreamError", std::move(dict));
}
// Information about the relationship between event phase enums and their
// symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
- dict->SetInteger("PHASE_BEGIN", static_cast<int>(NetLogEventPhase::BEGIN));
- dict->SetInteger("PHASE_END", static_cast<int>(NetLogEventPhase::END));
- dict->SetInteger("PHASE_NONE", static_cast<int>(NetLogEventPhase::NONE));
+ dict.SetIntKey("PHASE_BEGIN", static_cast<int>(NetLogEventPhase::BEGIN));
+ dict.SetIntKey("PHASE_END", static_cast<int>(NetLogEventPhase::END));
+ dict.SetIntKey("PHASE_NONE", static_cast<int>(NetLogEventPhase::NONE));
- constants_dict->Set("logEventPhase", std::move(dict));
+ constants_dict.SetKey("logEventPhase", std::move(dict));
}
// Information about the relationship between source type enums and
// their symbolic names.
- constants_dict->SetKey("logSourceType", NetLog::GetSourceTypesAsValue());
+ constants_dict.SetKey("logSourceType", NetLog::GetSourceTypesAsValue());
// Information about the relationship between address family enums and
// their symbolic names.
{
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ base::Value dict(base::Value::Type::DICTIONARY);
- dict->SetInteger("ADDRESS_FAMILY_UNSPECIFIED", ADDRESS_FAMILY_UNSPECIFIED);
- dict->SetInteger("ADDRESS_FAMILY_IPV4", ADDRESS_FAMILY_IPV4);
- dict->SetInteger("ADDRESS_FAMILY_IPV6", ADDRESS_FAMILY_IPV6);
+ dict.SetIntKey("ADDRESS_FAMILY_UNSPECIFIED", ADDRESS_FAMILY_UNSPECIFIED);
+ dict.SetIntKey("ADDRESS_FAMILY_IPV4", ADDRESS_FAMILY_IPV4);
+ dict.SetIntKey("ADDRESS_FAMILY_IPV6", ADDRESS_FAMILY_IPV6);
- constants_dict->Set("addressFamily", std::move(dict));
+ constants_dict.SetKey("addressFamily", std::move(dict));
}
// Information about how the "time ticks" values we have given it relate to
@@ -327,14 +325,15 @@ std::unique_ptr<base::DictionaryValue> GetNetConstants() {
base::TimeTicks::Now() - base::TimeTicks();
int64_t tick_to_unix_time_ms =
(time_since_epoch - reference_time_ticks).InMilliseconds();
- constants_dict->SetKey("timeTickOffset",
- NetLogNumberValue(tick_to_unix_time_ms));
+ constants_dict.SetKey("timeTickOffset",
+ NetLogNumberValue(tick_to_unix_time_ms));
}
// TODO(eroman): Is this needed?
// "clientInfo" key is required for some log readers. Provide a default empty
// value for compatibility.
- constants_dict->Set("clientInfo", std::make_unique<base::DictionaryValue>());
+ constants_dict.SetKey("clientInfo",
+ base::Value(base::Value::Type::DICTIONARY));
// Add a list of active field experiments.
{
@@ -346,8 +345,9 @@ std::unique_ptr<base::DictionaryValue> GetNetConstants() {
it != active_groups.end(); ++it) {
field_trial_groups->AppendString(it->trial_name + ":" + it->group_name);
}
- constants_dict->Set("activeFieldTrialGroups",
- std::move(field_trial_groups));
+ constants_dict.SetKey(
+ "activeFieldTrialGroups",
+ base::Value::FromUniquePtrValue(std::move(field_trial_groups)));
}
return constants_dict;
diff --git a/chromium/net/log/net_log_util.h b/chromium/net/log/net_log_util.h
index 62c3dd06b6d..b6391aae8fe 100644
--- a/chromium/net/log/net_log_util.h
+++ b/chromium/net/log/net_log_util.h
@@ -33,8 +33,8 @@ enum NetInfoSource {
// Returns a friendly string to use for a given NetInfoSource in the net log.
NET_EXPORT const char* NetInfoSourceToString(NetInfoSource source);
-// Create a dictionary containing a legend for net/ constants.
-NET_EXPORT std::unique_ptr<base::DictionaryValue> GetNetConstants();
+// Creates a dictionary containing a legend for net/ constants.
+NET_EXPORT base::Value GetNetConstants();
// Retrieves a dictionary containing information about the current state of
// |context|. |info_sources| is a set of NetInfoSources OR'd together,
diff --git a/chromium/net/log/net_log_util_unittest.cc b/chromium/net/log/net_log_util_unittest.cc
index 73ba2670b94..7da26248f9b 100644
--- a/chromium/net/log/net_log_util_unittest.cc
+++ b/chromium/net/log/net_log_util_unittest.cc
@@ -27,7 +27,7 @@ namespace {
// Make sure GetNetConstants doesn't crash.
TEST(NetLogUtil, GetNetConstants) {
- std::unique_ptr<base::Value> constants(GetNetConstants());
+ base::Value constants(GetNetConstants());
}
// Make sure GetNetInfo doesn't crash when called on contexts with and without
diff --git a/chromium/net/log/net_log_values.cc b/chromium/net/log/net_log_values.cc
index d92d3fa2352..cc8bb8cdaa8 100644
--- a/chromium/net/log/net_log_values.cc
+++ b/chromium/net/log/net_log_values.cc
@@ -82,9 +82,9 @@ base::Value NetLogParamsWithInt(base::StringPiece name, int value) {
}
base::Value NetLogParamsWithInt64(base::StringPiece name, int64_t value) {
- base::DictionaryValue event_params;
- event_params.SetKey(name, NetLogNumberValue(value));
- return std::move(event_params);
+ base::Value params(base::Value::Type::DICTIONARY);
+ params.SetKey(name, NetLogNumberValue(value));
+ return params;
}
base::Value NetLogParamsWithBool(base::StringPiece name, bool value) {
diff --git a/chromium/net/log/net_log_with_source.cc b/chromium/net/log/net_log_with_source.cc
index 5a6cbe10ea1..e1a44ff8b79 100644
--- a/chromium/net/log/net_log_with_source.cc
+++ b/chromium/net/log/net_log_with_source.cc
@@ -25,11 +25,11 @@ namespace {
base::Value BytesTransferredParams(int byte_count,
const char* bytes,
NetLogCaptureMode capture_mode) {
- base::DictionaryValue dict;
- dict.SetInteger("byte_count", byte_count);
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetIntKey("byte_count", byte_count);
if (NetLogCaptureIncludesSocketBytes(capture_mode) && byte_count > 0)
dict.SetKey("bytes", NetLogBinaryValue(bytes, byte_count));
- return std::move(dict);
+ return dict;
}
} // namespace
diff --git a/chromium/net/network_error_logging/network_error_logging_service.cc b/chromium/net/network_error_logging/network_error_logging_service.cc
index f8b47e3d030..c63d8e9a09c 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service.cc
@@ -143,12 +143,6 @@ bool IsHttpError(const NetworkErrorLoggingService::RequestDetails& request) {
return request.status_code >= 400 && request.status_code < 600;
}
-void RecordHeaderOutcome(NetworkErrorLoggingService::HeaderOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION(NetworkErrorLoggingService::kHeaderOutcomeHistogram,
- outcome,
- NetworkErrorLoggingService::HeaderOutcome::MAX);
-}
-
void RecordSignedExchangeRequestOutcome(
NetworkErrorLoggingService::RequestOutcome outcome) {
UMA_HISTOGRAM_ENUMERATION(
@@ -176,10 +170,8 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
const std::string& value) override {
// NEL is only available to secure origins, so don't permit insecure origins
// to set policies.
- if (!origin.GetURL().SchemeIsCryptographic()) {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_INSECURE_ORIGIN);
+ if (!origin.GetURL().SchemeIsCryptographic())
return;
- }
base::Time header_received_time = clock_->Now();
// base::Unretained is safe because the callback gets stored in
@@ -366,19 +358,18 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
policy.origin = origin;
policy.received_ip_address = received_ip_address;
policy.last_used = header_received_time;
- HeaderOutcome outcome = ParseHeader(value, clock_->Now(), &policy);
+
+ if (!ParseHeader(value, clock_->Now(), &policy))
+ return;
+
// Disallow eTLDs from setting include_subdomains policies.
- if ((outcome == HeaderOutcome::SET || outcome == HeaderOutcome::REMOVED) &&
- policy.include_subdomains &&
+ if (policy.include_subdomains &&
registry_controlled_domains::GetRegistryLength(
policy.origin.GetURL(),
registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES) == 0) {
- outcome = HeaderOutcome::DISCARDED_INCLUDE_SUBDOMAINS_NOT_ALLOWED;
- }
- RecordHeaderOutcome(outcome);
- if (outcome != HeaderOutcome::SET && outcome != HeaderOutcome::REMOVED)
return;
+ }
// If a policy for |origin| already existed, remove the old policy.
auto it = policies_.find(origin);
@@ -551,37 +542,42 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
policies_.clear();
}
- HeaderOutcome ParseHeader(const std::string& json_value,
- base::Time now,
- NelPolicy* policy_out) const {
+ // Returns whether the |json_value| was parsed as a valid header that either
+ // sets a NEL policy (max age > 0) or removes an existing one (max age == 0).
+ bool ParseHeader(const std::string& json_value,
+ base::Time now,
+ NelPolicy* policy_out) const {
DCHECK(policy_out);
+ // JSON is malformed (too large, syntax error, not a dictionary).
if (json_value.size() > kMaxJsonSize)
- return HeaderOutcome::DISCARDED_JSON_TOO_BIG;
+ return false;
std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(
json_value, base::JSON_PARSE_RFC, kMaxJsonDepth);
if (!value)
- return HeaderOutcome::DISCARDED_JSON_INVALID;
+ return false;
const base::DictionaryValue* dict = nullptr;
if (!value->GetAsDictionary(&dict))
- return HeaderOutcome::DISCARDED_NOT_DICTIONARY;
+ return false;
+ // Max-Age property is missing or malformed.
if (!dict->HasKey(kMaxAgeKey))
- return HeaderOutcome::DISCARDED_TTL_MISSING;
+ return false;
int max_age_sec;
if (!dict->GetInteger(kMaxAgeKey, &max_age_sec))
- return HeaderOutcome::DISCARDED_TTL_NOT_INTEGER;
+ return false;
if (max_age_sec < 0)
- return HeaderOutcome::DISCARDED_TTL_NEGATIVE;
+ return false;
+ // Report-To property is missing or malformed.
std::string report_to;
if (max_age_sec > 0) {
if (!dict->HasKey(kReportToKey))
- return HeaderOutcome::DISCARDED_REPORT_TO_MISSING;
+ return false;
if (!dict->GetString(kReportToKey, &report_to))
- return HeaderOutcome::DISCARDED_REPORT_TO_NOT_STRING;
+ return false;
}
bool include_subdomains = false;
@@ -605,13 +601,10 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
policy_out->include_subdomains = include_subdomains;
policy_out->success_fraction = success_fraction;
policy_out->failure_fraction = failure_fraction;
- if (max_age_sec > 0) {
- policy_out->expires = now + base::TimeDelta::FromSeconds(max_age_sec);
- return HeaderOutcome::SET;
- } else {
- policy_out->expires = base::Time();
- return HeaderOutcome::REMOVED;
- }
+ policy_out->expires = max_age_sec > 0
+ ? now + base::TimeDelta::FromSeconds(max_age_sec)
+ : base::Time();
+ return true;
}
const NelPolicy* FindPolicyForOrigin(const url::Origin& origin) const {
@@ -885,9 +878,6 @@ const char NetworkErrorLoggingService::kHeaderName[] = "NEL";
const char NetworkErrorLoggingService::kReportType[] = "network-error";
-const char NetworkErrorLoggingService::kHeaderOutcomeHistogram[] =
- "Net.NetworkErrorLogging.HeaderOutcome";
-
const char
NetworkErrorLoggingService::kSignedExchangeRequestOutcomeHistogram[] =
"Net.NetworkErrorLogging.SignedExchangeRequestOutcome";
@@ -921,29 +911,6 @@ const char NetworkErrorLoggingService::kCertUrlKey[] = "cert_url";
const size_t NetworkErrorLoggingService::kMaxPolicies = 1000u;
// static
-void NetworkErrorLoggingService::
- RecordHeaderDiscardedForNoNetworkErrorLoggingService() {
- RecordHeaderOutcome(
- HeaderOutcome::DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE);
-}
-
-// static
-void NetworkErrorLoggingService::RecordHeaderDiscardedForInvalidSSLInfo() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_INVALID_SSL_INFO);
-}
-
-// static
-void NetworkErrorLoggingService::RecordHeaderDiscardedForCertStatusError() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_CERT_STATUS_ERROR);
-}
-
-// static
-void NetworkErrorLoggingService::
- RecordHeaderDiscardedForMissingRemoteEndpoint() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_MISSING_REMOTE_ENDPOINT);
-}
-
-// static
std::unique_ptr<NetworkErrorLoggingService> NetworkErrorLoggingService::Create(
PersistentNelStore* store) {
return std::make_unique<NetworkErrorLoggingServiceImpl>(store);
diff --git a/chromium/net/network_error_logging/network_error_logging_service.h b/chromium/net/network_error_logging/network_error_logging_service.h
index 8f233bbe55a..514d61c5a64 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.h
+++ b/chromium/net/network_error_logging/network_error_logging_service.h
@@ -142,37 +142,8 @@ class NET_EXPORT NetworkErrorLoggingService {
// Maximum number of NEL policies to store before evicting.
static const size_t kMaxPolicies;
- // Histograms. These are mainly used in test cases to verify that interesting
- // events occurred.
-
- static const char kHeaderOutcomeHistogram[];
static const char kSignedExchangeRequestOutcomeHistogram[];
- enum class HeaderOutcome {
- DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE = 0,
- DISCARDED_INVALID_SSL_INFO = 1,
- DISCARDED_CERT_STATUS_ERROR = 2,
-
- DISCARDED_INSECURE_ORIGIN = 3,
-
- DISCARDED_JSON_TOO_BIG = 4,
- DISCARDED_JSON_INVALID = 5,
- DISCARDED_NOT_DICTIONARY = 6,
- DISCARDED_TTL_MISSING = 7,
- DISCARDED_TTL_NOT_INTEGER = 8,
- DISCARDED_TTL_NEGATIVE = 9,
- DISCARDED_REPORT_TO_MISSING = 10,
- DISCARDED_REPORT_TO_NOT_STRING = 11,
-
- REMOVED = 12,
- SET = 13,
-
- DISCARDED_MISSING_REMOTE_ENDPOINT = 14,
- DISCARDED_INCLUDE_SUBDOMAINS_NOT_ALLOWED = 15,
-
- MAX
- };
-
// Used for histogramming Signed Exchange request outcomes only. Previously,
// the outcome of all requests would be histogrammed, but this was removed in
// crbug.com/1007122 because the histogram was very large and not very useful.
@@ -193,11 +164,6 @@ class NET_EXPORT NetworkErrorLoggingService {
kMaxValue = kDiscardedIPAddressMismatch
};
- static void RecordHeaderDiscardedForNoNetworkErrorLoggingService();
- static void RecordHeaderDiscardedForInvalidSSLInfo();
- static void RecordHeaderDiscardedForCertStatusError();
- static void RecordHeaderDiscardedForMissingRemoteEndpoint();
-
// NEL policies are persisted to disk if |store| is not null.
// The store, if given, should outlive |*this|.
static std::unique_ptr<NetworkErrorLoggingService> Create(
diff --git a/chromium/net/proxy_resolution/configured_proxy_resolution_service.cc b/chromium/net/proxy_resolution/configured_proxy_resolution_service.cc
index c699df2bb33..68fc89b5455 100644
--- a/chromium/net/proxy_resolution/configured_proxy_resolution_service.cc
+++ b/chromium/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -391,34 +391,6 @@ GURL SanitizeUrl(const GURL& url) {
return url.ReplaceComponents(replacements);
}
-// Do not change the enumerated value as it is relied on by histograms.
-enum class PacUrlSchemeForHistogram {
- kOther = 0,
-
- kHttp = 1,
- kHttps = 2,
- kFtp = 3,
- kFile = 4,
- kData = 5,
-
- kMaxValue = kData,
-};
-
-PacUrlSchemeForHistogram GetPacUrlScheme(const GURL& pac_url) {
- if (pac_url.SchemeIs("http"))
- return PacUrlSchemeForHistogram::kHttp;
- if (pac_url.SchemeIs("https"))
- return PacUrlSchemeForHistogram::kHttps;
- if (pac_url.SchemeIs("data"))
- return PacUrlSchemeForHistogram::kData;
- if (pac_url.SchemeIs("ftp"))
- return PacUrlSchemeForHistogram::kFtp;
- if (pac_url.SchemeIs("file"))
- return PacUrlSchemeForHistogram::kFile;
-
- return PacUrlSchemeForHistogram::kOther;
-}
-
} // namespace
// ConfiguredProxyResolutionService::InitProxyResolver
@@ -1511,11 +1483,6 @@ void ConfiguredProxyResolutionService::OnProxyConfigChanged(
});
}
- if (config.value().has_pac_url()) {
- UMA_HISTOGRAM_ENUMERATION("Net.ProxyResolutionService.PacUrlScheme",
- GetPacUrlScheme(config.value().pac_url()));
- }
-
// Set the new configuration as the most recently fetched one.
fetched_config_ = effective_config;
diff --git a/chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc b/chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
index 9b129ee2e81..c9a5fb01269 100644
--- a/chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
+++ b/chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
@@ -346,42 +346,6 @@ JobMap GetCancelledJobsForURLs(const MockAsyncProxyResolver& resolver,
return GetJobsForURLs(map, urls);
}
-// Helper class to verify the bucket counts for PacUrlScheme histogram.
-class PacUrlSchemeHistogramTester {
- public:
- void VerifyHistogram() const {
- const char kPacUrlSchemeHistogram[] =
- "Net.ProxyResolutionService.PacUrlScheme";
-
- int total = GetTotal();
-
- histograms_.ExpectTotalCount(kPacUrlSchemeHistogram, total);
-
- if (total > 0) {
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 0, num_other);
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 1, num_http);
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 2, num_https);
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 3, num_ftp);
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 4, num_file);
- histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 5, num_data);
- }
- }
-
- int num_http = 0;
- int num_https = 0;
- int num_ftp = 0;
- int num_data = 0;
- int num_file = 0;
- int num_other = 0;
-
- private:
- int GetTotal() const {
- return num_http + num_https + num_ftp + num_data + num_file + num_other;
- }
-
- base::HistogramTester histograms_;
-};
-
} // namespace
TEST_F(ConfiguredProxyResolutionServiceTest, Direct) {
@@ -3999,61 +3963,6 @@ TEST_F(ConfiguredProxyResolutionServiceTest, OnShutdownFollowedByRequest) {
EXPECT_TRUE(info.is_direct());
}
-// Tests that the URL scheme for PAC files gets output to the histogram.
-TEST_F(ConfiguredProxyResolutionServiceTest, PacUrlSchemeHistogram) {
- PacUrlSchemeHistogramTester pac_histogram;
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService(ProxyConfig::CreateDirect());
-
- ConfiguredProxyResolutionService service(
- base::WrapUnique(config_service),
- std::make_unique<MockAsyncProxyResolverFactory>(false), nullptr,
- /*quick_check_enabled=*/true);
-
- pac_histogram.VerifyHistogram();
-
- // Set an http:// PAC.
- config_service->SetPacUrlConfig("http://example.test/");
- pac_histogram.num_http++;
- pac_histogram.VerifyHistogram();
-
- // Set an https:// PAC.
- config_service->SetPacUrlConfig("hTTps://example.test/wpad.dat");
- pac_histogram.num_https++;
- pac_histogram.VerifyHistogram();
-
- // Set an ftp:// PAC.
- config_service->SetPacUrlConfig("ftp://example.test/pac.js");
- pac_histogram.num_ftp++;
- pac_histogram.VerifyHistogram();
-
- // Set an file:// PAC.
- config_service->SetPacUrlConfig("file://example.test/boo");
- pac_histogram.num_file++;
- pac_histogram.VerifyHistogram();
-
- // Set an mailto: PAC.
- config_service->SetPacUrlConfig("mailto:foo@example.test");
- pac_histogram.num_other++;
- pac_histogram.VerifyHistogram();
-
- // Set an data: PAC.
- config_service->SetPacUrlConfig("data:,Hello%2C%20World!");
- pac_histogram.num_data++;
- pac_histogram.VerifyHistogram();
-
- // Set an filesystem: PAC.
- config_service->SetPacUrlConfig("filesystem:http://example.test/pac.js");
- pac_histogram.num_other++;
- pac_histogram.VerifyHistogram();
-
- // Set another https:// as PAC.
- config_service->SetPacUrlConfig("https://example2.test/wpad.dat");
- pac_histogram.num_https++;
- pac_histogram.VerifyHistogram();
-}
-
const char* kImplicityBypassedHosts[] = {
"localhost",
"localhost.",
diff --git a/chromium/net/proxy_resolution/network_delegate_error_observer_unittest.cc b/chromium/net/proxy_resolution/network_delegate_error_observer_unittest.cc
index dff170e9e55..b0c9ff4322c 100644
--- a/chromium/net/proxy_resolution/network_delegate_error_observer_unittest.cc
+++ b/chromium/net/proxy_resolution/network_delegate_error_observer_unittest.cc
@@ -59,7 +59,6 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
got_pac_error_ = true;
}
bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) override {
return allowed_from_caller;
}
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc b/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
index cedd67874ce..f31ae9a7b22 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
@@ -175,6 +175,8 @@ int PacFileFetcherImpl::Fetch(
cur_request_ = url_request_context_->CreateRequest(url, MAXIMUM_PRIORITY,
this, traffic_annotation);
+ cur_request_->set_isolation_info(isolation_info_);
+
// Make sure that the PAC script is downloaded using a direct connection,
// to avoid circular dependencies (fetching is a part of proxy resolution).
// Also disable the use of the disk cache. The cache is disabled so that if
@@ -316,6 +318,7 @@ void PacFileFetcherImpl::OnReadCompleted(URLRequest* request, int num_bytes) {
PacFileFetcherImpl::PacFileFetcherImpl(URLRequestContext* url_request_context)
: url_request_context_(url_request_context),
+ isolation_info_(IsolationInfo::CreateTransient()),
buf_(base::MakeRefCounted<IOBuffer>(kBufSize)),
next_id_(0),
cur_request_id_(0),
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl.h b/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
index efbba739f5c..0ceea27f615 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
@@ -17,6 +17,7 @@
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "net/base/completion_once_callback.h"
+#include "net/base/isolation_info.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -80,6 +81,8 @@ class NET_EXPORT PacFileFetcherImpl : public PacFileFetcher,
void OnResponseStarted(URLRequest* request, int net_error) override;
void OnReadCompleted(URLRequest* request, int num_bytes) override;
+ const IsolationInfo& isolation_info_for_testing() { return isolation_info_; }
+
private:
enum { kBufSize = 4096 };
@@ -110,6 +113,9 @@ class NET_EXPORT PacFileFetcherImpl : public PacFileFetcher,
// OnShutdown.
URLRequestContext* url_request_context_;
+ // Transient IsolationInfo used to fetch PAC scripts.
+ const IsolationInfo isolation_info_;
+
// Buffer that URLRequest writes into.
scoped_refptr<IOBuffer> buf_;
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index d5c60af6869..34095ea5147 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -18,8 +18,10 @@
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "net/base/features.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
#include "net/base/network_delegate_impl.h"
@@ -73,13 +75,12 @@ struct FetchResult {
base::string16 text;
};
-// A non-mock URL request which can access http:// and file:// urls, in the case
-// the tests were built with file support.
+// A non-mock URL request which can access http:// urls.
class RequestContext : public URLRequestContext {
public:
RequestContext() : storage_(this) {
ProxyConfig no_proxy;
- storage_.set_host_resolver(std::make_unique<MockHostResolver>());
+ storage_.set_host_resolver(std::make_unique<MockCachingHostResolver>());
storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
storage_.set_transport_security_state(
std::make_unique<TransportSecurityState>());
@@ -179,7 +180,6 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
}
bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) override {
return allowed_from_caller;
}
@@ -321,6 +321,58 @@ TEST_F(PacFileFetcherImplTest, ContentDisposition) {
EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
}
+// Verifies that fetches are made using the fetcher's IsolationInfo, by checking
+// the DNS cache.
+TEST_F(PacFileFetcherImplTest, IsolationInfo) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ // enabled_features
+ {features::kPartitionConnectionsByNetworkIsolationKey,
+ features::kSplitHostCacheByNetworkIsolationKey},
+ // disabled_features
+ {});
+ const char kHost[] = "foo.test";
+
+ ASSERT_TRUE(test_server_.Start());
+
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
+
+ GURL url(test_server_.GetURL(kHost, "/downloadable.pac"));
+ base::string16 text;
+ TestCompletionCallback callback;
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_THAT(callback.GetResult(result), IsOk());
+ EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
+
+ // Check that the URL in kDestination is in the HostCache, with
+ // the fetcher's IsolationInfo / NetworkIsolationKey, and no others.
+ const net::HostPortPair kHostPortPair =
+ net::HostPortPair(kHost, 0 /* port */);
+ net::HostResolver::ResolveHostParameters params;
+ params.source = net::HostResolverSource::LOCAL_ONLY;
+ std::unique_ptr<net::HostResolver::ResolveHostRequest> host_request =
+ context_.host_resolver()->CreateRequest(
+ kHostPortPair,
+ pac_fetcher->isolation_info_for_testing().network_isolation_key(),
+ net::NetLogWithSource(), params);
+ net::TestCompletionCallback callback2;
+ result = host_request->Start(callback2.callback());
+ EXPECT_EQ(net::OK, callback2.GetResult(result));
+
+ // Make sure there are no other entries in the HostCache (which would
+ // potentially be associated with other NetworkIsolationKeys).
+ EXPECT_EQ(1u, context_.host_resolver()->GetHostCache()->size());
+
+ // Make sure the cache is actually returning different results based on
+ // NetworkIsolationKey.
+ host_request = context_.host_resolver()->CreateRequest(
+ kHostPortPair, NetworkIsolationKey(), net::NetLogWithSource(), params);
+ net::TestCompletionCallback callback3;
+ result = host_request->Start(callback3.callback());
+ EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, callback3.GetResult(result));
+}
+
// Verifies that PAC scripts are not being cached.
TEST_F(PacFileFetcherImplTest, NoCache) {
ASSERT_TRUE(test_server_.Start());
diff --git a/chromium/net/proxy_resolution/proxy_resolver.h b/chromium/net/proxy_resolution/proxy_resolver.h
index 6cfdb32859b..5b7e65c5ca4 100644
--- a/chromium/net/proxy_resolution/proxy_resolver.h
+++ b/chromium/net/proxy_resolution/proxy_resolver.h
@@ -6,7 +6,6 @@
#define NET_PROXY_RESOLUTION_PROXY_RESOLVER_H_
#include "base/callback_forward.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
diff --git a/chromium/net/quic/OWNERS b/chromium/net/quic/OWNERS
index 9db36fa2026..4d12d7e8fff 100644
--- a/chromium/net/quic/OWNERS
+++ b/chromium/net/quic/OWNERS
@@ -1,6 +1,6 @@
dschinazi@chromium.org
nharper@chromium.org
-rch@chromium.org
+vasilvv@chromium.org
zhongyi@chromium.org
bnc@chromium.org
diff --git a/chromium/net/quic/bidirectional_stream_quic_impl_unittest.cc b/chromium/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 6cfc33e5862..e5410eaa44d 100644
--- a/chromium/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/chromium/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -463,6 +463,7 @@ class BidirectionalStreamQuicImplTest
printer_(version_),
destination_(kDefaultServerHostName, kDefaultServerPort) {
quic::QuicEnableVersion(version_);
+ FLAGS_quic_enable_http3_grease_randomness = false;
IPAddress ip(192, 0, 2, 33);
peer_addr_ = IPEndPoint(ip, 443);
self_addr_ = IPEndPoint(ip, 8435);
@@ -857,18 +858,14 @@ INSTANTIATE_TEST_SUITE_P(Version,
::testing::PrintToStringParamName());
TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("GET", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructClientAckPacket(3, 1, 2));
@@ -966,22 +963,18 @@ TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
}
TEST_P(BidirectionalStreamQuicImplTest, LoadTimingTwoRequests) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("GET", "/", DEFAULT_PRIORITY);
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), kFin, DEFAULT_PRIORITY,
- nullptr));
+ GetNthClientInitiatedBidirectionalStreamId(0), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY, nullptr));
// SetRequest() again for second request as |request_headers_| was moved.
SetRequest("GET", "/", DEFAULT_PRIORITY);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(1), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(1), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
GetNthClientInitiatedBidirectionalStreamId(0), nullptr));
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructClientAckPacket(3, 1, 2));
@@ -1045,10 +1038,6 @@ TEST_P(BidirectionalStreamQuicImplTest, LoadTimingTwoRequests) {
// Tests that when request headers are not delayed, only data buffers are
// coalesced.
TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1061,7 +1050,8 @@ TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) {
std::string header2 = ConstructDataHeader(kBody2.length());
std::vector<std::string> two_writes = {kBody1, kBody2};
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
if (!version_.UsesHttp3()) {
AddWrite(
@@ -1191,11 +1181,6 @@ TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) {
// request headers with data buffers.
TEST_P(BidirectionalStreamQuicImplTest,
SendDataCoalesceDataBufferAndHeaderFrame) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1206,8 +1191,7 @@ TEST_P(BidirectionalStreamQuicImplTest,
std::string header = ConstructDataHeader(strlen(kBody1));
if (version_.UsesHttp3()) {
AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
- !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- {header, kBody1}));
+ !kFin, MEDIUM, &spdy_request_headers_frame_length, {header, kBody1}));
} else {
AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
!kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, {kBody1}));
@@ -1312,11 +1296,6 @@ TEST_P(BidirectionalStreamQuicImplTest,
// request headers with data buffers.
TEST_P(BidirectionalStreamQuicImplTest,
SendvDataCoalesceDataBuffersAndHeaderFrame) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1330,7 +1309,7 @@ TEST_P(BidirectionalStreamQuicImplTest,
if (version_.UsesHttp3()) {
AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
- !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
+ !kFin, MEDIUM, &spdy_request_headers_frame_length,
{header + kBody1 + header2 + kBody2}));
} else {
AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
@@ -1453,11 +1432,6 @@ TEST_P(BidirectionalStreamQuicImplTest,
// headers to be sent, if that write fails the stream does not crash.
TEST_P(BidirectionalStreamQuicImplTest,
SendDataWriteErrorCoalesceDataBufferAndHeaderFrame) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
@@ -1495,10 +1469,6 @@ TEST_P(BidirectionalStreamQuicImplTest,
// headers to be sent, if that write fails the stream does not crash.
TEST_P(BidirectionalStreamQuicImplTest,
SendvDataWriteErrorCoalesceDataBufferAndHeaderFrame) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
@@ -1537,11 +1507,6 @@ TEST_P(BidirectionalStreamQuicImplTest,
}
TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1549,7 +1514,8 @@ TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
std::string header = ConstructDataHeader(strlen(kUploadData));
if (version_.UsesHttp3()) {
@@ -1637,18 +1603,14 @@ TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
}
TEST_P(BidirectionalStreamQuicImplTest, EarlyDataOverrideRequest) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("PUT", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructClientAckPacket(3, 1, 2));
@@ -1747,11 +1709,6 @@ TEST_P(BidirectionalStreamQuicImplTest, EarlyDataOverrideRequest) {
}
TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1759,7 +1716,8 @@ TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
std::string header = ConstructDataHeader(strlen(kUploadData));
@@ -1862,18 +1820,14 @@ TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
}
TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("GET", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Initialize();
@@ -1913,18 +1867,14 @@ TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
}
TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("GET", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
// Why does QUIC ack Rst? Is this expected?
@@ -1982,11 +1932,6 @@ TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
}
TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -1994,7 +1939,8 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
Initialize();
@@ -2099,11 +2045,6 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeStartNotConfirmed) {
}
TEST_P(BidirectionalStreamQuicImplTest, SessionCloseDuringOnStreamReady) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
@@ -2132,11 +2073,6 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionCloseDuringOnStreamReady) {
}
TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnStreamReady) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -2144,7 +2080,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnStreamReady) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
AddWrite(ConstructClientEarlyRstStreamPacket());
@@ -2171,11 +2108,6 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnStreamReady) {
}
TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamAfterReadData) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -2183,7 +2115,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamAfterReadData) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
AddWrite(ConstructClientAckAndRstStreamPacket(2, 1, 2));
@@ -2234,11 +2167,6 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamAfterReadData) {
}
TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -2246,7 +2174,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
AddWrite(ConstructClientAckAndRstStreamPacket(2, 1, 2));
@@ -2289,11 +2218,6 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
}
TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -2301,7 +2225,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
AddWrite(ConstructClientAckPacket(3, 1, 2));
AddWrite(ConstructClientRstStreamPacket());
@@ -2355,11 +2280,6 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
}
TEST_P(BidirectionalStreamQuicImplTest, AsyncFinRead) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
const char kBody[] = "here is some data";
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
@@ -2368,7 +2288,8 @@ TEST_P(BidirectionalStreamQuicImplTest, AsyncFinRead) {
AddWrite(ConstructInitialSettingsPacket());
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
AddWrite(ConstructRequestHeadersPacketInner(
- GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
+ version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
&spdy_request_headers_frame_length));
std::string header = ConstructDataHeader(strlen(kBody));
if (version_.UsesHttp3()) {
@@ -2437,18 +2358,15 @@ TEST_P(BidirectionalStreamQuicImplTest, AsyncFinRead) {
}
TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
SetRequest("GET", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
if (VersionUsesHttp3(version_.transport_version))
AddWrite(ConstructInitialSettingsPacket());
- AddWrite(ConstructRequestHeadersPacket(kFin, DEFAULT_PRIORITY,
- &spdy_request_headers_frame_length));
+ client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+ AddWrite(ConstructRequestHeadersPacket(
+ kFin, version_.UsesHttp3() ? MEDIUM : DEFAULT_PRIORITY,
+ &spdy_request_headers_frame_length));
AddWrite(ConstructClientAckPacket(3, 1, 2)); // Ack the data packet
AddWrite(ConstructClientAckAndRstStreamPacket(4, 4, 2));
@@ -2467,6 +2385,7 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
DeleteStreamDelegate::ON_TRAILERS_RECEIVED));
delegate->Start(&request, net_log().bound(),
session()->CreateHandle(destination_));
+ ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
// Server acks the request.
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.cc b/chromium/net/quic/crypto/proof_verifier_chromium.cc
index ee05dce91ca..d49b1db3218 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium.cc
+++ b/chromium/net/quic/crypto/proof_verifier_chromium.cc
@@ -16,6 +16,7 @@
#include "crypto/signature_verifier.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
@@ -459,7 +460,8 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
cert_verify_result.verified_cert.get(), cert_.get(),
verify_details_->ct_verify_result.scts,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- verify_details_->ct_verify_result.policy_compliance);
+ verify_details_->ct_verify_result.policy_compliance,
+ proof_verifier_->network_isolation_key_);
if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) {
verify_details_->ct_verify_result.policy_compliance_required = true;
if (verify_details_->cert_verify_result.is_issued_by_known_root) {
@@ -594,12 +596,14 @@ ProofVerifierChromium::ProofVerifierChromium(
CTPolicyEnforcer* ct_policy_enforcer,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- std::set<std::string> hostnames_to_allow_unknown_roots)
+ std::set<std::string> hostnames_to_allow_unknown_roots,
+ const NetworkIsolationKey& network_isolation_key)
: cert_verifier_(cert_verifier),
ct_policy_enforcer_(ct_policy_enforcer),
transport_security_state_(transport_security_state),
cert_transparency_verifier_(cert_transparency_verifier),
- hostnames_to_allow_unknown_roots_(hostnames_to_allow_unknown_roots) {
+ hostnames_to_allow_unknown_roots_(hostnames_to_allow_unknown_roots),
+ network_isolation_key_(network_isolation_key) {
DCHECK(cert_verifier_);
DCHECK(ct_policy_enforcer_);
DCHECK(transport_security_state_);
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.h b/chromium/net/quic/crypto/proof_verifier_chromium.h
index beacd3d0d63..f05da2eb259 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium.h
+++ b/chromium/net/quic/crypto/proof_verifier_chromium.h
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "net/base/net_export.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/x509_certificate.h"
@@ -74,7 +75,8 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public quic::ProofVerifier {
CTPolicyEnforcer* ct_policy_enforcer,
TransportSecurityState* transport_security_state,
CTVerifier* cert_transparency_verifier,
- std::set<std::string> hostnames_to_allow_unknown_roots);
+ std::set<std::string> hostnames_to_allow_unknown_roots,
+ const NetworkIsolationKey& network_isolation_key);
~ProofVerifierChromium() override;
// quic::ProofVerifier interface
@@ -120,6 +122,8 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public quic::ProofVerifier {
std::set<std::string> hostnames_to_allow_unknown_roots_;
+ const NetworkIsolationKey network_isolation_key_;
+
DISALLOW_COPY_AND_ASSIGN(ProofVerifierChromium);
};
diff --git a/chromium/net/quic/crypto/proof_verifier_chromium_test.cc b/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
index 62504d05827..e04f01a8566 100644
--- a/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
+++ b/chromium/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -10,6 +10,7 @@
#include "base/test/metrics/histogram_tester.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
@@ -113,6 +114,11 @@ const char kTestEmptySignature[] = "";
const char kLogDescription[] = "somelog";
+// This test exercises code that does not depend on the QUIC version in use
+// but that still requires a version so we just use the first one.
+const quic::QuicTransportVersion kTestTransportVersion =
+ quic::AllSupportedVersions().front().transport_version;
+
} // namespace
class ProofVerifierChromiumTest : public ::testing::Test {
@@ -152,7 +158,7 @@ class ProofVerifierChromiumTest : public ::testing::Test {
base::FilePath());
std::string signature;
source.GetProof(quic::QuicSocketAddress(), quic::QuicSocketAddress(),
- kTestHostname, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestConfig, kTestTransportVersion,
kTestChloHash,
std::make_unique<SignatureSaver>(&signature));
return signature;
@@ -204,14 +210,14 @@ TEST_F(ProofVerifierChromiumTest, VerifyProof) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -238,14 +244,14 @@ TEST_F(ProofVerifierChromiumTest, VerifyProof) {
// verification fails.
TEST_F(ProofVerifierChromiumTest, FailsIfCertFails) {
MockCertVerifier dummy_verifier;
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -264,14 +270,14 @@ TEST_F(ProofVerifierChromiumTest, ValidSCTList) {
MockCertVerifier cert_verifier;
- ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &cert_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, ct::GetSCTListForTesting(), kTestEmptySignature,
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -292,14 +298,14 @@ TEST_F(ProofVerifierChromiumTest, InvalidSCTList) {
ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));
MockCertVerifier cert_verifier;
- ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &cert_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, ct::GetSCTListWithInvalidSCT(),
kTestEmptySignature, verify_context_.get(), &error_details_, &details_,
std::move(callback));
@@ -319,14 +325,14 @@ TEST_F(ProofVerifierChromiumTest, InvalidSCTList) {
// signature fails.
TEST_F(ProofVerifierChromiumTest, FailsIfSignatureFails) {
FailsTestCertVerifier cert_verifier;
- ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &cert_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, kTestEmptySignature,
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -344,14 +350,14 @@ TEST_F(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -387,14 +393,14 @@ TEST_F(ProofVerifierChromiumTest, StripsEVIfNotAllowed) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -436,14 +442,14 @@ TEST_F(ProofVerifierChromiumTest, CTEVHistogramNonCompliant) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -492,14 +498,14 @@ TEST_F(ProofVerifierChromiumTest, CTEVHistogramCompliant) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -544,14 +550,14 @@ TEST_F(ProofVerifierChromiumTest, IsFatalErrorNotSetForNonFatalError) {
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_,
ERR_CERT_DATE_INVALID);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -581,14 +587,14 @@ TEST_F(ProofVerifierChromiumTest, IsFatalErrorSetForFatalError) {
base::Time::Now() + base::TimeDelta::FromSeconds(1000);
transport_security_state_.AddHSTS(kTestHostname, expiry, true);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -616,14 +622,14 @@ TEST_F(ProofVerifierChromiumTest, PKPEnforced) {
transport_security_state_.EnableStaticPinsForTesting();
ScopedTransportSecurityStateSource scoped_security_state_source;
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -662,14 +668,14 @@ TEST_F(ProofVerifierChromiumTest, PKPBypassFlagSet) {
transport_security_state_.EnableStaticPinsForTesting();
ScopedTransportSecurityStateSource scoped_security_state_source;
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {kCTAndPKPHost});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {kCTAndPKPHost}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -712,14 +718,14 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequired) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -769,14 +775,14 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramNonCompliant) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -824,14 +830,14 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramCompliant) {
{
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {kTestHostname});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -849,14 +855,14 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramCompliant) {
dummy_result_.is_issued_by_known_root = true;
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -892,14 +898,14 @@ TEST_F(ProofVerifierChromiumTest, CTIsNotRequiredHistogram) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {kTestHostname});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -938,14 +944,14 @@ TEST_F(ProofVerifierChromiumTest, PKPAndCTBothTested) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kCTAndPKPHost, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -989,14 +995,14 @@ TEST_F(ProofVerifierChromiumTest, CTComplianceStatusHistogram) {
{
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {kTestHostname});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -1016,14 +1022,14 @@ TEST_F(ProofVerifierChromiumTest, CTComplianceStatusHistogram) {
dummy_result_.is_issued_by_known_root = true;
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -1065,15 +1071,15 @@ TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagNotMet) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
{
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
@@ -1118,15 +1124,15 @@ TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagMet) {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
{
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
@@ -1160,14 +1166,14 @@ TEST_F(ProofVerifierChromiumTest, UnknownRootRejected) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_FAILURE, status);
@@ -1191,14 +1197,14 @@ TEST_F(ProofVerifierChromiumTest, UnknownRootAcceptedWithOverride) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {kTestHostname});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
@@ -1227,14 +1233,14 @@ TEST_F(ProofVerifierChromiumTest, UnknownRootAcceptedWithWildcardOverride) {
MockCertVerifier dummy_verifier;
dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
- ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
- &transport_security_state_,
- ct_verifier_.get(), {""});
+ ProofVerifierChromium proof_verifier(
+ &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
+ ct_verifier_.get(), {""}, NetworkIsolationKey());
std::unique_ptr<DummyProofVerifierCallback> callback(
new DummyProofVerifierCallback);
quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
- kTestHostname, kTestPort, kTestConfig, quic::QUIC_VERSION_43,
+ kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
verify_context_.get(), &error_details_, &details_, std::move(callback));
ASSERT_EQ(quic::QUIC_SUCCESS, status);
diff --git a/chromium/net/quic/crypto_test_utils_chromium.cc b/chromium/net/quic/crypto_test_utils_chromium.cc
index f284f7c4cdb..256dc0e28f5 100644
--- a/chromium/net/quic/crypto_test_utils_chromium.cc
+++ b/chromium/net/quic/crypto_test_utils_chromium.cc
@@ -11,6 +11,7 @@
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
@@ -53,7 +54,8 @@ class TestProofVerifierChromium : public ProofVerifierChromium {
ct_policy_enforcer.get(),
transport_security_state.get(),
cert_transparency_verifier.get(),
- {"test.example.com"}),
+ {"test.example.com"},
+ NetworkIsolationKey()),
cert_verifier_(std::move(cert_verifier)),
transport_security_state_(std::move(transport_security_state)),
cert_transparency_verifier_(std::move(cert_transparency_verifier)),
diff --git a/chromium/net/quic/mock_crypto_client_stream.cc b/chromium/net/quic/mock_crypto_client_stream.cc
index 9a8d2b55e39..3eb98fdef89 100644
--- a/chromium/net/quic/mock_crypto_client_stream.cc
+++ b/chromium/net/quic/mock_crypto_client_stream.cc
@@ -11,6 +11,7 @@
#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/http/quic_spdy_client_session_base.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,7 +33,6 @@ using quic::NullEncrypter;
using quic::PACKET_8BYTE_CONNECTION_ID;
using quic::Perspective;
using quic::ProofVerifyContext;
-using quic::PROTOCOL_TLS1_3;
using quic::QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE;
using quic::QUIC_NO_ERROR;
using quic::QUIC_PROOF_INVALID;
@@ -49,6 +49,19 @@ using quic::TransportParameters;
using quiche::QuicheStringPiece;
using std::string;
+namespace {
+
+// TODO(crbug.com/1085541): Consider moving this method into QuicTestUtils.
+quic::QuicConnectionId TestConnectionId(uint64_t connection_number) {
+ const uint64_t connection_id64_net =
+ quiche::QuicheEndian::HostToNet64(connection_number);
+ return quic::QuicConnectionId(
+ reinterpret_cast<const char*>(&connection_id64_net),
+ sizeof(connection_id64_net));
+}
+
+} // namespace
+
namespace net {
MockCryptoClientStream::MockCryptoClientStream(
@@ -138,13 +151,17 @@ bool MockCryptoClientStream::CryptoConnect() {
ENCRYPTION_ZERO_RTT,
std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
}
- session()->connection()->SetEncrypter(
+ if (session()->version().UsesHttp3()) {
+ SetConfigNegotiated();
+ }
+ session()->OnNewEncryptionKeyAvailable(
ENCRYPTION_ZERO_RTT,
std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
}
- if (session()->connection()->version().handshake_protocol ==
- quic::PROTOCOL_QUIC_CRYPTO) {
+ if (session()->version().UsesQuicCrypto()) {
session()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+ } else {
+ session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
}
break;
}
@@ -186,8 +203,7 @@ bool MockCryptoClientStream::CryptoConnect() {
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
}
- if (session()->connection()->version().handshake_protocol ==
- quic::PROTOCOL_TLS1_3) {
+ if (session()->version().UsesTls()) {
session()->OnOneRttKeysAvailable();
} else {
session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
@@ -238,44 +254,48 @@ void MockCryptoClientStream::OnOneRttPacketAcknowledged() {}
void MockCryptoClientStream::NotifySessionOneRttKeyAvailable() {
encryption_established_ = true;
- handshake_confirmed_ = true;
+ handshake_confirmed_ = true;
+ if (session()->version().UsesQuicCrypto())
SetConfigNegotiated();
- if (use_mock_crypter_) {
- if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
- session()->connection()->InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<MockDecrypter>(Perspective::IS_CLIENT));
- } else {
- session()->connection()->SetDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<MockDecrypter>(Perspective::IS_CLIENT));
- }
- session()->connection()->SetEncrypter(
+ if (use_mock_crypter_) {
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(
ENCRYPTION_FORWARD_SECURE,
- std::make_unique<MockEncrypter>(Perspective::IS_CLIENT));
+ std::make_unique<MockDecrypter>(Perspective::IS_CLIENT));
} else {
- if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
- session()->connection()->InstallDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- } else {
- session()->connection()->SetDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
- }
- session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
- session()->OnNewEncryptionKeyAvailable(
+ session()->connection()->SetDecrypter(
ENCRYPTION_FORWARD_SECURE,
- std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+ std::make_unique<MockDecrypter>(Perspective::IS_CLIENT));
}
- if (session()->connection()->version().handshake_protocol ==
- quic::PROTOCOL_TLS1_3) {
- session()->OnOneRttKeysAvailable();
+ session()->connection()->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<MockEncrypter>(Perspective::IS_CLIENT));
+ } else {
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
} else {
- session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ session()->connection()->SetDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
}
- session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- session()->NeuterHandshakeData();
+ session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, nullptr);
+ session()->OnNewEncryptionKeyAvailable(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
+ }
+ if (session()->version().UsesTls()) {
+ SetConfigNegotiated();
+ session()->OnOneRttKeysAvailable();
+ } else {
+ session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ }
+ session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+ if (session()->version().UsesTls()) {
+ session()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
+ }
+ session()->NeuterHandshakeData();
}
// static
@@ -286,7 +306,8 @@ CryptoHandshakeMessage MockCryptoClientStream::GetDummyCHLOMessage() {
}
void MockCryptoClientStream::SetConfigNegotiated() {
- ASSERT_FALSE(session()->config()->negotiated());
+ if (!session()->version().UsesHttp3())
+ ASSERT_FALSE(session()->config()->negotiated());
QuicTagVector cgst;
// TODO(rtenneti): Enable the following code after BBR code is checked in.
#if 0
@@ -304,10 +325,27 @@ void MockCryptoClientStream::SetConfigNegotiated() {
config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
quic::kMinimumFlowControlSendWindow);
+ if (quic::VersionHasIetfInvariantHeader(
+ session()->connection()->transport_version())) {
+ auto connection_id = TestConnectionId(0x1337);
+ config.SetStatelessResetTokenToSend(
+ quic::QuicUtils::GenerateStatelessResetToken(connection_id));
+ }
+ if (session()->version().AuthenticatesHandshakeConnectionIds()) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ config.SetOriginalConnectionIdToSend(
+ session()->connection()->connection_id());
+ config.SetInitialSourceConnectionIdToSend(
+ session()->connection()->connection_id());
+ } else {
+ config.SetInitialSourceConnectionIdToSend(
+ session()->connection()->client_connection_id());
+ }
+ }
+
QuicErrorCode error;
std::string error_details;
- if (session()->connection()->version().handshake_protocol ==
- PROTOCOL_TLS1_3) {
+ if (session()->version().UsesTls()) {
TransportParameters params;
ASSERT_TRUE(config.FillTransportParameters(&params));
error = session()->config()->ProcessTransportParameters(
@@ -324,8 +362,7 @@ void MockCryptoClientStream::SetConfigNegotiated() {
}
void MockCryptoClientStream::FillCryptoParams() {
- if (session()->connection()->version().handshake_protocol ==
- quic::PROTOCOL_QUIC_CRYPTO) {
+ if (session()->version().UsesQuicCrypto()) {
crypto_negotiated_params_->key_exchange = kC255;
crypto_negotiated_params_->aead = kAESG;
return;
diff --git a/chromium/net/quic/mock_quic_data.cc b/chromium/net/quic/mock_quic_data.cc
index 9c71eff9c95..d1b5cbc41cb 100644
--- a/chromium/net/quic/mock_quic_data.cc
+++ b/chromium/net/quic/mock_quic_data.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "net/quic/mock_quic_data.h"
+#include "net/base/hex_utils.h"
namespace net {
namespace test {
diff --git a/chromium/net/quic/network_connection.cc b/chromium/net/quic/network_connection.cc
index 6cf3d116f65..9c36d366445 100644
--- a/chromium/net/quic/network_connection.cc
+++ b/chromium/net/quic/network_connection.cc
@@ -4,6 +4,7 @@
#include "net/quic/network_connection.h"
+#include "base/logging.h"
#include "net/base/network_interfaces.h"
namespace net {
diff --git a/chromium/net/quic/platform/impl/quic_default_proof_providers_impl.cc b/chromium/net/quic/platform/impl/quic_default_proof_providers_impl.cc
index 28ec2766c6a..bbe4a7069e7 100644
--- a/chromium/net/quic/platform/impl/quic_default_proof_providers_impl.cc
+++ b/chromium/net/quic/platform/impl/quic_default_proof_providers_impl.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "net/base/network_isolation_key.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
@@ -64,7 +65,10 @@ class ProofVerifierChromiumWithOwnership : public net::ProofVerifierChromium {
&ct_policy_enforcer_,
&transport_security_state_,
&ct_verifier_,
- UnknownRootAllowlistForHost(host)),
+ UnknownRootAllowlistForHost(host),
+ // Fine to use an empty NetworkIsolationKey
+ // here, since this isn't used in Chromium.
+ net::NetworkIsolationKey()),
cert_verifier_(std::move(cert_verifier)) {}
private:
diff --git a/chromium/net/quic/platform/impl/quic_socket_utils.cc b/chromium/net/quic/platform/impl/quic_socket_utils.cc
index bb062039fe5..9fe56a19040 100644
--- a/chromium/net/quic/platform/impl/quic_socket_utils.cc
+++ b/chromium/net/quic/platform/impl/quic_socket_utils.cc
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <string>
+#include "base/notreached.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.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"
diff --git a/chromium/net/quic/platform/impl/quic_test_impl.h b/chromium/net/quic/platform/impl/quic_test_impl.h
index 98bc7b27c29..1bcda9fde67 100644
--- a/chromium/net/quic/platform/impl/quic_test_impl.h
+++ b/chromium/net/quic/platform/impl/quic_test_impl.h
@@ -5,7 +5,7 @@
#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
#define NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
-#include "base/logging.h"
+#include "base/check_op.h"
#include "net/test/test_with_task_environment.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
diff --git a/chromium/net/quic/quic_chromium_client_session.cc b/chromium/net/quic/quic_chromium_client_session.cc
index 780b8507c71..da5ac629afc 100644
--- a/chromium/net/quic/quic_chromium_client_session.cc
+++ b/chromium/net/quic/quic_chromium_client_session.cc
@@ -136,7 +136,7 @@ void RecordConnectionCloseErrorCode(const quic::QuicConnectionCloseFrame& frame,
quic::ConnectionCloseSource source,
const std::string& hostname,
bool handshake_confirmed) {
- bool is_google_host = HasGoogleHost(GURL("https://" + hostname));
+ bool is_google_host = IsGoogleHost(hostname);
std::string histogram = "Net.QuicSession.ConnectionCloseErrorCode";
if (source == quic::ConnectionCloseSource::FROM_SELF) {
@@ -161,10 +161,20 @@ void RecordConnectionCloseErrorCode(const quic::QuicConnectionCloseFrame& frame,
histogram += "IetfTransport";
RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
is_google_host, handshake_confirmed);
+ if (frame.quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) {
+ histogram += "GQuicErrorMissing";
+ RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
+ is_google_host, handshake_confirmed);
+ }
} else if (frame.close_type == quic::IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
histogram += "IetfApplication";
RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
is_google_host, handshake_confirmed);
+ if (frame.quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) {
+ histogram += "GQuicErrorMissing";
+ RecordConnectionCloseErrorCodeImpl(histogram, frame.wire_error_code,
+ is_google_host, handshake_confirmed);
+ }
}
}
@@ -826,8 +836,7 @@ QuicChromiumClientSession::QuicChromiumClientSession(
wait_for_new_network_(false),
ignore_read_error_(false),
headers_include_h2_stream_dependency_(
- headers_include_h2_stream_dependency &&
- this->connection()->transport_version() >= quic::QUIC_VERSION_43),
+ headers_include_h2_stream_dependency),
max_allowed_push_id_(max_allowed_push_id) {
// Make sure connection migration and goaway on path degrading are not turned
// on at the same time.
@@ -880,6 +889,9 @@ QuicChromiumClientSession::QuicChromiumClientSession(
QuicChromiumClientSession::~QuicChromiumClientSession() {
DCHECK(callback_.is_null());
+ for (auto& observer : connectivity_observer_list_)
+ observer.OnSessionRemoved(this);
+
net_log_.EndEvent(NetLogEventType::QUIC_SESSION);
DCHECK(waiting_for_confirmation_callbacks_.empty());
if (HasActiveRequestStreams())
@@ -995,6 +1007,13 @@ void QuicChromiumClientSession::Initialize() {
quic::QuicSpdyClientSessionBase::SetMaxPushId(max_allowed_push_id_);
}
set_max_inbound_header_list_size(kQuicMaxHeaderListSize);
+ if (config()->HasClientRequestedIndependentOption(
+ quic::kQLVE, quic::Perspective::IS_CLIENT)) {
+ connection()->EnableLegacyVersionEncapsulation(session_key_.host());
+ // Legacy Version Encapsulation needs CHLO padding to be disabled.
+ // TODO(dschinazi) remove this line once we deprecate quic_dont_pad_chlo.
+ crypto_config_->GetConfig()->set_disable_chlo_padding(true);
+ }
quic::QuicSpdyClientSessionBase::Initialize();
SetHpackEncoderDebugVisitor(std::make_unique<HpackEncoderDebugVisitor>());
SetHpackDecoderDebugVisitor(std::make_unique<HpackDecoderDebugVisitor>());
@@ -1078,6 +1097,16 @@ void QuicChromiumClientSession::RemoveHandle(Handle* handle) {
handles_.erase(handle);
}
+void QuicChromiumClientSession::AddConnectivityObserver(
+ ConnectivityObserver* observer) {
+ connectivity_observer_list_.AddObserver(observer);
+}
+
+void QuicChromiumClientSession::RemoveConnectivityObserver(
+ ConnectivityObserver* observer) {
+ connectivity_observer_list_.RemoveObserver(observer);
+}
+
// TODO(zhongyi): replace migration_session_* booleans with
// ConnectionMigrationMode.
ConnectionMigrationMode QuicChromiumClientSession::connection_migration_mode()
@@ -1363,7 +1392,7 @@ bool QuicChromiumClientSession::CanPool(
return SpdySession::CanPool(transport_security_state_, ssl_info,
*ssl_config_service_, session_key_.host(),
- hostname);
+ hostname, network_isolation_key);
}
bool QuicChromiumClientSession::ShouldCreateIncomingStream(
@@ -1383,7 +1412,7 @@ bool QuicChromiumClientSession::ShouldCreateIncomingStream(
if (quic::QuicUtils::IsClientInitiatedStreamId(
connection()->transport_version(), id) ||
(connection()->version().HasIetfQuicFrames() &&
- quic::QuicUtils::IsBidirectionalStreamId(id))) {
+ quic::QuicUtils::IsBidirectionalStreamId(id, connection()->version()))) {
LOG(WARNING) << "Received invalid push stream id " << id;
connection()->CloseConnection(
quic::QUIC_INVALID_STREAM_ID,
@@ -1537,36 +1566,26 @@ void QuicChromiumClientSession::OnConfigNegotiated() {
IPEndPoint old_address;
GetDefaultSocket()->GetPeerAddress(&old_address);
- // Migrate only if address families match, or if new address family is v6,
- // since a v4 address should be reachable over a v6 network (using a
- // v4-mapped v6 address).
+ // Migrate only if address families match.
IPEndPoint new_address;
if (old_address.GetFamily() == ADDRESS_FAMILY_IPV6) {
- if (config()->HasReceivedIPv6AlternateServerAddress()) {
+ if (!config()->HasReceivedIPv6AlternateServerAddress()) {
+ return;
+ }
new_address =
ToIPEndPoint(config()->ReceivedIPv6AlternateServerAddress());
- } else {
- new_address =
- ToIPEndPoint(config()->ReceivedIPv4AlternateServerAddress());
- // Use a v4-mapped v6 address.
- new_address =
- IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(new_address.address()),
- new_address.port());
- }
} else if (old_address.GetFamily() == ADDRESS_FAMILY_IPV4) {
- if (config()->HasReceivedIPv4AlternateServerAddress()) {
- new_address =
- ToIPEndPoint(config()->ReceivedIPv4AlternateServerAddress());
- } else {
+ if (!config()->HasReceivedIPv4AlternateServerAddress()) {
return;
}
+ new_address = ToIPEndPoint(config()->ReceivedIPv4AlternateServerAddress());
}
DCHECK_EQ(new_address.GetFamily(), old_address.GetFamily());
// Specifying kInvalidNetworkHandle for the |network| parameter
// causes the session to use the default network for the new socket.
Migrate(NetworkChangeNotifier::kInvalidNetworkHandle, new_address,
- /*close_session_on_error=*/true, net_log_);
+ /*close_session_on_error=*/true);
}
void QuicChromiumClientSession::SetDefaultEncryptionLevel(
@@ -1694,6 +1713,10 @@ void QuicChromiumClientSession::OnConnectionClosed(
UMA_HISTOGRAM_COUNTS_1000(
"Net.QuicSession.ClosedByRtoAtClient.SentPacketCount",
connection()->GetStats().packets_sent);
+ UMA_HISTOGRAM_COUNTS_100(
+ "Net.QuicSession."
+ "MaxConsecutiveRtoWithForwardProgressAndBlackholeDetected",
+ connection()->GetStats().max_consecutive_rto_with_forward_progress);
}
}
@@ -1740,6 +1763,9 @@ void QuicChromiumClientSession::OnConnectionClosed(
UMA_HISTOGRAM_COUNTS_100(
"Net.QuicSession.CryptoRetransmitCount.HandshakeConfirmed",
connection()->GetStats().crypto_retransmit_count);
+ UMA_HISTOGRAM_COUNTS_100(
+ "Net.QuicSession.MaxConsecutiveRtoWithForwardProgress",
+ connection()->GetStats().max_consecutive_rto_with_forward_progress);
} else {
if (error == quic::QUIC_PUBLIC_RESET) {
RecordHandshakeFailureReason(HANDSHAKE_FAILURE_PUBLIC_RESET);
@@ -1812,8 +1838,7 @@ int QuicChromiumClientSession::HandleWriteError(
return error_code;
}
- NetworkChangeNotifier::NetworkHandle current_network =
- GetDefaultSocket()->GetBoundNetwork();
+ NetworkChangeNotifier::NetworkHandle current_network = GetCurrentNetwork();
net_log_.AddEventWithInt64Params(
NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_WRITE_ERROR, "network",
@@ -1867,8 +1892,7 @@ void QuicChromiumClientSession::MigrateSessionOnWriteError(
if (migrate_idle_session_ && CheckIdleTimeExceedsIdleMigrationPeriod())
return;
- if (!migrate_idle_session_ && GetNumActiveStreams() == 0 &&
- GetNumDrainingStreams() == 0) {
+ if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
// connection close packet to be sent since socket may be borked.
connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
"Write error for non-migratable session",
@@ -1878,9 +1902,9 @@ void QuicChromiumClientSession::MigrateSessionOnWriteError(
// Do not migrate if connection migration is disabled.
if (config()->DisableConnectionMigration()) {
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_DISABLED_BY_CONFIG, connection_id(),
- "Migration disabled by config");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
+ connection_id(),
+ "Migration disabled by config");
// Close the connection since migration was disabled. Do not cause a
// connection close packet to be sent since socket may be borked.
connection()->CloseConnection(quic::QUIC_PACKET_WRITE_ERROR,
@@ -1890,22 +1914,21 @@ void QuicChromiumClientSession::MigrateSessionOnWriteError(
}
NetworkChangeNotifier::NetworkHandle new_network =
- stream_factory_->FindAlternateNetwork(
- GetDefaultSocket()->GetBoundNetwork());
+ stream_factory_->FindAlternateNetwork(GetCurrentNetwork());
if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) {
// No alternate network found.
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_NO_ALTERNATE_NETWORK, connection_id(),
- "No alternate network found");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
+ connection_id(),
+ "No alternate network found");
OnNoNewNetwork();
return;
}
- if (GetDefaultSocket()->GetBoundNetwork() == default_network_ &&
+ if (GetCurrentNetwork() == default_network_ &&
current_migrations_to_non_default_network_on_write_error_ >=
max_migrations_to_non_default_network_on_write_error_) {
HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_ON_WRITE_ERROR_DISABLED, connection_id(),
+ MIGRATION_STATUS_ON_WRITE_ERROR_DISABLED, connection_id(),
"Exceeds maximum number of migrations on write error");
connection()->CloseConnection(
quic::QUIC_PACKET_WRITE_ERROR,
@@ -1915,16 +1938,13 @@ void QuicChromiumClientSession::MigrateSessionOnWriteError(
}
current_migrations_to_non_default_network_on_write_error_++;
- const NetLogWithSource migration_net_log = NetLogWithSource::Make(
- net_log_.net_log(), NetLogSourceType::QUIC_CONNECTION_MIGRATION);
- migration_net_log.BeginEventWithStringParams(
+ net_log_.BeginEventWithStringParams(
NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
"WriteError");
MigrationResult result =
Migrate(new_network, ToIPEndPoint(connection()->peer_address()),
- /*close_session_on_error=*/false, migration_net_log);
- migration_net_log.EndEvent(
- NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
+ /*close_session_on_error=*/false);
+ net_log_.EndEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
if (result == MigrationResult::FAILURE) {
// Close the connection if migration failed. Do not cause a
@@ -2019,8 +2039,7 @@ void QuicChromiumClientSession::OnProbeSucceeded(
// Close streams that are not migratable to the probed |network|.
ResetNonMigratableStreams();
- if (!migrate_idle_session_ && GetNumActiveStreams() == 0 &&
- GetNumDrainingStreams() == 0) {
+ if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
// If idle sessions won't be migrated, close the connection.
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
@@ -2041,10 +2060,14 @@ void QuicChromiumClientSession::OnProbeSucceeded(
return;
}
+ // Notify the connection that migration succeeds after probing.
+ if (connection()->IsPathDegrading())
+ connection()->OnSuccessfulMigrationAfterProbing();
+
net_log_.AddEventWithInt64Params(
NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING,
"migrate_to_network", network);
- HistogramAndLogMigrationSuccess(net_log_, connection_id());
+ HistogramAndLogMigrationSuccess(connection_id());
if (network == default_network_) {
DVLOG(1) << "Client successfully migrated to default network: "
<< default_network_;
@@ -2080,7 +2103,7 @@ void QuicChromiumClientSession::OnProbeFailed(
DVLOG(1) << "Connectivity probing failed on <network: " << network
<< ", peer_address: " << peer_address.ToString() << ">.";
DVLOG_IF(1, network == default_network_ &&
- GetDefaultSocket()->GetBoundNetwork() != default_network_)
+ GetCurrentNetwork() != default_network_)
<< "Client probing failed on the default network, still using "
"non-default network.";
}
@@ -2093,9 +2116,17 @@ bool QuicChromiumClientSession::OnSendConnectivityProbingPacket(
}
void QuicChromiumClientSession::OnNetworkConnected(
- NetworkChangeNotifier::NetworkHandle network,
- const NetLogWithSource& net_log) {
- DCHECK(migrate_session_on_network_change_v2_);
+ NetworkChangeNotifier::NetworkHandle network) {
+ if (connection()->IsPathDegrading()) {
+ base::TimeDelta duration =
+ tick_clock_->NowTicks() - most_recent_path_degrading_timestamp_;
+ UMA_HISTOGRAM_CUSTOM_TIMES("Net.QuicNetworkDegradingDurationTillConnected",
+ duration, base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMinutes(10), 50);
+ }
+ if (!migrate_session_on_network_change_v2_)
+ return;
+
net_log_.AddEventWithInt64Params(
NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_CONNECTED,
"connected_network", network);
@@ -2104,15 +2135,8 @@ void QuicChromiumClientSession::OnNetworkConnected(
if (!wait_for_new_network_ && !connection()->IsPathDegrading())
return;
- if (connection()->IsPathDegrading()) {
- base::TimeDelta duration =
- tick_clock_->NowTicks() - most_recent_path_degrading_timestamp_;
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.QuicNetworkDegradingDurationTillConnected",
- duration, base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(10), 50);
-
+ if (connection()->IsPathDegrading())
current_migration_cause_ = NEW_NETWORK_CONNECTED_POST_PATH_DEGRADING;
- }
if (wait_for_new_network_) {
wait_for_new_network_ = false;
@@ -2124,18 +2148,18 @@ void QuicChromiumClientSession::OnNetworkConnected(
} else {
// The connection is path degrading.
DCHECK(connection()->IsPathDegrading());
- OnPathDegrading();
+ MaybeMigrateToAlternateNetworkOnPathDegrading();
}
}
void QuicChromiumClientSession::OnNetworkDisconnectedV2(
- NetworkChangeNotifier::NetworkHandle disconnected_network,
- const NetLogWithSource& migration_net_log) {
- DCHECK(migrate_session_on_network_change_v2_);
+ NetworkChangeNotifier::NetworkHandle disconnected_network) {
+ LogMetricsOnNetworkDisconnected();
+ if (!migrate_session_on_network_change_v2_)
+ return;
net_log_.AddEventWithInt64Params(
NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_DISCONNECTED,
"disconnected_network", disconnected_network);
- LogMetricsOnNetworkDisconnected();
// Stop probing the disconnected network if there is one.
probing_manager_.CancelProbing(disconnected_network, peer_address());
@@ -2146,7 +2170,7 @@ void QuicChromiumClientSession::OnNetworkDisconnectedV2(
}
// Ignore the signal if the current active network is not affected.
- if (GetDefaultSocket()->GetBoundNetwork() != disconnected_network) {
+ if (GetCurrentNetwork() != disconnected_network) {
DVLOG(1) << "Client's current default network is not affected by the "
<< "disconnected one.";
return;
@@ -2179,29 +2203,31 @@ void QuicChromiumClientSession::OnNetworkDisconnectedV2(
}
void QuicChromiumClientSession::OnNetworkMadeDefault(
- NetworkChangeNotifier::NetworkHandle new_network,
- const NetLogWithSource& migration_net_log) {
- DCHECK(migrate_session_on_network_change_v2_);
+ NetworkChangeNotifier::NetworkHandle new_network) {
+ LogMetricsOnNetworkMadeDefault();
+
+ if (!migrate_session_on_network_change_v2_)
+ return;
+
+ DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, new_network);
net_log_.AddEventWithInt64Params(
NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_MADE_DEFAULT,
"new_default_network", new_network);
- LogMetricsOnNetworkMadeDefault();
+ default_network_ = new_network;
- DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, new_network);
DVLOG(1) << "Network: " << new_network
<< " becomes default, old default: " << default_network_;
- default_network_ = new_network;
current_migration_cause_ = ON_NETWORK_MADE_DEFAULT;
current_migrations_to_non_default_network_on_write_error_ = 0;
current_migrations_to_non_default_network_on_path_degrading_ = 0;
// Simply cancel the timer to migrate back to the default network if session
// is already on the default network.
- if (GetDefaultSocket()->GetBoundNetwork() == new_network) {
+ if (GetCurrentNetwork() == new_network) {
CancelMigrateBackToDefaultNetworkTimer();
- HistogramAndLogMigrationFailure(
- migration_net_log, MIGRATION_STATUS_ALREADY_MIGRATED, connection_id(),
- "Already migrated on the new network");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_ALREADY_MIGRATED,
+ connection_id(),
+ "Already migrated on the new network");
return;
}
@@ -2221,10 +2247,8 @@ void QuicChromiumClientSession::MigrateNetworkImmediately(
// - otherwise, it's brought to default network, cancel the running timer to
// migrate back.
- if (!migrate_idle_session_ && GetNumActiveStreams() == 0 &&
- GetNumDrainingStreams() == 0) {
- HistogramAndLogMigrationFailure(net_log_,
- MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
+ if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
connection_id(), "No active streams");
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
@@ -2238,17 +2262,17 @@ void QuicChromiumClientSession::MigrateNetworkImmediately(
// Do not migrate if connection migration is disabled.
if (config()->DisableConnectionMigration()) {
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_DISABLED_BY_CONFIG, connection_id(),
- "Migration disabled by config");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
+ connection_id(),
+ "Migration disabled by config");
CloseSessionOnErrorLater(ERR_NETWORK_CHANGED,
quic::QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG,
quic::ConnectionCloseBehavior::SILENT_CLOSE);
return;
}
- if (network == GetDefaultSocket()->GetBoundNetwork()) {
- HistogramAndLogMigrationFailure(net_log_, MIGRATION_STATUS_ALREADY_MIGRATED,
+ if (network == GetCurrentNetwork()) {
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_ALREADY_MIGRATED,
connection_id(),
"Already bound to new network");
return;
@@ -2259,7 +2283,7 @@ void QuicChromiumClientSession::MigrateNetworkImmediately(
MigrationResult result =
Migrate(network, ToIPEndPoint(connection()->peer_address()),
- /*close_session_on_error=*/true, net_log_);
+ /*close_session_on_error=*/true);
if (result == MigrationResult::FAILURE)
return;
@@ -2308,6 +2332,9 @@ void QuicChromiumClientSession::OnWriteUnblocked() {
}
void QuicChromiumClientSession::OnPathDegrading() {
+ if (most_recent_path_degrading_timestamp_ == base::TimeTicks())
+ most_recent_path_degrading_timestamp_ = tick_clock_->NowTicks();
+
if (go_away_on_path_degrading_ && OneRttKeysAvailable()) {
net_log_.AddEvent(
NetLogEventType::QUIC_SESSION_CLIENT_GOAWAY_ON_PATH_DEGRADING);
@@ -2317,14 +2344,15 @@ void QuicChromiumClientSession::OnPathDegrading() {
GetNumActiveStreams());
UMA_HISTOGRAM_COUNTS_1M(
"Net.QuicSession.DrainingStreamsOnGoAwayAfterPathDegrading",
- GetNumDrainingStreams());
+ num_outgoing_draining_streams());
return;
}
- net_log_.AddEvent(
- NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_PATH_DEGRADING);
- if (most_recent_path_degrading_timestamp_ == base::TimeTicks())
- most_recent_path_degrading_timestamp_ = tick_clock_->NowTicks();
+ if (!go_away_on_path_degrading_) {
+ NetworkChangeNotifier::NetworkHandle current_network = GetCurrentNetwork();
+ for (auto& observer : connectivity_observer_list_)
+ observer.OnSessionPathDegrading(this, current_network);
+ }
if (!stream_factory_)
return;
@@ -2335,21 +2363,16 @@ void QuicChromiumClientSession::OnPathDegrading() {
return;
}
- current_migration_cause_ = CHANGE_NETWORK_ON_PATH_DEGRADING;
+ MaybeMigrateToAlternateNetworkOnPathDegrading();
+}
- if (migrate_session_early_v2_) {
- MaybeMigrateToAlternateNetworkOnPathDegrading();
+void QuicChromiumClientSession::OnForwardProgressMadeAfterPathDegrading() {
+ if (go_away_on_path_degrading_)
return;
- }
-
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED, connection_id(),
- "Migration on path degrading not enabled");
-}
-bool QuicChromiumClientSession::ShouldKeepConnectionAlive() const {
- return quic::QuicSpdySession::ShouldKeepConnectionAlive() ||
- GetNumDrainingOutgoingStreams() > 0;
+ NetworkChangeNotifier::NetworkHandle current_network = GetCurrentNetwork();
+ for (auto& observer : connectivity_observer_list_)
+ observer.OnSessionResumedPostPathDegrading(this, current_network);
}
void QuicChromiumClientSession::OnProofValid(
@@ -2488,43 +2511,50 @@ void QuicChromiumClientSession::MaybeMigrateToDifferentPortOnPathDegrading() {
// Migration before handshake is not allowed.
if (!OneRttKeysAvailable()) {
HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
+ MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
connection_id(), "Path degrading before handshake confirmed");
return;
}
- const NetLogWithSource migration_net_log = NetLogWithSource::Make(
- net_log_.net_log(), NetLogSourceType::QUIC_PORT_MIGRATION);
- migration_net_log.BeginEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
+ net_log_.BeginEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
if (!stream_factory_)
return;
// Probe a different port, session will migrate to the probed port on success.
- StartProbing(default_network_, peer_address(), migration_net_log);
- migration_net_log.EndEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
+ StartProbing(default_network_, peer_address());
+ net_log_.EndEvent(NetLogEventType::QUIC_PORT_MIGRATION_TRIGGERED);
}
void QuicChromiumClientSession::
MaybeMigrateToAlternateNetworkOnPathDegrading() {
- DCHECK(migrate_session_early_v2_);
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_PATH_DEGRADING);
+
+ current_migration_cause_ = CHANGE_NETWORK_ON_PATH_DEGRADING;
- if (GetDefaultSocket()->GetBoundNetwork() == default_network_ &&
+ if (!migrate_session_early_v2_) {
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED,
+ connection_id(),
+ "Migration on path degrading not enabled");
+ return;
+ }
+
+ if (GetCurrentNetwork() == default_network_ &&
current_migrations_to_non_default_network_on_path_degrading_ >=
max_migrations_to_non_default_network_on_path_degrading_) {
HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED, connection_id(),
+ MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED, connection_id(),
"Exceeds maximum number of migrations on path degrading");
return;
}
NetworkChangeNotifier::NetworkHandle alternate_network =
- stream_factory_->FindAlternateNetwork(
- GetDefaultSocket()->GetBoundNetwork());
+ stream_factory_->FindAlternateNetwork(GetCurrentNetwork());
if (alternate_network == NetworkChangeNotifier::kInvalidNetworkHandle) {
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_NO_ALTERNATE_NETWORK, connection_id(),
- "No alternative network on path degrading");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
+ connection_id(),
+ "No alternative network on path degrading");
return;
}
@@ -2532,37 +2562,31 @@ void QuicChromiumClientSession::
if (!OneRttKeysAvailable()) {
HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
+ MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
connection_id(), "Path degrading before handshake confirmed");
return;
}
- const NetLogWithSource migration_net_log = NetLogWithSource::Make(
- net_log_.net_log(), NetLogSourceType::QUIC_CONNECTION_MIGRATION);
- migration_net_log.BeginEventWithStringParams(
+ net_log_.BeginEventWithStringParams(
NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
"PathDegrading");
// Probe the alternative network, session will migrate to the probed
// network and decide whether it wants to migrate back to the default
// network on success.
- MaybeStartProbing(alternate_network, peer_address(), migration_net_log);
- migration_net_log.EndEvent(
- NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
+ MaybeStartProbing(alternate_network, peer_address());
+ net_log_.EndEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
}
ProbingResult QuicChromiumClientSession::MaybeStartProbing(
NetworkChangeNotifier::NetworkHandle network,
- const quic::QuicSocketAddress& peer_address,
- const NetLogWithSource& migration_net_log) {
+ const quic::QuicSocketAddress& peer_address) {
if (!stream_factory_)
return ProbingResult::FAILURE;
CHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network);
- if (!migrate_idle_session_ && GetNumActiveStreams() == 0 &&
- GetNumDrainingStreams() == 0) {
- HistogramAndLogMigrationFailure(migration_net_log,
- MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
+ if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
connection_id(), "No active streams");
CloseSessionOnErrorLater(
ERR_NETWORK_CHANGED,
@@ -2578,19 +2602,18 @@ ProbingResult QuicChromiumClientSession::MaybeStartProbing(
if (config()->DisableConnectionMigration()) {
DVLOG(1) << "Client disables probing network with connection migration "
<< "disabled by config";
- HistogramAndLogMigrationFailure(
- migration_net_log, MIGRATION_STATUS_DISABLED_BY_CONFIG, connection_id(),
- "Migration disabled by config");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_DISABLED_BY_CONFIG,
+ connection_id(),
+ "Migration disabled by config");
return ProbingResult::DISABLED_BY_CONFIG;
}
- return StartProbing(network, peer_address, migration_net_log);
+ return StartProbing(network, peer_address);
}
ProbingResult QuicChromiumClientSession::StartProbing(
NetworkChangeNotifier::NetworkHandle network,
- const quic::QuicSocketAddress& peer_address,
- const NetLogWithSource& migration_net_log) {
+ const quic::QuicSocketAddress& peer_address) {
// Check if probing manager is probing the same path.
if (probing_manager_.IsUnderProbing(network, peer_address))
return ProbingResult::PENDING;
@@ -2601,9 +2624,9 @@ ProbingResult QuicChromiumClientSession::StartProbing(
if (stream_factory_->ConfigureSocket(probing_socket.get(),
ToIPEndPoint(peer_address), network,
session_key_.socket_tag()) != OK) {
- HistogramAndLogMigrationFailure(
- migration_net_log, MIGRATION_STATUS_INTERNAL_ERROR, connection_id(),
- "Socket configuration failed");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_INTERNAL_ERROR,
+ connection_id(),
+ "Socket configuration failed");
return ProbingResult::INTERNAL_ERROR;
}
@@ -2664,8 +2687,7 @@ void QuicChromiumClientSession::TryMigrateBackToDefaultNetwork(
// the same network, this will be a no-op. Otherwise, previous probe
// will be cancelled and manager starts to probe |default_network_|
// immediately.
- ProbingResult result =
- MaybeStartProbing(default_network_, peer_address(), net_log_);
+ ProbingResult result = MaybeStartProbing(default_network_, peer_address());
if (result == ProbingResult::DISABLED_WITH_IDLE_SESSION)
return;
@@ -2689,7 +2711,7 @@ void QuicChromiumClientSession::TryMigrateBackToDefaultNetwork(
void QuicChromiumClientSession::MaybeRetryMigrateBackToDefaultNetwork() {
base::TimeDelta retry_migrate_back_timeout =
base::TimeDelta::FromSeconds(UINT64_C(1) << retry_migrate_back_count_);
- if (default_network_ == GetDefaultSocket()->GetBoundNetwork()) {
+ if (default_network_ == GetCurrentNetwork()) {
// If session has been back on the default already by other direct
// migration attempt, cancel migrate back now.
CancelMigrateBackToDefaultNetworkTimer();
@@ -2707,7 +2729,7 @@ bool QuicChromiumClientSession::CheckIdleTimeExceedsIdleMigrationPeriod() {
if (!migrate_idle_session_)
return false;
- if (GetNumActiveStreams() != 0 || GetNumDrainingStreams() != 0) {
+ if (HasActiveRequestStreams()) {
return false;
}
@@ -2718,9 +2740,9 @@ bool QuicChromiumClientSession::CheckIdleTimeExceedsIdleMigrationPeriod() {
return false;
}
- HistogramAndLogMigrationFailure(
- net_log_, MIGRATION_STATUS_IDLE_MIGRATION_TIMEOUT, connection_id(),
- "Ilde migration period exceeded");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_IDLE_MIGRATION_TIMEOUT,
+ connection_id(),
+ "Ilde migration period exceeded");
CloseSessionOnErrorLater(ERR_NETWORK_CHANGED, quic::QUIC_NETWORK_IDLE_TIMEOUT,
quic::ConnectionCloseBehavior::SILENT_CLOSE);
return true;
@@ -2840,7 +2862,6 @@ void QuicChromiumClientSession::LogHandshakeStatusOnMigrationSignal() const {
}
void QuicChromiumClientSession::HistogramAndLogMigrationFailure(
- const NetLogWithSource& net_log,
QuicConnectionMigrationStatus status,
quic::QuicConnectionId connection_id,
const char* reason) {
@@ -2849,7 +2870,7 @@ void QuicChromiumClientSession::HistogramAndLogMigrationFailure(
? NetLogEventType::QUIC_PORT_MIGRATION_FAILURE
: NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE;
- net_log.AddEvent(event_type, [&] {
+ net_log_.AddEvent(event_type, [&] {
return NetLogQuicMigrationFailureParams(connection_id, reason);
});
@@ -2858,14 +2879,13 @@ void QuicChromiumClientSession::HistogramAndLogMigrationFailure(
}
void QuicChromiumClientSession::HistogramAndLogMigrationSuccess(
- const NetLogWithSource& net_log,
quic::QuicConnectionId connection_id) {
NetLogEventType event_type =
current_migration_cause_ == CHANGE_PORT_ON_PATH_DEGRADING
? NetLogEventType::QUIC_PORT_MIGRATION_SUCCESS
: NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS;
- net_log.AddEvent(event_type, [&] {
+ net_log_.AddEvent(event_type, [&] {
return NetLogQuicMigrationSuccessParams(connection_id);
});
@@ -3030,7 +3050,7 @@ void QuicChromiumClientSession::OnCryptoHandshakeComplete() {
// confirmed if the session is not created on the default network.
if (migrate_session_on_network_change_v2_ &&
default_network_ != NetworkChangeNotifier::kInvalidNetworkHandle &&
- GetDefaultSocket()->GetBoundNetwork() != default_network_) {
+ GetCurrentNetwork() != default_network_) {
current_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
StartMigrateBackToDefaultNetworkTimer(
base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs));
@@ -3040,16 +3060,14 @@ void QuicChromiumClientSession::OnCryptoHandshakeComplete() {
MigrationResult QuicChromiumClientSession::Migrate(
NetworkChangeNotifier::NetworkHandle network,
IPEndPoint peer_address,
- bool close_session_on_error,
- const NetLogWithSource& migration_net_log) {
+ bool close_session_on_error) {
if (!stream_factory_)
return MigrationResult::FAILURE;
if (network != NetworkChangeNotifier::kInvalidNetworkHandle) {
// This is a migration attempt from connection migration.
ResetNonMigratableStreams();
- if (!migrate_idle_session_ && GetNumActiveStreams() == 0 &&
- GetNumDrainingStreams() == 0) {
+ if (!migrate_idle_session_ && !HasActiveRequestStreams()) {
// If idle sessions can not be migrated, close the session if needed.
if (close_session_on_error) {
CloseSessionOnErrorLater(
@@ -3066,9 +3084,9 @@ MigrationResult QuicChromiumClientSession::Migrate(
stream_factory_->CreateSocket(net_log_.net_log(), net_log_.source()));
if (stream_factory_->ConfigureSocket(socket.get(), peer_address, network,
session_key_.socket_tag()) != OK) {
- HistogramAndLogMigrationFailure(
- migration_net_log, MIGRATION_STATUS_INTERNAL_ERROR, connection_id(),
- "Socket configuration failed");
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_INTERNAL_ERROR,
+ connection_id(),
+ "Socket configuration failed");
if (close_session_on_error) {
if (migrate_session_on_network_change_v2_) {
CloseSessionOnErrorLater(ERR_NETWORK_CHANGED,
@@ -3099,8 +3117,7 @@ MigrationResult QuicChromiumClientSession::Migrate(
// Migrate to the new socket.
if (!MigrateToSocket(std::move(socket), std::move(new_reader),
std::move(new_writer))) {
- HistogramAndLogMigrationFailure(migration_net_log,
- MIGRATION_STATUS_TOO_MANY_CHANGES,
+ HistogramAndLogMigrationFailure(MIGRATION_STATUS_TOO_MANY_CHANGES,
connection_id(), "Too many changes");
if (close_session_on_error) {
if (migrate_session_on_network_change_v2_) {
@@ -3116,7 +3133,7 @@ MigrationResult QuicChromiumClientSession::Migrate(
}
return MigrationResult::FAILURE;
}
- HistogramAndLogMigrationSuccess(migration_net_log, connection_id());
+ HistogramAndLogMigrationSuccess(connection_id());
return MigrationResult::SUCCESS;
}
@@ -3165,6 +3182,16 @@ const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket()
return sockets_.back().get();
}
+NetworkChangeNotifier::NetworkHandle
+QuicChromiumClientSession::GetCurrentNetwork() const {
+ // If connection migration is enabled, alternate network interface may be
+ // used to send packet, it is identified as the bound network of the default
+ // socket. Otherwise, always use |default_network_|.
+ return migrate_session_on_network_change_v2_
+ ? GetDefaultSocket()->GetBoundNetwork()
+ : default_network_;
+}
+
bool QuicChromiumClientSession::IsAuthorized(const std::string& hostname) {
bool result = CanPool(
hostname, session_key_.privacy_mode(), session_key_.socket_tag(),
@@ -3268,4 +3295,17 @@ size_t QuicChromiumClientSession::EstimateMemoryUsage() const {
return base::trace_event::EstimateMemoryUsage(packet_readers_);
}
+bool QuicChromiumClientSession::ValidateStatelessReset(
+ const quic::QuicSocketAddress& self_address,
+ const quic::QuicSocketAddress& peer_address) {
+ if (probing_manager_.ValidateStatelessReset(self_address, peer_address)) {
+ // The stateless reset is received from probing path. We shouldn't close the
+ // connection, but should disable further port migration attempt.
+ if (allow_port_migration_)
+ allow_port_migration_ = false;
+ return false;
+ }
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/quic/quic_chromium_client_session.h b/chromium/net/quic/quic_chromium_client_session.h
index 34ea4fda6eb..3b1c2fda0ac 100644
--- a/chromium/net/quic/quic_chromium_client_session.h
+++ b/chromium/net/quic/quic_chromium_client_session.h
@@ -20,6 +20,7 @@
#include "base/containers/mru_cache.h"
#include "base/macros.h"
+#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/completion_once_callback.h"
@@ -139,6 +140,25 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
public:
class StreamRequest;
+ // An interface that when implemented and added via
+ // AddConnectivityObserver(), provides notifications when connectivity
+ // quality changes.
+ class NET_EXPORT_PRIVATE ConnectivityObserver : public base::CheckedObserver {
+ public:
+ // Called when path degrading is detected on |network|.
+ virtual void OnSessionPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) = 0;
+
+ // Called when forward progress is made after path degrading on |network|.
+ virtual void OnSessionResumedPostPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) = 0;
+
+ // Called when |session| is removed.
+ virtual void OnSessionRemoved(QuicChromiumClientSession* session) = 0;
+ };
+
// Wrapper for interacting with the session in a restricted fashion which
// hides the details of the underlying session's lifetime. All methods of
// the Handle are safe to use even after the underlying session is destroyed.
@@ -422,6 +442,9 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void AddHandle(Handle* handle);
void RemoveHandle(Handle* handle);
+ void AddConnectivityObserver(ConnectivityObserver* observer);
+ void RemoveConnectivityObserver(ConnectivityObserver* observer);
+
// Returns the session's connection migration mode.
ConnectionMigrationMode connection_migration_mode() const;
@@ -503,6 +526,9 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void OnGoAway(const quic::QuicGoAwayFrame& frame) override;
void OnRstStream(const quic::QuicRstStreamFrame& frame) override;
void OnCanCreateNewOutgoingStream(bool unidirectional) override;
+ bool ValidateStatelessReset(
+ const quic::QuicSocketAddress& self_address,
+ const quic::QuicSocketAddress& peer_address) override;
// QuicClientSessionBase methods:
void OnConfigNegotiated() override;
@@ -520,7 +546,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
const quic::QuicSocketAddress& peer_address,
bool is_connectivity_probe) override;
void OnPathDegrading() override;
- bool ShouldKeepConnectionAlive() const override;
+ void OnForwardProgressMadeAfterPathDegrading() override;
// QuicChromiumPacketReader::Visitor methods:
void OnReadError(int result, const DatagramClientSocket* socket) override;
@@ -599,8 +625,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// closed.
MigrationResult Migrate(NetworkChangeNotifier::NetworkHandle network,
IPEndPoint peer_address,
- bool close_session_on_error,
- const NetLogWithSource& migration_net_log);
+ bool close_session_on_error);
// Migrates session onto new socket, i.e., sets |writer| to be the new
// default writer and post a task to write to |socket|. |reader| *must*
@@ -617,19 +642,16 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Called when NetworkChangeNotifier notifies observers of a newly
// connected network. Migrates this session to the newly connected
// network if the session has a pending migration.
- void OnNetworkConnected(NetworkChangeNotifier::NetworkHandle network,
- const NetLogWithSource& net_log);
+ void OnNetworkConnected(NetworkChangeNotifier::NetworkHandle network);
// Called when NetworkChangeNotifier broadcasts to observers of
// |disconnected_network|.
void OnNetworkDisconnectedV2(
- NetworkChangeNotifier::NetworkHandle disconnected_network,
- const NetLogWithSource& migration_net_log);
+ NetworkChangeNotifier::NetworkHandle disconnected_network);
// Called when NetworkChangeNotifier broadcats to observers of a new default
// network. Migrates this session to |new_network| if appropriate.
- void OnNetworkMadeDefault(NetworkChangeNotifier::NetworkHandle new_network,
- const NetLogWithSource& migration_net_log);
+ void OnNetworkMadeDefault(NetworkChangeNotifier::NetworkHandle new_network);
// Schedules a migration alarm to wait for a new network.
void OnNoNewNetwork();
@@ -646,6 +668,11 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// returned socket.
const DatagramClientSocket* GetDefaultSocket() const;
+ // Returns the network interface that is currently used to send packets.
+ // If NetworkHandle is not supported, always return
+ // NetworkChangeNotifier::kInvalidNetworkHandle.
+ NetworkChangeNotifier::NetworkHandle GetCurrentNetwork() const;
+
bool IsAuthorized(const std::string& hostname) override;
bool HandlePromised(quic::QuicStreamId associated_id,
@@ -710,17 +737,17 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// If <network, peer_addres> is identical to the current path, the probe
// is sent on a different port.
ProbingResult StartProbing(NetworkChangeNotifier::NetworkHandle network,
- const quic::QuicSocketAddress& peer_address,
- const NetLogWithSource& migration_net_log);
+ const quic::QuicSocketAddress& peer_address);
// Perform a few checks before StartProbing. If any of those checks fails,
// StartProbing will be skipped.
ProbingResult MaybeStartProbing(NetworkChangeNotifier::NetworkHandle network,
- const quic::QuicSocketAddress& peer_address,
- const NetLogWithSource& migration_net_log);
+ const quic::QuicSocketAddress& peer_address);
// Helper method to perform a few checks and initiate connection migration
// attempt when path degrading is detected.
+ // Called when path is degrading and there is an alternate network or a new
+ // network is connected after path degrading.
void MaybeMigrateToAlternateNetworkOnPathDegrading();
// Helper method to initiate a port migration on path degrading is detected.
@@ -754,12 +781,10 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void LogMetricsOnNetworkMadeDefault();
void LogMigrationResultToHistogram(QuicConnectionMigrationStatus status);
void LogHandshakeStatusOnMigrationSignal() const;
- void HistogramAndLogMigrationFailure(const NetLogWithSource& net_log,
- QuicConnectionMigrationStatus status,
+ void HistogramAndLogMigrationFailure(QuicConnectionMigrationStatus status,
quic::QuicConnectionId connection_id,
const char* reason);
- void HistogramAndLogMigrationSuccess(const NetLogWithSource& net_log,
- quic::QuicConnectionId connection_id);
+ void HistogramAndLogMigrationSuccess(quic::QuicConnectionId connection_id);
// Notifies the factory that this session is going away and no more streams
// should be created from it. This needs to be called before closing any
@@ -810,6 +835,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
std::unique_ptr<quic::QuicCryptoClientStream> crypto_stream_;
QuicStreamFactory* stream_factory_;
+ base::ObserverList<ConnectivityObserver> connectivity_observer_list_;
std::vector<std::unique_ptr<DatagramClientSocket>> sockets_;
TransportSecurityState* transport_security_state_;
SSLConfigService* ssl_config_service_;
@@ -847,7 +873,8 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// written to an alternate socket when the migration completes and the
// alternate socket is unblocked.
scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> packet_;
- // Stores the latest default network platform marks.
+ // Stores the latest default network platform marks if migration is enabled.
+ // Otherwise, stores the network interface that is used by the connection.
NetworkChangeNotifier::NetworkHandle default_network_;
QuicConnectivityProbingManager probing_manager_;
int retry_migrate_back_count_;
diff --git a/chromium/net/quic/quic_chromium_client_session_peer.cc b/chromium/net/quic/quic_chromium_client_session_peer.cc
index 2c460a8c34f..8d4747f8ac5 100644
--- a/chromium/net/quic/quic_chromium_client_session_peer.cc
+++ b/chromium/net/quic/quic_chromium_client_session_peer.cc
@@ -48,5 +48,10 @@ bool QuicChromiumClientSessionPeer::GetSessionGoingAway(
return session->going_away_;
}
+bool QuicChromiumClientSessionPeer::DoesSessionAllowPortMigration(
+ QuicChromiumClientSession* session) {
+ return session->allow_port_migration_;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_chromium_client_session_peer.h b/chromium/net/quic/quic_chromium_client_session_peer.h
index 8b057727eb4..4832017dc31 100644
--- a/chromium/net/quic/quic_chromium_client_session_peer.h
+++ b/chromium/net/quic/quic_chromium_client_session_peer.h
@@ -34,6 +34,8 @@ class QuicChromiumClientSessionPeer {
static bool GetSessionGoingAway(QuicChromiumClientSession* session);
+ static bool DoesSessionAllowPortMigration(QuicChromiumClientSession* session);
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientSessionPeer);
};
diff --git a/chromium/net/quic/quic_chromium_client_session_test.cc b/chromium/net/quic/quic_chromium_client_session_test.cc
index 404d815f3af..075e6111ac9 100644
--- a/chromium/net/quic/quic_chromium_client_session_test.cc
+++ b/chromium/net/quic/quic_chromium_client_session_test.cc
@@ -31,6 +31,7 @@
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
+#include "net/quic/quic_connectivity_monitor.h"
#include "net/quic/quic_crypto_client_config_handle.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/quic_http_utils.h"
@@ -77,6 +78,9 @@ const char kServerHostname[] = "test.example.com";
const uint16_t kServerPort = 443;
const size_t kMaxReadersPerQuicSession = 5;
+const NetworkChangeNotifier::NetworkHandle kDefaultNetworkForTests = 1;
+const NetworkChangeNotifier::NetworkHandle kNewNetworkForTests = 2;
+
struct TestParams {
quic::ParsedQuicVersion version;
bool client_headers_include_h2_stream_dependency;
@@ -128,6 +132,7 @@ class QuicChromiumClientSessionTest
base::span<MockWrite>())),
random_(0),
helper_(&clock_, &random_),
+ transport_security_state_(std::make_unique<TransportSecurityState>()),
session_key_(kServerHostname,
kServerPort,
PRIVACY_MODE_DISABLED,
@@ -135,6 +140,7 @@ class QuicChromiumClientSessionTest
NetworkIsolationKey(),
false /* disable_secure_dns */),
destination_(kServerHostname, kServerPort),
+ default_network_(NetworkChangeNotifier::kInvalidNetworkHandle),
client_maker_(version_,
quic::QuicUtils::CreateRandomConnectionId(&random_),
&clock_,
@@ -180,12 +186,11 @@ class QuicChromiumClientSessionTest
session_.reset(new TestingQuicChromiumClientSession(
connection, std::move(socket),
/*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
- &transport_security_state_, /*ssl_config_service=*/nullptr,
+ transport_security_state_.get(), /*ssl_config_service=*/nullptr,
base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
/*require_confirmation=*/false,
/*max_allowed_push_id=*/0, migrate_session_early_v2_,
- /*migrate_session_on_network_change_v2=*/false,
- /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
+ /*migrate_session_on_network_change_v2=*/false, default_network_,
quic::QuicTime::Delta::FromMilliseconds(
kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
/*migrate_idle_session=*/false, /*allow_port_migration=*/false,
@@ -204,6 +209,10 @@ class QuicChromiumClientSessionTest
base::DefaultTickClock::GetInstance(),
base::ThreadTaskRunnerHandle::Get().get(),
/*socket_performance_watcher=*/nullptr, &net_log_));
+ if (connectivity_monitor_) {
+ connectivity_monitor_->SetInitialDefaultNetwork(default_network_);
+ session_->AddConnectivityObserver(connectivity_monitor_.get());
+ }
scoped_refptr<X509Certificate> cert(
ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
@@ -220,10 +229,13 @@ class QuicChromiumClientSessionTest
}
void TearDown() override {
- if (session_)
+ if (session_) {
+ if (connectivity_monitor_)
+ session_->RemoveConnectivityObserver(connectivity_monitor_.get());
session_->CloseSessionOnError(
ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ }
}
void CompleteCryptoHandshake() {
@@ -277,12 +289,14 @@ class QuicChromiumClientSessionTest
quic::test::MockRandom random_;
QuicChromiumConnectionHelper helper_;
quic::test::MockAlarmFactory alarm_factory_;
- TransportSecurityState transport_security_state_;
+ std::unique_ptr<TransportSecurityState> transport_security_state_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
quic::QuicClientPushPromiseIndex push_promise_index_;
QuicSessionKey session_key_;
HostPortPair destination_;
std::unique_ptr<TestingQuicChromiumClientSession> session_;
+ NetworkChangeNotifier::NetworkHandle default_network_;
+ std::unique_ptr<QuicConnectivityMonitor> connectivity_monitor_;
TestServerPushDelegate test_push_delegate_;
quic::QuicConnectionVisitorInterface* visitor_;
TestCompletionCallback callback_;
@@ -299,8 +313,88 @@ INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
::testing::ValuesIn(GetTestParams()),
::testing::PrintToStringParamName());
-// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
-// kAppendInitiatingFrameOriginToNetworkIsolationKey.
+// TODO(crbug.com/950069): Add testing for frame_origin in NetworkIsolationKey
+// using kAppendInitiatingFrameOriginToNetworkIsolationKey.
+
+// Basic test of ProofVerifyDetailsChromium is converted to SSLInfo retrieved
+// through QuicChromiumClientSession::GetSSLInfo(). Doesn't test some of the
+// more complicated fields.
+TEST_P(QuicChromiumClientSessionTest, GetSSLInfo1) {
+ MockQuicData quic_data(version_);
+ if (VersionUsesHttp3(version_.transport_version))
+ quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING);
+ quic_data.AddRead(ASYNC, OK); // EOF
+ quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ Initialize();
+
+ ProofVerifyDetailsChromium details;
+ details.is_fatal_cert_error = false;
+ details.cert_verify_result.verified_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ details.cert_verify_result.is_issued_by_known_root = true;
+ details.ct_verify_result.policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
+ details.ct_verify_result.policy_compliance_required = true;
+
+ CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
+
+ SSLInfo ssl_info;
+ ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(ssl_info.is_valid());
+
+ EXPECT_EQ(details.is_fatal_cert_error, ssl_info.is_fatal_cert_error);
+ EXPECT_TRUE(ssl_info.cert->EqualsIncludingChain(
+ details.cert_verify_result.verified_cert.get()));
+ EXPECT_EQ(details.cert_verify_result.cert_status, ssl_info.cert_status);
+ EXPECT_EQ(details.cert_verify_result.is_issued_by_known_root,
+ ssl_info.is_issued_by_known_root);
+ EXPECT_EQ(details.ct_verify_result.policy_compliance,
+ ssl_info.ct_policy_compliance);
+ EXPECT_EQ(details.ct_verify_result.policy_compliance_required,
+ ssl_info.ct_policy_compliance_required);
+}
+
+// Just like GetSSLInfo1, but uses different values.
+TEST_P(QuicChromiumClientSessionTest, GetSSLInfo2) {
+ MockQuicData quic_data(version_);
+ if (VersionUsesHttp3(version_.transport_version))
+ quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING);
+ quic_data.AddRead(ASYNC, OK); // EOF
+ quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ Initialize();
+
+ ProofVerifyDetailsChromium details;
+ details.is_fatal_cert_error = false;
+ details.cert_verify_result.verified_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ details.cert_verify_result.is_issued_by_known_root = false;
+ details.ct_verify_result.policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ details.ct_verify_result.policy_compliance_required = false;
+
+ CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
+
+ SSLInfo ssl_info;
+ ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(ssl_info.is_valid());
+
+ EXPECT_EQ(details.is_fatal_cert_error, ssl_info.is_fatal_cert_error);
+ EXPECT_TRUE(ssl_info.cert->EqualsIncludingChain(
+ details.cert_verify_result.verified_cert.get()));
+ EXPECT_EQ(details.cert_verify_result.cert_status, ssl_info.cert_status);
+ EXPECT_EQ(details.cert_verify_result.is_issued_by_known_root,
+ ssl_info.is_issued_by_known_root);
+ EXPECT_EQ(details.ct_verify_result.policy_compliance,
+ ssl_info.ct_policy_compliance);
+ EXPECT_EQ(details.ct_verify_result.policy_compliance_required,
+ ssl_info.ct_policy_compliance_required);
+}
TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
MockQuicData quic_data(version_);
@@ -872,7 +966,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
}
TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// TODO(nharper, b/112643533): Figure out why this test fails when TLS is
// enabled and fix it.
return;
@@ -1539,6 +1633,81 @@ TEST_P(QuicChromiumClientSessionTest, CanPool) {
}
}
+TEST_P(QuicChromiumClientSessionTest, CanPoolExpectCT) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey},
+ /* disabled_features */
+ {});
+
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
+ // Need to create a session key after setting
+ // kPartitionExpectCTStateByNetworkIsolationKey, otherwise, it will ignore the
+ // NetworkIsolationKey value.
+ session_key_ = QuicSessionKey(
+ kServerHostname, kServerPort, PRIVACY_MODE_DISABLED, SocketTag(),
+ network_isolation_key, false /* disable_secure_dns */);
+
+ // Need to create this after enabling
+ // kPartitionExpectCTStateByNetworkIsolationKey.
+ transport_security_state_ = std::make_unique<TransportSecurityState>();
+
+ MockQuicData quic_data(version_);
+ if (VersionUsesHttp3(version_.transport_version))
+ quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING);
+ quic_data.AddRead(ASYNC, OK); // EOF
+ quic_data.AddSocketDataToFactory(&socket_factory_);
+ Initialize();
+
+ // Load a cert that is valid for:
+ // www.example.org
+ // mail.example.org
+ // www.example.com
+
+ // Details with a CT error.
+ ProofVerifyDetailsChromium details;
+ details.cert_verify_result.verified_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
+ details.cert_verify_result.is_issued_by_known_root = true;
+ details.ct_verify_result.policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+
+ CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
+
+ // Pooling succeeds if CT isn't required.
+ EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
+ SocketTag(), network_isolation_key,
+ false /* disable_secure_dns */));
+
+ // Adding Expect-CT data for different NetworkIsolationKeys should have no
+ // effect.
+ base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1);
+ transport_security_state_->AddExpectCT(
+ "www.example.org", expiry, true /* enforce */, GURL() /* report_url */,
+ NetworkIsolationKey::CreateTransient());
+ transport_security_state_->AddExpectCT(
+ "www.example.org", expiry, true /* enforce */, GURL() /* report_url */,
+ NetworkIsolationKey());
+ EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
+ SocketTag(), network_isolation_key,
+ false /* disable_secure_dns */));
+
+ // Adding Expect-CT data for the same NetworkIsolationKey should prevent
+ // pooling.
+ transport_security_state_->AddExpectCT(
+ "www.example.org", expiry, true /* enforce */, GURL() /* report_url */,
+ network_isolation_key);
+ EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
+ SocketTag(), network_isolation_key,
+ false /* disable_secure_dns */));
+}
+
// Much as above, but uses a non-empty NetworkIsolationKey.
TEST_P(QuicChromiumClientSessionTest, CanPoolWithNetworkIsolationKey) {
base::test::ScopedFeatureList feature_list;
@@ -1629,7 +1798,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
quic_data.AddSocketDataToFactory(&socket_factory_);
Initialize();
- transport_security_state_.EnableStaticPinsForTesting();
+ transport_security_state_->EnableStaticPinsForTesting();
ProofVerifyDetailsChromium details;
details.cert_verify_result.verified_cert =
@@ -1661,7 +1830,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
quic_data.AddSocketDataToFactory(&socket_factory_);
Initialize();
- transport_security_state_.EnableStaticPinsForTesting();
+ transport_security_state_->EnableStaticPinsForTesting();
ProofVerifyDetailsChromium details;
details.cert_verify_result.verified_cert =
@@ -1752,7 +1921,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
session_->WritevData(stream->id(), 4, 0, quic::NO_FIN,
- quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ quic::NOT_RETRANSMISSION, QUICHE_NULLOPT);
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
@@ -2033,6 +2202,174 @@ TEST_P(QuicChromiumClientSessionTest, ResetOnEmptyResponseHeaders) {
EXPECT_TRUE(quic_data.AllWriteDataConsumed());
}
+// This test verifies that when NetworkHandle is not supported and there is no
+// network change, session reports to the connectivity monitor correctly on path
+// degrading detection and recovery.
+TEST_P(QuicChromiumClientSessionTest,
+ DegradingWithoutNetworkChange_NoNetworkHandle) {
+ // Add a connectivity monitor for testing.
+ default_network_ = NetworkChangeNotifier::kInvalidNetworkHandle;
+ connectivity_monitor_ =
+ std::make_unique<QuicConnectivityMonitor>(default_network_);
+
+ Initialize();
+
+ // Fire path degrading detection.
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Fire again.
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Close the session but keep the session around, the connectivity monitor
+ // will not remove the tracking immediately.
+ session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
+ quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Delete the session will remove the degrading count in connectivity
+ // monitor.
+ session_.reset();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+}
+
+// This test verifies that when the NetworkHandle is not supported, and there
+// are speculated network change reported via OnIPAddressChange, session
+// still reports to the connectivity monitor correctly on path degrading
+// detection and recovery.
+TEST_P(QuicChromiumClientSessionTest, DegradingWithIPAddressChange) {
+ // Default network is always set to kInvalidNetworkHandle.
+ default_network_ = NetworkChangeNotifier::kInvalidNetworkHandle;
+ connectivity_monitor_ =
+ std::make_unique<QuicConnectivityMonitor>(default_network_);
+
+ Initialize();
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // When NetworkHandle is not supported, network change is notified via
+ // IP address change.
+ connectivity_monitor_->OnIPAddressChanged();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // When NetworkHandle is not supported and IP address changes,
+ // session either goes away or gets closed. When it goes away,
+ // reporting to connectivity monitor is disabled.
+ connectivity_monitor_->OnSessionGoingAwayOnIPAddressChange(session_.get());
+
+ // Even if session detects recovery or degradation, this session is no longer
+ // on the default network and connectivity monitor will not update.
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
+ quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_.reset();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+}
+
+// This test verifies that when NetworkHandle is supported but migration is
+// not supported and there's no network change, session reports to
+// connectivity monitor correctly on path degrading detection or recovery.
+// Default network change is currently reported with valid NetworkHandles
+// while session's current network interface is tracked by |default_network_|.
+TEST_P(QuicChromiumClientSessionTest,
+ DegradingOnDeafultNetwork_WithoutMigration) {
+ default_network_ = kDefaultNetworkForTests;
+ connectivity_monitor_ =
+ std::make_unique<QuicConnectivityMonitor>(default_network_);
+
+ Initialize();
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+ // Close the session but keep the session around, the connectivity monitor
+ // should not remove the count immediately.
+ session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
+ quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Delete the session will remove the degrading count in connectivity
+ // monitor.
+ session_.reset();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+}
+
+// This test verifies that when NetworkHandle is supported but migrations is not
+// supported and there is network changes, session reports to the connectivity
+// monitor correctly on path degrading detection or recovery.
+TEST_P(QuicChromiumClientSessionTest,
+ DegradingWithDeafultNetworkChange_WithoutMigration) {
+ default_network_ = kDefaultNetworkForTests;
+ connectivity_monitor_ =
+ std::make_unique<QuicConnectivityMonitor>(default_network_);
+
+ Initialize();
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Simulate the default network change.
+ connectivity_monitor_->OnDefaultNetworkUpdated(kNewNetworkForTests);
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+ session_->OnNetworkMadeDefault(kNewNetworkForTests);
+
+ // Session stays on the old default network, and recovers.
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Session degrades again on the old default.
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Simulate that default network switches back to the old default.
+ connectivity_monitor_->OnDefaultNetworkUpdated(kDefaultNetworkForTests);
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+ session_->OnNetworkMadeDefault(kDefaultNetworkForTests);
+
+ // Session recovers again on the (old) default.
+ session_->OnForwardProgressMadeAfterPathDegrading();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+
+ // Session degrades again on the (old) default.
+ session_->ReallyOnPathDegrading();
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
+ quic::ConnectionCloseBehavior::SILENT_CLOSE);
+ EXPECT_EQ(1u, connectivity_monitor_->GetNumDegradingSessions());
+
+ session_.reset();
+ EXPECT_EQ(0u, connectivity_monitor_->GetNumDegradingSessions());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_chromium_client_stream.h b/chromium/net/quic/quic_chromium_client_stream.h
index 71372a16f52..6399b92a5e3 100644
--- a/chromium/net/quic/quic_chromium_client_stream.h
+++ b/chromium/net/quic/quic_chromium_client_stream.h
@@ -9,10 +9,10 @@
#include <stddef.h>
+#include <memory>
#include <vector>
#include "base/callback_forward.h"
-#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "net/base/completion_once_callback.h"
#include "net/base/ip_endpoint.h"
diff --git a/chromium/net/quic/quic_chromium_packet_writer.cc b/chromium/net/quic/quic_chromium_packet_writer.cc
index 2c5d194df73..e45613b9511 100644
--- a/chromium/net/quic/quic_chromium_packet_writer.cc
+++ b/chromium/net/quic/quic_chromium_packet_writer.cc
@@ -263,10 +263,10 @@ bool QuicChromiumPacketWriter::IsBatchMode() const {
return false;
}
-char* QuicChromiumPacketWriter::GetNextWriteLocation(
+quic::QuicPacketBuffer QuicChromiumPacketWriter::GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) {
- return nullptr;
+ return {nullptr, nullptr};
}
quic::WriteResult QuicChromiumPacketWriter::Flush() {
diff --git a/chromium/net/quic/quic_chromium_packet_writer.h b/chromium/net/quic/quic_chromium_packet_writer.h
index 82acb30f367..2f03d3914dc 100644
--- a/chromium/net/quic/quic_chromium_packet_writer.h
+++ b/chromium/net/quic/quic_chromium_packet_writer.h
@@ -94,7 +94,7 @@ class NET_EXPORT_PRIVATE QuicChromiumPacketWriter
const quic::QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
- char* GetNextWriteLocation(
+ quic::QuicPacketBuffer GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) override;
quic::WriteResult Flush() override;
diff --git a/chromium/net/quic/quic_client_session_cache.cc b/chromium/net/quic/quic_client_session_cache.cc
index 7bc5945225a..64e8d962993 100644
--- a/chromium/net/quic/quic_client_session_cache.cc
+++ b/chromium/net/quic/quic_client_session_cache.cc
@@ -46,9 +46,9 @@ QuicClientSessionCache::QuicClientSessionCache()
QuicClientSessionCache::QuicClientSessionCache(size_t max_entries)
: clock_(base::DefaultClock::GetInstance()), cache_(max_entries) {
- memory_pressure_listener_.reset(
- new base::MemoryPressureListener(base::BindRepeating(
- &QuicClientSessionCache::OnMemoryPressure, base::Unretained(this))));
+ memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
+ FROM_HERE, base::BindRepeating(&QuicClientSessionCache::OnMemoryPressure,
+ base::Unretained(this)));
}
QuicClientSessionCache::~QuicClientSessionCache() {
@@ -103,6 +103,18 @@ std::unique_ptr<quic::QuicResumptionState> QuicClientSessionCache::Lookup(
return state;
}
+void QuicClientSessionCache::ClearEarlyData(
+ const quic::QuicServerId& server_id) {
+ auto iter = cache_.Get(server_id);
+ if (iter == cache_.end())
+ return;
+ for (auto& session : iter->second.sessions) {
+ if (session) {
+ session.reset(SSL_SESSION_copy_without_early_data(session.get()));
+ }
+ }
+}
+
void QuicClientSessionCache::FlushInvalidEntries() {
time_t now = clock_->Now().ToTimeT();
auto iter = cache_.begin();
diff --git a/chromium/net/quic/quic_client_session_cache.h b/chromium/net/quic/quic_client_session_cache.h
index 8d7506ee4ec..c59c28a2937 100644
--- a/chromium/net/quic/quic_client_session_cache.h
+++ b/chromium/net/quic/quic_client_session_cache.h
@@ -39,6 +39,8 @@ class NET_EXPORT_PRIVATE QuicClientSessionCache : public quic::SessionCache {
const quic::QuicServerId& server_id,
const SSL_CTX* ctx) override;
+ void ClearEarlyData(const quic::QuicServerId& server_id) override;
+
void SetClockForTesting(base::Clock* clock) { clock_ = clock; }
size_t size() const { return cache_.size(); }
diff --git a/chromium/net/quic/quic_client_session_cache_unittests.cc b/chromium/net/quic/quic_client_session_cache_unittests.cc
index 0fac11c6840..c1e241df403 100644
--- a/chromium/net/quic/quic_client_session_cache_unittests.cc
+++ b/chromium/net/quic/quic_client_session_cache_unittests.cc
@@ -8,6 +8,8 @@
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
+#include "build/build_config.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
@@ -15,6 +17,7 @@ namespace net {
namespace {
+const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);
const quic::QuicVersionLabel kFakeVersionLabel = 0x01234567;
const quic::QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
@@ -53,37 +56,96 @@ std::unique_ptr<quic::TransportParameters> MakeFakeTransportParams() {
params->version = kFakeVersionLabel;
params->supported_versions.push_back(kFakeVersionLabel);
params->supported_versions.push_back(kFakeVersionLabel2);
- params->idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+ params->max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
params->stateless_reset_token = CreateFakeStatelessResetToken();
- params->max_packet_size.set_value(kFakeMaxPacketSize);
+ params->max_udp_payload_size.set_value(kFakeMaxPacketSize);
params->initial_max_data.set_value(kFakeInitialMaxData);
- params->disable_migration = kFakeDisableMigration;
+ params->disable_active_migration = kFakeDisableMigration;
params->custom_parameters[kCustomParameter1] = kCustomParameter1Value;
params->custom_parameters[kCustomParameter2] = kCustomParameter2Value;
return params;
}
+namespace {
+
+// Generated by running TlsClientHandshakerTest.ZeroRttResumption and in
+// TlsClientHandshaker::InsertSession calling SSL_SESSION_to_bytes to serialize
+// the received 0-RTT capable ticket.
+static const char kCachedSession[] =
+ "3082068702010102020304040213010420b9c2a657e565db0babd09e192a9fc4d768fbd706"
+ "9f03f9278a4a0be62392e55b0420d87ed2ab8cafc986fd2e288bd2d654cd57c3a2bed1d532"
+ "20726e55fed39d021ea10602045ed16771a205020302a300a382025f3082025b30820143a0"
+ "03020102020104300d06092a864886f70d01010b0500302c3110300e060355040a13074163"
+ "6d6520436f311830160603550403130f496e7465726d656469617465204341301e170d3133"
+ "303130313130303030305a170d3233313233313130303030305a302d3110300e060355040a"
+ "130741636d6520436f3119301706035504031310746573742e6578616d706c652e636f6d30"
+ "59301306072a8648ce3d020106082a8648ce3d030107034200040526220e77278300d06bc0"
+ "86aff4f999a828a2ed5cc75adc2972794befe885aa3a9b843de321b36b0a795289cebff1a5"
+ "428bad5e34665ce5e36daad08fb3ffd8a3523050300e0603551d0f0101ff04040302078030"
+ "130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000301b06"
+ "03551d11041430128210746573742e6578616d706c652e636f6d300d06092a864886f70d01"
+ "010b050003820101008c1f1e380831b6437a8b9284d28d4ead38d9503a9fc936db89048aa2"
+ "edd6ec2fb830d962ef7a4f384e679504f4d5520f3272e0b9e702b110aff31711578fa5aeb1"
+ "11e9d184c994b0f97e7b17d1995f3f477f25bc1258398ec0ec729caed55d594a009f48093a"
+ "17f33a7f3bb6e420cc3499838398a421d93c7132efa8bee5ed2645cbc55179c400da006feb"
+ "761badd356cac3bd7a0e6b22a511106a355ec62a4c0ac2541d2996adb4a918c866d10c3e31"
+ "62039a91d4ce600b276740d833380b37f66866d261bf6efa8855e7ae6c7d12a8a864cd9a1f"
+ "4663e07714b0204e51bbc189a2d04c2a5043202379ff1c8cbf30cbb44fde4ee9a1c0c976dc"
+ "4943df2c132ca4020400aa7f047d494e534543555245003072020101020203040402130104"
+ "000420d87ed2ab8cafc986fd2e288bd2d654cd57c3a2bed1d53220726e55fed39d021ea106"
+ "02045ed16771a205020302a300a4020400b20302011db5060404bd909308b807020500ffff"
+ "ffffb9050203093a80ba07040568332d3238bb030101ffbc03040100b20302011db3820307"
+ "30820303308201eba003020102020102300d06092a864886f70d01010b050030243110300e"
+ "060355040a130741636d6520436f3110300e06035504031307526f6f74204341301e170d31"
+ "33303130313130303030305a170d3233313233313130303030305a302c3110300e06035504"
+ "0a130741636d6520436f311830160603550403130f496e7465726d65646961746520434130"
+ "820122300d06092a864886f70d01010105000382010f003082010a0282010100cd3550e70a"
+ "6880e52bf0012b93110c50f723e1d8d2ed489aea3b649f82fae4ad2396a8a19b31d1d64ab2"
+ "79f1c18003184154a5303a82bd57109cfd5d34fd19d3211bcb06e76640e1278998822dd72e"
+ "0d5c059a740d45de325e784e81b4c86097f08b2a8ce057f6b9db5a53641d27e09347d993ee"
+ "acf67be7d297b1a6853775ffaaf78fae924e300b5654fd32f99d3cd82e95f56417ff26d265"
+ "e2b1786c835d67a4d8ae896b6eb34b35a5b1033c209779ed0bf8de25a13a507040ae9e0475"
+ "a26a2f15845b08c3e0554e47dbbc7925b02e580dbcaaa6f2eecde6b8028c5b00b33d44d0a6"
+ "bfb3e72e9d4670de45d1bd79bdc0f2470b71286091c29873152db4b1f30203010001a33830"
+ "36300e0603551d0f0101ff04040302020430130603551d25040c300a06082b060105050703"
+ "01300f0603551d130101ff040530030101ff300d06092a864886f70d01010b050003820101"
+ "00bc4f8234860558dd404a626403819bfc759029d625a002143e75ebdb2898d1befdd326c3"
+ "4b14dc3507d732bb29af7e6af31552db53052a2be0d950efee5e0f699304231611ed8bf73a"
+ "6f216a904c6c2f1a2186d1ed08a8005a7914394d71e7d4b643c808f86365c5fecad8b52934"
+ "2d3b3f03447126d278d75b1dab3ed53f23e36e9b3d695f28727916e5ee56ce22d387c81f05"
+ "919b2a37bd4981eb67d9f57b7072285dbbb61f48b6b14768c069a092aad5a094cf295dafd2"
+ "3ca008f89a5f5ab37a56e5f68df45091c7cb85574677127087a2887ba3baa6d4fc436c6e40"
+ "40885e81621d38974f0c7f0d792418c5adebb10e92a165f8d79b169617ff575c0d4a85b506"
+ "0404bd909308b603010100b70402020403b807020500ffffffffb9050203093a80ba070405"
+ "68332d3238bb030101ff";
+
+} // namespace
+
class QuicClientSessionCacheTest : public testing::Test {
public:
- QuicClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {}
+ QuicClientSessionCacheTest()
+ : ssl_ctx_(SSL_CTX_new(TLS_method())), clock_(MakeTestClock()) {}
protected:
bssl::UniquePtr<SSL_SESSION> NewSSLSession() {
- SSL_SESSION* session = SSL_SESSION_new(ssl_ctx_.get());
- if (!SSL_SESSION_set_protocol_version(session, TLS1_3_VERSION))
- return nullptr;
+ std::string cached_session =
+ quiche::QuicheTextUtils::HexDecode(kCachedSession);
+ SSL_SESSION* session = SSL_SESSION_from_bytes(
+ reinterpret_cast<const uint8_t*>(cached_session.data()),
+ cached_session.size(), ssl_ctx_.get());
return bssl::UniquePtr<SSL_SESSION>(session);
}
- bssl::UniquePtr<SSL_SESSION> MakeTestSession(base::Time now,
- base::TimeDelta timeout) {
+ bssl::UniquePtr<SSL_SESSION> MakeTestSession(
+ base::TimeDelta timeout = kTimeout) {
bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
- SSL_SESSION_set_time(session.get(), now.ToTimeT());
+ SSL_SESSION_set_time(session.get(), clock_->Now().ToTimeT());
SSL_SESSION_set_timeout(session.get(), timeout.InSeconds());
return session;
}
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+ std::unique_ptr<base::SimpleTestClock> clock_;
};
} // namespace
@@ -91,13 +153,14 @@ class QuicClientSessionCacheTest : public testing::Test {
// Tests that simple insertion and lookup work correctly.
TEST_F(QuicClientSessionCacheTest, SingleSession) {
QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
auto params2 = MakeFakeTransportParams();
- auto session2 = NewSSLSession();
+ auto session2 = MakeTestSession();
SSL_SESSION* unowned2 = session2.get();
quic::QuicServerId id2("b.com", 443);
@@ -115,7 +178,7 @@ TEST_F(QuicClientSessionCacheTest, SingleSession) {
// Lookup() will trigger a deletion of invalid entry.
EXPECT_EQ(0u, cache.size());
- auto session3 = NewSSLSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
quic::QuicServerId id3("c.com", 443);
cache.Insert(id3, std::move(session3), *params, nullptr);
@@ -133,13 +196,14 @@ TEST_F(QuicClientSessionCacheTest, SingleSession) {
TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = NewSSLSession();
+ auto session2 = MakeTestSession();
SSL_SESSION* unowned2 = session2.get();
- auto session3 = NewSSLSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
cache.Insert(id1, std::move(session), *params, nullptr);
@@ -156,12 +220,13 @@ TEST_F(QuicClientSessionCacheTest, MultipleSessions) {
// the same server id, the existing entry is removed.
TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = NewSSLSession();
- auto session3 = NewSSLSession();
+ auto session2 = MakeTestSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
cache.Insert(id1, std::move(session), *params, nullptr);
@@ -177,12 +242,13 @@ TEST_F(QuicClientSessionCacheTest, DifferentTransportParams) {
TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = NewSSLSession();
- auto session3 = NewSSLSession();
+ auto session2 = MakeTestSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
quic::ApplicationState state;
state.push_back('a');
@@ -198,12 +264,13 @@ TEST_F(QuicClientSessionCacheTest, DifferentApplicationState) {
TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = NewSSLSession();
- auto session3 = NewSSLSession();
+ auto session2 = MakeTestSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
quic::ApplicationState state;
state.push_back('a');
@@ -222,16 +289,17 @@ TEST_F(QuicClientSessionCacheTest, BothStatesDifferent) {
// When the size limit is exceeded, the oldest entry should be erased.
TEST_F(QuicClientSessionCacheTest, SizeLimit) {
QuicClientSessionCache cache(2);
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = NewSSLSession();
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = NewSSLSession();
+ auto session2 = MakeTestSession();
SSL_SESSION* unowned2 = session2.get();
quic::QuicServerId id2("b.com", 443);
- auto session3 = NewSSLSession();
+ auto session3 = MakeTestSession();
SSL_SESSION* unowned3 = session3.get();
quic::QuicServerId id3("c.com", 443);
@@ -245,19 +313,43 @@ TEST_F(QuicClientSessionCacheTest, SizeLimit) {
EXPECT_EQ(nullptr, cache.Lookup(id1, ssl_ctx_.get()));
}
+TEST_F(QuicClientSessionCacheTest, ClearEarlyData) {
+ QuicClientSessionCache cache;
+ cache.SetClockForTesting(clock_.get());
+ SSL_CTX_set_early_data_enabled(ssl_ctx_.get(), 1);
+ auto params = MakeFakeTransportParams();
+ auto session = MakeTestSession();
+ quic::QuicServerId id1("a.com", 443);
+ auto session2 = MakeTestSession();
+
+ EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
+ EXPECT_TRUE(SSL_SESSION_early_data_capable(session2.get()));
+
+ cache.Insert(id1, std::move(session), *params, nullptr);
+ cache.Insert(id1, std::move(session2), *params, nullptr);
+
+ cache.ClearEarlyData(id1);
+
+ auto resumption_state = cache.Lookup(id1, ssl_ctx_.get());
+ EXPECT_FALSE(
+ SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+ resumption_state = cache.Lookup(id1, ssl_ctx_.get());
+ EXPECT_FALSE(
+ SSL_SESSION_early_data_capable(resumption_state->tls_session.get()));
+ EXPECT_EQ(nullptr, cache.Lookup(id1, ssl_ctx_.get()));
+}
+
// Expired session isn't considered valid and nullptr will be returned upon
// Lookup.
TEST_F(QuicClientSessionCacheTest, Expiration) {
- const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);
QuicClientSessionCache cache;
- std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
- cache.SetClockForTesting(clock.get());
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = MakeTestSession(clock->Now(), kTimeout);
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession(clock->Now(), 3 * kTimeout);
+ auto session2 = MakeTestSession(3 * kTimeout);
SSL_SESSION* unowned2 = session2.get();
quic::QuicServerId id2("b.com", 443);
@@ -266,7 +358,7 @@ TEST_F(QuicClientSessionCacheTest, Expiration) {
EXPECT_EQ(2u, cache.size());
// Expire the session.
- clock->Advance(kTimeout * 2);
+ clock_->Advance(kTimeout * 2);
// The entry has not been removed yet.
EXPECT_EQ(2u, cache.size());
@@ -278,16 +370,14 @@ TEST_F(QuicClientSessionCacheTest, Expiration) {
TEST_F(QuicClientSessionCacheTest, FlushOnMemoryNotifications) {
base::test::TaskEnvironment task_environment;
- const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);
QuicClientSessionCache cache;
- std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
- cache.SetClockForTesting(clock.get());
+ cache.SetClockForTesting(clock_.get());
auto params = MakeFakeTransportParams();
- auto session = MakeTestSession(clock->Now(), kTimeout);
+ auto session = MakeTestSession();
quic::QuicServerId id1("a.com", 443);
- auto session2 = MakeTestSession(clock->Now(), 3 * kTimeout);
+ auto session2 = MakeTestSession(3 * kTimeout);
quic::QuicServerId id2("b.com", 443);
cache.Insert(id1, std::move(session), *params, nullptr);
@@ -295,7 +385,7 @@ TEST_F(QuicClientSessionCacheTest, FlushOnMemoryNotifications) {
EXPECT_EQ(2u, cache.size());
// Expire the session.
- clock->Advance(kTimeout * 2);
+ clock_->Advance(kTimeout * 2);
// The entry has not been removed yet.
EXPECT_EQ(2u, cache.size());
diff --git a/chromium/net/quic/quic_connection_logger.cc b/chromium/net/quic/quic_connection_logger.cc
index 1293fac42ac..71803309b69 100644
--- a/chromium/net/quic/quic_connection_logger.cc
+++ b/chromium/net/quic/quic_connection_logger.cc
@@ -227,6 +227,14 @@ base::Value NetLogQuicCryptoHandshakeMessageParams(
return dict;
}
+base::Value NetLogQuicTransportParametersParams(
+ const quic::TransportParameters& transport_parameters) {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetStringKey("quic_transport_parameters",
+ transport_parameters.ToString());
+ return dict;
+}
+
base::Value NetLogQuicOnConnectionClosedParams(
quic::QuicErrorCode error,
string error_details,
@@ -877,8 +885,6 @@ void QuicConnectionLogger::OnIncomingAck(
return;
net_log_.AddEvent(NetLogEventType::QUIC_SESSION_ACK_FRAME_RECEIVED,
[&] { return NetLogQuicAckFrameParams(&frame); });
-
- // TODO(rch, rtenneti) sort out histograms for QUIC_VERSION_34 and above.
}
void QuicConnectionLogger::OnStopWaitingFrame(
@@ -1142,6 +1148,26 @@ void QuicConnectionLogger::OnRttChanged(quic::QuicTime::Delta rtt) const {
}
}
+void QuicConnectionLogger::OnTransportParametersSent(
+ const quic::TransportParameters& transport_parameters) {
+ if (!net_log_.IsCapturing())
+ return;
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_SESSION_TRANSPORT_PARAMETERS_SENT, [&] {
+ return NetLogQuicTransportParametersParams(transport_parameters);
+ });
+}
+
+void QuicConnectionLogger::OnTransportParametersReceived(
+ const quic::TransportParameters& transport_parameters) {
+ if (!net_log_.IsCapturing())
+ return;
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_SESSION_TRANSPORT_PARAMETERS_RECEIVED, [&] {
+ return NetLogQuicTransportParametersParams(transport_parameters);
+ });
+}
+
void QuicConnectionLogger::RecordAggregatePacketLossRate() const {
// For short connections under 22 packets in length, we'll rely on the
// Net.QuicSession.21CumulativePacketsReceived_* histogram to indicate packet
diff --git a/chromium/net/quic/quic_connection_logger.h b/chromium/net/quic/quic_connection_logger.h
index 9c45bf983d9..879ebf1c986 100644
--- a/chromium/net/quic/quic_connection_logger.h
+++ b/chromium/net/quic/quic_connection_logger.h
@@ -109,6 +109,10 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
void OnSuccessfulVersionNegotiation(
const quic::ParsedQuicVersion& version) override;
void OnRttChanged(quic::QuicTime::Delta rtt) const override;
+ void OnTransportParametersSent(
+ const quic::TransportParameters& transport_parameters) override;
+ void OnTransportParametersReceived(
+ const quic::TransportParameters& transport_parameters) override;
void OnCryptoHandshakeMessageReceived(
const quic::CryptoHandshakeMessage& message);
diff --git a/chromium/net/quic/quic_connectivity_monitor.cc b/chromium/net/quic/quic_connectivity_monitor.cc
new file mode 100644
index 00000000000..00d0a774465
--- /dev/null
+++ b/chromium/net/quic/quic_connectivity_monitor.cc
@@ -0,0 +1,71 @@
+// 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/quic/quic_connectivity_monitor.h"
+
+#include "base/metrics/histogram_macros.h"
+
+namespace net {
+
+QuicConnectivityMonitor::QuicConnectivityMonitor(
+ NetworkChangeNotifier::NetworkHandle default_network)
+ : default_network_(default_network) {}
+
+QuicConnectivityMonitor::~QuicConnectivityMonitor() = default;
+
+size_t QuicConnectivityMonitor::GetNumDegradingSessions() const {
+ return degrading_sessions_.size();
+}
+
+void QuicConnectivityMonitor::SetInitialDefaultNetwork(
+ NetworkChangeNotifier::NetworkHandle default_network) {
+ default_network_ = default_network;
+}
+
+void QuicConnectivityMonitor::OnSessionPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) {
+ if (network == default_network_)
+ degrading_sessions_.insert(session);
+}
+
+void QuicConnectivityMonitor::OnSessionResumedPostPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) {
+ if (network == default_network_)
+ degrading_sessions_.erase(session);
+}
+
+void QuicConnectivityMonitor::OnSessionRemoved(
+ QuicChromiumClientSession* session) {
+ degrading_sessions_.erase(session);
+}
+
+void QuicConnectivityMonitor::OnDefaultNetworkUpdated(
+ NetworkChangeNotifier::NetworkHandle default_network) {
+ default_network_ = default_network;
+ degrading_sessions_.clear();
+}
+
+void QuicConnectivityMonitor::OnIPAddressChanged() {
+ // If NetworkHandle is supported, connectivity monitor will receive
+ // notifications via OnDefaultNetworkUpdated.
+ if (NetworkChangeNotifier::AreNetworkHandlesSupported())
+ return;
+
+ DCHECK_EQ(default_network_, NetworkChangeNotifier::kInvalidNetworkHandle);
+ degrading_sessions_.clear();
+}
+
+void QuicConnectivityMonitor::OnSessionGoingAwayOnIPAddressChange(
+ QuicChromiumClientSession* session) {
+ // This should only be called after ConnectivityMonitor gets notified via
+ // OnIPAddressChanged().
+ DCHECK(degrading_sessions_.empty());
+ // |session| that encounters IP address change will lose track which network
+ // it is bound to. Future connectivity monitoring may be misleading.
+ session->RemoveConnectivityObserver(this);
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_connectivity_monitor.h b/chromium/net/quic/quic_connectivity_monitor.h
new file mode 100644
index 00000000000..b8b7274a8d8
--- /dev/null
+++ b/chromium/net/quic/quic_connectivity_monitor.h
@@ -0,0 +1,74 @@
+// 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 NET_QUIC_QUIC_CONNECTIVITY_MONITOR_H_
+#define NET_QUIC_QUIC_CONNECTIVITY_MONITOR_H_
+
+#include "net/base/network_change_notifier.h"
+#include "net/quic/quic_chromium_client_session.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+
+namespace net {
+
+// Responsible for monitoring path degrading detection/recovery events on the
+// default network interface.
+// Reset all raw observations (reported by sessions) when the default network
+// is changed, which happens either:
+// - via OnDefaultNetworkUpdated if NetworkHandle is supported on the platform;
+// - via OnIPAddressChanged otherwise.
+class NET_EXPORT_PRIVATE QuicConnectivityMonitor
+ : public QuicChromiumClientSession::ConnectivityObserver {
+ public:
+ explicit QuicConnectivityMonitor(
+ NetworkChangeNotifier::NetworkHandle default_network);
+
+ ~QuicConnectivityMonitor() override;
+
+ // Returns the number of sessions that are currently degrading on the default
+ // network interface.
+ size_t GetNumDegradingSessions() const;
+
+ // Called to set up the initial default network, which happens when the
+ // default network tracking is lost upon |this| creation.
+ void SetInitialDefaultNetwork(
+ NetworkChangeNotifier::NetworkHandle default_network);
+
+ // Called when NetworkHandle is supported and the default network interface
+ // used by the platform is updated.
+ void OnDefaultNetworkUpdated(
+ NetworkChangeNotifier::NetworkHandle default_network);
+
+ // Called when NetworkHandle is NOT supported and the IP address of the
+ // primary interface changes. This includes when the primary interface itself
+ // changes.
+ void OnIPAddressChanged();
+
+ // Called when |session| is marked as going away due to IP address change.
+ void OnSessionGoingAwayOnIPAddressChange(QuicChromiumClientSession* session);
+
+ // QuicChromiumClientSession::ConnectivityObserver implementation.
+ void OnSessionPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) override;
+
+ void OnSessionResumedPostPathDegrading(
+ QuicChromiumClientSession* session,
+ NetworkChangeNotifier::NetworkHandle network) override;
+
+ void OnSessionRemoved(QuicChromiumClientSession* session) override;
+
+ private:
+ // If NetworkHandle is not supported, always set to
+ // NetworkChangeNotifier::kInvalidNetworkHandle.
+ NetworkChangeNotifier::NetworkHandle default_network_;
+ // Sessions that are currently degrading on the |default_network_|.
+ quic::QuicHashSet<QuicChromiumClientSession*> degrading_sessions_;
+
+ base::WeakPtrFactory<QuicConnectivityMonitor> weak_factory_{this};
+ DISALLOW_COPY_AND_ASSIGN(QuicConnectivityMonitor);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_CONNECTIVITY_MONITOR_H_
diff --git a/chromium/net/quic/quic_connectivity_probing_manager.cc b/chromium/net/quic/quic_connectivity_probing_manager.cc
index 9f0d16fbee4..dd240252bf6 100644
--- a/chromium/net/quic/quic_connectivity_probing_manager.cc
+++ b/chromium/net/quic/quic_connectivity_probing_manager.cc
@@ -60,7 +60,9 @@ QuicConnectivityProbingManager::QuicConnectivityProbingManager(
network_(NetworkChangeNotifier::kInvalidNetworkHandle),
retry_count_(0),
probe_start_time_(base::TimeTicks()),
- task_runner_(task_runner) {
+ task_runner_(task_runner),
+ last_self_address_(IPEndPoint()),
+ stateless_reset_received_(false) {
retransmit_timer_.SetTaskRunner(task_runner_);
}
@@ -98,14 +100,19 @@ void QuicConnectivityProbingManager::CancelProbing(
void QuicConnectivityProbingManager::CancelProbingIfAny() {
if (is_running_) {
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.StatelessResetDuringProbing",
+ stateless_reset_received_);
net_log_.AddEvent(
NetLogEventType::QUIC_CONNECTIVITY_PROBING_MANAGER_CANCEL_PROBING, [&] {
return NetLogProbingDestinationParams(network_, &peer_address_);
});
}
is_running_ = false;
+ if (socket_ != nullptr) {
+ socket_->GetLocalAddress(&last_self_address_);
+ }
network_ = NetworkChangeNotifier::kInvalidNetworkHandle;
- peer_address_ = quic::QuicSocketAddress();
+ stateless_reset_received_ = false;
socket_.reset();
writer_.reset();
reader_.reset();
@@ -198,6 +205,43 @@ void QuicConnectivityProbingManager::OnPacketReceived(
CancelProbingIfAny();
}
+bool QuicConnectivityProbingManager::ValidateStatelessReset(
+ const quic::QuicSocketAddress& self_address,
+ const quic::QuicSocketAddress& peer_address) {
+ IPEndPoint local_address;
+ if (!socket_) {
+ local_address = last_self_address_;
+ } else {
+ socket_->GetLocalAddress(&local_address);
+ }
+
+ if (local_address != ToIPEndPoint(self_address) ||
+ peer_address_ != peer_address) {
+ DVLOG(1) << "Probing lives at different path:";
+ DVLOG(1) << " peer_address: " << local_address.ToString();
+ DVLOG(1) << " self_address: " << self_address.ToString();
+ return false;
+ }
+
+ if (is_running_) {
+ stateless_reset_received_ = true;
+ } else {
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.StatelessResetAfterProbingCancelled",
+ true);
+ }
+
+ net_log_.AddEvent(
+ NetLogEventType::
+ QUIC_CONNECTIVITY_PROBING_MANAGER_STATELESS_RESET_RECEIVED,
+ [&] {
+ return NetLogProbeReceivedParams(network_, &local_address,
+ &peer_address_);
+ });
+
+ NotifyDelegateProbeFailed();
+ return true;
+}
+
void QuicConnectivityProbingManager::SendConnectivityProbingPacket(
base::TimeDelta timeout) {
net_log_.AddEventWithInt64Params(
diff --git a/chromium/net/quic/quic_connectivity_probing_manager.h b/chromium/net/quic/quic_connectivity_probing_manager.h
index 9d4de8e25bb..d7e0a9c5067 100644
--- a/chromium/net/quic/quic_connectivity_probing_manager.h
+++ b/chromium/net/quic/quic_connectivity_probing_manager.h
@@ -7,6 +7,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/log/net_log_with_source.h"
#include "net/quic/quic_chromium_packet_reader.h"
@@ -95,6 +96,11 @@ class NET_EXPORT_PRIVATE QuicConnectivityProbingManager
peer_address == peer_address_);
}
+ // Returns true if both |self_address| and |peer_address|
+ // match with the probing manager's socket address. Returns false otherwise.
+ bool ValidateStatelessReset(const quic::QuicSocketAddress& self_address,
+ const quic::QuicSocketAddress& peer_address);
+
private:
// Cancels undergoing probing.
void CancelProbingIfAny();
@@ -116,6 +122,8 @@ class NET_EXPORT_PRIVATE QuicConnectivityProbingManager
// if |is_running_| is true.
bool is_running_;
NetworkChangeNotifier::NetworkHandle network_;
+ // If |is_running| is false, |peer_address_| caches the peer address of the
+ // last probing path.
quic::QuicSocketAddress peer_address_;
std::unique_ptr<DatagramClientSocket> socket_;
@@ -129,6 +137,11 @@ class NET_EXPORT_PRIVATE QuicConnectivityProbingManager
base::SequencedTaskRunner* task_runner_;
+ // The cached local address set when probing is cancelled.
+ IPEndPoint last_self_address_;
+
+ bool stateless_reset_received_;
+
base::WeakPtrFactory<QuicConnectivityProbingManager> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(QuicConnectivityProbingManager);
};
diff --git a/chromium/net/quic/quic_connectivity_probing_manager_test.cc b/chromium/net/quic/quic_connectivity_probing_manager_test.cc
index 15bd236a20a..abce3d51857 100644
--- a/chromium/net/quic/quic_connectivity_probing_manager_test.cc
+++ b/chromium/net/quic/quic_connectivity_probing_manager_test.cc
@@ -378,6 +378,89 @@ TEST_F(QuicConnectivityProbingManagerTest, RetryProbingWithExponentailBackoff) {
EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount());
}
+TEST_F(QuicConnectivityProbingManagerTest, ProbingReceivedStatelessReset) {
+ int initial_timeout_ms = 100;
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .WillOnce(Return(true));
+ probing_manager_.StartProbing(
+ testNetworkHandle, testPeerAddress, std::move(socket_),
+ std::move(writer_), std::move(reader_),
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms),
+ bound_test_net_log_.bound());
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ // Fast forward initial_timeout_ms, timeout the first connectivity probing
+ // packet, cause another probing packet to be sent with timeout set to
+ // 2 * initial_timeout_ms.
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .WillOnce(Return(true));
+ test_task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms));
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ // Fast forward initial_timeout_ms, should be no-op.
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .Times(0);
+ test_task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms));
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ EXPECT_CALL(session_, OnProbeFailed(testNetworkHandle, testPeerAddress))
+ .Times(1);
+ EXPECT_TRUE(
+ probing_manager_.ValidateStatelessReset(self_address_, testPeerAddress));
+ EXPECT_FALSE(session_.is_successfully_probed());
+ EXPECT_FALSE(
+ probing_manager_.IsUnderProbing(testNetworkHandle, testPeerAddress));
+ test_task_runner_->RunUntilIdle();
+}
+
+TEST_F(QuicConnectivityProbingManagerTest,
+ StatelessResetReceivedAfterProbingCancelled) {
+ int initial_timeout_ms = 100;
+
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .WillOnce(Return(true));
+ probing_manager_.StartProbing(
+ testNetworkHandle, testPeerAddress, std::move(socket_),
+ std::move(writer_), std::move(reader_),
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms),
+ bound_test_net_log_.bound());
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ // Fast forward initial_timeout_ms, timeout the first connectivity probing
+ // packet, cause another probing packet to be sent with timeout set to
+ // 2 * initial_timeout_ms.
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .WillOnce(Return(true));
+ test_task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms));
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ // Fast forward initial_timeout_ms, should be no-op.
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, testPeerAddress))
+ .Times(0);
+ test_task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(initial_timeout_ms));
+ EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
+
+ // Request cancel probing, manager will no longer send connectivity probes.
+ EXPECT_CALL(session_, OnSendConnectivityProbingPacket(_, _)).Times(0);
+ EXPECT_CALL(session_, OnProbeFailed(_, _)).Times(0);
+ probing_manager_.CancelProbing(testNetworkHandle, testPeerAddress);
+ EXPECT_FALSE(
+ probing_manager_.IsUnderProbing(testNetworkHandle, testPeerAddress));
+
+ // Verify that the probing manager is still able to verify STATELESS_RESET
+ // received on the previous probing path.
+ EXPECT_TRUE(
+ probing_manager_.ValidateStatelessReset(self_address_, testPeerAddress));
+ EXPECT_FALSE(session_.is_successfully_probed());
+ EXPECT_FALSE(
+ probing_manager_.IsUnderProbing(testNetworkHandle, testPeerAddress));
+ test_task_runner_->RunUntilIdle();
+}
+
TEST_F(QuicConnectivityProbingManagerTest, CancelProbing) {
int initial_timeout_ms = 100;
diff --git a/chromium/net/quic/quic_context.h b/chromium/net/quic/quic_context.h
index 1f3ece3c0c7..e27af55433a 100644
--- a/chromium/net/quic/quic_context.h
+++ b/chromium/net/quic/quic_context.h
@@ -13,8 +13,8 @@
namespace net {
// Default QUIC version used in absence of any external configuration.
-constexpr quic::ParsedQuicVersion kDefaultSupportedQuicVersion{
- quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_46};
+constexpr quic::ParsedQuicVersion kDefaultSupportedQuicVersion =
+ quic::ParsedQuicVersion::Q050();
// Returns a list containing only the current default version.
inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector
@@ -165,6 +165,8 @@ struct NET_EXPORT QuicParams {
// The initial rtt that will be used in crypto handshake if no cached
// smoothed rtt is present.
base::TimeDelta initial_rtt_for_handshake;
+ // If true, QUIC with TLS will not try 0-RTT connection.
+ bool disable_tls_zero_rtt = false;
};
// QuicContext contains QUIC-related variables that are shared across all of the
@@ -187,6 +189,11 @@ class NET_EXPORT_PRIVATE QuicContext {
return params_.supported_versions;
}
+ void SetHelperForTesting(
+ std::unique_ptr<quic::QuicConnectionHelperInterface> helper) {
+ helper_ = std::move(helper);
+ }
+
private:
std::unique_ptr<quic::QuicConnectionHelperInterface> helper_;
diff --git a/chromium/net/quic/quic_flags_list.h b/chromium/net/quic/quic_flags_list.h
index e90d9ee34b2..8275a075e38 100644
--- a/chromium/net/quic/quic_flags_list.h
+++ b/chromium/net/quic/quic_flags_list.h
@@ -166,9 +166,6 @@ QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2,
false)
-// If true, will negotiate the ACK delay time.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_negotiate_ack_delay_time, true)
-
// If true, QuicFramer::WriteClientVersionNegotiationProbePacket uses
// length-prefixed connection IDs.
QUIC_FLAG(bool, FLAGS_quic_prober_uses_length_prefixed_connection_ids, false)
@@ -212,7 +209,7 @@ QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_probe_rtt_period_ms, 10000)
// The default loss threshold for QUIC BBRv2, should be a value
// between 0 and 1.
-QUIC_FLAG(double, FLAGS_quic_bbr2_default_loss_threshold, 0.3)
+QUIC_FLAG(double, FLAGS_quic_bbr2_default_loss_threshold, 0.02)
// The default minimum number of loss marking events to exit STARTUP.
QUIC_FLAG(int32_t, FLAGS_quic_bbr2_default_startup_full_loss_count, 8)
@@ -228,20 +225,26 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q046, false)
// If true, disable QUIC version Q048.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q048, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q048, true)
// If true, disable QUIC version Q049.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q049, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q049, true)
// If true, disable QUIC version Q050.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
-// If true, enable QUIC version T050.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_t050_v2, true)
-
// A testonly reloadable flag that will always default to false.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
+// A testonly reloadable flag that will always default to true.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
+
+// A testonly restart flag that will always default to false.
+QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_testonly_default_false, false)
+
+// A testonly restart flag that will always default to true.
+QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_testonly_default_true, true)
+
// In BBR, slow pacing rate if it is likely causing overshoot.
QUIC_FLAG(
bool,
@@ -263,20 +266,11 @@ QUIC_FLAG(bool,
// If true, use predictable grease settings identifiers and values.
QUIC_FLAG(bool, FLAGS_quic_enable_http3_grease_randomness, true)
-// If true, enable QUIC version h3-25.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_enable_version_draft_25_v3,
- true)
+// If true, disable QUIC version h3-25.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_draft_25, false)
-// If true, enable QUIC version h3-27.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_draft_27, true)
-
-// If true, fix QUIC bandwidth sampler to avoid over estimating bandwidth in
-// the presence of ack aggregation.
-QUIC_FLAG(
- bool,
- FLAGS_quic_reloadable_flag_quic_avoid_overestimate_bandwidth_with_aggregation,
- true)
+// If true, disable QUIC version h3-27.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_draft_27, false)
// If true, QUIC BBRv2 to take ack height into account when calculating
// queuing_threshold in PROBE_UP.
@@ -285,38 +279,13 @@ QUIC_FLAG(
FLAGS_quic_reloadable_flag_quic_bbr2_add_ack_height_to_queueing_threshold,
true)
-// If true, quic::BandwidthSampler will start in application limited phase.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_bw_sampler_app_limited_starting_value,
- true)
-
// If true, use idle network detector to detect handshake timeout and idle
// network timeout.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_use_idle_network_detector,
- false)
-
-// If true, QUIC will enable connection options LRTT+BBQ2 by default.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_bbr_default_exit_startup_on_loss,
- false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_idle_network_detector, true)
// If true, server push will be allowed in QUIC versions using HTTP/3.
QUIC_FLAG(bool, FLAGS_quic_enable_http3_server_push, false)
-// If true, disable QuicDispatcher workaround that replies to invalid QUIC
-// packets from the Android Conformance Test.
-QUIC_FLAG(
- bool,
- FLAGS_quic_reloadable_flag_quic_remove_android_conformance_test_workaround,
- true)
-
-// If true, lower the CWND gain in BBRv2 STARTUP to 2 when BBQ2 is in connection
-// options.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_bbr2_lower_startup_cwnd_gain,
- true)
-
// The divisor that controls how often MAX_STREAMS frames are sent.
QUIC_FLAG(int32_t, FLAGS_quic_max_streams_window_divisor, 2)
@@ -333,25 +302,10 @@ QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_bbr2_fewer_startup_round_trips,
false)
-// If true, remove draining_streams_ from QuicSession.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_deprecate_draining_streams,
- true)
-
-// If true, break session/stream close loop.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_break_session_stream_close_loop,
- true)
-
// Replace the usage of ConnectionData::encryption_level in
// quic_time_wait_list_manager with a new TimeWaitAction.
QUIC_FLAG(bool,
FLAGS_quic_restart_flag_quic_replace_time_wait_list_encryption_level,
- false)
-
-// If true, move Goolge QUIC stream accounting to LegacyQuicStreamIdManager.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_stream_id_manager_handles_accounting,
true)
// If true, enables support for TLS resumption in QUIC.
@@ -360,58 +314,153 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_tls_resumption, false)
// When true, QUIC's BBRv2 ignores inflight_lo in PROBE_BW.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr2_ignore_inflight_lo, false)
-// If true, returns min_rtt in rtt_stats_ if it is available.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_use_available_min_rtt, true)
+// If true, do not change ACK in PostProcessAckFrame if an ACK has been queued.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_donot_change_queued_ack, true)
+
+// If true, reject IETF QUIC connections with invalid SNI.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_tls_enforce_valid_sni, true)
+
+// If true, support for IETF QUIC 0-rtt is enabled.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_zero_rtt_for_tls, true)
+
+// If true, default on PTO which unifies TLP + RTO loss recovery.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
-// If true, notify handshakers when connection closes.
+// When true, QUIC+TLS will not send nor parse the old-format Google-specific
+// transport parameters.
QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_notify_handshaker_on_connection_close,
+ FLAGS_quic_restart_flag_quic_google_transport_param_omit_old,
+ false)
+
+// When true, QUIC+TLS will send and parse the new-format Google-specific
+// transport parameters.
+QUIC_FLAG(bool,
+ FLAGS_quic_restart_flag_quic_google_transport_param_send_new,
true)
-// If true, for QUIC + TLS, change default encryption level when new encryption
-// key is available.
+// If true, check ShouldGeneratePacket for every crypto packet.
QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_change_default_encryption_level,
+ FLAGS_quic_reloadable_flag_quic_fix_checking_should_generate_packet,
true)
-// If true, do not change ACK in PostProcessAckFrame if an ACK has been queued.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_donot_change_queued_ack, false)
+// If true, notify stream ID manager even connection disconnects.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_notify_stream_id_manager_when_disconnected,
+ true)
-// If true, reject IETF QUIC connections with invalid SNI.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_tls_enforce_valid_sni, false)
+// If true, return from QuicCryptoStream::WritePendingCryptoRetransmission after
+// partial writes.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_fix_write_pending_crypto_retransmission,
+ true)
-// If true, update ack timeout upon receiving an retransmittable frame.
+// If true, clear last_inflight_packets_sent_time_ of a packet number space when
+// there is no bytes in flight.
QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_advance_ack_timeout_update,
- false)
+ FLAGS_quic_reloadable_flag_quic_fix_last_inflight_packets_sent_time,
+ true)
-// If true, only extend idle time on decryptable packets.
+// If true, QUIC will free writer-allocated packet buffer if writer->WritePacket
+// is not called.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_avoid_leak_writer_buffer, false)
+
+// If true, QuicConnection::SendAllPendingAcks will Update instead of Set the
+// ack alarm.
QUIC_FLAG(
bool,
- FLAGS_quic_reloadable_flag_quic_extend_idle_time_on_decryptable_packets,
- false)
+ FLAGS_quic_reloadable_flag_quic_update_ack_alarm_in_send_all_pending_acks,
+ true)
-// If true, support for IETF QUIC 0-rtt is enabled.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_zero_rtt_for_tls, false)
+// If true, the B2HI connection option limits reduction of inflight_hi to
+// (1-Beta)*CWND.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr2_limit_inflight_hi, false)
-// If true, default on PTO which unifies TLP + RTO loss recovery.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
+// When true, always check the amplification limit before writing, not just for
+// handshake packets.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_move_amplification_limit, true)
-// When true, QUIC+TLS will not send nor parse the old-format Google-specific
-// transport parameters.
+// If true, SendAllPendingAcks always send the earliest ACK.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_always_send_earliest_ack, true)
+
+// If true, check connection level flow control for send control stream and
+// qpack streams in QuicSession::WillingAndAbleToWrite.
QUIC_FLAG(bool,
- FLAGS_quic_restart_flag_quic_google_transport_param_omit_old,
+ FLAGS_quic_reloadable_flag_quic_fix_willing_and_able_to_write,
+ true)
+
+// If true, disable QUIC version h3-T050.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_t050, false)
+
+// If true, do not arm PTO on half RTT packets if they are the only ones in
+// flight.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_server_pto_timeout, true)
+
+// If true, default-enable 5RTO blachole detection.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2,
+ true)
+
+// If true, session does not send duplicate MAX_STREAMS.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_stop_sending_duplicate_max_streams,
+ true)
+
+// If true, enable QUIC version h3-29.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_draft_29, true)
+
+// If true, support HANDSHAKE_DONE frame in T050
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_support_handshake_done_in_t050,
+ true)
+
+// If true, save user agent into in QuicSession.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_save_user_agent_in_quic_session,
false)
-// When true, QUIC+TLS will send and parse the new-format Google-specific
-// transport parameters.
+// When true, QUIC_CRYPTO versions of QUIC will not send the max ACK delay
+// unless it is configured to a non-default value.
QUIC_FLAG(bool,
- FLAGS_quic_restart_flag_quic_google_transport_param_send_new,
+ FLAGS_quic_reloadable_flag_quic_dont_send_max_ack_delay_if_default,
true)
-// If true, if a buffered MTU packet causes a write to return MSG_TOO_BIG, this
-// error will be ignored.
+// If true, remove the head of line blocking caused by an unprocessable packet
+// in the undecryptable packets list.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_undecryptable_packets, true)
+
+// If true, QUIC client only tries to retransmit data when 1-RTT key is
+// available.
QUIC_FLAG(
bool,
- FLAGS_quic_reloadable_flag_quic_ignore_msg_too_big_from_buffered_packets,
+ FLAGS_quic_reloadable_flag_quic_do_not_retransmit_immediately_on_zero_rtt_reject,
true)
+
+// If true, try to bundle INITIAL data when trying to send INITIAL ACK.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_bundle_crypto_data_with_initial_ack,
+ true)
+
+// If true, do not use QuicUtil::IsBidirectionalStreamId() to determine gQUIC
+// stream type.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_gquic_stream_type, true)
+
+// When true, do not pad the QUIC_CRYPTO CHLO message itself. Note that the
+// packet containing the CHLO will still be padded.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_dont_pad_chlo, false)
+
+// If true, include MinPlaintextPacketSize when determine whether removing soft
+// limit for crypto frames.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_min_crypto_frame_size, true)
+
+// When true, QuicDispatcher supports decapsulation of Legacy Version
+// Encapsulation packets.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_dispatcher_legacy_version_encapsulation,
+ false)
+
+// If true, update packet size when the first frame gets queued.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_update_packet_size, false)
diff --git a/chromium/net/quic/quic_http3_logger.cc b/chromium/net/quic/quic_http3_logger.cc
index c190156ff45..e93ff2987ea 100644
--- a/chromium/net/quic/quic_http3_logger.cc
+++ b/chromium/net/quic/quic_http3_logger.cc
@@ -9,10 +9,13 @@
#include <vector>
#include "base/metrics/histogram_macros.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
+#include "net/http/http_log_util.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_values.h"
+#include "net/spdy/spdy_log_util.h"
namespace net {
@@ -64,20 +67,19 @@ base::Value NetLogThreeIntParams(base::StringPiece name1,
return dict;
}
-base::Value NetLogHeadersToDict(const quic::QuicHeaderList& headers) {
- base::Value dict(base::Value::Type::DICTIONARY);
- for (auto header : headers) {
- dict.SetStringKey(header.first, header.second);
- }
- return dict;
-}
-
-base::Value NetLogHeadersToDict(const spdy::SpdyHeaderBlock& headers) {
- base::Value dict(base::Value::Type::DICTIONARY);
- for (auto header : headers) {
- dict.SetStringKey(header.first, header.second);
+base::ListValue ElideQuicHeaderListForNetLog(
+ const quic::QuicHeaderList& headers,
+ NetLogCaptureMode capture_mode) {
+ base::ListValue headers_list;
+ for (const auto& header : headers) {
+ base::StringPiece key = header.first;
+ base::StringPiece value = header.second;
+ headers_list.Append(NetLogStringValue(
+ base::StrCat({key, ": ",
+ ElideHeaderValueForNetLog(capture_mode, key.as_string(),
+ value.as_string())})));
}
- return dict;
+ return headers_list;
}
} // namespace
@@ -248,11 +250,13 @@ void QuicHttp3Logger::OnHeadersDecoded(quic::QuicStreamId stream_id,
return;
}
net_log_.AddEvent(
- NetLogEventType::HTTP3_HEADERS_DECODED, [stream_id, &headers] {
+ NetLogEventType::HTTP3_HEADERS_DECODED,
+ [stream_id, &headers](NetLogCaptureMode capture_mode) {
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetKey("stream_id",
NetLogNumberValue(static_cast<uint64_t>(stream_id)));
- dict.SetKey("headers", NetLogHeadersToDict(headers));
+ dict.SetKey("headers",
+ ElideQuicHeaderListForNetLog(headers, capture_mode));
return dict;
});
}
@@ -279,16 +283,18 @@ void QuicHttp3Logger::OnPushPromiseDecoded(quic::QuicStreamId stream_id,
if (!net_log_.IsCapturing()) {
return;
}
- net_log_.AddEvent(NetLogEventType::HTTP3_PUSH_PROMISE_DECODED, [stream_id,
- push_id,
- &headers] {
- base::Value dict(base::Value::Type::DICTIONARY);
- dict.SetKey("stream_id",
- NetLogNumberValue(static_cast<uint64_t>(stream_id)));
- dict.SetKey("push_id", NetLogNumberValue(static_cast<uint64_t>(push_id)));
- dict.SetKey("headers", NetLogHeadersToDict(headers));
- return dict;
- });
+ net_log_.AddEvent(
+ NetLogEventType::HTTP3_PUSH_PROMISE_DECODED,
+ [stream_id, push_id, &headers](NetLogCaptureMode capture_mode) {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetKey("stream_id",
+ NetLogNumberValue(static_cast<uint64_t>(stream_id)));
+ dict.SetKey("push_id",
+ NetLogNumberValue(static_cast<uint64_t>(push_id)));
+ dict.SetKey("headers",
+ ElideQuicHeaderListForNetLog(headers, capture_mode));
+ return dict;
+ });
}
void QuicHttp3Logger::OnUnknownFrameReceived(
@@ -357,11 +363,13 @@ void QuicHttp3Logger::OnHeadersFrameSent(
return;
}
net_log_.AddEvent(
- NetLogEventType::HTTP3_HEADERS_SENT, [stream_id, &header_block] {
+ NetLogEventType::HTTP3_HEADERS_SENT,
+ [stream_id, &header_block](NetLogCaptureMode capture_mode) {
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetKey("stream_id",
NetLogNumberValue(static_cast<uint64_t>(stream_id)));
- dict.SetKey("headers", NetLogHeadersToDict(header_block));
+ dict.SetKey("headers",
+ ElideSpdyHeaderBlockForNetLog(header_block, capture_mode));
return dict;
});
}
@@ -373,16 +381,18 @@ void QuicHttp3Logger::OnPushPromiseFrameSent(
if (!net_log_.IsCapturing()) {
return;
}
- net_log_.AddEvent(NetLogEventType::HTTP3_PUSH_PROMISE_SENT, [stream_id,
- push_id,
- &header_block] {
- base::Value dict(base::Value::Type::DICTIONARY);
- dict.SetKey("stream_id",
- NetLogNumberValue(static_cast<uint64_t>(stream_id)));
- dict.SetKey("push_id", NetLogNumberValue(static_cast<uint64_t>(push_id)));
- dict.SetKey("headers", NetLogHeadersToDict(header_block));
- return dict;
- });
+ net_log_.AddEvent(
+ NetLogEventType::HTTP3_PUSH_PROMISE_SENT,
+ [stream_id, push_id, &header_block](NetLogCaptureMode capture_mode) {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetKey("stream_id",
+ NetLogNumberValue(static_cast<uint64_t>(stream_id)));
+ dict.SetKey("push_id",
+ NetLogNumberValue(static_cast<uint64_t>(push_id)));
+ dict.SetKey("headers",
+ ElideSpdyHeaderBlockForNetLog(header_block, capture_mode));
+ return dict;
+ });
}
} // namespace net
diff --git a/chromium/net/quic/quic_http_stream.cc b/chromium/net/quic/quic_http_stream.cc
index 2107b89a840..5b21bb9e067 100644
--- a/chromium/net/quic/quic_http_stream.cc
+++ b/chromium/net/quic/quic_http_stream.cc
@@ -94,23 +94,26 @@ HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion(
case quic::QUIC_VERSION_46:
return HttpResponseInfo::CONNECTION_INFO_QUIC_46;
case quic::QUIC_VERSION_48:
- return quic_version.handshake_protocol == quic::PROTOCOL_TLS1_3
+ return quic_version.UsesTls()
? HttpResponseInfo::CONNECTION_INFO_QUIC_T048
: HttpResponseInfo::CONNECTION_INFO_QUIC_Q048;
case quic::QUIC_VERSION_49:
- return quic_version.handshake_protocol == quic::PROTOCOL_TLS1_3
+ return quic_version.UsesTls()
? HttpResponseInfo::CONNECTION_INFO_QUIC_T049
: HttpResponseInfo::CONNECTION_INFO_QUIC_Q049;
case quic::QUIC_VERSION_50:
- return quic_version.handshake_protocol == quic::PROTOCOL_TLS1_3
+ return quic_version.UsesTls()
? HttpResponseInfo::CONNECTION_INFO_QUIC_T050
: HttpResponseInfo::CONNECTION_INFO_QUIC_Q050;
case quic::QUIC_VERSION_IETF_DRAFT_25:
- DCHECK(quic_version.handshake_protocol == quic::PROTOCOL_TLS1_3);
+ DCHECK(quic_version.UsesTls());
return HttpResponseInfo::CONNECTION_INFO_QUIC_DRAFT_25;
case quic::QUIC_VERSION_IETF_DRAFT_27:
- DCHECK(quic_version.handshake_protocol == quic::PROTOCOL_TLS1_3);
+ DCHECK(quic_version.UsesTls());
return HttpResponseInfo::CONNECTION_INFO_QUIC_DRAFT_27;
+ case quic::QUIC_VERSION_IETF_DRAFT_29:
+ DCHECK(quic_version.UsesTls());
+ return HttpResponseInfo::CONNECTION_INFO_QUIC_DRAFT_29;
case quic::QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
return HttpResponseInfo::CONNECTION_INFO_QUIC_999;
}
diff --git a/chromium/net/quic/quic_http_stream_test.cc b/chromium/net/quic/quic_http_stream_test.cc
index c5638861d8c..7432512b4d8 100644
--- a/chromium/net/quic/quic_http_stream_test.cc
+++ b/chromium/net/quic/quic_http_stream_test.cc
@@ -1111,7 +1111,7 @@ TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
// TODO(nharper): Figure out why this test does not send packets
// when TLS is used.
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
Initialize();
return;
@@ -1615,10 +1615,11 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestAbortedByResetStream) {
kIncludeVersion, !kFin, DEFAULT_PRIORITY, 0,
&spdy_request_headers_frame_length, {header, kUploadData}));
AddWrite(ConstructClientAckPacket(packet_number++, 3, 1, 2));
- AddWrite(client_maker_.MakeRstPacket(
- packet_number++,
- /* include_version = */ true, stream_id_, quic::QUIC_STREAM_NO_ERROR,
- /* include_stop_sending_if_v99 = */ false));
+ AddWrite(client_maker_.MakeAckAndRstPacket(
+ packet_number++,
+ /* include_version = */ true, stream_id_, quic::QUIC_STREAM_NO_ERROR,
+ 4, 1, 1,
+ /* include_stop_sending_if_v99 = */ false));
} else {
AddWrite(ConstructRequestHeadersAndDataFramesPacket(
packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
diff --git a/chromium/net/quic/quic_http_utils.cc b/chromium/net/quic/quic_http_utils.cc
index 077bd50335e..1faf58cce2f 100644
--- a/chromium/net/quic/quic_http_utils.cc
+++ b/chromium/net/quic/quic_http_utils.cc
@@ -64,8 +64,9 @@ quic::ParsedQuicVersionVector FilterSupportedAltSvcVersions(
<< quic_alt_svc.protocol_id;
for (uint32_t quic_version : quic_alt_svc.version) {
- for (quic::ParsedQuicVersion supported : supported_versions) {
- if (supported.handshake_protocol == quic::PROTOCOL_QUIC_CRYPTO &&
+ for (const quic::ParsedQuicVersion& supported : supported_versions) {
+ if (supported.UsesQuicCrypto() &&
+ supported.SupportsGoogleAltSvcFormat() &&
static_cast<uint32_t>(supported.transport_version) == quic_version) {
supported_alt_svc_versions.push_back(supported);
RecordAltSvcFormat(GOOGLE_FORMAT);
diff --git a/chromium/net/quic/quic_http_utils_test.cc b/chromium/net/quic/quic_http_utils_test.cc
index d1609675277..34356cf2db1 100644
--- a/chromium/net/quic/quic_http_utils_test.cc
+++ b/chromium/net/quic/quic_http_utils_test.cc
@@ -11,9 +11,6 @@
#include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h"
#include "testing/gtest/include/gtest/gtest.h"
-using quic::ParsedQuicVersion;
-using quic::PROTOCOL_QUIC_CRYPTO;
-
namespace net {
namespace test {
@@ -45,20 +42,18 @@ TEST(QuicHttpUtilsTest, FilterSupportedAltSvcVersions) {
// finds the intersection of the two sets ... version C. Note that
// as QUIC versions are defined/undefined, the exact version numbers
// used may need to change. The actual version numbers are not
- // important.
+ // important. Note that FilterSupportedAltSvcVersions is only used
+ // for the old Google-specific Alt-Svc format which is now deprecated.
quic::ParsedQuicVersionVector supported_versions = {
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_48),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_43),
+ quic::ParsedQuicVersion::Q050(),
+ quic::ParsedQuicVersion::Q043(),
};
- std::vector<uint32_t> alt_svc_versions_google = {quic::QUIC_VERSION_48,
- quic::QUIC_VERSION_46};
- std::vector<uint32_t> alt_svc_versions_ietf = {
- QuicVersionToQuicVersionLabel(quic::QUIC_VERSION_48),
- QuicVersionToQuicVersionLabel(quic::QUIC_VERSION_46)};
+ std::vector<uint32_t> alt_svc_versions_google = {
+ 33, quic::ParsedQuicVersion::Q043().transport_version};
quic::ParsedQuicVersionVector supported_alt_svc_versions = {
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_48)};
+ quic::ParsedQuicVersion::Q043()};
spdy::SpdyAltSvcWireFormat::AlternativeService altsvc;
altsvc.protocol_id = "quic";
diff --git a/chromium/net/quic/quic_network_transaction_unittest.cc b/chromium/net/quic/quic_network_transaction_unittest.cc
index 5dc3abdbe8c..e1068b88a76 100644
--- a/chromium/net/quic/quic_network_transaction_unittest.cc
+++ b/chromium/net/quic/quic_network_transaction_unittest.cc
@@ -38,6 +38,7 @@
#include "net/http/http_stream.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_transaction_test_util.h"
+#include "net/http/test_upload_data_stream_not_allow_http1.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_event_type.h"
#include "net/log/test_net_log.h"
@@ -449,6 +450,16 @@ class QuicNetworkTransactionTest
}
std::unique_ptr<quic::QuicEncryptedPacket>
+ ConstructClientPriorityFramesPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
+ priority_frames) {
+ return client_maker_->MakeMultiplePriorityFramesPacket(
+ packet_number, should_include_version, priority_frames);
+ }
+
+ std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientAckAndPriorityFramesPacket(
uint64_t packet_number,
bool should_include_version,
@@ -462,6 +473,20 @@ class QuicNetworkTransactionTest
smallest_received, least_unacked, priority_frames);
}
+ std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ uint64_t largest_received,
+ uint64_t smallest_received,
+ quic::QuicStreamId id,
+ quic::QuicStreamId parent_stream_id,
+ RequestPriority request_priority) {
+ return client_maker_->MakeAckAndPriorityPacket(
+ packet_number, should_include_version, largest_received,
+ smallest_received, id, parent_stream_id,
+ ConvertRequestPriorityToQuicPriority(request_priority));
+ }
+
// Uses default QuicTestPacketMaker.
spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
const std::string& scheme,
@@ -1723,7 +1748,8 @@ TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
}
TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
- quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
+ quic::ParsedQuicVersion unsupported_version =
+ quic::ParsedQuicVersion::Unsupported();
// Add support for another QUIC version besides |version_|. Also find an
// unsupported version.
for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
@@ -1737,7 +1763,7 @@ TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
break;
}
ASSERT_EQ(2u, supported_versions_.size());
- ASSERT_NE(quic::UnsupportedQuicVersion(), unsupported_version);
+ ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
// Set up alternative service to use QUIC with a version that is not
// supported.
@@ -1816,10 +1842,10 @@ TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
alt_svc_info_vector =
session_->http_server_properties()->GetAlternativeServiceInfos(
server, NetworkIsolationKey());
- // All PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc entry,
- // therefore they aer accumulated in a single AlternativeServiceInfo, whereas
- // each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
- // AlternativeServiceInfo entry. Flatten to compare.
+ // Versions that support the legacy Google-specific Alt-Svc format are sent in
+ // a single Alt-Svc entry, therefore they are accumulated in a single
+ // AlternativeServiceInfo, whereas more recent versions all have their own
+ // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
for (const auto& alt_svc_info : alt_svc_info_vector) {
EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
@@ -2177,7 +2203,8 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
// Add support for another QUIC version besides |version_| on the client side.
// Also find a different version advertised by the server.
- quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
+ quic::ParsedQuicVersion advertised_version_2 =
+ quic::ParsedQuicVersion::Unsupported();
for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
if (version == version_)
continue;
@@ -2189,7 +2216,7 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
break;
}
ASSERT_EQ(2u, supported_versions_.size());
- ASSERT_NE(quic::UnsupportedQuicVersion(), advertised_version_2);
+ ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
std::string QuicAltSvcWithVersionHeader =
base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
@@ -2251,23 +2278,15 @@ TEST_P(QuicNetworkTransactionTest,
// TestPacketMakers and the response.
// Find an alternative commonly supported version other than |version_|.
- quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
- if (version_.handshake_protocol == quic::PROTOCOL_QUIC_CRYPTO) {
- for (const quic::ParsedQuicVersion& version :
- quic::AllSupportedVersions()) {
- if (version == version_)
- continue;
+ quic::ParsedQuicVersion common_version_2 =
+ quic::ParsedQuicVersion::Unsupported();
+ for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
+ if (version != version_) {
common_version_2 = version;
break;
}
- } else if (version_.transport_version == quic::QUIC_VERSION_IETF_DRAFT_27) {
- common_version_2 = quic::ParsedQuicVersion(
- quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_IETF_DRAFT_25);
- } else {
- common_version_2 = quic::ParsedQuicVersion(
- quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_IETF_DRAFT_27);
}
- ASSERT_NE(quic::UnsupportedQuicVersion(), common_version_2);
+ ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
// Setting up client's preference list: {|version_|, |common_version_2|}.
supported_versions_.clear();
@@ -2277,12 +2296,13 @@ TEST_P(QuicNetworkTransactionTest,
// Setting up server's Alt-Svc header in the following preference order:
// |common_version_2|, |version_|.
std::string QuicAltSvcWithVersionHeader;
- quic::ParsedQuicVersion picked_version = quic::UnsupportedQuicVersion();
- QuicAltSvcWithVersionHeader =
- "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
- "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
- "=\":443\"; ma=3600\r\n\r\n";
- picked_version = common_version_2; // Use server's preference.
+ quic::ParsedQuicVersion picked_version =
+ quic::ParsedQuicVersion::Unsupported();
+ QuicAltSvcWithVersionHeader =
+ "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
+ "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
+ "=\":443\"; ma=3600\r\n\r\n";
+ picked_version = common_version_2; // Use server's preference.
MockRead http_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
@@ -2534,10 +2554,10 @@ TEST_P(QuicNetworkTransactionTest,
const AlternativeServiceInfoVector alt_svc_info_vector =
session_->http_server_properties()->GetAlternativeServiceInfos(
https_server, NetworkIsolationKey());
- // However, all PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc
- // entry, therefore they aer accumulated in a single AlternativeServiceInfo,
- // whereas each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
- // AlternativeServiceInfo entry. Flatten to compare.
+ // Versions that support the legacy Google-specific Alt-Svc format are sent in
+ // a single Alt-Svc entry, therefore they are accumulated in a single
+ // AlternativeServiceInfo, whereas more recent versions all have their own
+ // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
for (const auto& alt_svc_info : alt_svc_info_vector) {
EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
@@ -2696,7 +2716,7 @@ TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
// alternate network as well, QUIC is marked as broken and the brokenness will
// not expire when default network changes.
TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 ||
+ if (version_.UsesTls() ||
GetQuicReloadableFlag(quic_use_idle_network_detector)) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
// TODO(fayang): Add time driven idle network detection test.
@@ -2806,7 +2826,7 @@ TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
// alternate network, QUIC is marked as broken. The brokenness will expire when
// the default network changes.
TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 ||
+ if (version_.UsesTls() ||
GetQuicReloadableFlag(quic_use_idle_network_detector)) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
// TODO(fayang): Add time driven idle network detection test.
@@ -2928,7 +2948,7 @@ TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
// Much like above test, but verifies NetworkIsolationKeys are respected.
TEST_P(QuicNetworkTransactionTest,
RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 ||
+ if (version_.UsesTls() ||
GetQuicReloadableFlag(quic_use_idle_network_detector)) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
// TODO(fayang): Add time driven idle network detection test.
@@ -3076,7 +3096,7 @@ TEST_P(QuicNetworkTransactionTest,
// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
// alternative network succeeds, QUIC is not marked as broken.
TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 ||
+ if (version_.UsesTls() ||
GetQuicReloadableFlag(quic_use_idle_network_detector)) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
// TODO(fayang): Add time driven idle network detection test.
@@ -3201,7 +3221,7 @@ TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
// Verify that if a QUIC connection times out, the QuicHttpStream will
// return QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -3327,11 +3347,6 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
// Verify that if a QUIC protocol error occurs after the handshake is confirmed
// the request fails with QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
context_.params()->retry_without_alt_svc_on_quic_errors = false;
// The request will initially go out over QUIC.
MockQuicData quic_data(version_);
@@ -3355,10 +3370,13 @@ TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
1, false, GetNthClientInitiatedBidirectionalStreamId(47),
quic::QUIC_STREAM_LAST_ERROR));
std::string quic_error_details = "Data for nonexistent stream";
- quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckAndConnectionClosePacket(
- packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
- quic_error_details, quic::IETF_RST_STREAM));
+ quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndConnectionClosePacket(
+ packet_num++, 1, 1, 1,
+ version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
+ : quic::QUIC_INVALID_STREAM_ID,
+ quic_error_details, quic::IETF_RST_STREAM));
quic_data.AddSocketDataToFactory(&socket_factory_);
// In order for a new QUIC session to be established via alternate-protocol
@@ -3402,7 +3420,7 @@ TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
// connection times out, then QUIC will be marked as broken and the request
// retried over TCP.
TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -3550,11 +3568,6 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
// retried over TCP and the QUIC will be marked as broken.
TEST_P(QuicNetworkTransactionTest,
ProtocolErrorAfterHandshakeConfirmedThenBroken) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
// The request will initially go out over QUIC.
@@ -3580,10 +3593,13 @@ TEST_P(QuicNetworkTransactionTest,
1, false, GetNthClientInitiatedBidirectionalStreamId(47),
quic::QUIC_STREAM_LAST_ERROR));
std::string quic_error_details = "Data for nonexistent stream";
- quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckAndConnectionClosePacket(
- packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
- quic_error_details, quic::IETF_RST_STREAM));
+ quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndConnectionClosePacket(
+ packet_num++, 1, 1, 1,
+ version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
+ : quic::QUIC_INVALID_STREAM_ID,
+ quic_error_details, quic::IETF_RST_STREAM));
quic_data.AddSocketDataToFactory(&socket_factory_);
// After that fails, it will be resent via TCP.
@@ -3648,7 +3664,7 @@ TEST_P(QuicNetworkTransactionTest,
// Much like above test, but verifies that NetworkIsolationKey is respected.
TEST_P(QuicNetworkTransactionTest,
ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -3779,11 +3795,6 @@ TEST_P(QuicNetworkTransactionTest,
// request is reset from, then QUIC will be marked as broken and the request
// retried over TCP.
TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
// The request will initially go out over QUIC.
MockQuicData quic_data(version_);
spdy::SpdyPriority priority =
@@ -3810,10 +3821,10 @@ TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
quic::QUIC_HEADERS_TOO_LARGE));
if (VersionUsesHttp3(version_.transport_version)) {
- quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientDataPacket(
- packet_num++, GetQpackDecoderStreamId(), true, false,
- StreamCancellationQpackDecoderInstruction(0)));
+ quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckAndDataPacket(
+ packet_num++, true, GetQpackDecoderStreamId(), 1, 1, 1,
+ false, StreamCancellationQpackDecoderInstruction(0)));
}
quic_data.AddRead(ASYNC, OK);
@@ -4079,10 +4090,12 @@ TEST_P(QuicNetworkTransactionTest,
quic::QUIC_HEADERS_TOO_LARGE));
if (VersionUsesHttp3(version_.transport_version)) {
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientDataPacket(
- packet_num++, GetQpackDecoderStreamId(), true, false,
- StreamCancellationQpackDecoderInstruction(1)));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndDataPacket(
+ packet_num++, /*include_version=*/true, GetQpackDecoderStreamId(),
+ 3, 2, 1,
+ /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
}
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
@@ -4992,7 +5005,7 @@ TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -5039,7 +5052,7 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -5117,11 +5130,6 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
MockQuicData mock_quic_data(version_);
int packet_num = 1;
client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -5181,11 +5189,6 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
uint64_t packet_number = 1;
MockQuicData mock_quic_data(version_);
client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -5282,11 +5285,6 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
uint64_t packet_number = 1;
MockQuicData mock_quic_data(version_);
client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -5339,7 +5337,7 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
SYNCHRONOUS,
ConstructClientAckAndDataPacket(
packet_number++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
- StreamCancellationQpackDecoderInstruction(1)));
+ StreamCancellationQpackDecoderInstruction(1, false)));
mock_quic_data.AddWrite(SYNCHRONOUS,
client_maker_->MakeRstPacket(
packet_number++, false,
@@ -5400,11 +5398,6 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
TEST_P(QuicNetworkTransactionTest,
LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
context_.params()->retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data(version_);
int packet_num = 1;
@@ -5462,11 +5455,6 @@ TEST_P(QuicNetworkTransactionTest,
TEST_P(QuicNetworkTransactionTest,
LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
context_.params()->retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data(version_);
int packet_num = 1;
@@ -5489,9 +5477,12 @@ TEST_P(QuicNetworkTransactionTest,
quic::QUIC_STREAM_LAST_ERROR));
std::string quic_error_details = "Data for nonexistent stream";
mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
- packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
- quic_error_details, quic::IETF_RST_STREAM));
+ SYNCHRONOUS,
+ ConstructClientAckAndConnectionClosePacket(
+ packet_num++, 1, 1, 1,
+ version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
+ : quic::QUIC_INVALID_STREAM_ID,
+ quic_error_details, quic::IETF_RST_STREAM));
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
// The non-alternate protocol job needs to hang in order to guarantee that
@@ -5524,15 +5515,13 @@ TEST_P(QuicNetworkTransactionTest,
EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
trans.PopulateNetErrorDetails(&details);
- EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
+ EXPECT_EQ(version_.HasIetfQuicFrames()
+ ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
+ : quic::QUIC_INVALID_STREAM_ID,
+ details.quic_connection_error);
}
TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
MockQuicData mock_quic_data(version_);
int packet_num = 1;
client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
@@ -5611,11 +5600,6 @@ TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
}
TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
context_.params()->retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data(version_);
int packet_num = 1;
@@ -5637,9 +5621,10 @@ TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
if (VersionUsesHttp3(version_.transport_version)) {
mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientDataPacket(
- packet_num++, GetQpackDecoderStreamId(), true, false,
- StreamCancellationQpackDecoderInstruction(0)));
+ SYNCHRONOUS,
+ ConstructClientAckAndDataPacket(
+ packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
+ StreamCancellationQpackDecoderInstruction(0)));
}
mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
@@ -5810,7 +5795,7 @@ TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
}
TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -5881,11 +5866,6 @@ TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
TEST_P(QuicNetworkTransactionTest,
DelayTCPOnStartWithQuicSupportOnDifferentIP) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // QUIC with TLS1.3 handshake doesn't support 0-rtt.
- return;
- }
-
// Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
// was recently supported on a different IP address on start.
@@ -6031,7 +6011,7 @@ TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
TEST_P(QuicNetworkTransactionTest,
FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// QUIC with TLS1.3 handshake doesn't support 0-rtt.
return;
}
@@ -6656,38 +6636,52 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
1, GetNthClientInitiatedBidirectionalStreamId(0),
GetNthServerInitiatedUnidirectionalStreamId(0), false,
GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
- if ((client_headers_include_h2_stream_dependency_ &&
- version_.transport_version >= quic::QUIC_VERSION_43 &&
- !VersionUsesHttp3(version_.transport_version))) {
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientPriorityPacket(
- client_packet_number++, false,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
+ const bool should_send_priority_packet =
+ client_headers_include_h2_stream_dependency_ &&
+ !VersionUsesHttp3(version_.transport_version);
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndPriorityPacket(
+ client_packet_number++, false,
+ /*largest_received=*/1, /*smallest_received=*/1,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
}
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
GetResponseHeaders("200 OK")));
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ }
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
false, GetResponseHeaders("200 OK")));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
+ }
std::string header = ConstructDataHeader(6);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
header + "hello!"));
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ }
std::string header2 = ConstructDataHeader(10);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
header2 + "and hello!"));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
+ }
if (!VersionUsesHttp3(version_.transport_version)) {
mock_quic_data.AddWrite(SYNCHRONOUS,
ConstructClientAckAndRstPacket(
@@ -6757,30 +6751,39 @@ TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
1, GetNthClientInitiatedBidirectionalStreamId(0),
GetNthServerInitiatedUnidirectionalStreamId(0), false,
GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
- if ((client_headers_include_h2_stream_dependency_ &&
- version_.transport_version >= quic::QUIC_VERSION_43 &&
- !VersionUsesHttp3(version_.transport_version))) {
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientPriorityPacket(
- client_packet_number++, false,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
+ const bool should_send_priority_packet =
+ client_headers_include_h2_stream_dependency_ &&
+ !VersionUsesHttp3(version_.transport_version);
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndPriorityPacket(
+ client_packet_number++, false,
+ /*largest_received=*/1, /*smallest_received=*/1,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
}
// Response headers for first request.
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
GetResponseHeaders("200 OK")));
- // Client ACKs the response headers.
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ if (!should_send_priority_packet) {
+ // Client ACKs the response headers.
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ }
// Response body for first request.
std::string header = ConstructDataHeader(6);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
header + "hello!"));
+ if (should_send_priority_packet) {
+ // Client ACKs the response headers.
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
+ }
// Write error for the third request.
mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
@@ -7027,15 +7030,17 @@ TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
initial;
}
- if ((client_headers_include_h2_stream_dependency_ &&
- version_.transport_version >= quic::QUIC_VERSION_43 &&
- !VersionUsesHttp3(version_.transport_version))) {
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientPriorityPacket(
- client_packet_number++, false,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
+ const bool should_send_priority_packet =
+ client_headers_include_h2_stream_dependency_ &&
+ !VersionUsesHttp3(version_.transport_version);
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndPriorityPacket(
+ client_packet_number++, false,
+ /*largest_received=*/1, /*smallest_received=*/1,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
}
const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
@@ -7053,26 +7058,38 @@ TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
quic::QuicStreamOffset expected_raw_header_response_size =
final_offset - initial_offset;
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ }
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
false, GetResponseHeaders("200 OK")));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
+ }
std::string header = ConstructDataHeader(20);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
header + "Pushed Resource Data"));
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ }
std::string header2 = ConstructDataHeader(18);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
header2 + "Main Resource Data"));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
+ }
mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
@@ -7709,48 +7726,70 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
GetNthServerInitiatedUnidirectionalStreamId(0), false,
GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
- if ((client_headers_include_h2_stream_dependency_ &&
- version_.transport_version >= quic::QUIC_VERSION_43 &&
- !VersionUsesHttp3(version_.transport_version))) {
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientPriorityPacket(
- client_packet_number++, false,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
+ const bool should_send_priority_packet =
+ client_headers_include_h2_stream_dependency_ &&
+ !VersionUsesHttp3(version_.transport_version);
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndPriorityPacket(
+ client_packet_number++, false,
+ /*largest_received=*/1, /*smallest_received=*/1,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
}
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
GetResponseHeaders("200 OK")));
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
+ }
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
false, GetResponseHeaders("200 OK")));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
+ }
std::string header = ConstructDataHeader(6);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
header + "hello!"));
- mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ if (!should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
+ }
std::string header2 = ConstructDataHeader(10);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
header2 + "and hello!"));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
+ }
// Because the matching request has a body, we will see the push
// stream get cancelled, and the matching request go out on the
// wire.
- mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckAndRstPacket(
- client_packet_number++,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
+ if (should_send_priority_packet) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRstPacket(client_packet_number++,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
+ } else {
+ mock_quic_data.AddWrite(SYNCHRONOUS,
+ ConstructClientAckAndRstPacket(
+ client_packet_number++,
+ GetNthServerInitiatedUnidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
+ }
const char kBody[] = "1";
std::string header3 = ConstructDataHeader(1);
if (!version_.HasIetfQuicFrames()) {
@@ -7839,30 +7878,28 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
1, GetNthClientInitiatedBidirectionalStreamId(0),
GetNthServerInitiatedUnidirectionalStreamId(0), false,
std::move(pushed_request_headers), &server_maker_));
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientRstPacket(packet_num++,
- GetNthServerInitiatedUnidirectionalStreamId(0),
- quic::QUIC_INVALID_PROMISE_URL));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndRstPacket(
+ packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
+ quic::QUIC_INVALID_PROMISE_URL, 1, 1, 1));
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
GetResponseHeaders("200 OK")));
- mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckPacket(packet_num++, 2, 1, 1));
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
false, GetResponseHeaders("200 OK")));
+ mock_quic_data.AddWrite(SYNCHRONOUS,
+ ConstructClientAckPacket(packet_num++, 3, 1, 1));
std::string header = ConstructDataHeader(6);
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
header + "hello!"));
- mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckPacket(packet_num++, 4, 3, 1));
mock_quic_data.AddRead(ASYNC, 0);
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -9120,8 +9157,7 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
// Only run this test if HTTP/2 stream dependency info is sent by client (sent
// in HEADERS frames for requests and PRIORITY frames).
- if (version_.transport_version < quic::QUIC_VERSION_43 ||
- !client_headers_include_h2_stream_dependency_) {
+ if (!client_headers_include_h2_stream_dependency_) {
return;
}
@@ -9199,31 +9235,33 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
ConstructServerPushPromisePacket(
5, client_stream_0, push_stream_1, false,
GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
- mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
- packet_num++, false, push_stream_1,
- push_stream_0, DEFAULT_PRIORITY));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckAndPriorityPacket(
+ packet_num++, false,
+ /*largest_received=*/5, /*smallest_received=*/4,
+ push_stream_1, push_stream_0, DEFAULT_PRIORITY));
// Server sends the response headers for the two push promises.
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
- mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckPacket(packet_num++, 6, 5, 1));
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
+ mock_quic_data.AddWrite(SYNCHRONOUS,
+ ConstructClientAckPacket(packet_num++, 7, 5, 1));
// Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
// priority updates to match the request's priority. Client sends PRIORITY
// frames to inform server of new HTTP/2 stream dependencies.
- mock_quic_data.AddWrite(
- SYNCHRONOUS,
- ConstructClientAckAndPriorityFramesPacket(
- packet_num++, false, 7, 7, 1,
- {{push_stream_1, client_stream_2,
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
- {push_stream_0, client_stream_0,
- ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientPriorityFramesPacket(
+ packet_num++, false,
+ {{push_stream_1, client_stream_2,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
+ {push_stream_0, client_stream_0,
+ ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
// Server sends data for the three requests and the two push promises.
std::string header = ConstructDataHeader(8);
@@ -9730,5 +9768,260 @@ TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
}
+TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
+ MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
+ MockRead(ASYNC, OK)};
+ StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
+ socket_factory_.AddSocketDataProvider(&http_data);
+ AddCertificate(&ssl_data_);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ CreateSession();
+
+ request_.method = "POST";
+ UploadDataStreamNotAllowHTTP1 upload_data("");
+ request_.upload_data_stream = &upload_data;
+
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
+ TestCompletionCallback callback;
+ int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
+}
+
+// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
+// QUIC.
+TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
+ context_.params()->origins_to_force_quic_on.insert(
+ HostPortPair::FromString("mail.example.org:443"));
+
+ MockQuicData mock_quic_data(version_);
+ int write_packet_index = 1;
+ if (VersionUsesHttp3(version_.transport_version)) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
+ }
+ const std::string upload_content = "foo";
+ if (!version_.HasIetfQuicFrames()) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {upload_content}));
+ } else {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {ConstructDataHeader(upload_content.length()), upload_content}));
+ }
+ mock_quic_data.AddRead(
+ ASYNC, ConstructServerResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
+ GetResponseHeaders("200 OK")));
+
+ std::string header2 = ConstructDataHeader(6);
+ mock_quic_data.AddRead(
+ ASYNC, ConstructServerDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
+ header2 + "hello!"));
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
+
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ // The non-alternate protocol job needs to hang in order to guarantee that
+ // the alternate-protocol job will "win".
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSession();
+ request_.method = "POST";
+ UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
+ request_.upload_data_stream = &upload_data;
+
+ SendRequestAndExpectQuicResponse("hello!");
+}
+
+TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
+ context_.params()->origins_to_force_quic_on.insert(
+ HostPortPair::FromString("mail.example.org:443"));
+
+ MockQuicData mock_quic_data(version_);
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
+ int write_packet_index = 1;
+ mock_quic_data.AddWrite(
+ ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
+ client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+ if (VersionUsesHttp3(version_.transport_version)) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
+ }
+ const std::string upload_content = "foo";
+ if (!version_.HasIetfQuicFrames()) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {upload_content}));
+ } else {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {ConstructDataHeader(upload_content.length()), upload_content}));
+ }
+ mock_quic_data.AddRead(
+ SYNCHRONOUS, ConstructServerResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ false, GetResponseHeaders("200 OK")));
+ std::string header2 = ConstructDataHeader(6);
+ mock_quic_data.AddRead(
+ SYNCHRONOUS, ConstructServerDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ true, header2 + "hello!"));
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
+
+ CreateSession();
+
+ AddQuicAlternateProtocolMapping(
+ MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
+
+ // Set up request.
+ request_.method = "POST";
+ UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
+ request_.upload_data_stream = &upload_data;
+
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
+ TestCompletionCallback callback;
+ int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ base::RunLoop().RunUntilIdle();
+ // Resume QUIC job
+ crypto_client_stream_factory_.last_stream()
+ ->NotifySessionOneRttKeyAvailable();
+ socket_data->Resume();
+
+ base::RunLoop().RunUntilIdle();
+ CheckResponseData(&trans, "hello!");
+}
+
+TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
+ // This test confirms failed main job should not bother quic job.
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
+ MockRead("1.1 Body"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
+ StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
+ socket_factory_.AddSocketDataProvider(&http_data);
+ AddCertificate(&ssl_data_);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ MockQuicData mock_quic_data(version_);
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
+ int write_packet_index = 1;
+ mock_quic_data.AddWrite(
+ ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
+ client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
+ if (VersionUsesHttp3(version_.transport_version)) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
+ }
+ const std::string upload_content = "foo";
+ if (!version_.HasIetfQuicFrames()) {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {upload_content}));
+ } else {
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, nullptr,
+ {ConstructDataHeader(upload_content.length()), upload_content}));
+ }
+ mock_quic_data.AddRead(
+ SYNCHRONOUS, ConstructServerResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ false, GetResponseHeaders("200 OK")));
+ std::string header = ConstructDataHeader(6);
+ mock_quic_data.AddRead(
+ SYNCHRONOUS, ConstructServerDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ true, header + "hello!"));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
+ mock_quic_data.AddRead(ASYNC, 0); // EOF
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_);
+ SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
+
+ // This packet won't be read because AllowHTTP1:false doesn't allow H/1
+ // connection.
+ MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
+ StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
+ socket_factory_.AddSocketDataProvider(&http_data2);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
+
+ CreateSession();
+
+ // Send the first request via TCP and set up alternative service (QUIC) for
+ // the origin.
+ SendRequestAndExpectHttpResponse("1.1 Body");
+
+ // Settings to resume main H/1 job quickly while pausing quic job.
+ AddQuicAlternateProtocolMapping(
+ MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
+ ServerNetworkStats stats1;
+ stats1.srtt = base::TimeDelta::FromMicroseconds(10);
+ http_server_properties_->SetServerNetworkStats(
+ url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
+
+ // Set up request.
+ request_.method = "POST";
+ UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
+ request_.upload_data_stream = &upload_data;
+
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
+ TestCompletionCallback callback;
+ int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ // Confirm TCP job was resumed.
+ // We can not check its failure because HttpStreamFactory::JobController.
+ // main_job_net_error is not exposed.
+ while (socket_factory_.mock_data().next_index() < 3u)
+ base::RunLoop().RunUntilIdle();
+ // Resume QUIC job.
+ crypto_client_stream_factory_.last_stream()
+ ->NotifySessionOneRttKeyAvailable();
+ socket_data->Resume();
+ base::RunLoop().RunUntilIdle();
+ CheckResponseData(&trans, "hello!");
+}
+
+// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_proxy_client_socket.cc b/chromium/net/quic/quic_proxy_client_socket.cc
index 2d87902522c..dad704704ac 100644
--- a/chromium/net/quic/quic_proxy_client_socket.cc
+++ b/chromium/net/quic/quic_proxy_client_socket.cc
@@ -458,25 +458,7 @@ int QuicProxyClientSocket::ProcessResponseHeaders(
DLOG(WARNING) << "Invalid headers";
return ERR_QUIC_PROTOCOL_ERROR;
}
- // Populate |connect_timing_| when response headers are received. This
- // should take care of 0-RTT where request is sent before handshake is
- // confirmed.
- connect_timing_ = session_->GetConnectTiming();
return OK;
}
-bool QuicProxyClientSocket::GetLoadTimingInfo(
- LoadTimingInfo* load_timing_info) const {
- bool is_first_stream = stream_->IsFirstStream();
- if (stream_)
- is_first_stream = stream_->IsFirstStream();
- if (is_first_stream) {
- load_timing_info->socket_reused = false;
- load_timing_info->connect_timing = connect_timing_;
- } else {
- load_timing_info->socket_reused = true;
- }
- return true;
-}
-
} // namespace net
diff --git a/chromium/net/quic/quic_proxy_client_socket.h b/chromium/net/quic/quic_proxy_client_socket.h
index 723b6670401..a65d0cc4bbb 100644
--- a/chromium/net/quic/quic_proxy_client_socket.h
+++ b/chromium/net/quic/quic_proxy_client_socket.h
@@ -10,7 +10,6 @@
#include <string>
#include "net/base/completion_once_callback.h"
-#include "net/base/load_timing_info.h"
#include "net/base/proxy_server.h"
#include "net/http/proxy_client_socket.h"
#include "net/quic/quic_chromium_client_session.h"
@@ -109,8 +108,6 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
int DoReadReply();
int DoReadReplyComplete(int result);
- bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
-
State next_state_;
// Handle to the QUIC Stream that this sits on top of.
@@ -148,9 +145,6 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
std::string user_agent_;
- // Session connect timing info.
- LoadTimingInfo::ConnectTiming connect_timing_;
-
const NetLogWithSource net_log_;
// The default weak pointer factory.
diff --git a/chromium/net/quic/quic_proxy_client_socket_unittest.cc b/chromium/net/quic/quic_proxy_client_socket_unittest.cc
index 045cfeec480..0129108e9fa 100644
--- a/chromium/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/chromium/net/quic/quic_proxy_client_socket_unittest.cc
@@ -187,9 +187,7 @@ class QuicProxyClientSocketTest : public ::testing::TestWithParam<TestParams>,
IPAddress ip(192, 0, 2, 33);
peer_addr_ = IPEndPoint(ip, 443);
clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- quic::QuicEnableVersion(version_);
- }
+ quic::QuicEnableVersion(version_);
}
void SetUp() override {}
diff --git a/chromium/net/quic/quic_session_key.cc b/chromium/net/quic/quic_session_key.cc
index b2393c547a7..ff1a8f524fc 100644
--- a/chromium/net/quic/quic_session_key.cc
+++ b/chromium/net/quic/quic_session_key.cc
@@ -30,7 +30,12 @@ QuicSessionKey::QuicSessionKey(const std::string& host,
const NetworkIsolationKey& network_isolation_key,
bool disable_secure_dns)
: QuicSessionKey(
- quic::QuicServerId(host, port, privacy_mode == PRIVACY_MODE_ENABLED),
+ // TODO(crbug.com/1103350): Handle non-boolean privacy modes.
+ quic::QuicServerId(
+ host,
+ port,
+ privacy_mode == PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS ||
+ privacy_mode == PRIVACY_MODE_ENABLED),
socket_tag,
network_isolation_key,
disable_secure_dns) {}
diff --git a/chromium/net/quic/quic_stream_factory.cc b/chromium/net/quic/quic_stream_factory.cc
index 3358bd3d4be..6361607eb00 100644
--- a/chromium/net/quic/quic_stream_factory.cc
+++ b/chromium/net/quic/quic_stream_factory.cc
@@ -45,6 +45,7 @@
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
+#include "net/quic/quic_client_session_cache.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/quic_http_stream.h"
@@ -118,39 +119,31 @@ base::Value NetLogQuicStreamFactoryJobParams(
return std::move(dict);
}
-// Helper class that is used to log a connection migration event.
-class ScopedConnectionMigrationEventLog {
- public:
- ScopedConnectionMigrationEventLog(NetLog* net_log, const char* trigger)
- : net_log_(NetLogWithSource::Make(
- net_log,
- NetLogSourceType::QUIC_CONNECTION_MIGRATION)) {
- net_log_.BeginEventWithStringParams(
- NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED, "trigger",
- trigger);
- }
-
- ~ScopedConnectionMigrationEventLog() {
- net_log_.EndEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
+std::string QuicPlatformNotificationToString(
+ QuicPlatformNotification notification) {
+ switch (notification) {
+ case NETWORK_CONNECTED:
+ return "OnNetworkConnected";
+ case NETWORK_MADE_DEFAULT:
+ return "OnNetworkMadeDefault";
+ case NETWORK_DISCONNECTED:
+ return "OnNetworkDisconnected";
+ case NETWORK_SOON_TO_DISCONNECT:
+ return "OnNetworkSoonToDisconnect";
+ case NETWORK_IP_ADDRESS_CHANGED:
+ return "OnIPAddressChanged";
+ default:
+ QUIC_NOTREACHED();
+ break;
}
-
- const NetLogWithSource& net_log() { return net_log_; }
-
- private:
- const NetLogWithSource net_log_;
-};
+ return "InvalidNotification";
+}
void HistogramCreateSessionFailure(enum CreateSessionFailure error) {
UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error,
CREATION_ERROR_MAX);
}
-void LogPlatformNotificationInHistogram(
- enum QuicPlatformNotification notification) {
- UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.PlatformNotification",
- notification, NETWORK_NOTIFICATION_MAX);
-}
-
void LogConnectionIpPooling(bool pooled) {
UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionIpPooled", pooled);
}
@@ -225,8 +218,9 @@ class QuicStreamFactory::QuicCryptoClientConfigOwner {
public:
QuicCryptoClientConfigOwner(
std::unique_ptr<quic::ProofVerifier> proof_verifier,
+ std::unique_ptr<QuicClientSessionCache> session_cache,
QuicStreamFactory* quic_stream_factory)
- : config_(std::move(proof_verifier)),
+ : config_(std::move(proof_verifier), std::move(session_cache)),
quic_stream_factory_(quic_stream_factory) {
DCHECK(quic_stream_factory_);
}
@@ -390,8 +384,11 @@ class QuicStreamFactory::Job {
if (session_) {
QuicChromiumClientSession* session = session_;
session_ = nullptr;
+ // Use ERR_FAILED instead of ERR_ABORTED out of paranoia - ERR_ABORTED
+ // should only be used when the next layer up cancels a request, and has
+ // special semantic meaning for some consumers when they see it.
session->CloseSessionOnErrorLater(
- ERR_ABORTED, quic::QUIC_STALE_CONNECTION_CANCELLED,
+ ERR_FAILED, quic::QUIC_STALE_CONNECTION_CANCELLED,
quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
}
@@ -769,7 +766,7 @@ int QuicStreamFactory::Job::DoConnect() {
NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT, NetLogEventPhase::BEGIN,
"require_confirmation", require_confirmation);
- DCHECK_NE(quic_version_.transport_version, quic::QUIC_VERSION_UNSUPPORTED);
+ DCHECK_NE(quic_version_, quic::ParsedQuicVersion::Unsupported());
int rv = factory_->CreateSession(
key_, quic_version_, cert_verify_flags_, require_confirmation,
resolve_host_request_->GetAddressResults().value(),
@@ -956,7 +953,7 @@ int QuicStreamRequest::Request(
NetErrorDetails* net_error_details,
CompletionOnceCallback failed_on_default_network_callback,
CompletionOnceCallback callback) {
- DCHECK_NE(quic_version.transport_version, quic::QUIC_VERSION_UNSUPPORTED);
+ DCHECK_NE(quic_version, quic::ParsedQuicVersion::Unsupported());
DCHECK(net_error_details);
DCHECK(callback_.is_null());
DCHECK(host_resolution_callback_.is_null());
@@ -1106,6 +1103,7 @@ QuicStreamFactory::QuicStreamFactory(
need_to_check_persisted_supports_quic_(true),
prefer_aes_gcm_recorded_(false),
num_push_streams_created_(0),
+ connectivity_monitor_(default_network_),
tick_clock_(nullptr),
task_runner_(nullptr),
ssl_config_service_(ssl_config_service),
@@ -1114,6 +1112,8 @@ QuicStreamFactory::QuicStreamFactory(
features::kPartitionHttpServerPropertiesByNetworkIsolationKey)) {
DCHECK(transport_security_state_);
DCHECK(http_server_properties_);
+ if (params_.disable_tls_zero_rtt)
+ SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, false);
InitializeMigrationOptions();
}
@@ -1174,7 +1174,7 @@ int QuicStreamFactory::Create(const QuicSessionKey& session_key,
QuicStreamRequest* request) {
if (clock_skew_detector_.ClockSkewDetected(base::TimeTicks::Now(),
base::Time::Now())) {
- MarkAllActiveSessionsGoingAway();
+ MarkAllActiveSessionsGoingAway(kClockSkewDetected);
}
DCHECK(HostPortPair(session_key.server_id().host(),
session_key.server_id().port())
@@ -1308,7 +1308,6 @@ void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
void QuicStreamFactory::OnSessionClosed(QuicChromiumClientSession* session) {
DCHECK_EQ(0u, session->GetNumActiveStreams());
OnSessionGoingAway(session);
-
for (const auto& iter : active_jobs_) {
if (iter.first == session->quic_session_key()) {
iter.second->OnSessionClosed(session);
@@ -1478,63 +1477,72 @@ std::unique_ptr<DatagramClientSocket> QuicStreamFactory::CreateSocket(
}
void QuicStreamFactory::OnIPAddressChanged() {
- LogPlatformNotificationInHistogram(NETWORK_IP_ADDRESS_CHANGED);
+ CollectDataOnPlatformNotification(
+ NETWORK_IP_ADDRESS_CHANGED, NetworkChangeNotifier::kInvalidNetworkHandle);
// Do nothing if connection migration is turned on.
if (params_.migrate_sessions_on_network_change_v2)
return;
+ connectivity_monitor_.OnIPAddressChanged();
+
set_is_quic_known_to_work_on_current_network(false);
if (params_.close_sessions_on_ip_change) {
CloseAllSessions(ERR_NETWORK_CHANGED, quic::QUIC_IP_ADDRESS_CHANGED);
} else {
DCHECK(params_.goaway_sessions_on_ip_change);
- MarkAllActiveSessionsGoingAway();
+ MarkAllActiveSessionsGoingAway(kIPAddressChanged);
}
}
void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) {
- LogPlatformNotificationInHistogram(NETWORK_CONNECTED);
- if (!params_.migrate_sessions_on_network_change_v2)
- return;
-
- ScopedConnectionMigrationEventLog scoped_event_log(net_log_,
- "OnNetworkConnected");
+ CollectDataOnPlatformNotification(NETWORK_CONNECTED, network);
+ if (params_.migrate_sessions_on_network_change_v2) {
+ NetLogWithSource net_log = NetLogWithSource::Make(
+ net_log_, NetLogSourceType::QUIC_CONNECTION_MIGRATION);
+ net_log.AddEventWithStringParams(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_PLATFORM_NOTIFICATION,
+ "signal", "OnNetworkConnected");
+ }
+ // Broadcast network connected to all sessions.
+ // If migration is not turned on, session will not migrate but collect data.
auto it = all_sessions_.begin();
// Sessions may be deleted while iterating through the map.
while (it != all_sessions_.end()) {
QuicChromiumClientSession* session = it->first;
++it;
- session->OnNetworkConnected(network, scoped_event_log.net_log());
+ session->OnNetworkConnected(network);
}
}
void QuicStreamFactory::OnNetworkDisconnected(NetworkHandle network) {
- LogPlatformNotificationInHistogram(NETWORK_DISCONNECTED);
- if (!params_.migrate_sessions_on_network_change_v2)
- return;
-
- ScopedConnectionMigrationEventLog scoped_event_log(net_log_,
- "OnNetworkDisconnected");
+ CollectDataOnPlatformNotification(NETWORK_DISCONNECTED, network);
+ if (params_.migrate_sessions_on_network_change_v2) {
+ NetLogWithSource net_log = NetLogWithSource::Make(
+ net_log_, NetLogSourceType::QUIC_CONNECTION_MIGRATION);
+ net_log.AddEventWithStringParams(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_PLATFORM_NOTIFICATION,
+ "signal", "OnNetworkDisconnected");
+ }
+ // Broadcast network disconnected to all sessions.
+ // If migration is not turned on, session will not migrate but collect data.
auto it = all_sessions_.begin();
// Sessions may be deleted while iterating through the map.
while (it != all_sessions_.end()) {
QuicChromiumClientSession* session = it->first;
++it;
- session->OnNetworkDisconnectedV2(/*disconnected_network*/ network,
- scoped_event_log.net_log());
+ session->OnNetworkDisconnectedV2(/*disconnected_network*/ network);
}
}
// This method is expected to only be called when migrating from Cellular to
// WiFi on Android, and should always be preceded by OnNetworkMadeDefault().
void QuicStreamFactory::OnNetworkSoonToDisconnect(NetworkHandle network) {
- LogPlatformNotificationInHistogram(NETWORK_SOON_TO_DISCONNECT);
+ CollectDataOnPlatformNotification(NETWORK_SOON_TO_DISCONNECT, network);
}
void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) {
- LogPlatformNotificationInHistogram(NETWORK_MADE_DEFAULT);
- if (!params_.migrate_sessions_on_network_change_v2)
- return;
+ CollectDataOnPlatformNotification(NETWORK_MADE_DEFAULT, network);
+ connectivity_monitor_.OnDefaultNetworkUpdated(network);
// Clear alternative services that were marked as broken until default network
// changes.
@@ -1546,17 +1554,24 @@ void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) {
DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network);
default_network_ = network;
- ScopedConnectionMigrationEventLog scoped_event_log(net_log_,
- "OnNetworkMadeDefault");
+
+ if (params_.migrate_sessions_on_network_change_v2) {
+ NetLogWithSource net_log = NetLogWithSource::Make(
+ net_log_, NetLogSourceType::QUIC_CONNECTION_MIGRATION);
+ net_log.AddEventWithStringParams(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_PLATFORM_NOTIFICATION,
+ "signal", "OnNetworkMadeDefault");
+ }
auto it = all_sessions_.begin();
// Sessions may be deleted while iterating through the map.
while (it != all_sessions_.end()) {
QuicChromiumClientSession* session = it->first;
++it;
- session->OnNetworkMadeDefault(network, scoped_event_log.net_log());
+ session->OnNetworkMadeDefault(network);
}
- set_is_quic_known_to_work_on_current_network(false);
+ if (params_.migrate_sessions_on_network_change_v2)
+ set_is_quic_known_to_work_on_current_network(false);
}
void QuicStreamFactory::OnCertDBChanged() {
@@ -1569,7 +1584,7 @@ void QuicStreamFactory::OnCertDBChanged() {
// Since the OnCertDBChanged method doesn't tell us what
// kind of change it is, we have to flush the socket
// pools to be safe.
- MarkAllActiveSessionsGoingAway();
+ MarkAllActiveSessionsGoingAway(kCertDBChanged);
}
void QuicStreamFactory::set_is_quic_known_to_work_on_current_network(
@@ -1742,6 +1757,7 @@ int QuicStreamFactory::CreateSession(
// creation, update |default_network_| when the first socket is bound
// to the default network.
default_network_ = *network;
+ connectivity_monitor_.SetInitialDefaultNetwork(default_network_);
} else {
UMA_HISTOGRAM_BOOLEAN("Net.QuicStreamFactory.DefaultNetworkMatch",
default_network_ == *network);
@@ -1782,7 +1798,9 @@ int QuicStreamFactory::CreateSession(
quic::QuicConfig config = config_;
ConfigureInitialRttEstimate(
server_id, key.session_key().network_isolation_key(), &config);
- if (quic_version.transport_version <= quic::QUIC_VERSION_43 &&
+ // QUIC versions that use the IETF invariant header all have NSTP
+ // enabled by default, so we only need to add it for those that don't.
+ if (!quic_version.HasIetfInvariantHeader() &&
!config.HasClientSentConnectionOption(quic::kNSTP,
quic::Perspective::IS_CLIENT)) {
// Enable the no stop waiting frames connection option by default.
@@ -1827,6 +1845,7 @@ int QuicStreamFactory::CreateSession(
all_sessions_[*session] = key; // owning pointer
writer->set_delegate(*session);
+ (*session)->AddConnectivityObserver(&connectivity_monitor_);
(*session)->Initialize();
bool closed_during_initialize = !base::Contains(all_sessions_, *session) ||
@@ -1855,9 +1874,14 @@ void QuicStreamFactory::ActivateSession(const QuicSessionAliasKey& key,
session_peer_ip_[session] = peer_address;
}
-void QuicStreamFactory::MarkAllActiveSessionsGoingAway() {
+void QuicStreamFactory::MarkAllActiveSessionsGoingAway(
+ AllActiveSessionsGoingAwayReason reason) {
while (!active_sessions_.empty()) {
QuicChromiumClientSession* session = active_sessions_.begin()->second;
+ // If IP address change is detected, disable session's connectivity
+ // monitoring by remove the Delegate.
+ if (reason == kIPAddressChanged)
+ connectivity_monitor_.OnSessionGoingAwayOnIPAddressChange(session);
OnSessionGoingAway(session);
}
}
@@ -2014,8 +2038,6 @@ void QuicStreamFactory::InitializeCachedStateInCryptoConfig(
quic::QuicConnectionId* connection_id) {
quic::QuicCryptoClientConfig::CachedState* cached =
crypto_config_handle.GetConfig()->LookupOrCreate(server_id);
- if (cached->has_server_designated_connection_id())
- *connection_id = cached->GetNextServerDesignatedConnectionId();
if (!cached->IsEmpty()) {
return;
@@ -2133,8 +2155,9 @@ QuicStreamFactory::CreateCryptoConfigHandle(
std::make_unique<ProofVerifierChromium>(
cert_verifier_, ct_policy_enforcer_, transport_security_state_,
cert_transparency_verifier_,
- HostsFromOrigins(params_.origins_to_force_quic_on)),
- this);
+ HostsFromOrigins(params_.origins_to_force_quic_on),
+ actual_network_isolation_key),
+ std::make_unique<QuicClientSessionCache>(), this);
quic::QuicCryptoClientConfig* crypto_config = crypto_config_owner->config();
crypto_config->set_user_agent_id(params_.user_agent_id);
@@ -2165,6 +2188,38 @@ void QuicStreamFactory::OnAllCryptoClientRefReleased(
active_crypto_config_map_.erase(map_iterator);
}
+void QuicStreamFactory::CollectDataOnPlatformNotification(
+ enum QuicPlatformNotification notification,
+ NetworkChangeNotifier::NetworkHandle affected_network) const {
+ UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.PlatformNotification",
+ notification, NETWORK_NOTIFICATION_MAX);
+ if (notification == NETWORK_SOON_TO_DISCONNECT ||
+ notification == NETWORK_DISCONNECTED) {
+ // If the disconnected network is not the default network, ignore
+ // stats collections.
+ if (affected_network != default_network_)
+ return;
+ }
+
+ // Skip degrading session collection if there are less than two sessions.
+ if (all_sessions_.size() < 2)
+ return;
+
+ size_t num_degrading_sessions =
+ connectivity_monitor_.GetNumDegradingSessions();
+ const std::string raw_histogram_name =
+ "Net.QuicStreamFactory.NumDegradingSessions." +
+ QuicPlatformNotificationToString(notification);
+ base::UmaHistogramExactLinear(raw_histogram_name, num_degrading_sessions,
+ 101);
+
+ int percentage = num_degrading_sessions * 100 / all_sessions_.size();
+ const std::string percentage_histogram_name =
+ "Net.QuicStreamFactory.PercentageDegradingSessions." +
+ QuicPlatformNotificationToString(notification);
+ base::UmaHistogramExactLinear(percentage_histogram_name, percentage, 101);
+}
+
std::unique_ptr<QuicCryptoClientConfigHandle>
QuicStreamFactory::GetCryptoConfigForTesting(
const NetworkIsolationKey& network_isolation_key) {
diff --git a/chromium/net/quic/quic_stream_factory.h b/chromium/net/quic/quic_stream_factory.h
index 6e33a290557..9dd5bb2ca03 100644
--- a/chromium/net/quic/quic_stream_factory.h
+++ b/chromium/net/quic/quic_stream_factory.h
@@ -17,7 +17,6 @@
#include "base/containers/mru_cache.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/tick_clock.h"
@@ -35,6 +34,7 @@
#include "net/quic/network_connection.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_clock_skew_detector.h"
+#include "net/quic/quic_connectivity_monitor.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_crypto_client_config_handle.h"
#include "net/quic/quic_session_key.h"
@@ -101,6 +101,12 @@ enum QuicPlatformNotification {
NETWORK_NOTIFICATION_MAX
};
+enum AllActiveSessionsGoingAwayReason {
+ kClockSkewDetected,
+ kIPAddressChanged,
+ kCertDBChanged
+};
+
// Encapsulates a pending request for a QuicChromiumClientSession.
// If the request is still pending when it is destroyed, it will
// cancel the request with the factory.
@@ -396,7 +402,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
NetworkChangeNotifier::NetworkHandle* network);
void ActivateSession(const QuicSessionAliasKey& key,
QuicChromiumClientSession* session);
- void MarkAllActiveSessionsGoingAway();
+ // Go away all active sessions. May disable session's connectivity monitoring
+ // based on the |reason|.
+ void MarkAllActiveSessionsGoingAway(AllActiveSessionsGoingAwayReason reason);
void ConfigureInitialRttEstimate(
const quic::QuicServerId& server_id,
@@ -457,6 +465,14 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
void OnAllCryptoClientRefReleased(
QuicCryptoClientConfigMap::iterator& map_iterator);
+ // Called when a network change happens.
+ // Collect platform notification metrics, and if the change affects the
+ // original default network interface, collect connectivity degradation
+ // metrics from |connectivity_monitor_| and add to histograms.
+ void CollectDataOnPlatformNotification(
+ enum QuicPlatformNotification notification,
+ NetworkChangeNotifier::NetworkHandle affected_network) const;
+
std::unique_ptr<QuicCryptoClientConfigHandle> GetCryptoConfigForTesting(
const NetworkIsolationKey& network_isolation_key);
@@ -556,6 +572,8 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
int num_push_streams_created_;
+ QuicConnectivityMonitor connectivity_monitor_;
+
quic::QuicClientPushPromiseIndex push_promise_index_;
const base::TickClock* tick_clock_;
diff --git a/chromium/net/quic/quic_stream_factory_peer.cc b/chromium/net/quic/quic_stream_factory_peer.cc
index ac673b84b67..63b316a5e30 100644
--- a/chromium/net/quic/quic_stream_factory_peer.cc
+++ b/chromium/net/quic/quic_stream_factory_peer.cc
@@ -185,6 +185,11 @@ int QuicStreamFactoryPeer::GetNumPushStreamsCreated(
return factory->num_push_streams_created_;
}
+size_t QuicStreamFactoryPeer::GetNumDegradingSessions(
+ QuicStreamFactory* factory) {
+ return factory->connectivity_monitor_.GetNumDegradingSessions();
+}
+
void QuicStreamFactoryPeer::SetAlarmFactory(
QuicStreamFactory* factory,
std::unique_ptr<quic::QuicAlarmFactory> alarm_factory) {
diff --git a/chromium/net/quic/quic_stream_factory_peer.h b/chromium/net/quic/quic_stream_factory_peer.h
index 507aedda772..7e2a59922fd 100644
--- a/chromium/net/quic/quic_stream_factory_peer.h
+++ b/chromium/net/quic/quic_stream_factory_peer.h
@@ -103,6 +103,8 @@ class QuicStreamFactoryPeer {
static int GetNumPushStreamsCreated(QuicStreamFactory* factory);
+ static size_t GetNumDegradingSessions(QuicStreamFactory* factory);
+
static void SetAlarmFactory(
QuicStreamFactory* factory,
std::unique_ptr<quic::QuicAlarmFactory> alarm_factory);
diff --git a/chromium/net/quic/quic_stream_factory_test.cc b/chromium/net/quic/quic_stream_factory_test.cc
index a4dd7ce26d3..031cfe38238 100644
--- a/chromium/net/quic/quic_stream_factory_test.cc
+++ b/chromium/net/quic/quic_stream_factory_test.cc
@@ -42,6 +42,7 @@
#include "net/quic/mock_quic_data.h"
#include "net/quic/properties_based_quic_server_info.h"
#include "net/quic/quic_chromium_alarm_factory.h"
+#include "net/quic/quic_chromium_client_session_peer.h"
#include "net/quic/quic_http_stream.h"
#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_server_info.h"
@@ -1002,11 +1003,6 @@ TEST_P(QuicStreamFactoryTest, Create) {
}
TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
Initialize();
factory_->set_is_quic_known_to_work_on_current_network(true);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
@@ -1097,11 +1093,6 @@ TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
}
TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
host_resolver_->set_synchronous_mode(true);
@@ -1144,11 +1135,6 @@ TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
}
TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
crypto_client_stream_factory_.set_handshake_mode(
MockCryptoClientStream::ZERO_RTT);
host_resolver_->set_synchronous_mode(true);
@@ -3152,24 +3138,24 @@ void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
// A RESET will be sent to the peer to cancel the non-migratable stream.
if (VersionUsesHttp3(version_.transport_version)) {
- quic_data1.AddWrite(SYNCHRONOUS,
- client_maker_.MakeDataAndRstPacket(
- packet_num++, true, GetQpackDecoderStreamId(),
- StreamCancellationQpackDecoderInstruction(0),
- GetNthClientInitiatedBidirectionalStreamId(0),
- quic::QUIC_STREAM_CANCELLED));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeDataRstAndAckPacket(
+ packet_num++, true, GetQpackDecoderStreamId(),
+ StreamCancellationQpackDecoderInstruction(0),
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED, 1, 1));
} else {
- quic_data1.AddWrite(SYNCHRONOUS,
- client_maker_.MakeRstPacket(
- packet_num++, false,
- GetNthClientInitiatedBidirectionalStreamId(0),
- quic::QUIC_STREAM_CANCELLED));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeAckAndRstPacket(
+ packet_num++, false,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
}
// Ping packet to send after migration is completed.
- quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckAndPingPacket(
- packet_num++, false, 1, 1, 1));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakePingPacket(packet_num++, false));
} else {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
if (VersionUsesHttp3(version_.transport_version)) {
socket_data.AddWrite(
SYNCHRONOUS,
@@ -3586,8 +3572,7 @@ void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
EXPECT_TRUE(HasActiveSession(host_port_pair_));
- EXPECT_EQ(0u, session->GetNumActiveStreams());
- EXPECT_EQ(0u, session->GetNumDrainingStreams());
+ EXPECT_FALSE(session->HasActiveRequestStreams());
// Trigger connection migration.
scoped_mock_network_change_notifier_->mock_network_change_notifier()
@@ -4079,9 +4064,11 @@ TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
callback_.callback()));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Cause the connection to report path degrading to the session.
// Session will start to probe the alternate network.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Next connectivity probe is scheduled to be sent in 2 *
// kDefaultRTTMilliSecs.
@@ -4111,6 +4098,8 @@ TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
EXPECT_EQ(base::TimeDelta(), next_task_delay);
task_runner->FastForwardBy(next_task_delay);
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Response headers are received over the new network.
EXPECT_THAT(callback_.WaitForResult(), IsOk());
EXPECT_EQ(200, response.headers->response_code());
@@ -4136,6 +4125,8 @@ TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
scoped_mock_network_change_notifier_->mock_network_change_notifier()
->NotifyNetworkMadeDefault(kNewNetworkForTests);
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
task_runner->FastForwardBy(next_task_delay);
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
@@ -4271,9 +4262,11 @@ void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
if (async_write_before)
session->SendPing();
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Cause the connection to report path degrading to the session.
// Session will start to probe the alternate network.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Next connectivity probe is scheduled to be sent in 2 *
// kDefaultRTTMilliSecs.
@@ -4303,10 +4296,14 @@ void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
EXPECT_EQ(base::TimeDelta(), next_task_delay);
task_runner->FastForwardBy(next_task_delay);
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Response headers are received over the new network.
EXPECT_THAT(callback_.WaitForResult(), IsOk());
EXPECT_EQ(200, response.headers->response_code());
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Now there are two pending tasks, the nearest one was to send connectivity
// probe and has been cancelled due to successful migration.
EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
@@ -4328,6 +4325,8 @@ void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
scoped_mock_network_change_notifier_->mock_network_change_notifier()
->NotifyNetworkMadeDefault(kNewNetworkForTests);
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
task_runner->FastForwardBy(next_task_delay);
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
@@ -4352,6 +4351,143 @@ TEST_P(QuicStreamFactoryTest, MigratePortOnPathDegrading_WithoutNetworkHandle) {
TestSimplePortMigrationOnPathDegrading();
}
+// Verifies that if a stateless reset is received on port migration probing
+// path, the session is still alive and probing is considered failed.
+TEST_P(QuicStreamFactoryTest, PortMigrationProbingReceivedStatelessReset) {
+ if (!VersionHasIetfInvariantHeader(version_.transport_version)) {
+ // STATELESS_RESET is only supported after QUIC V46.
+ return;
+ }
+ quic_params_->allow_port_migration = true;
+ socket_factory_.reset(new TestMigrationSocketFactory);
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ // Using a testing task runner so that we can control time.
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
+
+ int packet_number = 1;
+ MockQuicData quic_data1(version_);
+ quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // hanging read
+ if (VersionUsesHttp3(version_.transport_version)) {
+ quic_data1.AddWrite(SYNCHRONOUS,
+ ConstructInitialSettingsPacket(packet_number++));
+ }
+ quic_data1.AddWrite(
+ SYNCHRONOUS,
+ ConstructGetRequestPacket(packet_number++,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ true, true));
+ if (VersionUsesHttp3(version_.transport_version)) {
+ quic_data1.AddWrite(
+ SYNCHRONOUS, client_maker_.MakeDataPacket(
+ packet_number + 1, GetQpackDecoderStreamId(), true,
+ false, StreamCancellationQpackDecoderInstruction(0)));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeRstPacket(
+ packet_number + 2, false,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
+ } else {
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeRstPacket(
+ packet_number + 1, false,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
+ }
+ quic_data1.AddSocketDataToFactory(socket_factory_.get());
+
+ // Set up the second socket data provider that is used after migration.
+ // The response to the earlier request is read on the new socket.
+ MockQuicData quic_data2(version_);
+ // Connectivity probe to be sent on the new path.
+ quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
+ packet_number, true));
+ quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ // Stateless reset to receive from the server.
+ quic_data2.AddRead(ASYNC, server_maker_.MakeStatelessResetPacket());
+ quic_data2.AddSocketDataToFactory(socket_factory_.get());
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ request.Request(
+ host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
+ SocketTag(), NetworkIsolationKey(), false /* disable_secure_dns */,
+ /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
+ failed_on_default_network_callback_, callback_.callback()));
+ EXPECT_THAT(callback_.WaitForResult(), IsOk());
+ std::unique_ptr<HttpStream> stream = CreateStream(&request);
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = url_;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
+ net_log_, CompletionOnceCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Send GET request on stream.
+ HttpResponseInfo response;
+ HttpRequestHeaders request_headers;
+ EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
+ callback_.callback()));
+
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
+ // Cause the connection to report path degrading to the session.
+ // Session will start to probe a different port.
+ session->connection()->OnPathDegradingDetected();
+
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
+ // Next connectivity probe is scheduled to be sent in 2 *
+ // kDefaultRTTMilliSecs.
+ EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
+ base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
+ next_task_delay);
+
+ // The connection should still be alive, and not marked as going away.
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+ EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
+
+ // Resume quic data and a STATELESS_RESET is read from the probing path.
+ quic_data2.Resume();
+
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
+ // Verify that the session is still active, and the request stream is active.
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, session->GetNumActiveStreams());
+ EXPECT_FALSE(
+ QuicChromiumClientSessionPeer::DoesSessionAllowPortMigration(session));
+
+ // The task to resend connectivity probe is cancelled due to probe failure.
+ task_runner->FastForwardBy(next_task_delay);
+ EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
+
+ stream.reset();
+ EXPECT_TRUE(quic_data1.AllReadDataConsumed());
+ EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
+ EXPECT_TRUE(quic_data2.AllReadDataConsumed());
+ EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
+}
+
// Verifies that port migration can be attempted on the default network and
// succeed when path degrading is detected. NetworkHandle is supported.
TEST_P(QuicStreamFactoryTest, MigratePortOnPathDegrading_WithNetworkHandle) {
@@ -4488,9 +4624,13 @@ void QuicStreamFactoryTestBase::TestSimplePortMigrationOnPathDegrading() {
EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
callback_.callback()));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Cause the connection to report path degrading to the session.
// Session will start to probe a different port.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Next connectivity probe is scheduled to be sent in 2 *
// kDefaultRTTMilliSecs.
@@ -4512,6 +4652,9 @@ void QuicStreamFactoryTestBase::TestSimplePortMigrationOnPathDegrading() {
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
EXPECT_TRUE(HasActiveSession(host_port_pair_));
EXPECT_EQ(1u, session->GetNumActiveStreams());
+ // Successful port migration causes the path no longer degrading on the same
+ // network.
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// There should be pending tasks, the nearest one will complete
// migration to the new port.
@@ -4524,6 +4667,8 @@ void QuicStreamFactoryTestBase::TestSimplePortMigrationOnPathDegrading() {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
EXPECT_EQ(200, response.headers->response_code());
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Now there is one pending task to send connectivity probe and has been
// cancelled due to successful migration.
EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
@@ -4660,9 +4805,15 @@ TEST_P(QuicStreamFactoryTest, MultiplePortMigrationsExceedsMaxLimit) {
quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // EOF.
quic_data2.AddSocketDataToFactory(socket_factory_.get());
+ EXPECT_EQ(0u,
+ QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Cause the connection to report path degrading to the session.
// Session will start to probe a different port.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+
+ EXPECT_EQ(1u,
+ QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Next connectivity probe is scheduled to be sent in 2 *
// kDefaultRTTMilliSecs.
@@ -4784,9 +4935,15 @@ TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
callback_.callback()));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Trigger the connection to report path degrading to the session.
// Session will mark itself GOAWAY.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+
+ /// Path degrading detection on go_away_on_path_degrading detection is
+ // disabled.
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// The connection should still be alive, but marked as going away.
EXPECT_FALSE(HasActiveSession(host_port_pair_));
@@ -4920,9 +5077,11 @@ TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
callback_.callback()));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Cause the connection to report path degrading to the session.
// Session will start to probe the alternate network.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// The connection should still be alive, and not marked as going away.
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
@@ -5063,10 +5222,12 @@ void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, session->GetNumActiveStreams());
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Cause the connection to report path degrading to the session.
// Session should still start to probe the alternate network.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Next connectivity probe is scheduled to be sent in 2 *
// kDefaultRTTMilliSecs.
@@ -5085,7 +5246,7 @@ void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
EXPECT_TRUE(HasActiveSession(host_port_pair_));
EXPECT_EQ(0u, session->GetNumActiveStreams());
- EXPECT_EQ(1u, session->GetNumDrainingStreams());
+ EXPECT_TRUE(session->HasActiveRequestStreams());
// There should be three pending tasks, the nearest one will complete
// migration to the new network.
@@ -5233,12 +5394,18 @@ TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
callback_.callback()));
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Cause the connection to report path degrading to the session.
// Due to lack of alternate network, session will not mgirate connection.
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
- session->connection()->OnPathDegradingTimeout();
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+ session->connection()->OnPathDegradingDetected();
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Deliver a signal that a alternate network is connected now, this should
// cause the connection to start early migration on path degrading.
scoped_mock_network_change_notifier_->mock_network_change_notifier()
@@ -5275,6 +5442,10 @@ TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
EXPECT_EQ(base::TimeDelta(), next_task_delay);
task_runner->FastForwardBy(next_task_delay);
+ // Although the session successfully migrates, it is still considered
+ // degrading sessions.
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+
// Response headers are received over the new network.
EXPECT_THAT(callback_.WaitForResult(), IsOk());
EXPECT_EQ(200, response.headers->response_code());
@@ -5523,8 +5694,10 @@ TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
// Trigger connection migration on path degrading. Since there are no networks
// to migrate to, the session will remain on the original network, not marked
// as going away.
- session->connection()->OnPathDegradingTimeout();
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+ session->connection()->OnPathDegradingDetected();
EXPECT_TRUE(session->connection()->IsPathDegrading());
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
EXPECT_TRUE(HasActiveSession(host_port_pair_));
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
@@ -5586,24 +5759,25 @@ void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
// A RESET will be sent to the peer to cancel the non-migratable stream.
if (VersionUsesHttp3(version_.transport_version)) {
- quic_data1.AddWrite(SYNCHRONOUS,
- client_maker_.MakeDataAndRstPacket(
- packet_num++, true, GetQpackDecoderStreamId(),
- StreamCancellationQpackDecoderInstruction(0),
- GetNthClientInitiatedBidirectionalStreamId(0),
- quic::QUIC_STREAM_CANCELLED));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeDataRstAndAckPacket(
+ packet_num++, true, GetQpackDecoderStreamId(),
+ StreamCancellationQpackDecoderInstruction(0),
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED, 1, 1));
} else {
- quic_data1.AddWrite(SYNCHRONOUS,
- client_maker_.MakeRstPacket(
- packet_num++, false,
- GetNthClientInitiatedBidirectionalStreamId(0),
- quic::QUIC_STREAM_CANCELLED));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakeAckAndRstPacket(
+ packet_num++, false,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
}
// Ping packet to send after migration is completed.
- quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckAndPingPacket(
- packet_num++, false, 1, 1, 1));
+ quic_data1.AddWrite(SYNCHRONOUS,
+ client_maker_.MakePingPacket(packet_num++, false));
+
} else {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
if (VersionUsesHttp3(version_.transport_version)) {
socket_data.AddWrite(
SYNCHRONOUS,
@@ -6152,8 +6326,10 @@ TEST_P(QuicStreamFactoryTest,
// Cause the connection to report path degrading to the session.
// Session will ignore the signal as handshake is not completed.
- session->connection()->OnPathDegradingTimeout();
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
+ session->connection()->OnPathDegradingDetected();
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
EXPECT_FALSE(HasActiveSession(host_port_pair_));
EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
@@ -6212,9 +6388,11 @@ void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
+ EXPECT_EQ(0u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
// Cause the connection to report path degrading to the session.
// Session will ignore the signal as handshake is not completed.
- session->connection()->OnPathDegradingTimeout();
+ session->connection()->OnPathDegradingDetected();
+ EXPECT_EQ(1u, QuicStreamFactoryPeer::GetNumDegradingSessions(factory_.get()));
EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
EXPECT_FALSE(HasActiveSession(host_port_pair_));
EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
@@ -10135,8 +10313,7 @@ TEST_P(QuicStreamFactoryTest, ServerMigration) {
const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
const uint16_t kTestPort = 123;
session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
- IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
- net_log_);
+ IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true);
session->GetDefaultSocket()->GetPeerAddress(&ip);
DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
@@ -10184,7 +10361,10 @@ TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
VerifyServerMigration(config, alt_address);
}
-TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
+TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4Fails) {
+ quic_params_->allow_server_migration = true;
+ Initialize();
+
// Add a resolver rule to make initial connection to an IPv6 address.
host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
"fe80::aebc:32ff:febb:1e33", "");
@@ -10192,9 +10372,75 @@ TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
quic::QuicConfig config;
config.SetIPv4AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
- IPEndPoint expected_address(
- ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
- VerifyServerMigration(config, expected_address);
+
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ crypto_client_stream_factory_.SetConfig(config);
+
+ // Set up only socket data provider.
+ MockQuicData socket_data1(version_);
+ socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ int packet_num = 1;
+ if (VersionUsesHttp3(version_.transport_version)) {
+ socket_data1.AddWrite(SYNCHRONOUS,
+ ConstructInitialSettingsPacket(packet_num++));
+ socket_data1.AddWrite(
+ SYNCHRONOUS, client_maker_.MakeDataPacket(
+ packet_num++, GetQpackDecoderStreamId(), true, false,
+ StreamCancellationQpackDecoderInstruction(0)));
+ }
+ socket_data1.AddWrite(
+ SYNCHRONOUS,
+ client_maker_.MakeRstPacket(packet_num++, true,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
+ socket_data1.AddSocketDataToFactory(socket_factory_.get());
+
+ // Create request and QuicHttpStream.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ request.Request(
+ host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
+ SocketTag(), NetworkIsolationKey(), false /* disable_secure_dns */,
+ /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
+ failed_on_default_network_callback_, callback_.callback()));
+ EXPECT_EQ(OK, callback_.WaitForResult());
+ std::unique_ptr<HttpStream> stream = CreateStream(&request);
+ EXPECT_TRUE(stream.get());
+
+ // Cause QUIC stream to be created.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.example.org/");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
+ net_log_, CompletionOnceCallback()));
+
+ // Ensure that session is alive and active.
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ IPEndPoint actual_address;
+ session->GetDefaultSocket()->GetPeerAddress(&actual_address);
+ // No migration should have happened.
+ IPEndPoint expected_address =
+ IPEndPoint(IPAddress(0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0xae, 0xbc, 0x32, 0xff,
+ 0xfe, 0xbb, 0x1e, 0x33),
+ kDefaultServerPort);
+ EXPECT_EQ(actual_address, expected_address);
+ DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
+ << " " << actual_address.port();
+ DVLOG(1) << "Expected address: " << expected_address.address().ToString()
+ << " " << expected_address.port();
+
+ stream.reset();
+ EXPECT_TRUE(socket_data1.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
@@ -10431,11 +10677,6 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
}
TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
Initialize();
factory_->set_is_quic_known_to_work_on_current_network(true);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
@@ -10581,20 +10822,10 @@ TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
// Verifies that the QUIC stream factory is initialized correctly.
TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
VerifyInitialization(false /* vary_network_isolation_key */);
}
TEST_P(QuicStreamFactoryTest, MaybeInitializeWithNetworkIsolationKey) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
// enabled_features
@@ -10822,11 +11053,6 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigCacheMRUWithNetworkIsolationKey) {
// around, so evictions happen immediately.
TEST_P(QuicStreamFactoryTest,
CryptoConfigCacheMRUWithRealRequestsAndWithNetworkIsolationKey) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
const int kNumSessionsToMake = kMaxRecentCryptoConfigs + 5;
base::test::ScopedFeatureList feature_list;
@@ -10968,11 +11194,6 @@ TEST_P(QuicStreamFactoryTest,
}
TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
Initialize();
factory_->set_is_quic_known_to_work_on_current_network(true);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
@@ -11025,11 +11246,6 @@ TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
}
TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
Initialize();
factory_->set_is_quic_known_to_work_on_current_network(true);
ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
@@ -12306,11 +12522,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
// async, and then the result matches.
TEST_P(QuicStreamFactoryTest,
ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -12382,11 +12593,6 @@ TEST_P(QuicStreamFactoryTest,
// return, then connection finishes and matches with the result.
TEST_P(QuicStreamFactoryTest,
ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -12532,10 +12738,6 @@ TEST_P(QuicStreamFactoryTest,
// With dns race experiment on, dns resolve async, stale used and connects
// async, finishes before dns, but no match
TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // TODO(fayang): 0-rtt is not supported in IETF QUIC yet. Fix it.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -12550,7 +12752,7 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
kNonCachedIPAddress, "");
- // Set up a different address in the stale resolvercache.
+ // Set up a different address in the stale resolver cache.
HostCache::Key key(host_port_pair_.host(), DnsQueryType::UNSPECIFIED, 0,
HostResolverSource::ANY, NetworkIsolationKey());
HostCache::Entry entry(OK,
@@ -12621,10 +12823,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
// With dns race experiment on, dns resolve async, stale used and connects
// async, dns finishes first, but no match
TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // TODO(fayang): 0-rtt is not supported in IETF QUIC yet. Fix it.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -12988,10 +13186,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
// With dns race experiment on, dns resolve async and stale connect async, dns
// resolve returns error and then preconnect finishes
TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // TODO(fayang): 0-rtt is not supported in IETF QUIC yet. Fix it.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -13002,8 +13196,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
host_resolver_->set_ondemand_mode(true);
host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
factory_->set_is_quic_known_to_work_on_current_network(false);
- crypto_client_stream_factory_.set_handshake_mode(
- MockCryptoClientStream::ZERO_RTT);
// Set up an address in stale resolver cache.
HostCache::Key key(host_port_pair_.host(), DnsQueryType::UNSPECIFIED, 0,
@@ -13020,7 +13212,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
// Socket data for stale connection which is supposed to disconnect.
MockQuicData quic_data(version_);
quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
- client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
int packet_number = 1;
if (VersionUsesHttp3(version_.transport_version)) {
quic_data.AddWrite(SYNCHRONOUS,
@@ -13053,10 +13244,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
// resolve returns error and then preconnect fails.
TEST_P(QuicStreamFactoryTest,
ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- // TODO(fayang): 0-rtt is not supported in IETF QUIC yet. Fix it.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
Initialize();
@@ -13066,8 +13253,6 @@ TEST_P(QuicStreamFactoryTest,
// Add asynchronous failure to host resolver.
host_resolver_->set_ondemand_mode(true);
factory_->set_is_quic_known_to_work_on_current_network(false);
- crypto_client_stream_factory_.set_handshake_mode(
- MockCryptoClientStream::ZERO_RTT);
host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
// Set up an address in stale resolver cache.
@@ -13084,7 +13269,6 @@ TEST_P(QuicStreamFactoryTest,
MockQuicData quic_data(version_);
quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
- client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
int packet_number = 1;
if (VersionUsesHttp3(version_.transport_version)) {
quic_data.AddWrite(SYNCHRONOUS,
@@ -13163,11 +13347,6 @@ TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
// With stale dns and migration before handshake experiment on, migration failed
// after handshake confirmed, and then fresh resolve returns.
TEST_P(QuicStreamFactoryTest, StaleNetworkFailedAfterHandshake) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
@@ -13243,11 +13422,6 @@ TEST_P(QuicStreamFactoryTest, StaleNetworkFailedAfterHandshake) {
// With stale dns experiment on, the stale session is killed while waiting for
// handshake
TEST_P(QuicStreamFactoryTest, StaleNetworkFailedBeforeHandshake) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3 &&
- version_.HasIetfQuicFrames()) {
- // 0-rtt is not supported in IETF QUIC yet.
- return;
- }
quic_params_->race_stale_dns_on_connection = true;
host_resolver_ = std::make_unique<MockCachingHostResolver>();
InitializeConnectionMigrationV2Test(
@@ -13326,7 +13500,7 @@ TEST_P(QuicStreamFactoryTest, StaleNetworkFailedBeforeHandshake) {
}
TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
- if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
+ if (version_.UsesTls()) {
// IETF QUIC uses a different handshake timeout management system.
return;
}
diff --git a/chromium/net/quic/quic_test_packet_maker.cc b/chromium/net/quic/quic_test_packet_maker.cc
index db63151afa8..7539328b11e 100644
--- a/chromium/net/quic/quic_test_packet_maker.cc
+++ b/chromium/net/quic/quic_test_packet_maker.cc
@@ -91,6 +91,10 @@ quic::QuicFrames CloneFrames(const quic::QuicFrames& frames) {
frame.new_token_frame =
new quic::QuicNewTokenFrame(*frame.new_token_frame);
break;
+ case quic::ACK_FREQUENCY_FRAME:
+ frame.ack_frequency_frame =
+ new quic::QuicAckFrequencyFrame(*frame.ack_frequency_frame);
+ break;
case quic::NUM_FRAME_TYPES:
DCHECK(false) << "Cannot clone frame type: " << frame.type;
@@ -99,6 +103,15 @@ quic::QuicFrames CloneFrames(const quic::QuicFrames& frames) {
return new_frames;
}
+// TODO(crbug.com/1085541): Consider moving this method into QuicTestUtils.
+quic::QuicConnectionId TestConnectionId(uint64_t connection_number) {
+ const uint64_t connection_id64_net =
+ quiche::QuicheEndian::HostToNet64(connection_number);
+ return quic::QuicConnectionId(
+ reinterpret_cast<const char*>(&connection_id64_net),
+ sizeof(connection_id64_net));
+}
+
} // namespace
QuicTestPacketMaker::QuicTestPacketMaker(
@@ -120,8 +133,7 @@ QuicTestPacketMaker::QuicTestPacketMaker(
encryption_level_(quic::ENCRYPTION_FORWARD_SECURE),
long_header_type_(quic::INVALID_PACKET_TYPE),
client_headers_include_h2_stream_dependency_(
- client_headers_include_h2_stream_dependency &&
- version.transport_version >= quic::QUIC_VERSION_43),
+ client_headers_include_h2_stream_dependency),
save_packet_frames_(false) {
DCHECK(!(perspective_ == quic::Perspective::IS_SERVER &&
client_headers_include_h2_stream_dependency_));
@@ -246,7 +258,7 @@ std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
InitializeHeader(num, include_version);
if (!version_.HasIetfQuicFrames() ||
- quic::QuicUtils::IsBidirectionalStreamId(stream_id)) {
+ quic::QuicUtils::IsBidirectionalStreamId(stream_id, version_)) {
AddQuicRstStreamFrame(stream_id, error_code);
}
@@ -299,6 +311,30 @@ QuicTestPacketMaker::MakeDataAndRstPacket(
}
std::unique_ptr<quic::QuicReceivedPacket>
+QuicTestPacketMaker::MakeDataRstAndAckPacket(
+ uint64_t num,
+ bool include_version,
+ quic::QuicStreamId data_stream_id,
+ quiche::QuicheStringPiece data,
+ quic::QuicStreamId rst_stream_id,
+ quic::QuicRstStreamErrorCode rst_error_code,
+ uint64_t largest_received,
+ uint64_t smallest_received) {
+ InitializeHeader(num, include_version);
+
+ AddQuicAckFrame(largest_received, smallest_received);
+
+ AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
+ AddQuicRstStreamFrame(rst_stream_id, rst_error_code);
+
+ if (version_.HasIetfQuicFrames()) {
+ AddQuicStopSendingFrame(rst_stream_id, rst_error_code);
+ }
+
+ return BuildPacket();
+}
+
+std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndRstPacket(
uint64_t num,
bool include_version,
@@ -327,7 +363,7 @@ QuicTestPacketMaker::MakeAckAndRstPacket(
AddQuicAckFrame(largest_received, smallest_received);
if (!version_.HasIetfQuicFrames() ||
- quic::QuicUtils::IsBidirectionalStreamId(stream_id)) {
+ quic::QuicUtils::IsBidirectionalStreamId(stream_id, version_)) {
AddQuicRstStreamFrame(stream_id, error_code);
}
@@ -351,6 +387,8 @@ QuicTestPacketMaker::MakeRstAckAndConnectionClosePacket(
const std::string& quic_error_details) {
InitializeHeader(num, include_version);
+ AddQuicAckFrame(largest_received, smallest_received);
+
AddQuicRstStreamFrame(stream_id, error_code);
if (version_.HasIetfQuicFrames()) {
@@ -423,6 +461,8 @@ QuicTestPacketMaker::MakeDataRstAckAndConnectionClosePacket(
const std::string& quic_error_details) {
InitializeHeader(num, include_version);
+ AddQuicAckFrame(largest_received, smallest_received);
+
AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
AddQuicRstStreamFrame(rst_stream_id, error_code);
@@ -790,6 +830,44 @@ QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
}
std::unique_ptr<quic::QuicReceivedPacket>
+QuicTestPacketMaker::MakeAckAndPriorityPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ uint64_t largest_received,
+ uint64_t smallest_received,
+ quic::QuicStreamId id,
+ quic::QuicStreamId parent_stream_id,
+ spdy::SpdyPriority priority) {
+ InitializeHeader(packet_number, should_include_version);
+
+ AddQuicAckFrame(largest_received, smallest_received);
+
+ if (!client_headers_include_h2_stream_dependency_) {
+ parent_stream_id = 0;
+ }
+ int weight = spdy::Spdy3PriorityToHttp2Weight(priority);
+ bool exclusive = client_headers_include_h2_stream_dependency_;
+
+ if (!VersionUsesHttp3(version_.transport_version)) {
+ spdy::SpdyPriorityIR priority_frame(id, parent_stream_id, weight,
+ exclusive);
+ spdy::SpdySerializedFrame spdy_frame(
+ spdy_request_framer_.SerializeFrame(priority_frame));
+ AddQuicStreamFrame(
+ GetHeadersStreamId(), false,
+ quiche::QuicheStringPiece(spdy_frame.data(), spdy_frame.size()));
+
+ return BuildPacket();
+ }
+ if (priority != quic::QuicStream::kDefaultUrgency) {
+ std::string priority_data = GenerateHttp3PriorityData(priority, id);
+ AddQuicStreamFrame(2, false, priority_data);
+ }
+
+ return BuildPacket();
+}
+
+std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndPriorityUpdatePacket(
uint64_t packet_number,
bool should_include_version,
@@ -809,6 +887,30 @@ QuicTestPacketMaker::MakeAckAndPriorityUpdatePacket(
}
std::unique_ptr<quic::QuicReceivedPacket>
+QuicTestPacketMaker::MakeMultiplePriorityFramesPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ const std::vector<Http2StreamDependency>& priority_frames) {
+ InitializeHeader(packet_number, should_include_version);
+
+ const bool exclusive = client_headers_include_h2_stream_dependency_;
+ std::string coalesced_data;
+ for (const Http2StreamDependency& info : priority_frames) {
+ spdy::SpdyPriorityIR priority_frame(
+ info.stream_id, info.parent_stream_id,
+ spdy::Spdy3PriorityToHttp2Weight(info.spdy_priority), exclusive);
+ auto spdy_frame = spdy_request_framer_.SerializeFrame(priority_frame);
+ coalesced_data += std::string(spdy_frame.data(), spdy_frame.size());
+ }
+ AddQuicStreamFrame(quic::VersionUsesHttp3(version_.transport_version)
+ ? GetFirstBidirectionalStreamId()
+ : GetHeadersStreamId(),
+ false, coalesced_data);
+
+ return BuildPacket();
+}
+
+std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndMultiplePriorityFramesPacket(
uint64_t packet_number,
bool should_include_version,
@@ -847,6 +949,14 @@ QuicTestPacketMaker::MakeRetransmissionPacket(uint64_t original_packet_number,
saved_frames_[quic::QuicPacketNumber(original_packet_number)], nullptr);
}
+std::unique_ptr<quic::QuicEncryptedPacket>
+QuicTestPacketMaker::MakeStatelessResetPacket() {
+ auto connection_id = TestConnectionId(0x1337);
+ return quic::QuicFramer::BuildIetfStatelessResetPacket(
+ connection_id,
+ quic::QuicUtils::GenerateStatelessResetToken(connection_id));
+}
+
void QuicTestPacketMaker::RemoveSavedStreamFrames(
quic::QuicStreamId stream_id) {
for (auto& kv : saved_frames_) {
@@ -939,7 +1049,7 @@ std::string QuicTestPacketMaker::QpackEncodeHeaders(
&headers_frame_header);
// Possible add a PUSH stream type.
- if (!quic::QuicUtils::IsBidirectionalStreamId(stream_id) &&
+ if (!quic::QuicUtils::IsBidirectionalStreamId(stream_id, version_) &&
stream_offsets_[stream_id] == 0) {
// Push stream type header
data += "\x01";
@@ -1223,7 +1333,7 @@ spdy::SpdySerializedFrame QuicTestPacketMaker::MakeSpdyHeadersFrame(
}
bool QuicTestPacketMaker::ShouldIncludeVersion(bool include_version) const {
- if (version_.transport_version > quic::QUIC_VERSION_43) {
+ if (version_.HasIetfInvariantHeader()) {
return encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE;
}
return include_version;
@@ -1231,7 +1341,7 @@ bool QuicTestPacketMaker::ShouldIncludeVersion(bool include_version) const {
quic::QuicPacketNumberLength QuicTestPacketMaker::GetPacketNumberLength()
const {
- if (version_.transport_version > quic::QUIC_VERSION_43 &&
+ if (version_.HasIetfInvariantHeader() &&
encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE &&
!version_.SendsVariableLengthPacketNumberInLongHeader()) {
return quic::PACKET_4BYTE_PACKET_NUMBER;
diff --git a/chromium/net/quic/quic_test_packet_maker.h b/chromium/net/quic/quic_test_packet_maker.h
index 8df27cfbdb6..d0549ec20b2 100644
--- a/chromium/net/quic/quic_test_packet_maker.h
+++ b/chromium/net/quic/quic_test_packet_maker.h
@@ -116,6 +116,16 @@ class QuicTestPacketMaker {
quic::QuicStreamId rst_stream_id,
quic::QuicRstStreamErrorCode rst_error_code);
+ std::unique_ptr<quic::QuicReceivedPacket> MakeDataRstAndAckPacket(
+ uint64_t num,
+ bool include_version,
+ quic::QuicStreamId data_stream_id,
+ quiche::QuicheStringPiece data,
+ quic::QuicStreamId rst_stream_id,
+ quic::QuicRstStreamErrorCode rst_error_code,
+ uint64_t largest_received,
+ uint64_t smallest_received);
+
std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket(
uint64_t num,
bool include_version,
@@ -297,6 +307,20 @@ class QuicTestPacketMaker {
quic::QuicStreamId parent_stream_id,
spdy::SpdyPriority priority);
+ std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPriorityPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ uint64_t largest_received,
+ uint64_t smallest_received,
+ quic::QuicStreamId id,
+ quic::QuicStreamId parent_stream_id,
+ spdy::SpdyPriority priority);
+
+ std::unique_ptr<quic::QuicReceivedPacket> MakeMultiplePriorityFramesPacket(
+ uint64_t packet_number,
+ bool should_include_version,
+ const std::vector<Http2StreamDependency>& priority_frames);
+
std::unique_ptr<quic::QuicReceivedPacket>
MakeAckAndMultiplePriorityFramesPacket(
uint64_t packet_number,
@@ -320,6 +344,8 @@ class QuicTestPacketMaker {
quic::QuicStreamId id,
spdy::SpdyPriority priority);
+ std::unique_ptr<quic::QuicEncryptedPacket> MakeStatelessResetPacket();
+
// Removes all stream frames associated with |stream_id|.
void RemoveSavedStreamFrames(quic::QuicStreamId stream_id);
diff --git a/chromium/net/quic/quic_test_packet_printer.cc b/chromium/net/quic/quic_test_packet_printer.cc
index 2a5741df791..86edab085bd 100644
--- a/chromium/net/quic/quic_test_packet_printer.cc
+++ b/chromium/net/quic/quic_test_packet_printer.cc
@@ -180,6 +180,10 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface {
*output_ << "OnHandshakeDoneFrame: " << frame;
return true;
}
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+ *output_ << "OnAckFrequencyFrame: " << frame;
+ return true;
+ }
void OnPacketComplete() override { *output_ << "OnPacketComplete\n"; }
bool IsValidStatelessResetToken(QuicUint128 token) const override {
*output_ << "IsValidStatelessResetToken\n";
diff --git a/chromium/net/quic/quic_transport_client.cc b/chromium/net/quic/quic_transport_client.cc
index 6da53b0ac2e..8b2c4f3ea69 100644
--- a/chromium/net/quic/quic_transport_client.cc
+++ b/chromium/net/quic/quic_transport_client.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_transport_client.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_resolution_request.h"
@@ -17,6 +19,10 @@
namespace net {
namespace {
+// From
+// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
+constexpr int kCustomCertificateMaxValidityDays = 14;
+
std::set<std::string> HostsFromOrigins(std::set<HostPortPair> origins) {
std::set<std::string> hosts;
for (const auto& origin : origins) {
@@ -24,17 +30,47 @@ std::set<std::string> HostsFromOrigins(std::set<HostPortPair> origins) {
}
return hosts;
}
+
+std::unique_ptr<quic::ProofVerifier> CreateProofVerifier(
+ const NetworkIsolationKey& isolation_key,
+ URLRequestContext* context,
+ const QuicTransportClient::Parameters& parameters) {
+ if (parameters.server_certificate_fingerprints.empty()) {
+ return std::make_unique<ProofVerifierChromium>(
+ context->cert_verifier(), context->ct_policy_enforcer(),
+ context->transport_security_state(),
+ context->cert_transparency_verifier(),
+ HostsFromOrigins(
+ context->quic_context()->params()->origins_to_force_quic_on),
+ isolation_key);
+ }
+
+ auto verifier = std::make_unique<quic::WebTransportFingerprintProofVerifier>(
+ context->quic_context()->clock(), kCustomCertificateMaxValidityDays);
+ for (const quic::CertificateFingerprint& fingerprint :
+ parameters.server_certificate_fingerprints) {
+ bool success = verifier->AddFingerprint(fingerprint);
+ if (!success) {
+ DLOG(WARNING) << "Failed to add a certificate fingerprint: "
+ << fingerprint.fingerprint;
+ }
+ }
+ return verifier;
+}
} // namespace
-constexpr quic::ParsedQuicVersion
- QuicTransportClient::kQuicVersionForOriginTrial;
+QuicTransportClient::Parameters::Parameters() = default;
+QuicTransportClient::Parameters::~Parameters() = default;
+QuicTransportClient::Parameters::Parameters(const Parameters&) = default;
+QuicTransportClient::Parameters::Parameters(Parameters&&) = default;
QuicTransportClient::QuicTransportClient(
const GURL& url,
const url::Origin& origin,
Visitor* visitor,
const NetworkIsolationKey& isolation_key,
- URLRequestContext* context)
+ URLRequestContext* context,
+ const Parameters& parameters)
: url_(url),
origin_(origin),
isolation_key_(isolation_key),
@@ -53,15 +89,8 @@ QuicTransportClient::QuicTransportClient(
// (currently, all certificate verification errors result in "TLS
// handshake error" even when more detailed message is available). This
// requires implementing ProofHandler::OnProofVerifyDetailsAvailable.
- crypto_config_(
- std::make_unique<ProofVerifierChromium>(
- context->cert_verifier(),
- context->ct_policy_enforcer(),
- context->transport_security_state(),
- context->cert_transparency_verifier(),
- std::set<std::string>(HostsFromOrigins(
- quic_context_->params()->origins_to_force_quic_on))),
- /* session_cache */ nullptr) {}
+ crypto_config_(CreateProofVerifier(isolation_key_, context, parameters),
+ /* session_cache */ nullptr) {}
QuicTransportClient::~QuicTransportClient() = default;
@@ -139,13 +168,13 @@ int QuicTransportClient::DoInit() {
// Ensure that for the duration of the origin trial, a fixed QUIC transport
// version is available.
- supported_versions_.push_back(kQuicVersionForOriginTrial);
+ supported_versions_ = QuicVersionsForWebTransportOriginTrial();
// Add other supported versions if available.
for (quic::ParsedQuicVersion& version :
quic_context_->params()->supported_versions) {
if (!quic::IsVersionValidForQuicTransport(version))
continue;
- if (version == kQuicVersionForOriginTrial)
+ if (base::Contains(supported_versions_, version))
continue; // Skip as we've already added it above.
supported_versions_.push_back(version);
}
@@ -227,6 +256,20 @@ int QuicTransportClient::DoConnect() {
if (rv != OK)
return rv;
+ CreateConnection();
+ next_connect_state_ = CONNECT_STATE_CONFIRM_CONNECTION;
+ return ERR_IO_PENDING;
+}
+
+void QuicTransportClient::CreateConnection() {
+ // Delete the objects in the same order they would be normally deleted by the
+ // destructor.
+ packet_reader_ = nullptr;
+ session_ = nullptr;
+ connection_ = nullptr;
+
+ IPEndPoint server_address =
+ *resolve_host_request_->GetAddressResults()->begin();
quic::QuicConnectionId connection_id =
quic::QuicUtils::CreateRandomConnectionId(
quic_context_->random_generator());
@@ -251,9 +294,6 @@ int QuicTransportClient::DoConnect() {
session_->Initialize();
packet_reader_->StartReading();
session_->CryptoConnect();
-
- next_connect_state_ = CONNECT_STATE_CONFIRM_CONNECTION;
- return ERR_IO_PENDING;
}
int QuicTransportClient::DoConfirmConnection() {
@@ -292,6 +332,18 @@ void QuicTransportClient::TransitionToState(State next_state) {
error_.safe_to_report_details = session_->alpn_received();
}
+ base::UmaHistogramEnumeration("Net.QuicTransportClient.FailedAtState",
+ last_state, NUM_STATES);
+ base::UmaHistogramSparse("Net.QuicTransportClient.Error",
+ std::abs(error_.net_error));
+ if (last_state == CONNECTING) {
+ base::UmaHistogramEnumeration(
+ "Net.QuicTransportClient.FailedAtConnectState", next_connect_state_,
+ CONNECT_STATE_NUM_STATES);
+ base::UmaHistogramSparse("Net.QuicTransportClient.ConnectionError",
+ std::abs(error_.net_error));
+ }
+
DCHECK_NE(error_.net_error, OK);
if (error_.details.empty()) {
error_.details = ErrorToString(error_.net_error);
@@ -372,7 +424,38 @@ void QuicTransportClient::OnConnectionClosed(
quic::QuicConnectionId /*server_connection_id*/,
quic::QuicErrorCode error,
const std::string& error_details,
- quic::ConnectionCloseSource /*source*/) {
+ quic::ConnectionCloseSource source) {
+ if (!retried_with_new_version_ &&
+ session_->error() == quic::QUIC_INVALID_VERSION) {
+ retried_with_new_version_ = true;
+ base::EraseIf(
+ supported_versions_, [this](const quic::ParsedQuicVersion& version) {
+ return !base::Contains(
+ session_->connection()->server_supported_versions(), version);
+ });
+ if (!supported_versions_.empty()) {
+ // Since this is a callback from QuicConnection, we can't replace the
+ // connection object in this method; do it from the top of the event loop
+ // instead.
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&QuicTransportClient::CreateConnection,
+ weak_factory_.GetWeakPtr()));
+ return;
+ }
+ // If there are no supported versions, treat this as a regular error.
+ }
+
+ std::string histogram_name;
+ switch (source) {
+ case quic::ConnectionCloseSource::FROM_SELF:
+ histogram_name = "Net.QuicTransportClient.ConnectionCloseCodeClient";
+ break;
+ case quic::ConnectionCloseSource::FROM_PEER:
+ histogram_name = "Net.QuicTransportClient.ConnectionCloseCodeServer";
+ break;
+ }
+ base::UmaHistogramSparse(histogram_name, error);
+
if (error == quic::QUIC_NO_ERROR) {
TransitionToState(CLOSED);
return;
@@ -392,17 +475,4 @@ void QuicTransportClient::OnConnectionClosed(
TransitionToState(FAILED);
}
-std::string QuicTransportErrorToString(const QuicTransportError& error) {
- std::string message =
- ExtendedErrorToString(error.net_error, error.quic_error);
- if (error.details == message)
- return message;
- return quiche::QuicheStrCat(message, " (", error.details, ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const QuicTransportError& error) {
- os << QuicTransportErrorToString(error);
- return os;
-}
-
} // namespace net
diff --git a/chromium/net/quic/quic_transport_client.h b/chromium/net/quic/quic_transport_client.h
index 4f0f58ff8c8..de270225642 100644
--- a/chromium/net/quic/quic_transport_client.h
+++ b/chromium/net/quic/quic_transport_client.h
@@ -13,11 +13,13 @@
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
#include "net/quic/quic_context.h"
+#include "net/quic/quic_transport_error.h"
#include "net/socket/client_socket_factory.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
#include "net/third_party/quiche/src/quic/core/quic_config.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
+#include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -27,29 +29,6 @@ class ProxyResolutionRequest;
class QuicChromiumAlarmFactory;
class URLRequestContext;
-struct NET_EXPORT QuicTransportError {
- // |net_error| is always set to a meaningful value.
- int net_error = OK;
-
- // |quic_error| is set to a QUIC error, or to quic::QUIC_NO_ERROR if the error
- // originates non-QUIC parts of the stack.
- quic::QuicErrorCode quic_error = quic::QUIC_NO_ERROR;
-
- // Human-readable error summary.
- std::string details;
-
- // QuicTransport requires that the connection errors have to be
- // undistinguishable until the peer is confirmed to be a QuicTransport
- // endpoint. See https://wicg.github.io/web-transport/#protocol-security
- bool safe_to_report_details = false;
-};
-
-NET_EXPORT
-std::string QuicTransportErrorToString(const QuicTransportError& error);
-
-NET_EXPORT
-std::ostream& operator<<(std::ostream& os, const QuicTransportError& error);
-
// QuicTransportClient is the top-level API for QuicTransport in //net.
class NET_EXPORT QuicTransportClient
: public quic::QuicTransportClientSession::ClientVisitor,
@@ -65,6 +44,9 @@ class NET_EXPORT QuicTransportClient
// | |
// +---> FAILED <---+
//
+ // These values are logged to UMA. Entries should not be renumbered and
+ // numeric values should never be reused. Please keep in sync with
+ // "QuicTransportClientState" in src/tools/metrics/histograms/enums.xml.
enum State {
// The client object has been created but Connect() has not been called.
NEW,
@@ -78,6 +60,9 @@ class NET_EXPORT QuicTransportClient
CLOSED,
// The connection has been closed abruptly.
FAILED,
+
+ // Total number of possible states.
+ NUM_STATES,
};
class NET_EXPORT Visitor {
@@ -97,17 +82,35 @@ class NET_EXPORT QuicTransportClient
virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
};
- // QUIC protocol version that is used in the origin trial.
- static constexpr quic::ParsedQuicVersion kQuicVersionForOriginTrial =
- quic::ParsedQuicVersion(quic::PROTOCOL_TLS1_3,
- quic::QUIC_VERSION_IETF_DRAFT_27);
+ struct NET_EXPORT Parameters {
+ Parameters();
+ ~Parameters();
+ Parameters(const Parameters&);
+ Parameters(Parameters&&);
+
+ // A vector of fingerprints for expected server certificates, as described
+ // in
+ // https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
+ // When empty, Web PKI is used.
+ std::vector<quic::CertificateFingerprint> server_certificate_fingerprints;
+ };
+
+ // QUIC protocol versions that are used in the origin trial.
+ static quic::ParsedQuicVersionVector
+ QuicVersionsForWebTransportOriginTrial() {
+ return quic::ParsedQuicVersionVector{
+ quic::ParsedQuicVersion::Draft29(), // Enabled in M85.
+ quic::ParsedQuicVersion::Draft27() // Enabled in M84.
+ };
+ }
// |visitor| and |context| must outlive this object.
QuicTransportClient(const GURL& url,
const url::Origin& origin,
Visitor* visitor,
const NetworkIsolationKey& isolation_key,
- URLRequestContext* context);
+ URLRequestContext* context,
+ const Parameters& parameters);
~QuicTransportClient() override;
State state() const { return state_; }
@@ -154,6 +157,11 @@ class NET_EXPORT QuicTransportClient
private:
// State of the connection establishment process.
+ //
+ // These values are logged to UMA. Entries should not be renumbered and
+ // numeric values should never be reused. Please keep in sync with
+ // "QuicTransportClientConnectState" in
+ // src/tools/metrics/histograms/enums.xml.
enum ConnectState {
CONNECT_STATE_NONE,
CONNECT_STATE_INIT,
@@ -163,6 +171,8 @@ class NET_EXPORT QuicTransportClient
CONNECT_STATE_RESOLVE_HOST_COMPLETE,
CONNECT_STATE_CONNECT,
CONNECT_STATE_CONFIRM_CONNECTION,
+
+ CONNECT_STATE_NUM_STATES,
};
// DoLoop processing the Connect() call.
@@ -177,6 +187,7 @@ class NET_EXPORT QuicTransportClient
int DoResolveHostComplete(int rv);
// Establishes the QUIC connection.
int DoConnect();
+ void CreateConnection();
// Verifies that the connection has succeeded.
int DoConfirmConnection();
@@ -201,6 +212,7 @@ class NET_EXPORT QuicTransportClient
State state_ = NEW;
ConnectState next_connect_state_ = CONNECT_STATE_NONE;
QuicTransportError error_;
+ bool retried_with_new_version_ = false;
ProxyInfo proxy_info_;
std::unique_ptr<ProxyResolutionRequest> proxy_resolution_request_;
diff --git a/chromium/net/quic/quic_transport_end_to_end_test.cc b/chromium/net/quic/quic_transport_end_to_end_test.cc
index 9783a05ac60..95ae1538fa6 100644
--- a/chromium/net/quic/quic_transport_end_to_end_test.cc
+++ b/chromium/net/quic/quic_transport_end_to_end_test.cc
@@ -10,6 +10,7 @@
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
+#include "net/quic/crypto/proof_source_chromium.h"
#include "net/test/test_data_directory.h"
#include "net/test/test_with_task_environment.h"
#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
@@ -37,10 +38,48 @@ class MockVisitor : public QuicTransportClient::Visitor {
MOCK_METHOD0(OnCanCreateNewOutgoingUnidirectionalStream, void());
};
+// A clock that only mocks out WallNow(), but uses real Now() and
+// ApproximateNow(). Useful for certificate verification.
+class TestWallClock : public quic::QuicClock {
+ public:
+ quic::QuicTime Now() const override {
+ return quic::QuicChromiumClock::GetInstance()->Now();
+ }
+ quic::QuicTime ApproximateNow() const override {
+ return quic::QuicChromiumClock::GetInstance()->ApproximateNow();
+ }
+ quic::QuicWallTime WallNow() const override { return wall_now_; }
+
+ void set_wall_now(quic::QuicWallTime now) { wall_now_ = now; }
+
+ private:
+ quic::QuicWallTime wall_now_ = quic::QuicWallTime::Zero();
+};
+
+class TestConnectionHelper : public quic::QuicConnectionHelperInterface {
+ public:
+ const quic::QuicClock* GetClock() const override { return &clock_; }
+ quic::QuicRandom* GetRandomGenerator() override {
+ return quic::QuicRandom::GetInstance();
+ }
+ quic::QuicBufferAllocator* GetStreamSendBufferAllocator() override {
+ return &allocator_;
+ }
+
+ TestWallClock& clock() { return clock_; }
+
+ private:
+ TestWallClock clock_;
+ quic::SimpleBufferAllocator allocator_;
+};
+
class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
public:
QuicTransportEndToEndTest() {
- quic::QuicEnableVersion(QuicTransportClient::kQuicVersionForOriginTrial);
+ for (const quic::ParsedQuicVersion& version :
+ QuicTransportClient::QuicVersionsForWebTransportOriginTrial()) {
+ quic::QuicEnableVersion(version);
+ }
origin_ = url::Origin::Create(GURL{"https://example.org"});
isolation_key_ = NetworkIsolationKey(origin_, origin_);
@@ -56,7 +95,9 @@ class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
host_resolver->rules()->AddRule("test.example.com", "127.0.0.1");
builder.set_host_resolver(std::move(host_resolver));
- auto quic_context = std::make_unique<QuicContext>();
+ auto helper = std::make_unique<TestConnectionHelper>();
+ helper_ = helper.get();
+ auto quic_context = std::make_unique<QuicContext>(std::move(helper));
quic_context->params()->supported_versions.clear();
// This is required to bypass the check that only allows known certificate
// roots in QUIC.
@@ -75,8 +116,6 @@ class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
LOG(INFO) << "Connection error: " << client_->error();
run_loop_->Quit();
});
-
- StartServer();
}
GURL GetURL(const std::string& suffix) {
@@ -84,10 +123,13 @@ class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
"quic-transport://test.example.com:", port_, suffix)};
}
- void StartServer() {
+ void StartServer(std::unique_ptr<quic::ProofSource> proof_source = nullptr) {
+ if (proof_source == nullptr) {
+ proof_source = quic::test::crypto_test_utils::ProofSourceForTesting();
+ }
server_ = std::make_unique<QuicTransportSimpleServer>(
/* port */ 0, std::vector<url::Origin>({origin_}),
- quic::test::crypto_test_utils::ProofSourceForTesting());
+ std::move(proof_source));
ASSERT_EQ(EXIT_SUCCESS, server_->Start());
port_ = server_->server_address().port();
}
@@ -105,6 +147,7 @@ class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
QuicFlagSaver flags_; // Save/restore all QUIC flag values.
std::unique_ptr<URLRequestContext> context_;
std::unique_ptr<QuicTransportClient> client_;
+ TestConnectionHelper* helper_; // Owned by |context_|.
MockVisitor visitor_;
std::unique_ptr<QuicTransportSimpleServer> server_;
std::unique_ptr<base::RunLoop> run_loop_;
@@ -115,8 +158,10 @@ class QuicTransportEndToEndTest : public TestWithTaskEnvironment {
};
TEST_F(QuicTransportEndToEndTest, Connect) {
+ StartServer();
client_ = std::make_unique<QuicTransportClient>(
- GetURL("/discard"), origin_, &visitor_, isolation_key_, context_.get());
+ GetURL("/discard"), origin_, &visitor_, isolation_key_, context_.get(),
+ QuicTransportClient::Parameters());
client_->Connect();
EXPECT_CALL(visitor_, OnConnected()).WillOnce(StopRunning());
Run();
@@ -125,8 +170,10 @@ TEST_F(QuicTransportEndToEndTest, Connect) {
}
TEST_F(QuicTransportEndToEndTest, EchoUnidirectionalStream) {
+ StartServer();
client_ = std::make_unique<QuicTransportClient>(
- GetURL("/echo"), origin_, &visitor_, isolation_key_, context_.get());
+ GetURL("/echo"), origin_, &visitor_, isolation_key_, context_.get(),
+ QuicTransportClient::Parameters());
client_->Connect();
EXPECT_CALL(visitor_, OnConnected()).WillOnce(StopRunning());
Run();
@@ -151,6 +198,107 @@ TEST_F(QuicTransportEndToEndTest, EchoUnidirectionalStream) {
EXPECT_EQ("test", data);
}
+TEST_F(QuicTransportEndToEndTest, CertificateFingerprint) {
+ auto proof_source = std::make_unique<net::ProofSourceChromium>();
+ base::FilePath certs_dir = net::GetTestCertsDirectory();
+ ASSERT_TRUE(proof_source->Initialize(
+ certs_dir.AppendASCII("quic-short-lived.pem"),
+ certs_dir.AppendASCII("quic-leaf-cert.key"),
+ certs_dir.AppendASCII("quic-leaf-cert.key.sct")));
+ StartServer(std::move(proof_source));
+ // Set clock to a time in which quic-short-lived.pem is valid
+ // (2020-06-05T20:35:00.000Z).
+ helper_->clock().set_wall_now(
+ quic::QuicWallTime::FromUNIXSeconds(1591389300));
+
+ QuicTransportClient::Parameters parameters;
+ parameters.server_certificate_fingerprints.push_back(
+ quic::CertificateFingerprint{
+ .algorithm = quic::CertificateFingerprint::kSha256,
+ .fingerprint = "ED:3D:D7:C3:67:10:94:68:D1:DC:D1:26:5C:B2:74:D7:1C:"
+ "A2:63:3E:94:94:C0:84:39:D6:64:FA:08:B9:77:37"});
+ client_ = std::make_unique<QuicTransportClient>(GetURL("/discard"), origin_,
+ &visitor_, isolation_key_,
+ context_.get(), parameters);
+ client_->Connect();
+ EXPECT_CALL(visitor_, OnConnected()).WillOnce(StopRunning());
+ Run();
+ ASSERT_TRUE(client_->session() != nullptr);
+ EXPECT_TRUE(client_->session()->IsSessionReady());
+}
+
+TEST_F(QuicTransportEndToEndTest, CertificateFingerprintValidiyTooLong) {
+ StartServer();
+ QuicTransportClient::Parameters parameters;
+ // The default QUIC test certificate is valid for ten years, which exceeds
+ // the two-week limit.
+ parameters.server_certificate_fingerprints.push_back(
+ quic::CertificateFingerprint{
+ .algorithm = quic::CertificateFingerprint::kSha256,
+ .fingerprint = "25:17:B1:79:76:C8:94:BD:F0:B5:5C:0B:CC:70:C8:69:2B:"
+ "27:B8:84:F0:30:FE:A8:62:99:37:63:D2:A9:D6:EE"});
+ client_ = std::make_unique<QuicTransportClient>(GetURL("/discard"), origin_,
+ &visitor_, isolation_key_,
+ context_.get(), parameters);
+ client_->Connect();
+ EXPECT_CALL(visitor_, OnConnectionFailed()).WillOnce(StopRunning());
+ Run();
+ EXPECT_TRUE(client_->session() == nullptr);
+ EXPECT_EQ(client_->error().quic_error, quic::QUIC_HANDSHAKE_FAILED);
+}
+
+TEST_F(QuicTransportEndToEndTest, CertificateFingerprintMismatch) {
+ StartServer();
+
+ QuicTransportClient::Parameters parameters;
+ parameters.server_certificate_fingerprints.push_back(
+ quic::CertificateFingerprint{
+ .algorithm = quic::CertificateFingerprint::kSha256,
+ .fingerprint = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:"
+ "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"});
+ client_ = std::make_unique<QuicTransportClient>(GetURL("/discard"), origin_,
+ &visitor_, isolation_key_,
+ context_.get(), parameters);
+ client_->Connect();
+ EXPECT_CALL(visitor_, OnConnectionFailed()).WillOnce(StopRunning());
+ Run();
+ EXPECT_TRUE(client_->session() == nullptr);
+ EXPECT_EQ(client_->error().quic_error, quic::QUIC_HANDSHAKE_FAILED);
+}
+
+TEST_F(QuicTransportEndToEndTest, OldVersion) {
+ // Ensure all WebTransport versions are enabled except the first one.
+ quic::QuicDisableVersion(
+ QuicTransportClient::QuicVersionsForWebTransportOriginTrial().front());
+
+ StartServer();
+ client_ = std::make_unique<QuicTransportClient>(
+ GetURL("/discard"), origin_, &visitor_, isolation_key_, context_.get(),
+ QuicTransportClient::Parameters());
+ client_->Connect();
+ EXPECT_CALL(visitor_, OnConnected()).WillOnce(StopRunning());
+ Run();
+ ASSERT_TRUE(client_->session() != nullptr);
+ EXPECT_TRUE(client_->session()->IsSessionReady());
+}
+
+TEST_F(QuicTransportEndToEndTest, NoCommonVersion) {
+ // Disable all WebTransport versions.
+ for (const quic::ParsedQuicVersion& version :
+ QuicTransportClient::QuicVersionsForWebTransportOriginTrial()) {
+ quic::QuicDisableVersion(version);
+ }
+
+ StartServer();
+ client_ = std::make_unique<QuicTransportClient>(
+ GetURL("/discard"), origin_, &visitor_, isolation_key_, context_.get(),
+ QuicTransportClient::Parameters());
+ client_->Connect();
+ EXPECT_CALL(visitor_, OnConnectionFailed()).WillOnce(StopRunning());
+ Run();
+ EXPECT_TRUE(client_->session() == nullptr);
+ EXPECT_EQ(client_->error().quic_error, quic::QUIC_INVALID_VERSION);
+}
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/quic_transport_error.cc b/chromium/net/quic/quic_transport_error.cc
new file mode 100644
index 00000000000..8c76d6705e9
--- /dev/null
+++ b/chromium/net/quic/quic_transport_error.cc
@@ -0,0 +1,24 @@
+// 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.
+
+#include "net/quic/quic_transport_error.h"
+
+#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
+
+namespace net {
+
+std::string QuicTransportErrorToString(const QuicTransportError& error) {
+ std::string message =
+ ExtendedErrorToString(error.net_error, error.quic_error);
+ if (error.details == message)
+ return message;
+ return quiche::QuicheStrCat(message, " (", error.details, ")");
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicTransportError& error) {
+ os << QuicTransportErrorToString(error);
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/quic_transport_error.h b/chromium/net/quic/quic_transport_error.h
new file mode 100644
index 00000000000..d970e094074
--- /dev/null
+++ b/chromium/net/quic/quic_transport_error.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef NET_QUIC_QUIC_TRANSPORT_ERROR_H_
+#define NET_QUIC_QUIC_TRANSPORT_ERROR_H_
+
+#include <ostream>
+#include <string>
+
+#include "base/strings/string_piece.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_export.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+
+namespace net {
+
+struct NET_EXPORT QuicTransportError {
+ QuicTransportError() = default;
+ QuicTransportError(int net_error,
+ quic::QuicErrorCode quic_error,
+ base::StringPiece details,
+ bool safe_to_report_details)
+ : net_error(net_error),
+ quic_error(quic_error),
+ details(details),
+ safe_to_report_details(safe_to_report_details) {}
+
+ // |net_error| is always set to a meaningful value.
+ int net_error = OK;
+
+ // |quic_error| is set to a QUIC error, or to quic::QUIC_NO_ERROR if the error
+ // originates non-QUIC parts of the stack.
+ quic::QuicErrorCode quic_error = quic::QUIC_NO_ERROR;
+
+ // Human-readable error summary.
+ std::string details;
+
+ // QuicTransport requires that the connection errors have to be
+ // undistinguishable until the peer is confirmed to be a QuicTransport
+ // endpoint. See https://wicg.github.io/web-transport/#protocol-security
+ bool safe_to_report_details = false;
+};
+
+NET_EXPORT
+std::string QuicTransportErrorToString(const QuicTransportError& error);
+
+NET_EXPORT
+std::ostream& operator<<(std::ostream& os, const QuicTransportError& error);
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_TRANSPORT_ERROR_H_
diff --git a/chromium/net/quic/quic_transport_parameters_fuzzer.cc b/chromium/net/quic/quic_transport_parameters_fuzzer.cc
index 4225bc00b6b..e6b1b129f7a 100644
--- a/chromium/net/quic/quic_transport_parameters_fuzzer.cc
+++ b/chromium/net/quic/quic_transport_parameters_fuzzer.cc
@@ -19,14 +19,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
quic::TransportParameters transport_parameters;
std::vector<uint8_t> remaining_bytes =
data_provider.ConsumeRemainingBytes<uint8_t>();
- quic::ParsedQuicVersion version = quic::UnsupportedQuicVersion();
- for (const quic::ParsedQuicVersion& vers : quic::AllSupportedVersions()) {
- if (vers.handshake_protocol == quic::PROTOCOL_TLS1_3) {
- version = vers;
- break;
- }
- }
- CHECK_NE(version.transport_version, quic::QUIC_VERSION_UNSUPPORTED);
+ quic::ParsedQuicVersion version = quic::AllSupportedVersionsWithTls().front();
+ CHECK(version.UsesTls());
std::string error_details;
quic::ParseTransportParameters(version, perspective, remaining_bytes.data(),
remaining_bytes.size(), &transport_parameters,
diff --git a/chromium/net/quic/quic_utils_chromium.cc b/chromium/net/quic/quic_utils_chromium.cc
deleted file mode 100644
index 90e08fcfa11..00000000000
--- a/chromium/net/quic/quic_utils_chromium.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/quic/quic_utils_chromium.h"
-
-#include "base/containers/adapters.h"
-#include "base/strings/string_split.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace net {
-
-quic::QuicTagVector ParseQuicConnectionOptions(
- const std::string& connection_options) {
- quic::QuicTagVector options;
- // Tokens are expected to be no more than 4 characters long, but
- // handle overflow gracefully.
- for (const quiche::QuicheStringPiece& token :
- base::SplitStringPiece(connection_options, ",", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_ALL)) {
- uint32_t option = 0;
- for (char token_char : base::Reversed(token)) {
- option <<= 8;
- option |= static_cast<unsigned char>(token_char);
- }
- options.push_back(option);
- }
- return options;
-}
-
-} // namespace net
diff --git a/chromium/net/quic/quic_utils_chromium.h b/chromium/net/quic/quic_utils_chromium.h
deleted file mode 100644
index 7f8a7de9064..00000000000
--- a/chromium/net/quic/quic_utils_chromium.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 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.
-//
-// Some helpers for quic that are for chromium codebase.
-
-#ifndef NET_QUIC_QUIC_UTILS_CHROMIUM_H_
-#define NET_QUIC_QUIC_UTILS_CHROMIUM_H_
-
-#include <string>
-
-#include "base/logging.h"
-#include "net/base/net_export.h"
-#include "net/third_party/quiche/src/quic/core/quic_tag.h"
-#include "net/third_party/quiche/src/quic/core/quic_versions.h"
-
-namespace net {
-
-// Returns the list of QUIC tags represented by the comma separated
-// string in |connection_options|.
-NET_EXPORT quic::QuicTagVector ParseQuicConnectionOptions(
- const std::string& connection_options);
-
-} // namespace net
-
-#endif // NET_QUIC_QUIC_UTILS_CHROMIUM_H_
diff --git a/chromium/net/quic/quic_utils_chromium_test.cc b/chromium/net/quic/quic_utils_chromium_test.cc
deleted file mode 100644
index 2af22a0d5e3..00000000000
--- a/chromium/net/quic/quic_utils_chromium_test.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 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/quic/quic_utils_chromium.h"
-
-#include <map>
-
-#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-
-namespace net {
-namespace test {
-namespace {
-
-TEST(QuicUtilsChromiumTest, ParseQuicConnectionOptions) {
- quic::QuicTagVector empty_options = ParseQuicConnectionOptions("");
- EXPECT_TRUE(empty_options.empty());
-
- quic::QuicTagVector parsed_options =
- ParseQuicConnectionOptions("TIMER,TBBR,REJ");
- quic::QuicTagVector expected_options;
- expected_options.push_back(quic::kTIME);
- expected_options.push_back(quic::kTBBR);
- expected_options.push_back(quic::kREJ);
- EXPECT_EQ(expected_options, parsed_options);
-}
-
-} // namespace
-} // namespace test
-} // namespace net
diff --git a/chromium/net/quiche/common/platform/impl/quiche_logging_impl.h b/chromium/net/quiche/common/platform/impl/quiche_logging_impl.h
index d3261b023f3..0d1d111be61 100644
--- a/chromium/net/quiche/common/platform/impl/quiche_logging_impl.h
+++ b/chromium/net/quiche/common/platform/impl/quiche_logging_impl.h
@@ -5,7 +5,9 @@
#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
+#include "base/check_op.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/quiche/common/platform/impl/quiche_optional_impl.h b/chromium/net/quiche/common/platform/impl/quiche_optional_impl.h
index bbdb0a80308..9d1648695bc 100644
--- a/chromium/net/quiche/common/platform/impl/quiche_optional_impl.h
+++ b/chromium/net/quiche/common/platform/impl/quiche_optional_impl.h
@@ -12,7 +12,7 @@ namespace quiche {
template <typename T>
using QuicheOptionalImpl = base::Optional<T>;
-#define QuicheNullOptImpl base::nullopt
+#define QUICHE_NULLOPT_IMPL base::nullopt
} // namespace quiche
diff --git a/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.cc b/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.cc
new file mode 100644
index 00000000000..7c78cbc5bcb
--- /dev/null
+++ b/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.cc
@@ -0,0 +1,50 @@
+// 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.
+
+#include "net/quiche/common/platform/impl/quiche_time_utils_impl.h"
+
+#include "base/time/time.h"
+
+#include <iostream>
+
+namespace quiche {
+QuicheOptional<int64_t> QuicheUtcDateTimeToUnixSecondsInner(int year,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ int second) {
+ base::Time::Exploded exploded{
+ year, month,
+ 0, // day_of_week
+ day, hour, minute, second,
+ };
+ base::Time time;
+ if (!base::Time::FromUTCExploded(exploded, &time)) {
+ return base::nullopt;
+ }
+ return (time - base::Time::UnixEpoch()).InSeconds();
+}
+
+QuicheOptional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ int second) {
+ // Handle leap seconds without letting any other irregularities happen.
+ if (second == 60) {
+ auto previous_second = QuicheUtcDateTimeToUnixSecondsInner(
+ year, month, day, hour, minute, second - 1);
+ if (!previous_second.has_value()) {
+ return base::nullopt;
+ }
+ return *previous_second + 1;
+ }
+
+ return QuicheUtcDateTimeToUnixSecondsInner(year, month, day, hour, minute,
+ second);
+}
+
+} // namespace quiche
diff --git a/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.h b/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.h
new file mode 100644
index 00000000000..60dda04eb65
--- /dev/null
+++ b/chromium/net/quiche/common/platform/impl/quiche_time_utils_impl.h
@@ -0,0 +1,25 @@
+// 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.
+
+#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
+#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
+
+#include <cstdint>
+
+#include "net/base/net_export.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
+
+namespace quiche {
+
+NET_EXPORT_PRIVATE QuicheOptional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(
+ int year,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ int second);
+
+} // namespace quiche
+
+#endif // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
diff --git a/chromium/net/reporting/reporting_browsing_data_remover.cc b/chromium/net/reporting/reporting_browsing_data_remover.cc
index 310242aa14a..084b8d6c96f 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover.cc
+++ b/chromium/net/reporting/reporting_browsing_data_remover.cc
@@ -15,7 +15,7 @@ namespace net {
// static
void ReportingBrowsingDataRemover::RemoveBrowsingData(
ReportingCache* cache,
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
if ((data_type_mask & DATA_TYPE_REPORTS) != 0) {
std::vector<const ReportingReport*> all_reports;
@@ -42,8 +42,9 @@ void ReportingBrowsingDataRemover::RemoveBrowsingData(
}
// static
-void ReportingBrowsingDataRemover::RemoveAllBrowsingData(ReportingCache* cache,
- int data_type_mask) {
+void ReportingBrowsingDataRemover::RemoveAllBrowsingData(
+ ReportingCache* cache,
+ uint64_t data_type_mask) {
if ((data_type_mask & DATA_TYPE_REPORTS) != 0) {
cache->RemoveAllReports(
ReportingReport::Outcome::ERASED_BROWSING_DATA_REMOVED);
diff --git a/chromium/net/reporting/reporting_browsing_data_remover.h b/chromium/net/reporting/reporting_browsing_data_remover.h
index ce3df31ffc0..f4a9e2b68b9 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover.h
+++ b/chromium/net/reporting/reporting_browsing_data_remover.h
@@ -32,13 +32,14 @@ class NET_EXPORT ReportingBrowsingDataRemover {
// persisted, it will need to be cleared as well.
static void RemoveBrowsingData(
ReportingCache* cache,
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter);
// Like RemoveBrowsingData except removes data for all origins without a
// filter. Allows slight optimization over passing an always-true filter to
// RemoveBrowsingData.
- static void RemoveAllBrowsingData(ReportingCache* cache, int data_type_mask);
+ static void RemoveAllBrowsingData(ReportingCache* cache,
+ uint64_t data_type_mask);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ReportingBrowsingDataRemover);
diff --git a/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc b/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
index 1ddb5c266ad..687bf5a4e95 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -24,7 +24,7 @@ class ReportingBrowsingDataRemoverTest : public ReportingTestBase {
void RemoveBrowsingData(bool remove_reports,
bool remove_clients,
std::string host) {
- int data_type_mask = 0;
+ uint64_t data_type_mask = 0;
if (remove_reports)
data_type_mask |= ReportingBrowsingDataRemover::DATA_TYPE_REPORTS;
if (remove_clients)
@@ -43,15 +43,15 @@ class ReportingBrowsingDataRemoverTest : public ReportingTestBase {
// TODO(chlily): Take NIK.
void AddReport(const GURL& url) {
- cache()->AddReport(NetworkIsolationKey::Todo(), url, kUserAgent_, kGroup_,
- kType_, std::make_unique<base::DictionaryValue>(), 0,
+ cache()->AddReport(NetworkIsolationKey(), url, kUserAgent_, kGroup_, kType_,
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
}
// TODO(chlily): Take NIK.
void SetEndpoint(const url::Origin& origin) {
SetEndpointInCache(
- ReportingEndpointGroupKey(NetworkIsolationKey::Todo(), origin, kGroup_),
+ ReportingEndpointGroupKey(NetworkIsolationKey(), origin, kGroup_),
kEndpoint_, base::Time::Now() + base::TimeDelta::FromDays(7));
}
@@ -154,14 +154,12 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeClients) {
RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ true,
/* host= */ kUrl1_.host());
EXPECT_EQ(2u, report_count());
- EXPECT_FALSE(
- FindEndpointInCache(ReportingEndpointGroupKey(NetworkIsolationKey::Todo(),
- kOrigin1_, kGroup_),
- kEndpoint_));
- EXPECT_TRUE(
- FindEndpointInCache(ReportingEndpointGroupKey(NetworkIsolationKey::Todo(),
- kOrigin2_, kGroup_),
- kEndpoint_));
+ EXPECT_FALSE(FindEndpointInCache(
+ ReportingEndpointGroupKey(NetworkIsolationKey(), kOrigin1_, kGroup_),
+ kEndpoint_));
+ EXPECT_TRUE(FindEndpointInCache(
+ ReportingEndpointGroupKey(NetworkIsolationKey(), kOrigin2_, kGroup_),
+ kEndpoint_));
}
} // namespace
diff --git a/chromium/net/reporting/reporting_cache_impl.cc b/chromium/net/reporting/reporting_cache_impl.cc
index 14fc211c02d..7b4e0345b27 100644
--- a/chromium/net/reporting/reporting_cache_impl.cc
+++ b/chromium/net/reporting/reporting_cache_impl.cc
@@ -176,15 +176,11 @@ void ReportingCacheImpl::IncrementEndpointDeliveries(
void ReportingCacheImpl::RemoveReports(
const std::vector<const ReportingReport*>& reports,
ReportingReport::Outcome outcome) {
- base::Optional<base::TimeTicks> delivered = base::nullopt;
- if (outcome == ReportingReport::Outcome::DELIVERED)
- delivered = tick_clock().NowTicks();
for (const ReportingReport* report : reports) {
auto it = reports_.find(report);
DCHECK(it != reports_.end());
it->get()->outcome = outcome;
- it->get()->delivered = delivered;
if (it->get()->IsUploadPending()) {
it->get()->status = ReportingReport::Status::DOOMED;
diff --git a/chromium/net/reporting/reporting_delivery_agent.cc b/chromium/net/reporting/reporting_delivery_agent.cc
index fca2421b239..80a7a8c9e75 100644
--- a/chromium/net/reporting/reporting_delivery_agent.cc
+++ b/chromium/net/reporting/reporting_delivery_agent.cc
@@ -4,9 +4,10 @@
#include "net/reporting/reporting_delivery_agent.h"
+#include <algorithm>
#include <map>
+#include <set>
#include <string>
-#include <unordered_set>
#include <utility>
#include <vector>
@@ -17,6 +18,7 @@
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/base/network_isolation_key.h"
+#include "net/base/url_util.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_cache_observer.h"
#include "net/reporting/reporting_context.h"
@@ -31,9 +33,9 @@ namespace net {
namespace {
-void SerializeReports(const std::vector<const ReportingReport*>& reports,
- base::TimeTicks now,
- std::string* json_out) {
+using ReportList = std::vector<const ReportingReport*>;
+
+std::string SerializeReports(const ReportList& reports, base::TimeTicks now) {
base::ListValue reports_value;
for (const ReportingReport* report : reports) {
@@ -49,10 +51,112 @@ void SerializeReports(const std::vector<const ReportingReport*>& reports,
reports_value.Append(std::move(report_value));
}
- bool json_written = base::JSONWriter::Write(reports_value, json_out);
+ std::string json_out;
+ bool json_written = base::JSONWriter::Write(reports_value, &json_out);
DCHECK(json_written);
+ return json_out;
+}
+
+bool CompareReportGroupKeys(const ReportingReport* lhs,
+ const ReportingReport* rhs) {
+ return lhs->GetGroupKey() < rhs->GetGroupKey();
}
+// Each Delivery corresponds to one upload URLRequest.
+class Delivery {
+ public:
+ // The target of a delivery. All reports uploaded together must share the
+ // same values for these parameters.
+ // Note that |origin| here (which matches the report's |origin|) is not
+ // necessarily the same as the |origin| of the ReportingEndpoint's group key
+ // (if the endpoint is configured to include subdomains). Reports with
+ // different group keys can be in the same delivery, as long as the NIK and
+ // report origin are the same, and they all get assigned to the same endpoint
+ // URL.
+ struct Target {
+ Target(const NetworkIsolationKey& network_isolation_key,
+ const url::Origin& origin,
+ const GURL& endpoint_url)
+ : network_isolation_key(network_isolation_key),
+ origin(origin),
+ endpoint_url(endpoint_url) {}
+
+ ~Target() = default;
+
+ bool operator<(const Target& other) const {
+ return std::tie(network_isolation_key, origin, endpoint_url) <
+ std::tie(other.network_isolation_key, other.origin,
+ other.endpoint_url);
+ }
+
+ NetworkIsolationKey network_isolation_key;
+ url::Origin origin;
+ GURL endpoint_url;
+ };
+
+ explicit Delivery(const Target& target) : target_(target) {}
+
+ ~Delivery() = default;
+
+ // Add the reports in [reports_begin, reports_end) into this delivery.
+ // Modify the report counter for the |endpoint| to which this delivery is
+ // destined.
+ void AddReports(const ReportingEndpoint& endpoint,
+ const ReportList::const_iterator reports_begin,
+ const ReportList::const_iterator reports_end) {
+ DCHECK(reports_begin != reports_end);
+ DCHECK_EQ(endpoint.group_key.network_isolation_key,
+ network_isolation_key());
+ DCHECK(IsSubdomainOf(target_.origin.host() /* subdomain */,
+ endpoint.group_key.origin.host() /* superdomain */));
+ for (auto it = reports_begin; it != reports_end; ++it) {
+ DCHECK_EQ((*reports_begin)->GetGroupKey(), (*it)->GetGroupKey());
+ DCHECK_EQ((*it)->network_isolation_key, network_isolation_key());
+ DCHECK_EQ(url::Origin::Create((*it)->url), target_.origin);
+ DCHECK_EQ((*it)->group, endpoint.group_key.group_name);
+ // Report origin is equal to, or a subdomain of, the endpoint
+ // configuration's origin.
+ DCHECK(IsSubdomainOf((*it)->url.host_piece() /* subdomain */,
+ endpoint.group_key.origin.host() /* superdomain */));
+ }
+
+ reports_per_group_[endpoint.group_key] +=
+ std::distance(reports_begin, reports_end);
+ reports_.insert(reports_.end(), reports_begin, reports_end);
+ }
+
+ // Records statistics for reports after an upload has completed.
+ // Either removes successfully delivered reports, or increments the failure
+ // counter if delivery was unsuccessful.
+ void ProcessOutcome(ReportingCache* cache, bool success) {
+ for (const auto& group_name_and_count : reports_per_group_) {
+ cache->IncrementEndpointDeliveries(group_name_and_count.first,
+ target_.endpoint_url,
+ group_name_and_count.second, success);
+ }
+ if (success) {
+ cache->RemoveReports(reports_, ReportingReport::Outcome::DELIVERED);
+ } else {
+ cache->IncrementReportsAttempts(reports_);
+ }
+ }
+
+ const NetworkIsolationKey& network_isolation_key() const {
+ return target_.network_isolation_key;
+ }
+ const GURL& endpoint_url() const { return target_.endpoint_url; }
+ const ReportList& reports() const { return reports_; }
+
+ private:
+ const Target target_;
+ ReportList reports_;
+
+ // Used to track statistics for each ReportingEndpoint.
+ // The endpoint is uniquely identified by the key in conjunction with
+ // |target_.endpoint_url|. See ProcessOutcome().
+ std::map<ReportingEndpointGroupKey, int> reports_per_group_;
+};
+
class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
public ReportingCacheObserver {
public:
@@ -89,33 +193,8 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
}
private:
- // TODO(chlily): Add NIK.
- using OriginEndpoint = std::pair<url::Origin, GURL>;
- using GroupEndpoint = std::pair<ReportingEndpointGroupKey, GURL>;
-
- class Delivery {
- public:
- explicit Delivery(const OriginEndpoint& report_origin_endpoint)
- : report_origin(report_origin_endpoint.first),
- endpoint(report_origin_endpoint.second) {}
-
- ~Delivery() = default;
-
- void AddReports(const ReportingEndpoint& endpoint,
- const std::vector<const ReportingReport*>& to_add) {
- GroupEndpoint key = std::make_pair(endpoint.group_key, endpoint.info.url);
- reports_per_endpoint[key] += to_add.size();
- reports.insert(reports.end(), to_add.begin(), to_add.end());
- }
-
- const url::Origin report_origin;
- const GURL endpoint;
- std::vector<const ReportingReport*> reports;
- std::map<GroupEndpoint, int> reports_per_endpoint;
- };
-
bool CacheHasReports() {
- std::vector<const ReportingReport*> reports;
+ ReportList reports;
context_->cache()->GetReports(&reports);
return !reports.empty();
}
@@ -134,8 +213,9 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
}
void SendReports() {
- std::vector<const ReportingReport*> reports =
- cache()->GetReportsToDeliver();
+ ReportList reports = cache()->GetReportsToDeliver();
+ if (reports.empty())
+ return;
// First determine which origins we're allowed to upload reports about.
std::set<url::Origin> report_origins;
@@ -148,84 +228,79 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
weak_factory_.GetWeakPtr(), std::move(reports)));
}
- void OnSendPermissionsChecked(std::vector<const ReportingReport*> reports,
+ void OnSendPermissionsChecked(ReportList reports,
std::set<url::Origin> allowed_report_origins) {
- // Sort reports into buckets by endpoint group.
- std::map<ReportingEndpointGroupKey, std::vector<const ReportingReport*>>
- origin_group_reports;
- for (const ReportingReport* report : reports) {
- url::Origin report_origin = url::Origin::Create(report->url);
- if (allowed_report_origins.find(report_origin) ==
- allowed_report_origins.end()) {
+ DCHECK(!reports.empty());
+ std::map<Delivery::Target, std::unique_ptr<Delivery>> deliveries;
+
+ // Sort by group key
+ std::sort(reports.begin(), reports.end(), &CompareReportGroupKeys);
+
+ // Iterate over "buckets" of reports with the same group key.
+ for (auto bucket_it = reports.begin(); bucket_it != reports.end();) {
+ auto bucket_start = bucket_it;
+ // Set the iterator to the beginning of the next group bucket.
+ bucket_it = std::upper_bound(bucket_it, reports.end(), *bucket_it,
+ &CompareReportGroupKeys);
+
+ // Skip this group if we don't have origin permissions for this origin.
+ const ReportingEndpointGroupKey& report_group_key =
+ (*bucket_start)->GetGroupKey();
+ if (!base::Contains(allowed_report_origins, report_group_key.origin))
continue;
- }
- // TODO(chlily): Use proper NIK once reports are double-keyed.
- ReportingEndpointGroupKey group_key(NetworkIsolationKey::Todo(),
- report_origin, report->group);
- origin_group_reports[group_key].push_back(report);
- }
- // Find an endpoint for each (origin, group) bucket and sort reports into
- // endpoint buckets. Don't allow concurrent deliveries to the same (origin,
- // group) bucket.
- std::map<OriginEndpoint, std::unique_ptr<Delivery>> deliveries;
- for (auto& it : origin_group_reports) {
- const ReportingEndpointGroupKey& group_key = it.first;
-
- if (base::Contains(pending_groups_, group_key))
+ // Skip this group if there is already a pending upload for it.
+ // We don't allow multiple concurrent uploads for the same group.
+ if (base::Contains(pending_groups_, report_group_key))
continue;
+ // Find an endpoint to deliver these reports to.
const ReportingEndpoint endpoint =
- endpoint_manager_->FindEndpointForDelivery(group_key);
-
- if (!endpoint) {
- // TODO(chlily): Remove reports for which there are no valid
- // delivery endpoints.
+ endpoint_manager_->FindEndpointForDelivery(report_group_key);
+ // TODO(chlily): Remove reports for which there are no valid delivery
+ // endpoints.
+ if (!endpoint)
continue;
- }
- OriginEndpoint report_origin_endpoint(group_key.origin,
- endpoint.info.url);
- Delivery* delivery;
- auto delivery_it = deliveries.find(report_origin_endpoint);
+ pending_groups_.insert(report_group_key);
+
+ // Add the reports to the appropriate delivery.
+ Delivery::Target target(report_group_key.network_isolation_key,
+ report_group_key.origin, endpoint.info.url);
+ auto delivery_it = deliveries.find(target);
if (delivery_it == deliveries.end()) {
- auto new_delivery = std::make_unique<Delivery>(report_origin_endpoint);
- delivery = new_delivery.get();
- deliveries[report_origin_endpoint] = std::move(new_delivery);
- } else {
- delivery = delivery_it->second.get();
+ bool inserted;
+ auto new_delivery = std::make_unique<Delivery>(target);
+ std::tie(delivery_it, inserted) = deliveries.insert(
+ std::make_pair(std::move(target), std::move(new_delivery)));
+ DCHECK(inserted);
}
-
- delivery->AddReports(endpoint, it.second);
- pending_groups_.insert(group_key);
+ delivery_it->second->AddReports(endpoint, bucket_start, bucket_it);
}
// Keep track of which of these reports we don't queue for delivery; we'll
// need to mark them as not-pending.
- std::unordered_set<const ReportingReport*> undelivered_reports(
- reports.begin(), reports.end());
+ std::set<const ReportingReport*> undelivered_reports(reports.begin(),
+ reports.end());
// Start an upload for each delivery.
- for (auto& it : deliveries) {
- const OriginEndpoint& report_origin_endpoint = it.first;
- const url::Origin& report_origin = report_origin_endpoint.first;
- const GURL& endpoint = report_origin_endpoint.second;
- std::unique_ptr<Delivery>& delivery = it.second;
-
- std::string json;
- SerializeReports(delivery->reports, tick_clock().NowTicks(), &json);
+ for (auto& target_and_delivery : deliveries) {
+ const Delivery::Target& target = target_and_delivery.first;
+ std::unique_ptr<Delivery>& delivery = target_and_delivery.second;
int max_depth = 0;
- for (const ReportingReport* report : delivery->reports) {
+ for (const ReportingReport* report : delivery->reports()) {
undelivered_reports.erase(report);
- if (report->depth > max_depth)
- max_depth = report->depth;
+ max_depth = std::max(report->depth, max_depth);
}
+ std::string upload_data =
+ SerializeReports(delivery->reports(), tick_clock().NowTicks());
+
// TODO: Calculate actual max depth.
- // TODO(mmenke): Populate NetworkIsolationKey.
uploader()->StartUpload(
- report_origin, endpoint, NetworkIsolationKey::Todo(), json, max_depth,
+ target.origin, target.endpoint_url, target.network_isolation_key,
+ upload_data, max_depth,
base::BindOnce(&ReportingDeliveryAgentImpl::OnUploadComplete,
weak_factory_.GetWeakPtr(), std::move(delivery)));
}
@@ -236,39 +311,24 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
void OnUploadComplete(std::unique_ptr<Delivery> delivery,
ReportingUploader::Outcome outcome) {
- for (const auto& endpoint_and_count : delivery->reports_per_endpoint) {
- const ReportingEndpointGroupKey& group_key =
- endpoint_and_count.first.first;
- const GURL& endpoint = endpoint_and_count.first.second;
- int report_count = endpoint_and_count.second;
- cache()->IncrementEndpointDeliveries(
- group_key, endpoint, report_count,
- outcome == ReportingUploader::Outcome::SUCCESS);
- }
+ bool success = outcome == ReportingUploader::Outcome::SUCCESS;
+ delivery->ProcessOutcome(cache(), success);
- if (outcome == ReportingUploader::Outcome::SUCCESS) {
- cache()->RemoveReports(delivery->reports,
- ReportingReport::Outcome::DELIVERED);
- // TODO(mmenke): Populate NetworkIsolationKey argument.
- endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey::Todo(),
- delivery->endpoint, true);
- } else {
- cache()->IncrementReportsAttempts(delivery->reports);
- // TODO(mmenke): Populate NetworkIsolationKey argument.
- endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey::Todo(),
- delivery->endpoint, false);
- }
+ endpoint_manager_->InformOfEndpointRequest(
+ delivery->network_isolation_key(), delivery->endpoint_url(), success);
+ // TODO(chlily): This leaks information across NIKs. If the endpoint URL is
+ // configured for both NIK1 and NIK2, and it responds with a 410 on a NIK1
+ // connection, then the change in configuration will be detectable on a NIK2
+ // connection.
if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT)
- cache()->RemoveEndpointsForUrl(delivery->endpoint);
+ cache()->RemoveEndpointsForUrl(delivery->endpoint_url());
- for (const ReportingReport* report : delivery->reports) {
- ReportingEndpointGroupKey group_key(
- NetworkIsolationKey::Todo(), delivery->report_origin, report->group);
- pending_groups_.erase(group_key);
+ for (const ReportingReport* report : delivery->reports()) {
+ pending_groups_.erase(report->GetGroupKey());
}
- cache()->ClearReportsPending(delivery->reports);
+ cache()->ClearReportsPending(delivery->reports());
}
const ReportingPolicy& policy() const { return context_->policy(); }
diff --git a/chromium/net/reporting/reporting_delivery_agent.h b/chromium/net/reporting/reporting_delivery_agent.h
index b857fd16b98..08cb97f4c91 100644
--- a/chromium/net/reporting/reporting_delivery_agent.h
+++ b/chromium/net/reporting/reporting_delivery_agent.h
@@ -19,32 +19,27 @@ namespace net {
class ReportingContext;
-// Takes reports from the ReportingCache, assembles reports into deliveries to
-// endpoints, and sends those deliveries using ReportingUploader.
+// Batches reports fetched from the ReportingCache and uploads them using the
+// ReportingUploader.
//
-// Since the Reporting spec is completely silent on issues of concurrency, the
-// delivery agent handles it as so:
+// Reports are only considered for delivery if all of the following are true:
+// - The report is not already part of a pending upload request.
+// - Uploads are allowed for the report's origin (i.e. the origin of the URL
+// associated with the reported event).
+// - There is not already a pending upload for any reports sharing the same
+// (NIK, origin, group) key.
//
-// 1. An individual report can only be included in one delivery at once -- if
-// SendReports is called again while a report is being delivered, it won't
-// be included in another delivery during that call to SendReports. (This is,
-// in fact, made redundant by rule 3, but it's included anyway in case rule 3
-// changes.)
+// Reports are batched for upload to an endpoint URL such that:
+// - The available reports with the same (NIK, origin, group) are always
+// uploaded together.
+// - All reports uploaded together must share a NIK and origin.
+// - Reports for the same (NIK, origin) can be uploaded separately if they are
+// for different groups.
+// - Reports for different groups can be batched together, if they are assigned
+// to ReportingEndpoints sharing a URL (that is, the upload URL).
//
-// 2. An endpoint can only be the target of one delivery at once -- if
-// SendReports is called again with reports that could be delivered to that
-// endpoint, they won't be delivered to that endpoint.
-//
-// 3. Reports for an (origin, group) tuple can only be included in one delivery
-// at once -- if SendReports is called again with reports in that (origin,
-// group), they won't be included in any delivery during that call to
-// SendReports. (This prevents the agent from getting around rule 2 by using
-// other endpoints in the same group.)
-//
-// 4. Reports for the same origin *can* be included in multiple parallel
-// deliveries if they are in different groups within that origin.
-//
-// (Note that a single delivery can contain an infinite number of reports.)
+// There is no limit to the number of reports that can be uploaded together.
+// (Aside from the global cap on total reports.)
//
// TODO(juliatuttle): Consider capping the maximum number of reports per
// delivery attempt.
diff --git a/chromium/net/reporting/reporting_delivery_agent_unittest.cc b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
index 893cdd61eb2..7812de93c4d 100644
--- a/chromium/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
@@ -37,12 +37,47 @@ class ReportingDeliveryAgentTest : public ReportingTestBase {
policy.endpoint_backoff_policy.entry_lifetime_ms = 0;
policy.endpoint_backoff_policy.always_use_initial_delay = false;
UsePolicy(policy);
+ report_body_.SetStringKey("key", "value");
}
- const NetworkIsolationKey kNik_ = NetworkIsolationKey::Todo();
+ void AddReport(const NetworkIsolationKey& network_isolation_key,
+ const GURL& url,
+ const std::string& group) {
+ cache()->AddReport(network_isolation_key, url, kUserAgent_, group, kType_,
+ std::make_unique<base::Value>(report_body_.Clone()),
+ 0 /* depth */, tick_clock()->NowTicks() /* queued */,
+ 0 /* attempts */);
+ }
+
+ // The first report added to the cache is uploaded immediately, and a timer is
+ // started for all subsequent reports (which may then be batched). To test
+ // behavior involving batching multiple reports, we need to add, upload, and
+ // immediately resolve a dummy report to prime the delivery timer.
+ void UploadFirstReportAndStartTimer() {
+ ReportingEndpointGroupKey dummy_group(
+ NetworkIsolationKey(), url::Origin::Create(GURL("https://dummy.test")),
+ "dummy");
+ ASSERT_TRUE(SetEndpointInCache(
+ dummy_group, GURL("https://dummy.test/upload"), kExpires_));
+ AddReport(dummy_group.network_isolation_key, dummy_group.origin.GetURL(),
+ dummy_group.group_name);
+
+ ASSERT_EQ(1u, pending_uploads().size());
+ pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
+ EXPECT_EQ(0u, pending_uploads().size());
+ EXPECT_TRUE(delivery_timer()->IsRunning());
+ }
+
+ base::Value report_body_{base::Value::Type::DICTIONARY};
const GURL kUrl_ = GURL("https://origin/path");
+ const GURL kOtherUrl_ = GURL("https://other-origin/path");
const GURL kSubdomainUrl_ = GURL("https://sub.origin/path");
const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
+ const url::Origin kOtherOrigin_ =
+ url::Origin::Create(GURL("https://other-origin/"));
+ const NetworkIsolationKey kNik_;
+ const NetworkIsolationKey kOtherNik_ =
+ NetworkIsolationKey(kOrigin_, kOtherOrigin_);
const GURL kEndpoint_ = GURL("https://endpoint/");
const std::string kUserAgent_ = "Mozilla/1.0";
const std::string kGroup_ = "group";
@@ -53,12 +88,8 @@ class ReportingDeliveryAgentTest : public ReportingTestBase {
};
TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
- base::DictionaryValue body;
- body.SetString("key", "value");
-
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -79,7 +110,8 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
ExpectDictStringValue(kType_, *report, "type");
ExpectDictStringValue(kUrl_.spec(), *report, "url");
ExpectDictStringValue(kUserAgent_, *report, "user_agent");
- ExpectDictDictionaryValue(body, *report, "body");
+ base::Value* body = report->FindDictKey("body");
+ EXPECT_EQ("value", *body->FindStringKey("key"));
}
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
@@ -89,7 +121,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
EXPECT_TRUE(reports.empty());
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(1, stats.attempted_uploads);
EXPECT_EQ(1, stats.successful_uploads);
@@ -101,13 +133,9 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
}
TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
- base::DictionaryValue body;
- body.SetString("key", "value");
-
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
OriginSubdomains::INCLUDE));
- cache()->AddReport(kNik_, kSubdomainUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kSubdomainUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -128,7 +156,8 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
ExpectDictStringValue(kType_, *report, "type");
ExpectDictStringValue(kSubdomainUrl_.spec(), *report, "url");
ExpectDictStringValue(kUserAgent_, *report, "user_agent");
- ExpectDictDictionaryValue(body, *report, "body");
+ base::Value* body = report->FindDictKey("body");
+ EXPECT_EQ("value", *body->FindStringKey("key"));
}
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
@@ -138,7 +167,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
EXPECT_TRUE(reports.empty());
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(1, stats.attempted_uploads);
EXPECT_EQ(1, stats.successful_uploads);
@@ -151,13 +180,9 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) {
TEST_F(ReportingDeliveryAgentTest,
SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) {
- base::DictionaryValue body;
- body.SetString("key", "value");
-
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_,
OriginSubdomains::INCLUDE));
- cache()->AddReport(kNik_, kSubdomainUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kSubdomainUrl_, kGroup_);
// Upload is automatically started when cache is modified.
@@ -168,7 +193,7 @@ TEST_F(ReportingDeliveryAgentTest,
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(1, stats.attempted_uploads);
EXPECT_EQ(1, stats.successful_uploads);
@@ -183,18 +208,13 @@ TEST_F(ReportingDeliveryAgentTest,
}
TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
- base::DictionaryValue body;
- body.SetString("key", "value");
-
// Trigger and complete an upload to start the delivery timer.
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
// Add another report to upload after a delay.
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -216,12 +236,13 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
ExpectDictStringValue(kType_, *report, "type");
ExpectDictStringValue(kUrl_.spec(), *report, "url");
ExpectDictStringValue(kUserAgent_, *report, "user_agent");
- ExpectDictDictionaryValue(body, *report, "body");
+ base::Value* body = report->FindDictKey("body");
+ EXPECT_EQ("value", *body->FindStringKey("key"));
}
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(2, stats.attempted_uploads);
EXPECT_EQ(2, stats.successful_uploads);
@@ -239,9 +260,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -250,7 +269,7 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE);
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(1, stats.attempted_uploads);
EXPECT_EQ(0, stats.successful_uploads);
@@ -272,7 +291,7 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
EXPECT_TRUE(pending_uploads().empty());
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(1, stats.attempted_uploads);
EXPECT_EQ(0, stats.successful_uploads);
@@ -292,8 +311,7 @@ TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
body.SetString("key", "value");
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- body.CreateDeepCopy(), 0, tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis));
@@ -305,7 +323,7 @@ TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
EXPECT_TRUE(pending_uploads().empty());
{
- const ReportingEndpoint::Statistics stats =
+ ReportingEndpoint::Statistics stats =
GetEndpointStatistics(kGroupKey_, kEndpoint_);
EXPECT_EQ(0, stats.attempted_uploads);
EXPECT_EQ(0, stats.successful_uploads);
@@ -320,17 +338,13 @@ TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
}
TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
- static const url::Origin kDifferentOrigin =
- url::Origin::Create(GURL("https://origin2/"));
- static const ReportingEndpointGroupKey kOtherGroupKey(
- NetworkIsolationKey(), kDifferentOrigin, kGroup_);
+ static const ReportingEndpointGroupKey kOtherGroupKey(kNik_, kOtherOrigin_,
+ kGroup_);
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -357,9 +371,7 @@ TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -393,9 +405,7 @@ TEST_F(ReportingDeliveryAgentTest, ConcurrentRemoveDuringPermissionsCheck) {
context()->test_delegate()->set_pause_permissions_check(true);
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused());
@@ -421,134 +431,126 @@ TEST_F(ReportingDeliveryAgentTest, ConcurrentRemoveDuringPermissionsCheck) {
EXPECT_TRUE(reports.empty());
}
-// Test that the agent will combine reports destined for the same endpoint, even
-// if the reports are from different origins.
-TEST_F(ReportingDeliveryAgentTest,
- BatchReportsFromDifferentOriginsToSameEndpoint) {
- static const GURL kDifferentUrl("https://origin2/path");
- static const url::Origin kDifferentOrigin =
- url::Origin::Create(kDifferentUrl);
- const ReportingEndpointGroupKey kDifferentGroupKey(NetworkIsolationKey(),
- kDifferentOrigin, kGroup_);
-
- ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
- ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_));
+// Reports uploaded together must share a NIK and origin.
+// Test that the agent will not combine reports destined for the same endpoint
+// if the reports are from different origins or NIKs, but does combine all
+// reports for the same (NIK, origin).
+TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNikAndOrigin) {
+ const ReportingEndpointGroupKey kGroupKeys[] = {
+ ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_),
+ ReportingEndpointGroupKey(kNik_, kOtherOrigin_, kGroup_),
+ ReportingEndpointGroupKey(kOtherNik_, kOrigin_, kGroup_),
+ ReportingEndpointGroupKey(kOtherNik_, kOtherOrigin_, kGroup_),
+ };
+ for (const ReportingEndpointGroupKey& group_key : kGroupKeys) {
+ ASSERT_TRUE(SetEndpointInCache(group_key, kEndpoint_, kExpires_));
+ }
// Trigger and complete an upload to start the delivery timer.
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
- pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
+ UploadFirstReportAndStartTimer();
// Now that the delivery timer is running, these reports won't be immediately
// uploaded.
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kNik_, kDifferentUrl, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kNik_, kOtherUrl_, kGroup_);
+ AddReport(kNik_, kOtherUrl_, kGroup_);
+ AddReport(kOtherNik_, kUrl_, kGroup_);
+ AddReport(kOtherNik_, kUrl_, kGroup_);
+ AddReport(kOtherNik_, kUrl_, kGroup_);
+ AddReport(kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kOtherNik_, kOtherUrl_, kGroup_);
+ AddReport(kOtherNik_, kOtherUrl_, kGroup_);
EXPECT_EQ(0u, pending_uploads().size());
- // When we fire the delivery timer, we should NOT batch these two reports into
- // a single upload, since each upload must only contain reports about a single
- // origin.
+ // There should be one upload per (NIK, origin).
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
- ASSERT_EQ(2u, pending_uploads().size());
+ ASSERT_EQ(4u, pending_uploads().size());
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
- EXPECT_EQ(0u, pending_uploads().size());
-}
-
-// Test that the agent won't start a second upload to the same endpoint for a
-// particular origin while one is pending, but will once it is no longer
-// pending.
-TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) {
- ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
-
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
-
- EXPECT_TRUE(delivery_timer()->IsRunning());
- delivery_timer()->Fire();
- EXPECT_EQ(1u, pending_uploads().size());
-
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
-
- EXPECT_TRUE(delivery_timer()->IsRunning());
- delivery_timer()->Fire();
- ASSERT_EQ(1u, pending_uploads().size());
-
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
- EXPECT_EQ(0u, pending_uploads().size());
-
- EXPECT_TRUE(delivery_timer()->IsRunning());
- delivery_timer()->Fire();
- ASSERT_EQ(1u, pending_uploads().size());
-
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
EXPECT_EQ(0u, pending_uploads().size());
+
+ for (int i = 0; i < 4; ++i) {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kGroupKeys[i], kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(i + 1, stats.attempted_reports);
+ EXPECT_EQ(i + 1, stats.successful_reports);
+ }
}
-// Test that the agent won't start a second upload for an (origin, group) while
-// one is pending, even if a different endpoint is available, but will once the
-// original delivery is complete and the (origin, group) is no longer pending.
+// Test that the agent won't start a second upload for a (NIK, origin, group)
+// while one is pending, even if a different endpoint is available, but will
+// once the original delivery is complete and the (NIK, origin, group) is no
+// longer pending.
TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
static const GURL kDifferentEndpoint("https://endpoint2/");
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kDifferentEndpoint, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ // Trigger and complete an upload to start the delivery timer.
+ UploadFirstReportAndStartTimer();
+ // First upload causes this group key to become pending.
+ AddReport(kNik_, kUrl_, kGroup_);
+ EXPECT_EQ(0u, pending_uploads().size());
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
EXPECT_EQ(1u, pending_uploads().size());
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
-
+ // Second upload isn't started because the group is pending.
+ AddReport(kNik_, kUrl_, kGroup_);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
ASSERT_EQ(1u, pending_uploads().size());
+ // Resolve the first upload.
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
EXPECT_EQ(0u, pending_uploads().size());
+ // Now the other upload can happen.
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
ASSERT_EQ(1u, pending_uploads().size());
-
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
EXPECT_EQ(0u, pending_uploads().size());
+
+ // A total of 2 reports were uploaded.
+ {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kGroupKey_, kEndpoint_);
+ ReportingEndpoint::Statistics different_stats =
+ GetEndpointStatistics(kGroupKey_, kDifferentEndpoint);
+ EXPECT_EQ(2, stats.attempted_uploads + different_stats.attempted_uploads);
+ EXPECT_EQ(2, stats.successful_uploads + different_stats.successful_uploads);
+ EXPECT_EQ(2, stats.attempted_reports + different_stats.attempted_reports);
+ EXPECT_EQ(2, stats.successful_reports + different_stats.successful_reports);
+ }
}
// Tests that the agent will start parallel uploads to different groups within
-// the same origin.
+// the same (NIK, origin) to endpoints with different URLs.
TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
static const GURL kDifferentEndpoint("https://endpoint2/");
static const std::string kDifferentGroup("group2");
- const ReportingEndpointGroupKey kDifferentGroupKey(NetworkIsolationKey(),
- kOrigin_, kDifferentGroup);
+ const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_,
+ kDifferentGroup);
ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
ASSERT_TRUE(
SetEndpointInCache(kDifferentGroupKey, kDifferentEndpoint, kExpires_));
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kNik_, kUrl_, kUserAgent_, kDifferentGroup, kType_,
- std::make_unique<base::DictionaryValue>(), 0,
- tick_clock()->NowTicks(), 0);
+ // Trigger and complete an upload to start the delivery timer.
+ UploadFirstReportAndStartTimer();
+
+ AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kNik_, kUrl_, kDifferentGroup);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -557,6 +559,63 @@ TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS);
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
EXPECT_EQ(0u, pending_uploads().size());
+
+ {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kGroupKey_, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(1, stats.successful_reports);
+ }
+ {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kDifferentGroupKey, kDifferentEndpoint);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(1, stats.successful_reports);
+ }
+}
+
+// Tests that the agent will include reports for different groups for the same
+// (NIK, origin) in the same upload if they are destined for the same endpoint
+// URL.
+TEST_F(ReportingDeliveryAgentTest, BatchReportsAcrossGroups) {
+ static const std::string kDifferentGroup("group2");
+ const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_,
+ kDifferentGroup);
+
+ ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_));
+ ASSERT_TRUE(SetEndpointInCache(kDifferentGroupKey, kEndpoint_, kExpires_));
+
+ UploadFirstReportAndStartTimer();
+
+ AddReport(kNik_, kUrl_, kGroup_);
+ AddReport(kNik_, kUrl_, kDifferentGroup);
+
+ EXPECT_TRUE(delivery_timer()->IsRunning());
+ delivery_timer()->Fire();
+ ASSERT_EQ(1u, pending_uploads().size());
+ pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
+ EXPECT_EQ(0u, pending_uploads().size());
+
+ {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kGroupKey_, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(1, stats.successful_reports);
+ }
+ {
+ ReportingEndpoint::Statistics stats =
+ GetEndpointStatistics(kDifferentGroupKey, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(1, stats.successful_reports);
+ }
}
} // namespace
diff --git a/chromium/net/reporting/reporting_header_parser.cc b/chromium/net/reporting/reporting_header_parser.cc
index 294f9039841..ec881490fdd 100644
--- a/chromium/net/reporting/reporting_header_parser.cc
+++ b/chromium/net/reporting/reporting_header_parser.cc
@@ -26,28 +26,6 @@ namespace net {
namespace {
-using HeaderEndpointGroupOutcome =
- ReportingHeaderParser::HeaderEndpointGroupOutcome;
-using HeaderEndpointOutcome = ReportingHeaderParser::HeaderEndpointOutcome;
-using HeaderOutcome = ReportingHeaderParser::HeaderOutcome;
-
-void RecordHeaderOutcome(HeaderOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION(ReportingHeaderParser::kHeaderOutcomeHistogram,
- outcome, HeaderOutcome::MAX);
-}
-
-void RecordHeaderEndpointGroupOutcome(HeaderEndpointGroupOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION(
- ReportingHeaderParser::kHeaderEndpointGroupOutcomeHistogram, outcome,
- HeaderEndpointGroupOutcome::MAX);
-}
-
-void RecordHeaderEndpointOutcome(HeaderEndpointOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION(
- ReportingHeaderParser::kHeaderEndpointOutcomeHistogram, outcome,
- HeaderEndpointOutcome::MAX);
-}
-
const char kUrlKey[] = "url";
const char kIncludeSubdomainsKey[] = "include_subdomains";
const char kEndpointsKey[] = "endpoints";
@@ -64,21 +42,21 @@ const char kWeightKey[] = "weight";
// |value| is the parsed JSON value of the endpoint tuple.
//
// |*endpoint_out| will contain the endpoint URL parsed out of the tuple.
-HeaderEndpointOutcome ProcessEndpoint(
- ReportingDelegate* delegate,
- const ReportingEndpointGroupKey& group_key,
- const base::Value& value,
- ReportingEndpoint::EndpointInfo* endpoint_info_out) {
+// Returns true on success or false if endpoint was discarded.
+bool ProcessEndpoint(ReportingDelegate* delegate,
+ const ReportingEndpointGroupKey& group_key,
+ const base::Value& value,
+ ReportingEndpoint::EndpointInfo* endpoint_info_out) {
const base::DictionaryValue* dict = nullptr;
if (!value.GetAsDictionary(&dict))
- return HeaderEndpointOutcome::DISCARDED_NOT_DICTIONARY;
+ return false;
DCHECK(dict);
std::string endpoint_url_string;
if (!dict->HasKey(kUrlKey))
- return HeaderEndpointOutcome::DISCARDED_URL_MISSING;
+ return false;
if (!dict->GetString(kUrlKey, &endpoint_url_string))
- return HeaderEndpointOutcome::DISCARDED_URL_NOT_STRING;
+ return false;
GURL endpoint_url;
// Support path-absolute-URL string
@@ -88,29 +66,26 @@ HeaderEndpointOutcome ProcessEndpoint(
endpoint_url = GURL(endpoint_url_string);
}
if (!endpoint_url.is_valid())
- return HeaderEndpointOutcome::DISCARDED_URL_INVALID;
+ return false;
if (!endpoint_url.SchemeIsCryptographic())
- return HeaderEndpointOutcome::DISCARDED_URL_INSECURE;
+ return false;
endpoint_info_out->url = std::move(endpoint_url);
int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority;
if (dict->HasKey(kPriorityKey) && !dict->GetInteger(kPriorityKey, &priority))
- return HeaderEndpointOutcome::DISCARDED_PRIORITY_NOT_INTEGER;
+ return false;
if (priority < 0)
- return HeaderEndpointOutcome::DISCARDED_PRIORITY_NEGATIVE;
+ return false;
endpoint_info_out->priority = priority;
int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight;
if (dict->HasKey(kWeightKey) && !dict->GetInteger(kWeightKey, &weight))
- return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_INTEGER;
+ return false;
if (weight < 0)
- return HeaderEndpointOutcome::DISCARDED_WEIGHT_NEGATIVE;
+ return false;
endpoint_info_out->weight = weight;
- if (!delegate->CanSetClient(group_key.origin, endpoint_url))
- return HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE;
-
- return HeaderEndpointOutcome::SET;
+ return delegate->CanSetClient(group_key.origin, endpoint_url);
}
// Processes a single endpoint group tuple received in a Report-To header.
@@ -118,36 +93,37 @@ HeaderEndpointOutcome ProcessEndpoint(
// |origin| is the origin that sent the Report-To header.
//
// |value| is the parsed JSON value of the endpoint group tuple.
-HeaderEndpointGroupOutcome ProcessEndpointGroup(
- ReportingDelegate* delegate,
- ReportingCache* cache,
- const NetworkIsolationKey& network_isolation_key,
- const url::Origin& origin,
- const base::Value& value,
- ReportingEndpointGroup* parsed_endpoint_group_out) {
+// Returns true on successfully adding a non-empty group, or false if endpoint
+// group was discarded or processed as a deletion.
+bool ProcessEndpointGroup(ReportingDelegate* delegate,
+ ReportingCache* cache,
+ const NetworkIsolationKey& network_isolation_key,
+ const url::Origin& origin,
+ const base::Value& value,
+ ReportingEndpointGroup* parsed_endpoint_group_out) {
const base::DictionaryValue* dict = nullptr;
if (!value.GetAsDictionary(&dict))
- return HeaderEndpointGroupOutcome::DISCARDED_NOT_DICTIONARY;
+ return false;
DCHECK(dict);
std::string group_name = kDefaultGroupName;
if (dict->HasKey(kGroupKey) && !dict->GetString(kGroupKey, &group_name))
- return HeaderEndpointGroupOutcome::DISCARDED_GROUP_NOT_STRING;
+ return false;
ReportingEndpointGroupKey group_key(network_isolation_key, origin,
group_name);
parsed_endpoint_group_out->group_key = group_key;
int ttl_sec = -1;
if (!dict->HasKey(kMaxAgeKey))
- return HeaderEndpointGroupOutcome::DISCARDED_TTL_MISSING;
+ return false;
if (!dict->GetInteger(kMaxAgeKey, &ttl_sec))
- return HeaderEndpointGroupOutcome::DISCARDED_TTL_NOT_INTEGER;
+ return false;
if (ttl_sec < 0)
- return HeaderEndpointGroupOutcome::DISCARDED_TTL_NEGATIVE;
+ return false;
// max_age: 0 signifies removal of the endpoint group.
if (ttl_sec == 0) {
cache->RemoveEndpointGroup(group_key);
- return HeaderEndpointGroupOutcome::REMOVED_TTL_ZERO;
+ return false;
}
parsed_endpoint_group_out->ttl = base::TimeDelta::FromSeconds(ttl_sec);
@@ -160,8 +136,7 @@ HeaderEndpointGroupOutcome ProcessEndpointGroup(
origin.GetURL(),
registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES) == 0) {
- return HeaderEndpointGroupOutcome::
- DISCARDED_INCLUDE_SUBDOMAINS_NOT_ALLOWED;
+ return false;
}
parsed_endpoint_group_out->include_subdomains = OriginSubdomains::INCLUDE;
@@ -169,9 +144,9 @@ HeaderEndpointGroupOutcome ProcessEndpointGroup(
const base::ListValue* endpoint_list = nullptr;
if (!dict->HasKey(kEndpointsKey))
- return HeaderEndpointGroupOutcome::DISCARDED_ENDPOINTS_MISSING;
+ return false;
if (!dict->GetList(kEndpointsKey, &endpoint_list))
- return HeaderEndpointGroupOutcome::DISCARDED_ENDPOINTS_NOT_LIST;
+ return false;
std::vector<ReportingEndpoint::EndpointInfo> endpoints;
@@ -182,66 +157,24 @@ HeaderEndpointGroupOutcome ProcessEndpointGroup(
ReportingEndpoint::EndpointInfo parsed_endpoint;
- HeaderEndpointOutcome outcome =
- ProcessEndpoint(delegate, group_key, *endpoint, &parsed_endpoint);
-
- if (outcome == HeaderEndpointOutcome::SET)
+ if (ProcessEndpoint(delegate, group_key, *endpoint, &parsed_endpoint))
endpoints.push_back(std::move(parsed_endpoint));
-
- RecordHeaderEndpointOutcome(outcome);
}
// Remove the group if it is empty.
if (endpoints.empty()) {
cache->RemoveEndpointGroup(group_key);
- return HeaderEndpointGroupOutcome::REMOVED_EMPTY;
+ return false;
}
parsed_endpoint_group_out->endpoints = std::move(endpoints);
- return HeaderEndpointGroupOutcome::PARSED;
+ return true;
}
} // namespace
// static
-const char ReportingHeaderParser::kHeaderOutcomeHistogram[] =
- "Net.Reporting.HeaderOutcome";
-
-// static
-const char ReportingHeaderParser::kHeaderEndpointGroupOutcomeHistogram[] =
- "Net.Reporting.HeaderEndpointGroupOutcome";
-
-// static
-const char ReportingHeaderParser::kHeaderEndpointOutcomeHistogram[] =
- "Net.Reporting.HeaderEndpointOutcome";
-
-// static
-void ReportingHeaderParser::RecordHeaderDiscardedForNoReportingService() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE);
-}
-
-// static
-void ReportingHeaderParser::RecordHeaderDiscardedForInvalidSSLInfo() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_INVALID_SSL_INFO);
-}
-
-// static
-void ReportingHeaderParser::RecordHeaderDiscardedForCertStatusError() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_CERT_STATUS_ERROR);
-}
-
-// static
-void ReportingHeaderParser::RecordHeaderDiscardedForJsonInvalid() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_INVALID);
-}
-
-// static
-void ReportingHeaderParser::RecordHeaderDiscardedForJsonTooBig() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_TOO_BIG);
-}
-
-// static
void ReportingHeaderParser::ParseHeader(
ReportingContext* context,
const NetworkIsolationKey& network_isolation_key,
@@ -265,25 +198,21 @@ void ReportingHeaderParser::ParseHeader(
bool got_group = group_list->Get(i, &group_value);
DCHECK(got_group);
ReportingEndpointGroup parsed_endpoint_group;
- HeaderEndpointGroupOutcome outcome =
- ProcessEndpointGroup(delegate, cache, network_isolation_key, origin,
- *group_value, &parsed_endpoint_group);
- RecordHeaderEndpointGroupOutcome(outcome);
- if (outcome == HeaderEndpointGroupOutcome::PARSED)
+ if (ProcessEndpointGroup(delegate, cache, network_isolation_key, origin,
+ *group_value, &parsed_endpoint_group)) {
parsed_header.push_back(std::move(parsed_endpoint_group));
+ }
}
// Remove the client if it has no valid endpoint groups.
if (parsed_header.empty()) {
// TODO(chlily): Pass NIK to cache.
cache->RemoveClient(NetworkIsolationKey::Todo(), origin);
- RecordHeaderOutcome(HeaderOutcome::REMOVED_EMPTY);
return;
}
cache->OnParsedHeader(network_isolation_key, origin,
std::move(parsed_header));
- RecordHeaderOutcome(HeaderOutcome::PARSED);
}
} // namespace net
diff --git a/chromium/net/reporting/reporting_header_parser.h b/chromium/net/reporting/reporting_header_parser.h
index adba204742a..2e167f2ccde 100644
--- a/chromium/net/reporting/reporting_header_parser.h
+++ b/chromium/net/reporting/reporting_header_parser.h
@@ -22,64 +22,6 @@ class ReportingContext;
class NET_EXPORT ReportingHeaderParser {
public:
- // Histograms. These are mainly used in test cases to verify that interesting
- // events occurred.
-
- static const char kHeaderOutcomeHistogram[];
- static const char kHeaderEndpointGroupOutcomeHistogram[];
- static const char kHeaderEndpointOutcomeHistogram[];
-
- enum class HeaderOutcome {
- DISCARDED_NO_REPORTING_SERVICE = 0,
- DISCARDED_INVALID_SSL_INFO = 1,
- DISCARDED_CERT_STATUS_ERROR = 2,
- DISCARDED_JSON_TOO_BIG = 3,
- DISCARDED_JSON_INVALID = 4,
- PARSED = 5,
- REMOVED_EMPTY = 6,
- MAX
- };
-
- enum class HeaderEndpointGroupOutcome {
- DISCARDED_NOT_DICTIONARY = 0,
- DISCARDED_GROUP_NOT_STRING = 1,
- DISCARDED_TTL_MISSING = 2,
- DISCARDED_TTL_NOT_INTEGER = 3,
- DISCARDED_TTL_NEGATIVE = 4,
- DISCARDED_ENDPOINTS_MISSING = 5,
- DISCARDED_ENDPOINTS_NOT_LIST = 6,
-
- PARSED = 7,
- REMOVED_TTL_ZERO = 8,
- REMOVED_EMPTY = 9,
- DISCARDED_INCLUDE_SUBDOMAINS_NOT_ALLOWED = 10,
- MAX
- };
-
- enum class HeaderEndpointOutcome {
- DISCARDED_NOT_DICTIONARY = 0,
- DISCARDED_URL_MISSING = 1,
- DISCARDED_URL_NOT_STRING = 2,
- DISCARDED_URL_INVALID = 3,
- DISCARDED_URL_INSECURE = 4,
- DISCARDED_PRIORITY_NOT_INTEGER = 5,
- DISCARDED_WEIGHT_NOT_INTEGER = 6,
- DISCARDED_WEIGHT_NEGATIVE = 7,
-
- REMOVED = 8, // Obsolete: removing for max_age: 0 is done on a group basis.
- SET_REJECTED_BY_DELEGATE = 9,
- SET = 10,
- DISCARDED_PRIORITY_NEGATIVE = 11,
-
- MAX
- };
-
- static void RecordHeaderDiscardedForNoReportingService();
- static void RecordHeaderDiscardedForInvalidSSLInfo();
- static void RecordHeaderDiscardedForCertStatusError();
- static void RecordHeaderDiscardedForJsonInvalid();
- static void RecordHeaderDiscardedForJsonTooBig();
-
static void ParseHeader(ReportingContext* context,
const NetworkIsolationKey& network_isolation_key,
const GURL& url,
diff --git a/chromium/net/reporting/reporting_report.cc b/chromium/net/reporting/reporting_report.cc
index 63648cff1b9..3bc047dfcb6 100644
--- a/chromium/net/reporting/reporting_report.cc
+++ b/chromium/net/reporting/reporting_report.cc
@@ -45,16 +45,14 @@ ReportingReport::ReportingReport(
attempts(attempts) {}
ReportingReport::~ReportingReport() {
- if (outcome == Outcome::DELIVERED) {
- // |delivered| should always have a value here, since the ReportingCache
- // records the delivery time for any successful delivery.
- UMA_HISTOGRAM_LONG_TIMES_100("Net.Reporting.ReportDeliveredLatency",
- delivered.value() - queued);
- UMA_HISTOGRAM_COUNTS_100("Net.Reporting.ReportDeliveredAttempts", attempts);
- }
RecordReportOutcome(outcome);
}
+ReportingEndpointGroupKey ReportingReport::GetGroupKey() const {
+ return ReportingEndpointGroupKey(network_isolation_key,
+ url::Origin::Create(url), group);
+}
+
// static
void ReportingReport::RecordReportDiscardedForNoURLRequestContext() {
RecordReportOutcome(Outcome::DISCARDED_NO_URL_REQUEST_CONTEXT);
diff --git a/chromium/net/reporting/reporting_report.h b/chromium/net/reporting/reporting_report.h
index 02018ad25df..dee358878cc 100644
--- a/chromium/net/reporting/reporting_report.h
+++ b/chromium/net/reporting/reporting_report.h
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/base/network_isolation_key.h"
+#include "net/reporting/reporting_endpoint.h"
#include "url/gurl.h"
namespace base {
@@ -65,6 +66,13 @@ struct NET_EXPORT ReportingReport {
// Records metrics about report outcome.
~ReportingReport();
+ // Bundles together the NIK, origin of the report URL, and group name.
+ // This is not exactly the same as the group key of the endpoint that the
+ // report will be delivered to. The origin may differ if the endpoint is
+ // configured for a superdomain of the report's origin. The NIK and group name
+ // will be the same.
+ ReportingEndpointGroupKey GetGroupKey() const;
+
static void RecordReportDiscardedForNoURLRequestContext();
static void RecordReportDiscardedForNoReportingService();
@@ -101,10 +109,6 @@ struct NET_EXPORT ReportingReport {
// relative to the time of the delivery attempt.)
base::TimeTicks queued;
- // Time when report was delivered, if it was delivered successfully.
- // The destructor assumes that this has a value if the outcome is DELIVERED.
- base::Optional<base::TimeTicks> delivered = base::nullopt;
-
// The number of delivery attempts made so far, not including an active
// attempt. (Not included in the delivered report.)
int attempts = 0;
diff --git a/chromium/net/reporting/reporting_service.cc b/chromium/net/reporting/reporting_service.cc
index 2a410343302..ca44492f9e2 100644
--- a/chromium/net/reporting/reporting_service.cc
+++ b/chromium/net/reporting/reporting_service.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/json/json_reader.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/tick_clock.h"
@@ -81,18 +82,14 @@ class ReportingServiceImpl : public ReportingService {
void ProcessHeader(const GURL& url,
const std::string& header_string) override {
- if (header_string.size() > kMaxJsonSize) {
- ReportingHeaderParser::RecordHeaderDiscardedForJsonTooBig();
+ if (header_string.size() > kMaxJsonSize)
return;
- }
std::unique_ptr<base::Value> header_value =
base::JSONReader::ReadDeprecated("[" + header_string + "]",
base::JSON_PARSE_RFC, kMaxJsonDepth);
- if (!header_value) {
- ReportingHeaderParser::RecordHeaderDiscardedForJsonInvalid();
+ if (!header_value)
return;
- }
DVLOG(1) << "Received Reporting policy for " << url.GetOrigin();
// TODO(chlily): Get the proper NetworkIsolationKey from the caller.
@@ -101,7 +98,7 @@ class ReportingServiceImpl : public ReportingService {
NetworkIsolationKey::Todo(), url, std::move(header_value)));
}
- void RemoveBrowsingData(int data_type_mask,
+ void RemoveBrowsingData(uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>&
origin_filter) override {
DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoRemoveBrowsingData,
@@ -109,7 +106,7 @@ class ReportingServiceImpl : public ReportingService {
origin_filter));
}
- void RemoveAllBrowsingData(int data_type_mask) override {
+ void RemoveAllBrowsingData(uint64_t data_type_mask) override {
DoOrBacklogTask(
base::BindOnce(&ReportingServiceImpl::DoRemoveAllBrowsingData,
base::Unretained(this), data_type_mask));
@@ -174,14 +171,14 @@ class ReportingServiceImpl : public ReportingService {
}
void DoRemoveBrowsingData(
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
DCHECK(initialized_);
ReportingBrowsingDataRemover::RemoveBrowsingData(
context_->cache(), data_type_mask, origin_filter);
}
- void DoRemoveAllBrowsingData(int data_type_mask) {
+ void DoRemoveAllBrowsingData(uint64_t data_type_mask) {
DCHECK(initialized_);
ReportingBrowsingDataRemover::RemoveAllBrowsingData(context_->cache(),
data_type_mask);
diff --git a/chromium/net/reporting/reporting_service.h b/chromium/net/reporting/reporting_service.h
index 233608c0b2a..e2152361002 100644
--- a/chromium/net/reporting/reporting_service.h
+++ b/chromium/net/reporting/reporting_service.h
@@ -68,12 +68,12 @@ class NET_EXPORT ReportingService {
// Removes browsing data from the Reporting system. See
// ReportingBrowsingDataRemover for more details.
virtual void RemoveBrowsingData(
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0;
// Like RemoveBrowsingData except removes data for all origins without a
// filter.
- virtual void RemoveAllBrowsingData(int data_type_mask) = 0;
+ virtual void RemoveAllBrowsingData(uint64_t data_type_mask) = 0;
// Shuts down the Reporting service so that no new headers or reports are
// processed, and pending uploads are cancelled.
diff --git a/chromium/net/reporting/reporting_service_unittest.cc b/chromium/net/reporting/reporting_service_unittest.cc
index 96365b1adf0..0ac00ac44d7 100644
--- a/chromium/net/reporting/reporting_service_unittest.cc
+++ b/chromium/net/reporting/reporting_service_unittest.cc
@@ -44,11 +44,9 @@ class ReportingServiceTest : public ::testing::TestWithParam<bool>,
const std::string kGroup_ = "group";
const std::string kType_ = "type";
const ReportingEndpointGroupKey kGroupKey_ =
- ReportingEndpointGroupKey(NetworkIsolationKey::Todo(), kOrigin_, kGroup_);
+ ReportingEndpointGroupKey(NetworkIsolationKey(), kOrigin_, kGroup_);
const ReportingEndpointGroupKey kGroupKey2_ =
- ReportingEndpointGroupKey(NetworkIsolationKey::Todo(),
- kOrigin2_,
- kGroup_);
+ ReportingEndpointGroupKey(NetworkIsolationKey(), kOrigin2_, kGroup_);
ReportingServiceTest() {
if (GetParam())
diff --git a/chromium/net/reporting/reporting_test_util.cc b/chromium/net/reporting/reporting_test_util.cc
index 47ebd724330..fc3b0150182 100644
--- a/chromium/net/reporting/reporting_test_util.cc
+++ b/chromium/net/reporting/reporting_test_util.cc
@@ -334,12 +334,12 @@ void TestReportingService::ProcessHeader(const GURL& url,
}
void TestReportingService::RemoveBrowsingData(
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
NOTREACHED();
}
-void TestReportingService::RemoveAllBrowsingData(int data_type_mask) {
+void TestReportingService::RemoveAllBrowsingData(uint64_t data_type_mask) {
NOTREACHED();
}
diff --git a/chromium/net/reporting/reporting_test_util.h b/chromium/net/reporting/reporting_test_util.h
index 5f7c990e5f6..e58f449154a 100644
--- a/chromium/net/reporting/reporting_test_util.h
+++ b/chromium/net/reporting/reporting_test_util.h
@@ -320,10 +320,10 @@ class TestReportingService : public ReportingService {
void ProcessHeader(const GURL& url, const std::string& header_value) override;
void RemoveBrowsingData(
- int data_type_mask,
+ uint64_t data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override;
- void RemoveAllBrowsingData(int data_type_mask) override;
+ void RemoveAllBrowsingData(uint64_t data_type_mask) override;
void OnShutdown() override;
diff --git a/chromium/net/reporting/reporting_uploader.cc b/chromium/net/reporting/reporting_uploader.cc
index aacec913e1f..a54bfc4fcbe 100644
--- a/chromium/net/reporting/reporting_uploader.cc
+++ b/chromium/net/reporting/reporting_uploader.cc
@@ -9,8 +9,6 @@
#include <vector>
#include "base/callback_helpers.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "net/base/elements_upload_data_stream.h"
@@ -78,27 +76,6 @@ ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) {
return ReportingUploader::Outcome::FAILURE;
}
-enum class UploadOutcome {
- CANCELED_REDIRECT_TO_INSECURE_URL = 0,
- CANCELED_AUTH_REQUIRED = 1,
- CANCELED_CERTIFICATE_REQUESTED = 2,
- CANCELED_SSL_CERTIFICATE_ERROR = 3,
- CANCELED_REPORTING_SHUTDOWN = 4,
- FAILED = 5, // See Net.Reporting.UploadError for breakdown.
- SUCCEEDED_SUCCESS = 6,
- SUCCEEDED_REMOVE_ENDPOINT = 7,
- CORS_PREFLIGHT_ERROR = 8,
-
- MAX
-};
-
-void RecordUploadOutcome(UploadOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION("Net.Reporting.UploadOutcome", outcome,
- UploadOutcome::MAX);
-}
-
-// TODO: Record net and HTTP error.
-
struct PendingUpload {
enum State { CREATED, SENDING_PREFLIGHT, SENDING_PAYLOAD };
@@ -269,8 +246,6 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
uploads_.erase(it);
if (net_error != OK) {
- RecordUploadOutcome(UploadOutcome::FAILED);
- base::UmaHistogramSparse("Net.Reporting.UploadError", net_error);
upload->RunCallback(ReportingUploader::Outcome::FAILURE);
return;
}
@@ -310,7 +285,6 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
HasHeaderValues(request, "Access-Control-Allow-Headers",
{"content-type"});
if (!preflight_succeeded) {
- RecordUploadOutcome(UploadOutcome::CORS_PREFLIGHT_ERROR);
upload->RunCallback(ReportingUploader::Outcome::FAILURE);
return;
}
@@ -320,14 +294,6 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
void HandlePayloadResponse(std::unique_ptr<PendingUpload> upload,
int response_code) {
- if (response_code >= 200 && response_code <= 299) {
- RecordUploadOutcome(UploadOutcome::SUCCEEDED_SUCCESS);
- } else if (response_code == 410) {
- RecordUploadOutcome(UploadOutcome::SUCCEEDED_REMOVE_ENDPOINT);
- } else {
- RecordUploadOutcome(UploadOutcome::FAILED);
- base::UmaHistogramSparse("Net.Reporting.UploadError", response_code);
- }
upload->RunCallback(ResponseCodeToOutcome(response_code));
}
diff --git a/chromium/net/reporting/reporting_uploader_unittest.cc b/chromium/net/reporting/reporting_uploader_unittest.cc
index 66b61e7e4ef..364585b3cfd 100644
--- a/chromium/net/reporting/reporting_uploader_unittest.cc
+++ b/chromium/net/reporting/reporting_uploader_unittest.cc
@@ -14,6 +14,7 @@
#include "base/test/scoped_feature_list.h"
#include "net/base/features.h"
#include "net/base/network_isolation_key.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/http/http_status_code.h"
@@ -446,8 +447,7 @@ TEST_F(ReportingUploaderTest, DontSendCookies) {
server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
ASSERT_TRUE(server_.Start());
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus>
- cookie_callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> cookie_callback;
GURL url = server_.GetURL("/");
auto cookie = CanonicalCookie::Create(url, "foo=bar", base::Time::Now(),
base::nullopt /* server_time */);
diff --git a/chromium/net/socket/client_socket_handle.h b/chromium/net/socket/client_socket_handle.h
index 727972d7de4..9282dae7dd8 100644
--- a/chromium/net/socket/client_socket_handle.h
+++ b/chromium/net/socket/client_socket_handle.h
@@ -10,7 +10,7 @@
#include <utility>
#include "base/bind.h"
-#include "base/logging.h"
+#include "base/check.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
diff --git a/chromium/net/socket/client_socket_pool_base_unittest.cc b/chromium/net/socket/client_socket_pool_base_unittest.cc
index be3196e53bc..29e27ab3e7d 100644
--- a/chromium/net/socket/client_socket_pool_base_unittest.cc
+++ b/chromium/net/socket/client_socket_pool_base_unittest.cc
@@ -4224,11 +4224,11 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
// Verify the backup timer doesn't create a backup job, by making
// the backup job a pending job instead of a waiting job, so it
// *would* complete if it were created.
+ base::RunLoop loop;
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- base::TimeDelta::FromSeconds(1));
- base::RunLoop().Run();
+ FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromSeconds(1));
+ loop.Run();
EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
}
diff --git a/chromium/net/socket/socket_posix.cc b/chromium/net/socket/socket_posix.cc
index 61cc75851ca..807ef26f78b 100644
--- a/chromium/net/socket/socket_posix.cc
+++ b/chromium/net/socket/socket_posix.cc
@@ -384,7 +384,7 @@ int SocketPosix::GetPeerAddress(SockaddrStorage* address) const {
void SocketPosix::SetPeerAddress(const SockaddrStorage& address) {
DCHECK(thread_checker_.CalledOnValidThread());
- // |peer_address_| will be non-NULL if Connect() has been called. Unless
+ // |peer_address_| will be non-nullptr if Connect() has been called. Unless
// Close() is called to reset the internal state, a second call to Connect()
// is not allowed.
// Please note that we don't allow a second Connect() even if the previous
@@ -397,7 +397,7 @@ void SocketPosix::SetPeerAddress(const SockaddrStorage& address) {
bool SocketPosix::HasPeerAddress() const {
DCHECK(thread_checker_.CalledOnValidThread());
- return peer_address_ != NULL;
+ return peer_address_ != nullptr;
}
void SocketPosix::Close() {
@@ -455,7 +455,7 @@ void SocketPosix::AcceptCompleted() {
bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok);
- accept_socket_ = NULL;
+ accept_socket_ = nullptr;
std::move(accept_callback_).Run(rv);
}
@@ -560,7 +560,7 @@ void SocketPosix::StopWatchingAndCleanUp(bool close_socket) {
}
if (!accept_callback_.is_null()) {
- accept_socket_ = NULL;
+ accept_socket_ = nullptr;
accept_callback_.Reset();
}
diff --git a/chromium/net/socket/socket_test_util.h b/chromium/net/socket/socket_test_util.h
index fee1b1f7aa2..8cc3aeedef4 100644
--- a/chromium/net/socket/socket_test_util.h
+++ b/chromium/net/socket/socket_test_util.h
@@ -16,8 +16,8 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/check_op.h"
#include "base/containers/span.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/net/socket/ssl_client_socket_impl.cc b/chromium/net/socket/ssl_client_socket_impl.cc
index 12fb37570a5..fcada6e3420 100644
--- a/chromium/net/socket/ssl_client_socket_impl.cc
+++ b/chromium/net/socket/ssl_client_socket_impl.cc
@@ -900,8 +900,12 @@ int SSLClientSocketImpl::Init() {
// TODO(https://crbug.com/775438), if |ssl_config_.privacy_mode| is enabled,
// this should always continue with no client certificate.
- send_client_cert_ = context_->GetClientCertificate(
- host_and_port_, &client_cert_, &client_private_key_);
+ if (ssl_config_.privacy_mode == PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS) {
+ send_client_cert_ = true;
+ } else {
+ send_client_cert_ = context_->GetClientCertificate(
+ host_and_port_, &client_cert_, &client_private_key_);
+ }
return OK;
}
@@ -1012,13 +1016,10 @@ int SSLClientSocketImpl::DoHandshakeComplete(int result) {
// See how feasible enforcing RSA key usage would be. See
// https://crbug.com/795089.
- RSAKeyUsage rsa_key_usage =
- CheckRSAKeyUsage(server_cert_.get(), SSL_get_current_cipher(ssl_.get()));
- if (rsa_key_usage != RSAKeyUsage::kNotRSA) {
- if (server_cert_verify_result_.is_issued_by_known_root) {
- UMA_HISTOGRAM_ENUMERATION("Net.SSLRSAKeyUsage.KnownRoot", rsa_key_usage,
- static_cast<int>(RSAKeyUsage::kLastValue) + 1);
- } else {
+ if (!server_cert_verify_result_.is_issued_by_known_root) {
+ RSAKeyUsage rsa_key_usage = CheckRSAKeyUsage(
+ server_cert_.get(), SSL_get_current_cipher(ssl_.get()));
+ if (rsa_key_usage != RSAKeyUsage::kNotRSA) {
UMA_HISTOGRAM_ENUMERATION("Net.SSLRSAKeyUsage.UnknownRoot", rsa_key_usage,
static_cast<int>(RSAKeyUsage::kLastValue) + 1);
}
@@ -1648,7 +1649,8 @@ int SSLClientSocketImpl::VerifyCT() {
server_cert_verify_result_.verified_cert.get(), server_cert_.get(),
ct_verify_result_.scts,
TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
- ct_verify_result_.policy_compliance);
+ ct_verify_result_.policy_compliance,
+ ssl_config_.network_isolation_key);
if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) {
ct_verify_result_.policy_compliance_required = true;
if (server_cert_verify_result_.is_issued_by_known_root) {
diff --git a/chromium/net/socket/ssl_client_socket_unittest.cc b/chromium/net/socket/ssl_client_socket_unittest.cc
index 41aea1c8951..31e4179058c 100644
--- a/chromium/net/socket/ssl_client_socket_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_unittest.cc
@@ -563,34 +563,40 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
MockExpectCTReporter() : num_failures_(0) {}
~MockExpectCTReporter() override = default;
- void OnExpectCTFailed(const HostPortPair& host_port_pair,
- const GURL& report_uri,
- base::Time expiration,
- const X509Certificate* validated_certificate_chain,
- const X509Certificate* served_certificate_chain,
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps) override {
+ void OnExpectCTFailed(
+ const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ base::Time expiration,
+ const X509Certificate* validated_certificate_chain,
+ const X509Certificate* served_certificate_chain,
+ const SignedCertificateTimestampAndStatusList&
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) override {
num_failures_++;
host_port_pair_ = host_port_pair;
report_uri_ = report_uri;
served_certificate_chain_ = served_certificate_chain;
validated_certificate_chain_ = validated_certificate_chain;
signed_certificate_timestamps_ = signed_certificate_timestamps;
+ network_isolation_key_ = network_isolation_key;
}
- const HostPortPair& host_port_pair() { return host_port_pair_; }
- const GURL& report_uri() { return report_uri_; }
- uint32_t num_failures() { return num_failures_; }
- const X509Certificate* served_certificate_chain() {
+ const HostPortPair& host_port_pair() const { return host_port_pair_; }
+ const GURL& report_uri() const { return report_uri_; }
+ uint32_t num_failures() const { return num_failures_; }
+ const X509Certificate* served_certificate_chain() const {
return served_certificate_chain_;
}
- const X509Certificate* validated_certificate_chain() {
+ const X509Certificate* validated_certificate_chain() const {
return validated_certificate_chain_;
}
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps() {
+ const SignedCertificateTimestampAndStatusList& signed_certificate_timestamps()
+ const {
return signed_certificate_timestamps_;
}
+ const NetworkIsolationKey network_isolation_key() const {
+ return network_isolation_key_;
+ }
private:
HostPortPair host_port_pair_;
@@ -599,6 +605,7 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
const X509Certificate* served_certificate_chain_;
const X509Certificate* validated_certificate_chain_;
SignedCertificateTimestampAndStatusList signed_certificate_timestamps_;
+ NetworkIsolationKey network_isolation_key_;
};
// A mock CTVerifier that records every call to Verify but doesn't verify
@@ -4172,9 +4179,9 @@ TEST_P(SSLClientSocketVersionTest, CTRequiredHistogramCompliant) {
// Set up the Expect-CT opt-in.
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- transport_security_state_->AddExpectCT(host_port_pair().host(), expiry,
- true /* enforce */,
- GURL("https://example-report.test"));
+ transport_security_state_->AddExpectCT(
+ host_port_pair().host(), expiry, true /* enforce */,
+ GURL("https://example-report.test"), NetworkIsolationKey());
MockExpectCTReporter reporter;
transport_security_state_->SetExpectCTReporter(&reporter);
@@ -4257,9 +4264,9 @@ TEST_P(SSLClientSocketVersionTest, CTRequiredHistogramNonCompliant) {
// Set up the Expect-CT opt-in.
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- transport_security_state_->AddExpectCT(host_port_pair().host(), expiry,
- true /* enforce */,
- GURL("https://example-report.test"));
+ transport_security_state_->AddExpectCT(
+ host_port_pair().host(), expiry, true /* enforce */,
+ GURL("https://example-report.test"), NetworkIsolationKey());
MockExpectCTReporter reporter;
transport_security_state_->SetExpectCTReporter(&reporter);
@@ -4301,7 +4308,8 @@ TEST_P(SSLClientSocketVersionTest, CTRequirementsFlagNotMet) {
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
transport_security_state_->AddExpectCT(host_port_pair().host(), expiry,
- true /* enforce */, GURL());
+ true /* enforce */, GURL(),
+ NetworkIsolationKey());
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
.WillRepeatedly(
@@ -4335,7 +4343,8 @@ TEST_P(SSLClientSocketVersionTest, CTRequirementsFlagMet) {
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
transport_security_state_->AddExpectCT(host_port_pair().host(), expiry,
- true /* enforce */, GURL());
+ true /* enforce */, GURL(),
+ NetworkIsolationKey());
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
.WillRepeatedly(
@@ -4417,11 +4426,13 @@ TEST_P(SSLClientSocketVersionTest, CTIsRequiredByExpectCT) {
cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
// Set up the Expect-CT opt-in.
+ NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- transport_security_state_->AddExpectCT(host_port_pair().host(), expiry,
- true /* enforce */,
- GURL("https://example-report.test"));
+ transport_security_state_->AddExpectCT(
+ host_port_pair().host(), expiry, true /* enforce */,
+ GURL("https://example-report.test"), NetworkIsolationKey());
MockExpectCTReporter reporter;
transport_security_state_->SetExpectCTReporter(&reporter);
@@ -4430,6 +4441,7 @@ TEST_P(SSLClientSocketVersionTest, CTIsRequiredByExpectCT) {
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
SSLConfig ssl_config;
+ ssl_config.network_isolation_key = network_isolation_key;
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
SSLInfo ssl_info;
@@ -4446,6 +4458,7 @@ TEST_P(SSLClientSocketVersionTest, CTIsRequiredByExpectCT) {
reporter.served_certificate_chain());
EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
transport_security_state_->ClearReportCachesForTesting();
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
@@ -4465,6 +4478,7 @@ TEST_P(SSLClientSocketVersionTest, CTIsRequiredByExpectCT) {
reporter.served_certificate_chain());
EXPECT_EQ(ssl_info.cert.get(), reporter.validated_certificate_chain());
EXPECT_EQ(0u, reporter.signed_certificate_timestamps().size());
+ EXPECT_EQ(network_isolation_key, reporter.network_isolation_key());
// If the connection is CT compliant, then there should be no socket error nor
// a report.
@@ -5586,6 +5600,7 @@ TEST_P(TLS13DowngradeMetricsTest, Metrics) {
SSLContextConfig config;
config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
+ config.tls13_hardening_for_local_anchors_enabled = false;
ssl_config_service_->UpdateSSLConfigAndNotify(config);
std::unique_ptr<SSLClientSocket> ssl_socket =
diff --git a/chromium/net/socket/transport_client_socket_pool.cc b/chromium/net/socket/transport_client_socket_pool.cc
index 3d5aff54368..6e01e7c0be5 100644
--- a/chromium/net/socket/transport_client_socket_pool.cc
+++ b/chromium/net/socket/transport_client_socket_pool.cc
@@ -1201,13 +1201,6 @@ void TransportClientSocketPool::HandOutSocket(
static_cast<int>(idle_time.InMilliseconds()));
}
- if (reuse_type != ClientSocketHandle::UNUSED) {
- // The socket being handed out is no longer considered idle, but was
- // considered idle until just before this method was called.
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Socket.NumIdleSockets",
- idle_socket_count_ + 1, 1, 256, 50);
- }
-
net_log.AddEventReferencingSource(
NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
handle->socket()->NetLog().source());
diff --git a/chromium/net/socket/udp_socket_posix.cc b/chromium/net/socket/udp_socket_posix.cc
index 0b61ca9bac2..32f0f199824 100644
--- a/chromium/net/socket/udp_socket_posix.cc
+++ b/chromium/net/socket/udp_socket_posix.cc
@@ -197,7 +197,7 @@ UDPSocketPosix::UDPSocketPosix(DatagramSocket::BindType bind_type,
write_async_timer_running_(false),
write_async_outstanding_(0),
read_buf_len_(0),
- recv_from_address_(NULL),
+ recv_from_address_(nullptr),
write_buf_len_(0),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)),
bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle),
@@ -220,8 +220,8 @@ int UDPSocketPosix::Open(AddressFamily address_family) {
if (socket_ == kInvalidSocket)
return MapSystemError(errno);
#if defined(OS_MACOSX) && !defined(OS_IOS)
- PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard,
- GUARD_CLOSE | GUARD_DUP, NULL) == 0);
+ PCHECK(change_fdguard_np(socket_, nullptr, 0, &kSocketFdGuard,
+ GUARD_CLOSE | GUARD_DUP, nullptr) == 0);
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
socket_hash_ = GetSocketFDHash(socket_);
if (!base::SetNonBlocking(socket_)) {
@@ -299,7 +299,7 @@ void UDPSocketPosix::Close() {
read_buf_.reset();
read_buf_len_ = 0;
read_callback_.Reset();
- recv_from_address_ = NULL;
+ recv_from_address_ = nullptr;
write_buf_.reset();
write_buf_len_ = 0;
write_callback_.Reset();
@@ -375,7 +375,7 @@ int UDPSocketPosix::GetLocalAddress(IPEndPoint* address) const {
int UDPSocketPosix::Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) {
- return RecvFrom(buf, buf_len, NULL, std::move(callback));
+ return RecvFrom(buf, buf_len, nullptr, std::move(callback));
}
int UDPSocketPosix::RecvFrom(IOBuffer* buf,
@@ -398,7 +398,7 @@ int UDPSocketPosix::RecvFrom(IOBuffer* buf,
&read_socket_watcher_, &read_watcher_)) {
PLOG(ERROR) << "WatchFileDescriptor failed on read";
int result = MapSystemError(errno);
- LogRead(result, NULL, 0, NULL);
+ LogRead(result, nullptr, 0, nullptr);
return result;
}
@@ -414,7 +414,7 @@ int UDPSocketPosix::Write(
int buf_len,
CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) {
- return SendToOrWrite(buf, buf_len, NULL, std::move(callback));
+ return SendToOrWrite(buf, buf_len, nullptr, std::move(callback));
}
int UDPSocketPosix::SendTo(IOBuffer* buf,
@@ -443,7 +443,7 @@ int UDPSocketPosix::SendToOrWrite(IOBuffer* buf,
&write_socket_watcher_, &write_watcher_)) {
DVPLOG(1) << "WatchFileDescriptor failed on write";
int result = MapSystemError(errno);
- LogWrite(result, NULL, NULL);
+ LogWrite(result, nullptr, nullptr);
return result;
}
@@ -742,7 +742,7 @@ void UDPSocketPosix::DidCompleteRead() {
if (result != ERR_IO_PENDING) {
read_buf_.reset();
read_buf_len_ = 0;
- recv_from_address_ = NULL;
+ recv_from_address_ = nullptr;
bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
DCHECK(ok);
DoReadCallback(result);
@@ -884,12 +884,12 @@ int UDPSocketPosix::InternalSendTo(IOBuffer* buf,
SockaddrStorage storage;
struct sockaddr* addr = storage.addr;
if (!address) {
- addr = NULL;
+ addr = nullptr;
storage.addr_len = 0;
} else {
if (!address->ToSockAddr(storage.addr, &storage.addr_len)) {
int result = ERR_ADDRESS_INVALID;
- LogWrite(result, NULL, NULL);
+ LogWrite(result, nullptr, nullptr);
return result;
}
}
@@ -1382,7 +1382,7 @@ void UDPSocketPosix::DidSendBuffers(SendResult send_result) {
it = buffers.cbegin();
for (int i = 0; i < write_count; i++, it++) {
auto& buffer = *it;
- LogWrite(buffer->length(), buffer->data(), NULL);
+ LogWrite(buffer->length(), buffer->data(), nullptr);
written_bytes_ += buffer->length();
}
// Return written buffers to pool
@@ -1413,7 +1413,7 @@ void UDPSocketPosix::DidSendBuffers(SendResult send_result) {
if (!WatchFileDescriptor()) {
DVPLOG(1) << "WatchFileDescriptor failed on write";
last_async_result_ = MapSystemError(errno);
- LogWrite(last_async_result_, NULL, NULL);
+ LogWrite(last_async_result_, nullptr, nullptr);
} else {
last_async_result_ = 0;
}
diff --git a/chromium/net/socket/udp_socket_posix.h b/chromium/net/socket/udp_socket_posix.h
index ce96046e720..df3bf9735ba 100644
--- a/chromium/net/socket/udp_socket_posix.h
+++ b/chromium/net/socket/udp_socket_posix.h
@@ -11,6 +11,7 @@
#include <memory>
+#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_pump_for_io.h"
@@ -493,7 +494,7 @@ class NET_EXPORT UDPSocketPosix {
// Same as SendTo(), except that address is passed by pointer
// instead of by reference. It is called from Write() with |address|
- // set to NULL.
+ // set to nullptr.
int SendToOrWrite(IOBuffer* buf,
int buf_len,
const IPEndPoint* address,
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager.h b/chromium/net/socket/websocket_endpoint_lock_manager.h
index 4e96c736a10..cdd8e033b9d 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager.h
+++ b/chromium/net/socket/websocket_endpoint_lock_manager.h
@@ -11,7 +11,6 @@
#include <memory>
#include "base/containers/linked_list.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/ip_endpoint.h"
diff --git a/chromium/net/spdy/OWNERS b/chromium/net/spdy/OWNERS
index b608e73eafc..e041764c5b6 100644
--- a/chromium/net/spdy/OWNERS
+++ b/chromium/net/spdy/OWNERS
@@ -2,7 +2,6 @@ birenroy@chromium.org
bnc@chromium.org
dahollings@chromium.org
diannahu@chromium.org
-rch@chromium.org
yasong@chromium.org
# COMPONENT: Internals>Network>HTTP2
diff --git a/chromium/net/spdy/platform/impl/spdy_logging_impl.h b/chromium/net/spdy/platform/impl/spdy_logging_impl.h
index cc79854df01..a9ba72bbb76 100644
--- a/chromium/net/spdy/platform/impl/spdy_logging_impl.h
+++ b/chromium/net/spdy/platform/impl/spdy_logging_impl.h
@@ -5,7 +5,9 @@
#ifndef NET_SPDY_PLATFORM_IMPL_SPDY_LOGGING_IMPL_H_
#define NET_SPDY_PLATFORM_IMPL_SPDY_LOGGING_IMPL_H_
+#include "base/check_op.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "build/build_config.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/spdy/platform/impl/spdy_macros_impl.h b/chromium/net/spdy/platform/impl/spdy_macros_impl.h
index fb286bc9ab0..3c1da5102c3 100644
--- a/chromium/net/spdy/platform/impl/spdy_macros_impl.h
+++ b/chromium/net/spdy/platform/impl/spdy_macros_impl.h
@@ -6,7 +6,6 @@
#define NET_SPDY_PLATFORM_IMPL_SPDY_MACROS_IMPL_H_
#include "base/compiler_specific.h"
-#include "base/logging.h"
#define SPDY_MUST_USE_RESULT_IMPL WARN_UNUSED_RESULT
#define SPDY_UNUSED_IMPL ALLOW_UNUSED_TYPE
diff --git a/chromium/net/spdy/spdy_network_transaction_unittest.cc b/chromium/net/spdy/spdy_network_transaction_unittest.cc
index 1da839038e0..0caead021a1 100644
--- a/chromium/net/spdy/spdy_network_transaction_unittest.cc
+++ b/chromium/net/spdy/spdy_network_transaction_unittest.cc
@@ -41,6 +41,8 @@
#include "net/http/http_response_info.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_transaction_test_util.h"
+#include "net/http/test_upload_data_stream_not_allow_http1.h"
+#include "net/http/transport_security_state.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
@@ -411,7 +413,8 @@ class SpdyNetworkTransactionTest : public TestWithTaskEnvironment {
SpdySessionKey key(HostPortPair::FromURL(request_.url),
ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
SpdySessionKey::IsProxySession::kFalse, SocketTag(),
- NetworkIsolationKey(), false /* disable_secure_dns */);
+ request_.network_isolation_key,
+ false /* disable_secure_dns */);
HttpNetworkSession* session = helper.session();
base::WeakPtr<SpdySession> spdy_session =
session->spdy_session_pool()->FindAvailableSession(
@@ -5177,7 +5180,7 @@ TEST_F(SpdyNetworkTransactionTest, FailOnGoAway) {
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
- EXPECT_THAT(out.rv, IsError(ERR_ABORTED));
+ EXPECT_THAT(out.rv, IsError(ERR_HTTP2_PROTOCOL_ERROR));
}
// Request should be retried on a new connection upon receiving a GOAWAY frame
@@ -6414,28 +6417,53 @@ struct PushUrlTestParams {
const char* url_to_fetch;
const char* url_to_push;
bool client_cert_sent;
+ bool expect_ct_error;
SpdyPushedStreamFate expected_fate;
} push_url_test_cases[] = {
// http scheme cannot be pushed (except by trusted proxy).
- {"https://www.example.org/foo.html", "http://www.example.org/foo.js", false,
+ {"https://www.example.org/foo.html", "http://www.example.org/foo.js",
+ false /* client_cert_sent */, false /* expect_ct_error */,
SpdyPushedStreamFate::kNonHttpsPushedScheme},
// ftp scheme cannot be pushed.
- {"https://www.example.org/foo.html", "ftp://www.example.org/foo.js", false,
+ {"https://www.example.org/foo.html", "ftp://www.example.org/foo.js",
+ false /* client_cert_sent */, false /* expect_ct_error */,
SpdyPushedStreamFate::kInvalidUrl},
// Cross subdomain, certificate not valid.
{"https://www.example.org/foo.html", "https://blat.www.example.org/foo.js",
- false, SpdyPushedStreamFate::kCertificateMismatch},
+ false /* client_cert_sent */, false /* expect_ct_error */,
+ SpdyPushedStreamFate::kCertificateMismatch},
// Cross domain, certificate not valid.
- {"https://www.example.org/foo.html", "https://www.foo.com/foo.js", false,
+ {"https://www.example.org/foo.html", "https://www.foo.com/foo.js",
+ false /* client_cert_sent */, false /* expect_ct_error */,
SpdyPushedStreamFate::kCertificateMismatch},
// Cross domain, certificate valid, but cross-origin push is rejected on a
// connection with client certificate.
{"https://www.example.org/foo.html", "https://mail.example.org/foo.js",
- true, SpdyPushedStreamFate::kCertificateMismatch}};
+ true /* client_cert_sent */, false /* expect_ct_error */,
+ SpdyPushedStreamFate::kCertificateMismatch},
+ // Cross domain, certificate valid, but cross-origin push is rejected on a
+ // connection with an Expect-CT error.
+ {"https://www.example.org/foo.html", "https://mail.example.org/foo.js",
+ false /* client_cert_sent */, true /* expect_ct_error */,
+ SpdyPushedStreamFate::kCertificateMismatch}};
class SpdyNetworkTransactionPushUrlTest
: public SpdyNetworkTransactionTest,
public ::testing::WithParamInterface<PushUrlTestParams> {
+ public:
+ SpdyNetworkTransactionPushUrlTest() {
+ // Set features needed for the |expect_ct_error| case, where it's important
+ // to check that NetworkIsolationKeys are respected.
+ feature_list_.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey,
+ features::kPartitionConnectionsByNetworkIsolationKey,
+ features::kPartitionSSLSessionsByNetworkIsolationKey},
+ /* disabled_features */
+ {});
+ }
+
protected:
// In this test we want to verify that we can't accidentally push content
// which can't be pushed by this content server.
@@ -6478,6 +6506,9 @@ class SpdyNetworkTransactionPushUrlTest
SequencedSocketData data(reads, writes);
request_.url = GURL(GetParam().url_to_fetch);
+ // Set a NetworkIsolationKey for the |expect_ct_error| case, to make sure
+ // NetworkIsolationKeys are respected.
+ request_.network_isolation_key = NetworkIsolationKey::CreateTransient();
// Enable cross-origin push. Since we are not using a proxy, this should
// not actually enable cross-origin SPDY push.
@@ -6487,15 +6518,33 @@ class SpdyNetworkTransactionPushUrlTest
"https://123.45.67.89:443", net::ProxyServer::SCHEME_HTTP));
session_deps->proxy_resolution_service->SetProxyDelegate(
proxy_delegate.get());
- NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
- std::move(session_deps));
-
- helper.RunPreTestSetup();
auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
ssl_provider->ssl_info.client_cert_sent = GetParam().client_cert_sent;
ssl_provider->ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ if (GetParam().expect_ct_error) {
+ ssl_provider->ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_provider->ssl_info.is_issued_by_known_root = true;
+
+ session_deps->transport_security_state->AddExpectCT(
+ "mail.example.org",
+ base::Time::Now() + base::TimeDelta::FromDays(1) /* expiry */, true,
+ GURL(), request_.network_isolation_key);
+ }
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
+ std::move(session_deps));
+
+ helper.RunPreTestSetup();
+
+ if (GetParam().expect_ct_error) {
+ ssl_provider->ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_provider->ssl_info.is_issued_by_known_root = true;
+ }
+
helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
HttpNetworkTransaction* trans = helper.trans();
@@ -6533,6 +6582,8 @@ class SpdyNetworkTransactionPushUrlTest
1);
histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}
+
+ base::test::ScopedFeatureList feature_list_;
};
INSTANTIATE_TEST_SUITE_P(All,
@@ -10438,4 +10489,30 @@ TEST_F(SpdyNetworkTransactionTest, OnDataSentDoesNotCrashWithGreasedFrameType) {
helper.VerifyDataConsumed();
}
+TEST_F(SpdyNetworkTransactionTest, NotAllowHTTP1NotBlockH2Post) {
+ spdy::SpdySerializedFrame req(
+ spdy_util_.ConstructChunkedSpdyPost(nullptr, 0));
+ spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
+ MockWrite writes[] = {
+ CreateMockWrite(req, 0), CreateMockWrite(body, 1), // POST upload frame
+ };
+ spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
+ MockRead reads[] = {
+ CreateMockRead(resp, 2), CreateMockRead(body, 3),
+ MockRead(ASYNC, 0, 4) // EOF
+ };
+ SequencedSocketData data(reads, writes);
+
+ request_.method = "POST";
+ UploadDataStreamNotAllowHTTP1 upload_data(kUploadData);
+ request_.upload_data_stream = &upload_data;
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+ helper.RunToCompletion(&data);
+ TransactionHelperResult out = helper.output();
+ EXPECT_THAT(out.rv, IsOk());
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
+ EXPECT_EQ("hello!", out.response_data);
+}
+
} // namespace net
diff --git a/chromium/net/spdy/spdy_session.cc b/chromium/net/spdy/spdy_session.cc
index b61963f6716..eef09df91ed 100644
--- a/chromium/net/spdy/spdy_session.cc
+++ b/chromium/net/spdy/spdy_session.cc
@@ -27,6 +27,7 @@
#include "base/trace_event/memory_usage_estimator.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
+#include "net/base/features.h"
#include "net/base/url_util.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_verify_result.h"
@@ -836,11 +837,13 @@ void SpdyStreamRequest::OnConfirmHandshakeComplete(int rv) {
}
// static
-bool SpdySession::CanPool(TransportSecurityState* transport_security_state,
- const SSLInfo& ssl_info,
- const SSLConfigService& ssl_config_service,
- const std::string& old_hostname,
- const std::string& new_hostname) {
+bool SpdySession::CanPool(
+ TransportSecurityState* transport_security_state,
+ const SSLInfo& ssl_info,
+ const SSLConfigService& ssl_config_service,
+ const std::string& old_hostname,
+ const std::string& new_hostname,
+ const net::NetworkIsolationKey& network_isolation_key) {
// Pooling is prohibited if the server cert is not valid for the new domain,
// and for connections on which client certs were sent. It is also prohibited
// when channel ID was sent if the hosts are from different eTLDs+1.
@@ -875,7 +878,7 @@ bool SpdySession::CanPool(TransportSecurityState* transport_security_state,
ssl_info.public_key_hashes, ssl_info.cert.get(),
ssl_info.unverified_cert.get(), ssl_info.signed_certificate_timestamps,
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
- ssl_info.ct_policy_compliance)) {
+ ssl_info.ct_policy_compliance, network_isolation_key)) {
case TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
return false;
case TransportSecurityState::CT_REQUIREMENTS_MET:
@@ -1098,7 +1101,8 @@ bool SpdySession::VerifyDomainAuthentication(const std::string& domain) const {
return true; // This is not a secure session, so all domains are okay.
return CanPool(transport_security_state_, ssl_info, *ssl_config_service_,
- host_port_pair().host(), domain);
+ host_port_pair().host(), domain,
+ spdy_session_key_.network_isolation_key());
}
void SpdySession::EnqueueStreamWrite(
@@ -1165,15 +1169,13 @@ std::unique_ptr<spdy::SpdySerializedFrame> SpdySession::CreateHeaders(
priority_dependency_state_.OnStreamCreation(
stream_id, spdy_priority, &parent_stream_id, &weight, &exclusive);
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
- [&](NetLogCaptureMode capture_mode) {
- return NetLogSpdyHeadersSentParams(
- &block, (flags & spdy::CONTROL_FLAG_FIN) != 0,
- stream_id, has_priority, weight, parent_stream_id,
- exclusive, source_dependency, capture_mode);
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_HEADERS,
+ [&](NetLogCaptureMode capture_mode) {
+ return NetLogSpdyHeadersSentParams(
+ &block, (flags & spdy::CONTROL_FLAG_FIN) != 0,
+ stream_id, has_priority, weight, parent_stream_id,
+ exclusive, source_dependency, capture_mode);
+ });
spdy::SpdyHeadersIR headers(stream_id, std::move(block));
headers.set_has_priority(has_priority);
@@ -1241,7 +1243,7 @@ std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(
// Even though we're currently stalled only by the stream, we
// might end up being stalled by the session also.
QueueSendStalledStream(*stream);
- net_log().AddEventWithIntParams(
+ net_log_.AddEventWithIntParams(
NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW,
"stream_id", stream_id);
return std::unique_ptr<SpdyBuffer>();
@@ -1253,7 +1255,7 @@ std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(
if (send_stalled_by_session) {
stream->set_send_stalled_by_flow_control(true);
QueueSendStalledStream(*stream);
- net_log().AddEventWithIntParams(
+ net_log_.AddEventWithIntParams(
NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW,
"stream_id", stream_id);
return std::unique_ptr<SpdyBuffer>();
@@ -1268,12 +1270,10 @@ std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(
if (effective_len < len)
flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN);
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_DATA, [&] {
- return NetLogSpdyDataParams(stream_id, effective_len,
- (flags & spdy::DATA_FLAG_FIN) != 0);
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_DATA, [&] {
+ return NetLogSpdyDataParams(stream_id, effective_len,
+ (flags & spdy::DATA_FLAG_FIN) != 0);
+ });
// Send PrefacePing for DATA_FRAMEs with nonzero payload size.
if (effective_len > 0)
@@ -1316,6 +1316,9 @@ void SpdySession::UpdateStreamPriority(SpdyStream* stream,
DCHECK(IsStreamActive(stream_id));
+ if (base::FeatureList::IsEnabled(features::kAvoidH2Reprioritization))
+ return;
+
auto updates = priority_dependency_state_.OnStreamUpdate(
stream_id, ConvertRequestPriorityToSpdyPriority(new_priority));
for (auto u : updates) {
@@ -1745,13 +1748,12 @@ int SpdySession::TryCreateStream(
return CreateStream(*request, stream);
}
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS, [&] {
- return NetLogSpdySessionStalledParams(
- active_streams_.size(), created_streams_.size(), num_pushed_streams_,
- max_concurrent_streams_, request->url().spec());
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS, [&] {
+ return NetLogSpdySessionStalledParams(
+ active_streams_.size(), created_streams_.size(), num_pushed_streams_,
+ max_concurrent_streams_, request->url().spec());
+ });
+
RequestPriority priority = request->priority();
CHECK_GE(priority, MINIMUM_PRIORITY);
CHECK_LE(priority, MAXIMUM_PRIORITY);
@@ -1999,7 +2001,8 @@ void SpdySession::TryCreatePushStream(spdy::SpdyStreamId stream_id,
SSLInfo ssl_info;
CHECK(GetSSLInfo(&ssl_info));
if (!CanPool(transport_security_state_, ssl_info, *ssl_config_service_,
- associated_url.host(), gurl.host())) {
+ associated_url.host(), gurl.host(),
+ spdy_session_key_.network_isolation_key())) {
RecordSpdyPushedStreamFateHistogram(
SpdyPushedStreamFate::kCertificateMismatch);
EnqueueResetStreamFrame(stream_id, request_priority,
@@ -2167,7 +2170,7 @@ void SpdySession::EnqueueResetStreamFrame(spdy::SpdyStreamId stream_id,
const std::string& description) {
DCHECK_NE(stream_id, 0u);
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM, [&] {
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM, [&] {
return NetLogSpdySendRstStreamParams(stream_id, error_code, description);
});
@@ -2184,7 +2187,7 @@ void SpdySession::EnqueuePriorityFrame(spdy::SpdyStreamId stream_id,
spdy::SpdyStreamId dependency_id,
int weight,
bool exclusive) {
- net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY, [&] {
+ net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY, [&] {
return NetLogSpdyPriorityParams(stream_id, dependency_id, weight,
exclusive);
});
@@ -2600,7 +2603,7 @@ void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
break;
case spdy::SETTINGS_INITIAL_WINDOW_SIZE: {
if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
- net_log().AddEventWithIntParams(
+ net_log_.AddEventWithIntParams(
NetLogEventType::HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE,
"initial_window_size", value);
return;
@@ -2612,7 +2615,7 @@ void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
static_cast<int32_t>(value) - stream_initial_send_window_size_;
stream_initial_send_window_size_ = static_cast<int32_t>(value);
UpdateStreamsSendWindowSize(delta_window_size);
- net_log().AddEventWithIntParams(
+ net_log_.AddEventWithIntParams(
NetLogEventType::HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE,
"delta_window_size", delta_window_size);
break;
@@ -2697,11 +2700,10 @@ void SpdySession::WritePingFrame(spdy::SpdyPingId unique_id, bool is_ack) {
EnqueueSessionWrite(HIGHEST, spdy::SpdyFrameType::PING,
std::move(ping_frame));
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_PING, [&] {
- return NetLogSpdyPingParams(unique_id, is_ack, "sent");
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_PING, [&] {
+ return NetLogSpdyPingParams(unique_id, is_ack, "sent");
+ });
+
if (!is_ack) {
DCHECK(!ping_in_flight_);
@@ -3078,7 +3080,7 @@ void SpdySession::OnRstStream(spdy::SpdyStreamId stream_id,
spdy::SpdyErrorCode error_code) {
CHECK(in_io_loop_);
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_RST_STREAM, [&] {
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_RST_STREAM, [&] {
return NetLogSpdyRecvRstStreamParams(stream_id, error_code);
});
@@ -3101,19 +3103,15 @@ void SpdySession::OnRstStream(spdy::SpdyStreamId stream_id,
CloseActiveStreamIterator(it, ERR_HTTP2_SERVER_REFUSED_STREAM);
} else if (error_code == spdy::ERROR_CODE_HTTP_1_1_REQUIRED) {
// TODO(bnc): Record histogram with number of open streams capped at 50.
- if (net_log().IsCapturing()) {
- it->second->LogStreamError(ERR_HTTP_1_1_REQUIRED,
- "Closing session because server reset stream "
- "with ERR_HTTP_1_1_REQUIRED.");
- }
+ it->second->LogStreamError(ERR_HTTP_1_1_REQUIRED,
+ "Closing session because server reset stream "
+ "with ERR_HTTP_1_1_REQUIRED.");
DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream.");
} else {
RecordProtocolErrorHistogram(
PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM);
- if (net_log().IsCapturing()) {
- it->second->LogStreamError(ERR_HTTP2_PROTOCOL_ERROR,
- "Server reset stream.");
- }
+ it->second->LogStreamError(ERR_HTTP2_PROTOCOL_ERROR,
+ "Server reset stream.");
// TODO(mbelshe): Map from Spdy-protocol errors to something sensical.
// For now, it doesn't matter much - it is a protocol error.
CloseActiveStreamIterator(it, ERR_HTTP2_PROTOCOL_ERROR);
@@ -3142,7 +3140,7 @@ void SpdySession::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
} else if (error_code == spdy::ERROR_CODE_NO_ERROR) {
StartGoingAway(last_accepted_stream_id, ERR_HTTP2_SERVER_REFUSED_STREAM);
} else {
- StartGoingAway(last_accepted_stream_id, ERR_ABORTED);
+ StartGoingAway(last_accepted_stream_id, ERR_HTTP2_PROTOCOL_ERROR);
}
// This is to handle the case when we already don't have any active
// streams (i.e., StartGoingAway() did nothing). Otherwise, we have
@@ -3174,11 +3172,10 @@ void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id,
size_t len) {
CHECK(in_io_loop_);
DCHECK_LT(len, 1u << 24);
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, [&] {
- return NetLogSpdyDataParams(stream_id, len, false);
- });
- }
+
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, [&] {
+ return NetLogSpdyDataParams(stream_id, len, false);
+ });
// Build the buffer as early as possible so that we go through the
// session flow control checks and update
@@ -3213,11 +3210,8 @@ void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id,
void SpdySession::OnStreamEnd(spdy::SpdyStreamId stream_id) {
CHECK(in_io_loop_);
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, [&] {
- return NetLogSpdyDataParams(stream_id, 0, true);
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA,
+ [&] { return NetLogSpdyDataParams(stream_id, 0, true); });
auto it = active_streams_.find(stream_id);
// By the time data comes in, the stream may already be inactive.
@@ -3249,10 +3243,8 @@ void SpdySession::OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) {
void SpdySession::OnSettings() {
CHECK(in_io_loop_);
- if (net_log_.IsCapturing()) {
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS);
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS_ACK);
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS);
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS_ACK);
// Send an acknowledgment of the setting.
spdy::SpdySettingsIR settings_ir;
@@ -3265,8 +3257,7 @@ void SpdySession::OnSettings() {
void SpdySession::OnSettingsAck() {
CHECK(in_io_loop_);
- if (net_log_.IsCapturing())
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS_ACK);
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS_ACK);
}
void SpdySession::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
@@ -3329,14 +3320,12 @@ void SpdySession::OnPushPromise(spdy::SpdyStreamId stream_id,
spdy::SpdyHeaderBlock headers) {
CHECK(in_io_loop_);
- if (net_log_.IsCapturing()) {
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE,
- [&](NetLogCaptureMode capture_mode) {
- return NetLogSpdyPushPromiseReceivedParams(
- &headers, stream_id, promised_stream_id,
- capture_mode);
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE,
+ [&](NetLogCaptureMode capture_mode) {
+ return NetLogSpdyPushPromiseReceivedParams(
+ &headers, stream_id, promised_stream_id,
+ capture_mode);
+ });
TryCreatePushStream(promised_stream_id, stream_id, std::move(headers));
}
@@ -3351,13 +3340,11 @@ void SpdySession::OnHeaders(spdy::SpdyStreamId stream_id,
base::TimeTicks recv_first_byte_time) {
CHECK(in_io_loop_);
- if (net_log().IsCapturing()) {
- net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_HEADERS,
- [&](NetLogCaptureMode capture_mode) {
- return NetLogSpdyHeadersReceivedParams(
- &headers, fin, stream_id, capture_mode);
- });
- }
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_HEADERS,
+ [&](NetLogCaptureMode capture_mode) {
+ return NetLogSpdyHeadersReceivedParams(
+ &headers, fin, stream_id, capture_mode);
+ });
auto it = active_streams_.find(stream_id);
if (it == active_streams_.end()) {
@@ -3412,7 +3399,8 @@ void SpdySession::OnAltSvc(
if (!GetSSLInfo(&ssl_info))
return;
if (!CanPool(transport_security_state_, ssl_info, *ssl_config_service_,
- host_port_pair().host(), gurl.host())) {
+ host_port_pair().host(), gurl.host(),
+ spdy_session_key_.network_isolation_key())) {
return;
}
scheme_host_port = url::SchemeHostPort(gurl);
diff --git a/chromium/net/spdy/spdy_session.h b/chromium/net/spdy/spdy_session.h
index 9c1c504859f..35bb0836e02 100644
--- a/chromium/net/spdy/spdy_session.h
+++ b/chromium/net/spdy/spdy_session.h
@@ -329,7 +329,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
const SSLInfo& ssl_info,
const SSLConfigService& ssl_config_service,
const std::string& old_hostname,
- const std::string& new_hostname);
+ const std::string& new_hostname,
+ const net::NetworkIsolationKey& network_isolation_key);
// Create a new SpdySession.
// |spdy_session_key| is the host/port that this session connects to, privacy
@@ -1106,8 +1107,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// and maximum HPACK dynamic table size.
const spdy::SettingsMap initial_settings_;
- // If set, an HTTP/2 frame with a reserved frame type will be sent after every
- // valid HTTP/2 frame. See
+ // If set, an HTTP/2 frame with a reserved frame type will be sent after
+ // every HTTP/2 SETTINGS frame and before every HTTP/2 DATA frame. See
// https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
const base::Optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame_;
diff --git a/chromium/net/spdy/spdy_session_unittest.cc b/chromium/net/spdy/spdy_session_unittest.cc
index bffd8d2f7d3..65c23fa9999 100644
--- a/chromium/net/spdy/spdy_session_unittest.cc
+++ b/chromium/net/spdy/spdy_session_unittest.cc
@@ -22,6 +22,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/privacy_mode.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
@@ -2778,6 +2779,63 @@ TEST_F(SpdySessionTest, VerifyDomainAuthentication) {
EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.google.com"));
}
+// Check that VerifyDomainAuthentication respects Expect-CT failures, and uses
+// the correct NetworkIsolationKey.
+TEST_F(SpdySessionTest, VerifyDomainAuthenticationExpectCT) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey,
+ features::kPartitionConnectionsByNetworkIsolationKey,
+ features::kPartitionSSLSessionsByNetworkIsolationKey},
+ /* disabled_features */
+ {});
+
+ key_ = SpdySessionKey(HostPortPair::FromURL(test_url_), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED,
+ SpdySessionKey::IsProxySession::kFalse, SocketTag(),
+ NetworkIsolationKey::CreateTransient(),
+ false /* disable_secure_dns */);
+ ssl_.ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_.ssl_info.is_issued_by_known_root = true;
+
+ // Need to create this after enabling features.
+ session_deps_.transport_security_state =
+ std::make_unique<TransportSecurityState>();
+
+ SequencedSocketData data;
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+ CreateSpdySession();
+
+ EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
+ EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
+ EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.com"));
+ EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.google.com"));
+
+ // Add Expect-CT data for all three hosts that passed the above checks, using
+ // different NetworkIsolationKeys.
+ const base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1);
+ session_deps_.transport_security_state->AddExpectCT(
+ "www.example.org", expiry, true, GURL(), NetworkIsolationKey());
+ session_deps_.transport_security_state->AddExpectCT(
+ "mail.example.org", expiry, true, GURL(), key_.network_isolation_key());
+ session_deps_.transport_security_state->AddExpectCT(
+ "mail.example.com", expiry, true, GURL(),
+ NetworkIsolationKey::CreateTransient());
+
+ // The host with the Expect-CT data that matches the SpdySession's should fail
+ // the check now.
+ EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
+ EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.example.org"));
+ EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.com"));
+}
+
TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
// TODO(rtenneti): Define a helper class/methods and move the common code in
// this file.
@@ -6232,7 +6290,11 @@ class AltSvcFrameTest : public SpdySessionTest {
"alternative.example.org",
443,
86400,
- spdy::SpdyAltSvcWireFormat::VersionVector()) {}
+ spdy::SpdyAltSvcWireFormat::VersionVector()) {
+ // Since the default |alternative_service_| is QUIC, need to enable QUIC for
+ // the not added tests to be meaningful.
+ session_deps_.enable_quic = true;
+ }
void AddSocketData(const spdy::SpdyAltSvcIR& altsvc_ir) {
altsvc_frame_ = spdy_util_.SerializeFrame(altsvc_ir);
@@ -6258,8 +6320,6 @@ class AltSvcFrameTest : public SpdySessionTest {
};
TEST_F(AltSvcFrameTest, ProcessAltSvcFrame) {
- session_deps_.enable_quic = true;
-
const char origin[] = "https://mail.example.org";
spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
altsvc_ir.add_altsvc(alternative_service_);
@@ -6290,15 +6350,14 @@ TEST_F(AltSvcFrameTest, ProcessAltSvcFrame) {
// Regression test for https://crbug.com/736063.
TEST_F(AltSvcFrameTest, IgnoreQuicAltSvcWithUnsupportedVersion) {
+ session_deps_.enable_quic = true;
+
+ // Note that this test only uses the legacy Google-specific Alt-Svc format.
const char origin[] = "https://mail.example.org";
spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
spdy::SpdyAltSvcWireFormat::AlternativeService quic_alternative_service(
"quic", "alternative.example.org", 443, 86400,
spdy::SpdyAltSvcWireFormat::VersionVector());
- // TODO(zhongyi): spdy::SpdyAltSvcWireFormat::ParseHeaderFieldValue expects
- // positve versions while VersionVector allows nonnegative verisons. Fix the
- // parse function and change the hardcoded invalid version to
- // quic::QUIC_VERSION_UNSUPPORTED.
quic_alternative_service.version.push_back(/* invalid QUIC version */ 1);
altsvc_ir.add_altsvc(quic_alternative_service);
altsvc_ir.set_origin(origin);
@@ -6323,7 +6382,64 @@ TEST_F(AltSvcFrameTest, IgnoreQuicAltSvcWithUnsupportedVersion) {
ASSERT_EQ(0u, altsvc_info_vector.size());
}
+TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameWithExpectCTError) {
+ const char origin[] = "https://mail.example.org";
+
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey,
+ features::kPartitionConnectionsByNetworkIsolationKey,
+ features::kPartitionSSLSessionsByNetworkIsolationKey},
+ /* disabled_features */
+ {});
+
+ key_ = SpdySessionKey(HostPortPair::FromURL(test_url_), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED,
+ SpdySessionKey::IsProxySession::kFalse, SocketTag(),
+ NetworkIsolationKey::CreateTransient(),
+ false /* disable_secure_dns */);
+ ssl_.ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
+ ssl_.ssl_info.is_issued_by_known_root = true;
+
+ // Need to create this after enabling features.
+ session_deps_.transport_security_state =
+ std::make_unique<TransportSecurityState>();
+ session_deps_.transport_security_state->AddExpectCT(
+ GURL(origin).host(),
+ base::Time::Now() + base::TimeDelta::FromDays(1) /* expiry */, true,
+ GURL(), key_.network_isolation_key());
+
+ spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
+ altsvc_ir.add_altsvc(alternative_service_);
+ altsvc_ir.set_origin(origin);
+ AddSocketData(altsvc_ir);
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+ CreateSpdySession();
+
+ base::RunLoop().RunUntilIdle();
+
+ const url::SchemeHostPort session_origin("https", test_url_.host(),
+ test_url_.EffectiveIntPort());
+ ASSERT_TRUE(spdy_session_pool_->http_server_properties()
+ ->GetAlternativeServiceInfos(session_origin,
+ key_.network_isolation_key())
+ .empty());
+
+ ASSERT_TRUE(
+ spdy_session_pool_->http_server_properties()
+ ->GetAlternativeServiceInfos(url::SchemeHostPort(GURL(origin)),
+ key_.network_isolation_key())
+ .empty());
+}
+
TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameForOriginNotCoveredByCert) {
+ session_deps_.enable_quic = true;
+
const char origin[] = "https://invalid.example.org";
spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
altsvc_ir.add_altsvc(alternative_service_);
@@ -6394,8 +6510,6 @@ TEST_F(AltSvcFrameTest,
}
TEST_F(AltSvcFrameTest, ProcessAltSvcFrameOnActiveStream) {
- session_deps_.enable_quic = true;
-
spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
altsvc_ir.add_altsvc(alternative_service_);
@@ -6453,8 +6567,6 @@ TEST_F(AltSvcFrameTest, ProcessAltSvcFrameOnActiveStream) {
TEST_F(AltSvcFrameTest,
ProcessAltSvcFrameOnActiveStreamWithNetworkIsolationKey) {
- session_deps_.enable_quic = true;
-
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
// enabled_features
@@ -6761,19 +6873,27 @@ TEST(CanPoolTest, CanPool) {
"spdy_pooling.pem");
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "www.example.org"));
+ "www.example.org", "www.example.org",
+ NetworkIsolationKey()));
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.com"));
+ "www.example.org", "mail.example.com",
+ NetworkIsolationKey()));
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.google.com"));
+ "www.example.org", "mail.google.com",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanPoolExpectCT) {
base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- TransportSecurityState::kDynamicExpectCTFeature);
+ feature_list.InitWithFeatures(
+ /* enabled_features */
+ {TransportSecurityState::kDynamicExpectCTFeature,
+ features::kPartitionExpectCTStateByNetworkIsolationKey},
+ /* disabled_features */
+ {});
// Load a cert that is valid for:
// www.example.org
// mail.example.org
@@ -6789,8 +6909,11 @@ TEST(CanPoolTest, CanPoolExpectCT) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
ssl_info.is_issued_by_known_root = true;
+ net::NetworkIsolationKey network_isolation_key =
+ NetworkIsolationKey::CreateTransient();
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "www.example.org"));
+ "www.example.org", "www.example.org",
+ network_isolation_key));
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
@@ -6798,20 +6921,31 @@ TEST(CanPoolTest, CanPoolExpectCT) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
// A different Expect-CT enabled host should not be allowed to pool.
- tss.AddExpectCT("mail.example.org", expiry, true, GURL());
+ tss.AddExpectCT("mail.example.org", expiry, true, GURL(),
+ network_isolation_key);
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ network_isolation_key));
// A report-only Expect-CT configuration should not prevent pooling.
tss.AddExpectCT("mail.example.org", expiry, false,
- GURL("https://report.test"));
+ GURL("https://report.test"), network_isolation_key);
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ network_isolation_key));
// If Expect-CT becomes enabled for the same host for which the connection was
// already made, subsequent connections to that host should not be allowed to
// pool.
- tss.AddExpectCT("www.example.org", expiry, true, GURL());
+ tss.AddExpectCT("www.example.org", expiry, true, GURL(),
+ network_isolation_key);
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "www.example.org"));
+ "www.example.org", "www.example.org",
+ network_isolation_key));
+
+ // With a different NetworkIsolationKey, CanPool() should still return true,
+ // as CT information is scoped to a single NetworkIsolationKey.
+ EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
+ "www.example.org", "www.example.org",
+ NetworkIsolationKey::CreateTransient()));
}
TEST(CanPoolTest, CanNotPoolWithCertErrors) {
@@ -6828,7 +6962,8 @@ TEST(CanPoolTest, CanNotPoolWithCertErrors) {
ssl_info.cert_status = CERT_STATUS_REVOKED;
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanNotPoolWithClientCerts) {
@@ -6845,7 +6980,8 @@ TEST(CanPoolTest, CanNotPoolWithClientCerts) {
ssl_info.client_cert_sent = true;
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanNotPoolWithBadPins) {
@@ -6862,7 +6998,8 @@ TEST(CanPoolTest, CanNotPoolWithBadPins) {
ssl_info.public_key_hashes.push_back(test::GetTestHashValue(bad_pin));
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "example.test"));
+ "www.example.org", "example.test",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanNotPoolWithBadCTWhenCTRequired) {
@@ -6890,7 +7027,8 @@ TEST(CanPoolTest, CanNotPoolWithBadCTWhenCTRequired) {
tss.SetRequireCTDelegate(&require_ct_delegate);
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanPoolWithBadCTWhenCTNotRequired) {
@@ -6918,7 +7056,8 @@ TEST(CanPoolTest, CanPoolWithBadCTWhenCTNotRequired) {
tss.SetRequireCTDelegate(&require_ct_delegate);
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanPoolWithGoodCTWhenCTRequired) {
@@ -6946,7 +7085,8 @@ TEST(CanPoolTest, CanPoolWithGoodCTWhenCTRequired) {
tss.SetRequireCTDelegate(&require_ct_delegate);
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanPoolWithAcceptablePins) {
@@ -6966,7 +7106,8 @@ TEST(CanPoolTest, CanPoolWithAcceptablePins) {
ssl_info.public_key_hashes.push_back(hash);
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
}
TEST(CanPoolTest, CanPoolWithClientCertsAndPolicy) {
@@ -6986,11 +7127,14 @@ TEST(CanPoolTest, CanPoolWithClientCertsAndPolicy) {
// CanShareConnectionWithClientCerts returns true for both hostnames, but not
// just one hostname.
EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.org"));
+ "www.example.org", "mail.example.org",
+ NetworkIsolationKey()));
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "www.example.org", "mail.example.com"));
+ "www.example.org", "mail.example.com",
+ NetworkIsolationKey()));
EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
- "mail.example.com", "www.example.org"));
+ "mail.example.com", "www.example.org",
+ NetworkIsolationKey()));
}
TEST(RecordPushedStreamHistogramTest, VaryResponseHeader) {
diff --git a/chromium/net/spdy/spdy_stream.cc b/chromium/net/spdy/spdy_stream.cc
index ba8ffe66aff..0c28112f6e5 100644
--- a/chromium/net/spdy/spdy_stream.cc
+++ b/chromium/net/spdy/spdy_stream.cc
@@ -35,11 +35,11 @@ namespace {
base::Value NetLogSpdyStreamErrorParams(spdy::SpdyStreamId stream_id,
int net_error,
- const std::string* description) {
+ base::StringPiece description) {
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetIntKey("stream_id", static_cast<int>(stream_id));
dict.SetStringKey("net_error", ErrorToShortString(net_error));
- dict.SetStringKey("description", *description);
+ dict.SetStringKey("description", description);
return dict;
}
@@ -412,6 +412,10 @@ void SpdyStream::OnHeadersReceived(
// in which case it needs to pass through so that the WebSocket layer
// can signal an error.
if (status / 100 == 1 && status != 101) {
+ // Record the timing of the 103 Early Hints response for the experiment
+ // (https://crbug.com/1093693).
+ if (status == 103 && first_early_hints_time_.is_null())
+ first_early_hints_time_ = recv_first_byte_time;
return;
}
@@ -660,9 +664,9 @@ int SpdyStream::OnDataSent(size_t frame_size) {
}
}
-void SpdyStream::LogStreamError(int error, const std::string& description) {
+void SpdyStream::LogStreamError(int error, base::StringPiece description) {
net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ERROR, [&] {
- return NetLogSpdyStreamErrorParams(stream_id_, error, &description);
+ return NetLogSpdyStreamErrorParams(stream_id_, error, description);
});
}
@@ -816,6 +820,7 @@ bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
// first bytes of the HEADERS frame were received to BufferedSpdyFramer
// (https://crbug.com/568024).
load_timing_info->receive_headers_start = recv_first_byte_time_;
+ load_timing_info->first_early_hints_time = first_early_hints_time_;
return result;
}
diff --git a/chromium/net/spdy/spdy_stream.h b/chromium/net/spdy/spdy_stream.h
index e9245b01b6f..922c43fefc1 100644
--- a/chromium/net/spdy/spdy_stream.h
+++ b/chromium/net/spdy/spdy_stream.h
@@ -301,7 +301,7 @@ class NET_EXPORT_PRIVATE SpdyStream {
void OnClose(int status);
// Called by the SpdySession to log stream related errors.
- void LogStreamError(int error, const std::string& description);
+ void LogStreamError(int error, base::StringPiece description);
// If this stream is active, reset it, and close it otherwise. In
// either case the stream is deleted.
@@ -515,6 +515,8 @@ class NET_EXPORT_PRIVATE SpdyStream {
base::TimeTicks send_time_;
base::TimeTicks recv_first_byte_time_;
base::TimeTicks recv_last_byte_time_;
+ // The time at which the first 103 Early Hints response is received.
+ base::TimeTicks first_early_hints_time_;
// Number of bytes that have been received on this stream, including frame
// overhead and headers.
diff --git a/chromium/net/spdy/spdy_stream_test_util.cc b/chromium/net/spdy/spdy_stream_test_util.cc
index 8307e999c69..b8309626edb 100644
--- a/chromium/net/spdy/spdy_stream_test_util.cc
+++ b/chromium/net/spdy/spdy_stream_test_util.cc
@@ -83,6 +83,7 @@ void StreamDelegateBase::OnClose(int status) {
if (!stream_.get())
return;
stream_id_ = stream_->stream_id();
+ stream_->GetLoadTimingInfo(&load_timing_info_);
stream_.reset();
callback_.callback().Run(status);
}
@@ -118,6 +119,11 @@ std::string StreamDelegateBase::GetResponseHeaderValue(
: it->second.as_string();
}
+const LoadTimingInfo& StreamDelegateBase::GetLoadTimingInfo() {
+ DCHECK(StreamIsClosed());
+ return load_timing_info_;
+}
+
StreamDelegateDoNothing::StreamDelegateDoNothing(
const base::WeakPtr<SpdyStream>& stream)
: StreamDelegateBase(stream) {}
diff --git a/chromium/net/spdy/spdy_stream_test_util.h b/chromium/net/spdy/spdy_stream_test_util.h
index cb1dd50875d..2453c78bd41 100644
--- a/chromium/net/spdy/spdy_stream_test_util.h
+++ b/chromium/net/spdy/spdy_stream_test_util.h
@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_timing_info.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_source.h"
#include "net/spdy/spdy_read_queue.h"
@@ -83,6 +84,10 @@ class StreamDelegateBase : public SpdyStream::Delegate {
std::string GetResponseHeaderValue(const std::string& name) const;
bool send_headers_completed() const { return send_headers_completed_; }
+ // Returns the load timing info on the stream. This must be called after the
+ // stream is closed in order to get the up-to-date information.
+ const LoadTimingInfo& GetLoadTimingInfo();
+
protected:
const base::WeakPtr<SpdyStream>& stream() { return stream_; }
@@ -93,6 +98,7 @@ class StreamDelegateBase : public SpdyStream::Delegate {
bool send_headers_completed_;
spdy::SpdyHeaderBlock response_headers_;
SpdyReadQueue received_data_queue_;
+ LoadTimingInfo load_timing_info_;
};
// Test delegate that does nothing. Used to capture data about the
diff --git a/chromium/net/spdy/spdy_stream_unittest.cc b/chromium/net/spdy/spdy_stream_unittest.cc
index 0f56bcdb5a8..c3fad7a4173 100644
--- a/chromium/net/spdy/spdy_stream_unittest.cc
+++ b/chromium/net/spdy/spdy_stream_unittest.cc
@@ -1084,6 +1084,69 @@ TEST_F(SpdyStreamTest, InformationalHeaders) {
EXPECT_TRUE(data.AllReadDataConsumed());
}
+// 103 Early Hints hasn't been implemented yet, but we collect timing
+// information for the experiment (https://crbug.com/1093693). This tests it.
+TEST_F(SpdyStreamTest, EarlyHints) {
+ spdy::SpdySerializedFrame req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
+ AddWrite(req);
+
+ // Serve the early hints.
+ spdy::SpdyHeaderBlock informational_headers;
+ informational_headers[":status"] = "103";
+ spdy::SpdySerializedFrame informational_response(
+ spdy_util_.ConstructSpdyResponseHeaders(
+ 1, std::move(informational_headers), false));
+ AddRead(informational_response);
+
+ spdy::SpdySerializedFrame reply(
+ spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ AddRead(reply);
+
+ spdy::SpdySerializedFrame body(
+ spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true));
+ AddRead(body);
+
+ AddReadEOF();
+
+ SequencedSocketData data(GetReads(), GetWrites());
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ AddSSLSocketData();
+
+ base::WeakPtr<SpdySession> session(CreateDefaultSpdySession());
+
+ base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
+ SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
+ ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
+
+ StreamDelegateDoNothing delegate(stream);
+ stream->SetDelegate(&delegate);
+
+ spdy::SpdyHeaderBlock headers(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
+ EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
+ NO_MORE_DATA_TO_SEND));
+
+ EXPECT_THAT(delegate.WaitForClose(), IsOk());
+ EXPECT_EQ("200", delegate.GetResponseHeaderValue(spdy::kHttp2StatusHeader));
+ EXPECT_EQ(std::string(kPostBody, kPostBodyLength),
+ delegate.TakeReceivedData());
+
+ // Check if the timing of the early hints response is captured.
+ const LoadTimingInfo& load_timing_info = delegate.GetLoadTimingInfo();
+ EXPECT_FALSE(load_timing_info.first_early_hints_time.is_null());
+
+ // Finish async network reads and writes.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(data.AllWriteDataConsumed());
+ EXPECT_TRUE(data.AllReadDataConsumed());
+}
+
TEST_F(SpdyStreamTest, StatusMustBeNumber) {
spdy::SpdySerializedFrame req(
spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
diff --git a/chromium/net/ssl/openssl_ssl_util.cc b/chromium/net/ssl/openssl_ssl_util.cc
index 77fa36a277d..b03c9b32ed0 100644
--- a/chromium/net/ssl/openssl_ssl_util.cc
+++ b/chromium/net/ssl/openssl_ssl_util.cc
@@ -11,6 +11,7 @@
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/values.h"
#include "build/build_config.h"
#include "crypto/openssl_util.h"
diff --git a/chromium/net/ssl/ssl_client_session_cache.cc b/chromium/net/ssl/ssl_client_session_cache.cc
index 00bd91764cc..1869eba9669 100644
--- a/chromium/net/ssl/ssl_client_session_cache.cc
+++ b/chromium/net/ssl/ssl_client_session_cache.cc
@@ -48,9 +48,9 @@ SSLClientSessionCache::SSLClientSessionCache(const Config& config)
config_(config),
cache_(config.max_entries),
lookups_since_flush_(0) {
- memory_pressure_listener_.reset(
- new base::MemoryPressureListener(base::BindRepeating(
- &SSLClientSessionCache::OnMemoryPressure, base::Unretained(this))));
+ memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
+ FROM_HERE, base::BindRepeating(&SSLClientSessionCache::OnMemoryPressure,
+ base::Unretained(this)));
}
SSLClientSessionCache::~SSLClientSessionCache() {
diff --git a/chromium/net/ssl/ssl_config_service.h b/chromium/net/ssl/ssl_config_service.h
index 6a553c64df7..0b2b947d58e 100644
--- a/chromium/net/ssl/ssl_config_service.h
+++ b/chromium/net/ssl/ssl_config_service.h
@@ -46,10 +46,7 @@ struct NET_EXPORT SSLContextConfig {
// If true, enables TLS 1.3 downgrade hardening for connections using
// local trust anchors. (Hardening for known roots is always enabled.)
- //
- // TODO(https://crbug.com/1033598): Enable this it has successfully been
- // enabled in Chrome.
- bool tls13_hardening_for_local_anchors_enabled = false;
+ bool tls13_hardening_for_local_anchors_enabled = true;
};
// The interface for retrieving global SSL configuration. This interface
diff --git a/chromium/net/ssl/ssl_connection_status_flags.h b/chromium/net/ssl/ssl_connection_status_flags.h
index cd3ad50cb87..a2f2b0e146c 100644
--- a/chromium/net/ssl/ssl_connection_status_flags.h
+++ b/chromium/net/ssl/ssl_connection_status_flags.h
@@ -7,7 +7,7 @@
#include <stdint.h>
-#include "base/logging.h"
+#include "base/check_op.h"
#include "base/macros.h"
namespace net {
diff --git a/chromium/net/test/cert_test_util_nss.cc b/chromium/net/test/cert_test_util_nss.cc
index 2b55ebc979c..096285d0963 100644
--- a/chromium/net/test/cert_test_util_nss.cc
+++ b/chromium/net/test/cert_test_util_nss.cc
@@ -12,6 +12,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/logging.h"
#include "crypto/ec_private_key.h"
#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.cc b/chromium/net/test/embedded_test_server/embedded_test_server.cc
index 36873f21b8a..d143a79ff94 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc
@@ -219,6 +219,28 @@ bool MaybeCreateOCSPResponse(CertBuilder* target,
} // namespace
+EmbeddedTestServerHandle::EmbeddedTestServerHandle(
+ EmbeddedTestServerHandle&& other) {
+ operator=(std::move(other));
+}
+
+EmbeddedTestServerHandle& EmbeddedTestServerHandle::operator=(
+ EmbeddedTestServerHandle&& other) {
+ EmbeddedTestServerHandle temporary;
+ std::swap(other.test_server_, temporary.test_server_);
+ std::swap(temporary.test_server_, test_server_);
+ return *this;
+}
+
+EmbeddedTestServerHandle::EmbeddedTestServerHandle(
+ EmbeddedTestServer* test_server)
+ : test_server_(test_server) {}
+
+EmbeddedTestServerHandle::~EmbeddedTestServerHandle() {
+ if (test_server_)
+ CHECK(test_server_->ShutdownAndWaitUntilComplete());
+}
+
EmbeddedTestServer::OCSPConfig::OCSPConfig() = default;
EmbeddedTestServer::OCSPConfig::OCSPConfig(ResponseType response_type)
: response_type(response_type) {}
@@ -268,9 +290,8 @@ EmbeddedTestServer::EmbeddedTestServer(Type type)
EmbeddedTestServer::~EmbeddedTestServer() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (Started() && !ShutdownAndWaitUntilComplete()) {
- LOG(ERROR) << "EmbeddedTestServer failed to shut down.";
- }
+ if (Started())
+ CHECK(ShutdownAndWaitUntilComplete());
{
base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait_for_thread_join;
@@ -288,23 +309,21 @@ void EmbeddedTestServer::RegisterTestCerts() {
void EmbeddedTestServer::SetConnectionListener(
EmbeddedTestServerConnectionListener* listener) {
- DCHECK(!io_thread_.get())
+ DCHECK(!io_thread_)
<< "ConnectionListener must be set before starting the server.";
connection_listener_ = listener;
}
EmbeddedTestServerHandle EmbeddedTestServer::StartAndReturnHandle(int port) {
- if (!Start(port))
- return EmbeddedTestServerHandle();
- return EmbeddedTestServerHandle(this);
+ bool result = Start(port);
+ return result ? EmbeddedTestServerHandle(this) : EmbeddedTestServerHandle();
}
bool EmbeddedTestServer::Start(int port) {
bool success = InitializeAndListen(port);
- if (!success)
- return false;
- StartAcceptingConnections();
- return true;
+ if (success)
+ StartAcceptingConnections();
+ return success;
}
bool EmbeddedTestServer::InitializeAndListen(int port) {
@@ -543,7 +562,7 @@ bool EmbeddedTestServer::GenerateCertAndKey() {
// StartAcceptingConnections so that this server and the AIA server start at
// the same time. (If the test only called InitializeAndListen they expect no
// threads to be created yet.)
- if (io_thread_.get())
+ if (io_thread_)
aia_http_server_->StartAcceptingConnections();
return true;
@@ -562,10 +581,14 @@ bool EmbeddedTestServer::InitializeSSLServerContext() {
return true;
}
+EmbeddedTestServerHandle
+EmbeddedTestServer::StartAcceptingConnectionsAndReturnHandle() {
+ return EmbeddedTestServerHandle(this);
+}
+
void EmbeddedTestServer::StartAcceptingConnections() {
DCHECK(Started());
- DCHECK(!io_thread_.get())
- << "Server must not be started while server is running";
+ DCHECK(!io_thread_) << "Server must not be started while server is running";
if (aia_http_server_)
aia_http_server_->StartAcceptingConnections();
@@ -584,8 +607,18 @@ void EmbeddedTestServer::StartAcceptingConnections() {
bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() {
DCHECK(thread_checker_.CalledOnValidThread());
- return PostTaskToIOThreadAndWait(base::BindOnce(
- &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this)));
+ // Ensure that the AIA HTTP server is no longer Started().
+ bool aia_http_server_not_started = true;
+ if (aia_http_server_ && aia_http_server_->Started()) {
+ aia_http_server_not_started =
+ aia_http_server_->ShutdownAndWaitUntilComplete();
+ }
+
+ // Return false if either this or the AIA HTTP server are still Started().
+ return PostTaskToIOThreadAndWait(
+ base::BindOnce(&EmbeddedTestServer::ShutdownOnIOThread,
+ base::Unretained(this))) &&
+ aia_http_server_not_started;
}
// static
@@ -793,21 +826,21 @@ void EmbeddedTestServer::AddDefaultHandlers(const base::FilePath& directory) {
void EmbeddedTestServer::RegisterRequestHandler(
const HandleRequestCallback& callback) {
- DCHECK(!io_thread_.get())
+ DCHECK(!io_thread_)
<< "Handlers must be registered before starting the server.";
request_handlers_.push_back(callback);
}
void EmbeddedTestServer::RegisterRequestMonitor(
const MonitorRequestCallback& callback) {
- DCHECK(!io_thread_.get())
+ DCHECK(!io_thread_)
<< "Monitors must be registered before starting the server.";
request_monitors_.push_back(callback);
}
void EmbeddedTestServer::RegisterDefaultHandler(
const HandleRequestCallback& callback) {
- DCHECK(!io_thread_.get())
+ DCHECK(!io_thread_)
<< "Handlers must be registered before starting the server.";
default_request_handlers_.push_back(callback);
}
@@ -1008,27 +1041,5 @@ bool EmbeddedTestServer::PostTaskToIOThreadAndWaitWithResult(
return task_result;
}
-EmbeddedTestServerHandle::EmbeddedTestServerHandle(
- EmbeddedTestServerHandle&& other) {
- operator=(std::move(other));
-}
-
-EmbeddedTestServerHandle& EmbeddedTestServerHandle::operator=(
- EmbeddedTestServerHandle&& other) {
- EmbeddedTestServerHandle temporary;
- std::swap(other.test_server_, temporary.test_server_);
- std::swap(temporary.test_server_, test_server_);
- return *this;
-}
-
-EmbeddedTestServerHandle::EmbeddedTestServerHandle(
- EmbeddedTestServer* test_server)
- : test_server_(test_server) {}
-
-EmbeddedTestServerHandle::~EmbeddedTestServerHandle() {
- if (test_server_)
- EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
-}
-
} // namespace test_server
} // namespace net
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.h b/chromium/net/test/embedded_test_server/embedded_test_server.h
index 699e64f6a4c..b296db0223f 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.h
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.h
@@ -39,11 +39,33 @@ class TCPServerSocket;
namespace test_server {
class EmbeddedTestServerConnectionListener;
-class EmbeddedTestServerHandle;
class HttpConnection;
class HttpResponse;
struct HttpRequest;
+class EmbeddedTestServer;
+
+// Returned by the Start[AcceptingConnections]WithHandle() APIs, to simplify
+// correct shutdown ordering of the EmbeddedTestServer. Shutdown() is invoked
+// on the associated test server when the handle goes out of scope. The handle
+// must therefore be destroyed before the test server.
+class EmbeddedTestServerHandle {
+ public:
+ EmbeddedTestServerHandle() = default;
+ EmbeddedTestServerHandle(EmbeddedTestServerHandle&& other);
+ EmbeddedTestServerHandle& operator=(EmbeddedTestServerHandle&& other);
+ ~EmbeddedTestServerHandle();
+
+ bool is_valid() const { return test_server_; }
+ explicit operator bool() const { return test_server_; }
+
+ private:
+ friend class EmbeddedTestServer;
+
+ explicit EmbeddedTestServerHandle(EmbeddedTestServer* test_server);
+ EmbeddedTestServer* test_server_ = nullptr;
+};
+
// Class providing an HTTP server for testing purpose. This is a basic server
// providing only an essential subset of HTTP/1.1 protocol. Especially,
// it assumes that the request syntax is correct. It *does not* support
@@ -61,7 +83,7 @@ struct HttpRequest;
// std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
// GURL absolute_url = test_server_->GetURL(request.relative_url);
// if (absolute_url.path() != "/test")
-// return std::unique_ptr<HttpResponse>();
+// return nullptr;
//
// auto http_response = std::make_unique<BasicHttpResponse>();
// http_response->set_code(net::HTTP_OK);
@@ -274,7 +296,8 @@ class EmbeddedTestServer {
typedef base::RepeatingCallback<void(const HttpRequest& request)>
MonitorRequestCallback;
- // Creates a http test server. Start() must be called to start the server.
+ // Creates a http test server. StartAndReturnHandle() must be called to start
+ // the server.
// |type| indicates the protocol type of the server (HTTP/HTTPS).
//
// When a TYPE_HTTPS server is created, EmbeddedTestServer will call
@@ -299,13 +322,14 @@ class EmbeddedTestServer {
// Initializes and waits until the server is ready to accept requests.
// This is the equivalent of calling InitializeAndListen() followed by
- // StartAcceptingConnections().
+ // StartAcceptingConnectionsAndReturnHandle().
// Returns a "handle" which will ShutdownAndWaitUntilComplete() when
// destroyed, or null if the listening socket could not be created.
EmbeddedTestServerHandle StartAndReturnHandle(int port = 0)
WARN_UNUSED_RESULT;
- // Deprecated equivalent of StartAndReturnHandle().
+ // Equivalent of StartAndReturnHandle(), but requires manual Shutdown() by
+ // the caller.
bool Start(int port = 0) WARN_UNUSED_RESULT;
// Starts listening for incoming connections but will not yet accept them.
@@ -313,9 +337,16 @@ class EmbeddedTestServer {
bool InitializeAndListen(int port = 0) WARN_UNUSED_RESULT;
// Starts the Accept IO Thread and begins accepting connections.
+ EmbeddedTestServerHandle StartAcceptingConnectionsAndReturnHandle()
+ WARN_UNUSED_RESULT;
+
+ // Equivalent of StartAcceptingConnectionsAndReturnHandle(), but requires
+ // manual Shutdown() by the caller.
void StartAcceptingConnections();
// Shuts down the http server and waits until the shutdown is complete.
+ // Prefer to use the Start*AndReturnHandle() APIs to manage shutdown, if
+ // possible.
bool ShutdownAndWaitUntilComplete() WARN_UNUSED_RESULT;
// Checks if the server has started listening for incoming connections.
@@ -386,23 +417,22 @@ class EmbeddedTestServer {
// |directory| directory, relative to DIR_SOURCE_ROOT.
void AddDefaultHandlers(const base::FilePath& directory);
- // The most general purpose method. Any request processing can be added using
- // this method. Takes ownership of the object. The |callback| is called
- // on the server's IO thread so all handlers must be registered before the
- // server is started.
+ // Adds a request handler that can perform any general-purpose processing.
+ // |callback| will be invoked on the server's IO thread. Note that:
+ // 1. All handlers must be registered before the server is Start()ed.
+ // 2. The server should be Shutdown() before any variables referred to by
+ // |callback| (e.g. via base::Unretained(&local)) are deleted. Using the
+ // Start*WithHandle() API variants is recommended for this reason.
void RegisterRequestHandler(const HandleRequestCallback& callback);
- // Adds request monitors. The |callback| is called before any handlers are
- // called, but can not respond it. This is useful to monitor requests that
- // will be handled by other request handlers. The |callback| is called
- // on the server's IO thread so all monitors must be registered before the
- // server is started.
+ // Adds a request monitor that will be called before any handlers. Monitors
+ // can be used to observe requests, but not to respond to them.
+ // See RegisterRequestHandler() for notes on usage.
void RegisterRequestMonitor(const MonitorRequestCallback& callback);
- // Adds default handlers, including those added by AddDefaultHandlers, to be
- // tried after all other user-specified handlers have been tried. The
- // |callback| is called on the server's IO thread so all handlers must be
- // registered before the server is started.
+ // Adds a default request handler, to be called if no user-specified handler
+ // handles the request.
+ // See RegisterRequestHandler() for notes on usage.
void RegisterDefaultHandler(const HandleRequestCallback& callback);
bool FlushAllSocketsAndConnectionsOnUIThread();
@@ -525,23 +555,6 @@ class EmbeddedTestServer {
DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer);
};
-class EmbeddedTestServerHandle {
- public:
- EmbeddedTestServerHandle() = default;
- EmbeddedTestServerHandle(EmbeddedTestServerHandle&& other);
- EmbeddedTestServerHandle& operator=(EmbeddedTestServerHandle&& other);
-
- ~EmbeddedTestServerHandle();
-
- explicit operator bool() const { return test_server_; }
-
- private:
- friend class EmbeddedTestServer;
-
- explicit EmbeddedTestServerHandle(EmbeddedTestServer* test_server);
- EmbeddedTestServer* test_server_ = nullptr;
-};
-
} // namespace test_server
// TODO(svaldez): Refactor EmbeddedTestServer to be in the net namespace.
diff --git a/chromium/net/test/embedded_test_server/request_handler_util.cc b/chromium/net/test/embedded_test_server/request_handler_util.cc
index 91d4275f94b..f08d3c34a0b 100644
--- a/chromium/net/test/embedded_test_server/request_handler_util.cc
+++ b/chromium/net/test/embedded_test_server/request_handler_util.cc
@@ -60,6 +60,10 @@ std::string GetContentType(const base::FilePath& path) {
return "audio/wav";
if (path.MatchesExtension(FILE_PATH_LITERAL(".webp")))
return "image/webp";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".mp4")))
+ return "video/mp4";
+ if (path.MatchesExtension(FILE_PATH_LITERAL(".webm")))
+ return "video/webm";
if (path.MatchesExtension(FILE_PATH_LITERAL(".xml")))
return "text/xml";
if (path.MatchesExtension(FILE_PATH_LITERAL(".mhtml")))
diff --git a/chromium/net/test/spawned_test_server/base_test_server.cc b/chromium/net/test/spawned_test_server/base_test_server.cc
index 22fd960a7f3..8330ccda5d2 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.cc
+++ b/chromium/net/test/spawned_test_server/base_test_server.cc
@@ -19,6 +19,7 @@
#include "net/base/address_list.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/port_util.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/test_root_certs.h"
@@ -221,7 +222,8 @@ bool BaseTestServer::GetAddressList(AddressList* address_list) const {
parameters.dns_query_type = DnsQueryType::A;
std::unique_ptr<HostResolver::ResolveHostRequest> request =
- resolver->CreateRequest(host_port_pair_, NetLogWithSource(), parameters);
+ resolver->CreateRequest(host_port_pair_, NetworkIsolationKey(),
+ NetLogWithSource(), parameters);
TestCompletionCallback callback;
int rv = request->Start(callback.callback());
@@ -361,15 +363,14 @@ void BaseTestServer::SetResourcePath(const base::FilePath& document_root,
bool BaseTestServer::SetAndParseServerData(const std::string& server_data,
int* port) {
VLOG(1) << "Server data: " << server_data;
- base::JSONReader json_reader;
- base::Optional<base::Value> value(json_reader.ReadToValue(server_data));
- if (!value || !value->is_dict()) {
- LOG(ERROR) << "Could not parse server data: "
- << json_reader.GetErrorMessage();
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(server_data);
+ if (!parsed_json.value || !parsed_json.value->is_dict()) {
+ LOG(ERROR) << "Could not parse server data: " << parsed_json.error_message;
return false;
}
- server_data_ = std::move(value);
+ server_data_ = std::move(parsed_json.value);
base::Optional<int> port_value = server_data_->FindIntKey("port");
if (!port_value) {
diff --git a/chromium/net/test/spawned_test_server/local_test_server.cc b/chromium/net/test/spawned_test_server/local_test_server.cc
index 3f46015d4fc..eb5016bd805 100644
--- a/chromium/net/test/spawned_test_server/local_test_server.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
+#include "base/notreached.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
diff --git a/chromium/net/test/spawned_test_server/local_test_server_win.cc b/chromium/net/test/spawned_test_server/local_test_server_win.cc
index 085a3f8cd59..319eee0789e 100644
--- a/chromium/net/test/spawned_test_server/local_test_server_win.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server_win.cc
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/string_number_conversions.h"
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.cc b/chromium/net/test/url_request/url_request_slow_download_job.cc
deleted file mode 100644
index 2195db86e6f..00000000000
--- a/chromium/net/test/url_request/url_request_slow_download_job.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2012 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/test/url_request/url_request_slow_download_job.h"
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_interceptor.h"
-#include "url/gurl.h"
-
-namespace net {
-
-const char URLRequestSlowDownloadJob::kUnknownSizeUrl[] =
- "http://url.handled.by.slow.download/download-unknown-size";
-const char URLRequestSlowDownloadJob::kKnownSizeUrl[] =
- "http://url.handled.by.slow.download/download-known-size";
-const char URLRequestSlowDownloadJob::kFinishDownloadUrl[] =
- "http://url.handled.by.slow.download/download-finish";
-const char URLRequestSlowDownloadJob::kErrorDownloadUrl[] =
- "http://url.handled.by.slow.download/download-error";
-
-const int URLRequestSlowDownloadJob::kFirstDownloadSize = 1024 * 35;
-const int URLRequestSlowDownloadJob::kSecondDownloadSize = 1024 * 10;
-
-class URLRequestSlowDownloadJob::Interceptor : public URLRequestInterceptor {
- public:
- Interceptor() = default;
- ~Interceptor() override = default;
-
- // URLRequestInterceptor implementation:
- URLRequestJob* MaybeInterceptRequest(
- URLRequest* request,
- NetworkDelegate* network_delegate) const override {
- URLRequestSlowDownloadJob* job =
- new URLRequestSlowDownloadJob(request, network_delegate);
- if (request->url().spec() != kFinishDownloadUrl &&
- request->url().spec() != kErrorDownloadUrl) {
- pending_requests_.Get().insert(job);
- }
- return job;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Interceptor);
-};
-
-// static
-base::LazyInstance<URLRequestSlowDownloadJob::SlowJobsSet>::Leaky
- URLRequestSlowDownloadJob::pending_requests_ = LAZY_INSTANCE_INITIALIZER;
-
-void URLRequestSlowDownloadJob::Start() {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&URLRequestSlowDownloadJob::StartAsync,
- weak_factory_.GetWeakPtr()));
-}
-
-int64_t URLRequestSlowDownloadJob::GetTotalReceivedBytes() const {
- return bytes_already_sent_;
-}
-
-// static
-void URLRequestSlowDownloadJob::AddUrlHandler() {
- URLRequestFilter* filter = URLRequestFilter::GetInstance();
- filter->AddUrlInterceptor(
- GURL(kUnknownSizeUrl),
- std::unique_ptr<URLRequestInterceptor>(new Interceptor()));
- filter->AddUrlInterceptor(
- GURL(kKnownSizeUrl),
- std::unique_ptr<URLRequestInterceptor>(new Interceptor()));
- filter->AddUrlInterceptor(
- GURL(kFinishDownloadUrl),
- std::unique_ptr<URLRequestInterceptor>(new Interceptor()));
- filter->AddUrlInterceptor(
- GURL(kErrorDownloadUrl),
- std::unique_ptr<URLRequestInterceptor>(new Interceptor()));
-}
-
-// static
-size_t URLRequestSlowDownloadJob::NumberOutstandingRequests() {
- return pending_requests_.Get().size();
-}
-
-// static
-void URLRequestSlowDownloadJob::FinishPendingRequests() {
- for (auto it = pending_requests_.Get().begin();
- it != pending_requests_.Get().end(); ++it) {
- (*it)->set_should_finish_download();
- }
-}
-
-void URLRequestSlowDownloadJob::ErrorPendingRequests() {
- for (auto it = pending_requests_.Get().begin();
- it != pending_requests_.Get().end(); ++it) {
- (*it)->set_should_error_download();
- }
-}
-
-URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(
- URLRequest* request,
- NetworkDelegate* network_delegate)
- : URLRequestJob(request, network_delegate),
- bytes_already_sent_(0),
- should_error_download_(false),
- should_finish_download_(false),
- buffer_size_(0) {}
-
-void URLRequestSlowDownloadJob::StartAsync() {
- if (base::LowerCaseEqualsASCII(kFinishDownloadUrl,
- request_->url().spec().c_str()))
- URLRequestSlowDownloadJob::FinishPendingRequests();
- if (base::LowerCaseEqualsASCII(kErrorDownloadUrl,
- request_->url().spec().c_str()))
- URLRequestSlowDownloadJob::ErrorPendingRequests();
-
- NotifyHeadersComplete();
-}
-
-// ReadRawData and CheckDoneStatus together implement a state
-// machine. ReadRawData may be called arbitrarily by the network stack.
-// It responds by:
-// * If there are bytes remaining in the first chunk, they are
-// returned.
-// [No bytes remaining in first chunk. ]
-// * If should_finish_download_ is not set, it returns IO_PENDING,
-// and starts calling CheckDoneStatus on a regular timer.
-// [should_finish_download_ set.]
-// * If there are bytes remaining in the second chunk, they are filled.
-// * Otherwise, return *bytes_read = 0 to indicate end of request.
-// CheckDoneStatus is called on a regular basis, in the specific
-// case where we have transmitted all of the first chunk and none of the
-// second. If should_finish_download_ becomes set, it will "complete"
-// the ReadRawData call that spawned off the CheckDoneStatus() repeated call.
-//
-// FillBufferHelper is a helper function that does the actual work of figuring
-// out where in the state machine we are and how we should fill the buffer.
-// It returns an enum indicating the state of the read.
-URLRequestSlowDownloadJob::ReadStatus
-URLRequestSlowDownloadJob::FillBufferHelper(IOBuffer* buf,
- int buf_size,
- int* bytes_written) {
- if (bytes_already_sent_ < kFirstDownloadSize) {
- int bytes_to_write =
- std::min(kFirstDownloadSize - bytes_already_sent_, buf_size);
- for (int i = 0; i < bytes_to_write; ++i) {
- buf->data()[i] = '*';
- }
- *bytes_written = bytes_to_write;
- bytes_already_sent_ += bytes_to_write;
- return BUFFER_FILLED;
- }
-
- if (!should_finish_download_)
- return REQUEST_BLOCKED;
-
- if (bytes_already_sent_ < kFirstDownloadSize + kSecondDownloadSize) {
- int bytes_to_write =
- std::min(kFirstDownloadSize + kSecondDownloadSize - bytes_already_sent_,
- buf_size);
- for (int i = 0; i < bytes_to_write; ++i) {
- buf->data()[i] = '*';
- }
- *bytes_written = bytes_to_write;
- bytes_already_sent_ += bytes_to_write;
- return BUFFER_FILLED;
- }
-
- return REQUEST_COMPLETE;
-}
-
-int URLRequestSlowDownloadJob::ReadRawData(IOBuffer* buf, int buf_size) {
- if (base::LowerCaseEqualsASCII(kFinishDownloadUrl,
- request_->url().spec().c_str()) ||
- base::LowerCaseEqualsASCII(kErrorDownloadUrl,
- request_->url().spec().c_str())) {
- VLOG(10) << __FUNCTION__ << " called w/ kFinish/ErrorDownloadUrl.";
- return 0;
- }
-
- VLOG(10) << __FUNCTION__ << " called at position " << bytes_already_sent_
- << " in the stream.";
- int bytes_read = 0;
- ReadStatus status = FillBufferHelper(buf, buf_size, &bytes_read);
- switch (status) {
- case BUFFER_FILLED:
- case REQUEST_COMPLETE:
- return bytes_read;
- case REQUEST_BLOCKED:
- buffer_ = buf;
- buffer_size_ = buf_size;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&URLRequestSlowDownloadJob::CheckDoneStatus,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(100));
- return ERR_IO_PENDING;
- }
- NOTREACHED();
- return OK;
-}
-
-void URLRequestSlowDownloadJob::CheckDoneStatus() {
- if (should_finish_download_) {
- VLOG(10) << __FUNCTION__ << " called w/ should_finish_download_ set.";
- DCHECK(nullptr != buffer_.get());
- int bytes_written = 0;
- ReadStatus status =
- FillBufferHelper(buffer_.get(), buffer_size_, &bytes_written);
- DCHECK_EQ(BUFFER_FILLED, status);
- buffer_ = nullptr; // Release the reference.
- ReadRawDataComplete(bytes_written);
- } else if (should_error_download_) {
- VLOG(10) << __FUNCTION__ << " called w/ should_finish_ownload_ set.";
- ReadRawDataComplete(ERR_CONNECTION_RESET);
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&URLRequestSlowDownloadJob::CheckDoneStatus,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(100));
- }
-}
-
-// Public virtual version.
-void URLRequestSlowDownloadJob::GetResponseInfo(HttpResponseInfo* info) {
- // Forward to private const version.
- GetResponseInfoConst(info);
-}
-
-URLRequestSlowDownloadJob::~URLRequestSlowDownloadJob() {
- pending_requests_.Get().erase(this);
-}
-
-// Private const version.
-void URLRequestSlowDownloadJob::GetResponseInfoConst(
- HttpResponseInfo* info) const {
- // Send back mock headers.
- std::string raw_headers;
- if (base::LowerCaseEqualsASCII(kFinishDownloadUrl,
- request_->url().spec().c_str()) ||
- base::LowerCaseEqualsASCII(kErrorDownloadUrl,
- request_->url().spec().c_str())) {
- raw_headers.append(
- "HTTP/1.1 200 OK\n"
- "Content-type: text/plain\n");
- } else {
- raw_headers.append(
- "HTTP/1.1 200 OK\n"
- "Content-type: application/octet-stream\n"
- "Cache-Control: max-age=0\n");
-
- if (base::LowerCaseEqualsASCII(kKnownSizeUrl,
- request_->url().spec().c_str())) {
- raw_headers.append(base::StringPrintf(
- "Content-Length: %d\n", kFirstDownloadSize + kSecondDownloadSize));
- }
- }
-
- // ParseRawHeaders expects \0 to end each header line.
- base::ReplaceSubstringsAfterOffset(
- &raw_headers, 0, "\n", base::StringPiece("\0", 1));
- info->headers = new HttpResponseHeaders(raw_headers);
-}
-
-bool URLRequestSlowDownloadJob::GetMimeType(std::string* mime_type) const {
- HttpResponseInfo info;
- GetResponseInfoConst(&info);
- return info.headers.get() && info.headers->GetMimeType(mime_type);
-}
-
-} // namespace net
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.h b/chromium/net/test/url_request/url_request_slow_download_job.h
deleted file mode 100644
index c7302c9074c..00000000000
--- a/chromium/net/test/url_request/url_request_slow_download_job.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 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 class simulates a slow download. Requests to |kUnknownSizeUrl| and
-// |kKnownSizeUrl| start downloads that pause after the first N bytes, to be
-// completed by sending a request to |kFinishDownloadUrl|.
-
-#ifndef NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
-#define NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <set>
-#include <string>
-
-#include "base/lazy_instance.h"
-#include "base/memory/weak_ptr.h"
-#include "net/url_request/url_request_job.h"
-
-namespace net {
-
-class URLRequestSlowDownloadJob : public URLRequestJob {
- public:
- // Test URLs.
- static const char kUnknownSizeUrl[];
- static const char kKnownSizeUrl[];
- static const char kFinishDownloadUrl[];
- static const char kErrorDownloadUrl[];
-
- // Download sizes.
- static const int kFirstDownloadSize;
- static const int kSecondDownloadSize;
-
- // Timer callback, used to check to see if we should finish our download and
- // send the second chunk.
- void CheckDoneStatus();
-
- // URLRequestJob methods
- void Start() override;
- int64_t GetTotalReceivedBytes() const override;
- bool GetMimeType(std::string* mime_type) const override;
- void GetResponseInfo(HttpResponseInfo* info) override;
- int ReadRawData(IOBuffer* buf, int buf_size) override;
-
- // Returns the current number of URLRequestSlowDownloadJobs that have
- // not yet completed.
- static size_t NumberOutstandingRequests();
-
- // Adds the testing URLs to the URLRequestFilter.
- static void AddUrlHandler();
-
- private:
- class Interceptor;
-
- // Enum indicating where we are in the read after a call to
- // FillBufferHelper.
- enum ReadStatus {
- // The buffer was filled with data and may be returned.
- BUFFER_FILLED,
-
- // No data was added to the buffer because kFinishDownloadUrl has
- // not yet been seen and we've already returned the first chunk.
- REQUEST_BLOCKED,
-
- // No data was added to the buffer because we've already returned
- // all the data.
- REQUEST_COMPLETE
- };
-
- URLRequestSlowDownloadJob(URLRequest* request,
- NetworkDelegate* network_delegate);
- ~URLRequestSlowDownloadJob() override;
-
- ReadStatus FillBufferHelper(IOBuffer* buf, int buf_size, int* bytes_written);
-
- void GetResponseInfoConst(HttpResponseInfo* info) const;
-
- // Mark all pending requests to be finished. We keep track of pending
- // requests in |pending_requests_|.
- static void FinishPendingRequests();
- static void ErrorPendingRequests();
- typedef std::set<URLRequestSlowDownloadJob*> SlowJobsSet;
- static base::LazyInstance<SlowJobsSet>::Leaky pending_requests_;
-
- void StartAsync();
-
- void set_should_finish_download() { should_finish_download_ = true; }
- void set_should_error_download() { should_error_download_ = true; }
-
- int bytes_already_sent_;
- bool should_error_download_;
- bool should_finish_download_;
- scoped_refptr<IOBuffer> buffer_;
- int buffer_size_;
-
- base::WeakPtrFactory<URLRequestSlowDownloadJob> weak_factory_{this};
-};
-
-} // namespace net
-
-#endif // NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
diff --git a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
index 7174f9947b7..39e9a6267d3 100644
--- a/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
+++ b/chromium/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
@@ -44,6 +44,7 @@
#include <secerr.h>
#include "base/logging.h"
+#include "base/notreached.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"
diff --git a/chromium/net/third_party/quiche/BUILD.gn b/chromium/net/third_party/quiche/BUILD.gn
index 59a75e2132a..a715ea8e2cc 100644
--- a/chromium/net/third_party/quiche/BUILD.gn
+++ b/chromium/net/third_party/quiche/BUILD.gn
@@ -23,6 +23,7 @@ source_set("quiche") {
"src/common/platform/api/quiche_str_cat.h",
"src/common/platform/api/quiche_string_piece.h",
"src/common/platform/api/quiche_text_utils.h",
+ "src/common/platform/api/quiche_time_utils.h",
"src/common/platform/api/quiche_unordered_containers.h",
"src/common/quiche_data_reader.cc",
"src/common/quiche_data_reader.h",
@@ -253,6 +254,8 @@ source_set("quiche") {
"src/quic/core/crypto/transport_parameters.h",
"src/quic/core/frames/quic_ack_frame.cc",
"src/quic/core/frames/quic_ack_frame.h",
+ "src/quic/core/frames/quic_ack_frequency_frame.cc",
+ "src/quic/core/frames/quic_ack_frequency_frame.h",
"src/quic/core/frames/quic_blocked_frame.cc",
"src/quic/core/frames/quic_blocked_frame.h",
"src/quic/core/frames/quic_connection_close_frame.cc",
@@ -431,6 +434,8 @@ source_set("quiche") {
"src/quic/core/quic_interval.h",
"src/quic/core/quic_interval_deque.h",
"src/quic/core/quic_interval_set.h",
+ "src/quic/core/quic_legacy_version_encapsulator.cc",
+ "src/quic/core/quic_legacy_version_encapsulator.h",
"src/quic/core/quic_lru_cache.h",
"src/quic/core/quic_mtu_discovery.cc",
"src/quic/core/quic_mtu_discovery.h",
@@ -548,6 +553,8 @@ source_set("quiche") {
"src/quic/quic_transport/quic_transport_session_interface.h",
"src/quic/quic_transport/quic_transport_stream.cc",
"src/quic/quic_transport/quic_transport_stream.h",
+ "src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc",
+ "src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h",
"src/spdy/core/fifo_write_scheduler.h",
"src/spdy/core/hpack/hpack_constants.cc",
"src/spdy/core/hpack/hpack_constants.h",
@@ -1230,6 +1237,7 @@ source_set("quiche_tests") {
"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/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",
@@ -1329,6 +1337,7 @@ source_set("quiche_tests") {
"src/quic/core/quic_interval_deque_test.cc",
"src/quic/core/quic_interval_set_test.cc",
"src/quic/core/quic_interval_test.cc",
+ "src/quic/core/quic_legacy_version_encapsulator_test.cc",
"src/quic/core/quic_lru_cache_test.cc",
"src/quic/core/quic_network_blackhole_detector_test.cc",
"src/quic/core/quic_one_block_arena_test.cc",
@@ -1374,6 +1383,7 @@ source_set("quiche_tests") {
"src/quic/quic_transport/quic_transport_integration_test.cc",
"src/quic/quic_transport/quic_transport_server_session_test.cc",
"src/quic/quic_transport/quic_transport_stream_test.cc",
+ "src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc",
"src/quic/test_tools/crypto_test_utils_test.cc",
"src/quic/test_tools/mock_quic_time_wait_list_manager.cc",
"src/quic/test_tools/mock_quic_time_wait_list_manager.h",
@@ -1426,58 +1436,6 @@ source_set("quiche_tests") {
"src/spdy/platform/api/spdy_test_helpers.h",
]
- # Disable building Quartc tests on iOS as they appear to be flaky there.
- if (!is_ios) {
- sources += [
- "src/quic/quartc/counting_packet_filter.h",
- "src/quic/quartc/quartc_connection_helper.cc",
- "src/quic/quartc/quartc_connection_helper.h",
- "src/quic/quartc/quartc_crypto_helpers.cc",
- "src/quic/quartc/quartc_crypto_helpers.h",
- "src/quic/quartc/quartc_dispatcher.cc",
- "src/quic/quartc/quartc_dispatcher.h",
- "src/quic/quartc/quartc_endpoint.cc",
- "src/quic/quartc/quartc_endpoint.h",
- "src/quic/quartc/quartc_endpoint_test.cc",
- "src/quic/quartc/quartc_factory.cc",
- "src/quic/quartc/quartc_factory.h",
- "src/quic/quartc/quartc_fakes.h",
- "src/quic/quartc/quartc_interval_counter.h",
- "src/quic/quartc/quartc_interval_counter_test.cc",
- "src/quic/quartc/quartc_multiplexer.cc",
- "src/quic/quartc/quartc_multiplexer.h",
- "src/quic/quartc/quartc_multiplexer_test.cc",
- "src/quic/quartc/quartc_packet_writer.cc",
- "src/quic/quartc/quartc_packet_writer.h",
- "src/quic/quartc/quartc_session.cc",
- "src/quic/quartc/quartc_session.h",
- "src/quic/quartc/quartc_session_test.cc",
- "src/quic/quartc/quartc_stream.cc",
- "src/quic/quartc/quartc_stream.h",
- "src/quic/quartc/quartc_stream_test.cc",
- "src/quic/quartc/simulated_packet_transport.cc",
- "src/quic/quartc/simulated_packet_transport.h",
- "src/quic/quartc/simulated_packet_transport_test.cc",
- "src/quic/quartc/test/bidi_test_runner.cc",
- "src/quic/quartc/test/bidi_test_runner.h",
- "src/quic/quartc/test/quartc_bidi_test.cc",
- "src/quic/quartc/test/quartc_competing_endpoint.cc",
- "src/quic/quartc/test/quartc_competing_endpoint.h",
- "src/quic/quartc/test/quartc_data_source.cc",
- "src/quic/quartc/test/quartc_data_source.h",
- "src/quic/quartc/test/quartc_data_source_test.cc",
- "src/quic/quartc/test/quartc_peer.cc",
- "src/quic/quartc/test/quartc_peer.h",
- "src/quic/quartc/test/quartc_peer_test.cc",
- "src/quic/quartc/test/quic_trace_interceptor.cc",
- "src/quic/quartc/test/quic_trace_interceptor.h",
- "src/quic/quartc/test/random_delay_link.cc",
- "src/quic/quartc/test/random_delay_link.h",
- "src/quic/quartc/test/random_packet_filter.cc",
- "src/quic/quartc/test/random_packet_filter.h",
- ]
- }
-
deps = [
"//net",
"//net:quic_test_tools",
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
index 141c0e49cd8..d5d3dac3538 100644
--- 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
@@ -13,7 +13,8 @@ namespace quiche {
template <typename T>
using QuicheOptional = QuicheOptionalImpl<T>;
-#define QuicheNullOpt QuicheNullOptImpl
+
+#define QUICHE_NULLOPT QUICHE_NULLOPT_IMPL
} // 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
new file mode 100644
index 00000000000..7319568172b
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+
+#include <cstdint>
+
+#include "net/quiche/common/platform/impl/quiche_time_utils_impl.h"
+
+namespace quiche {
+
+// Converts a civil time specified in UTC into a number of seconds since the
+// Unix epoch. This function is strict about validity of accepted dates. For
+// 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,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ int second) {
+ return QuicheUtcDateTimeToUnixSecondsImpl(year, month, day, hour, minute,
+ second);
+}
+
+} // namespace quiche
+
+#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
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
new file mode 100644
index 00000000000..3ae296dbd81
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/common/platform/api/quiche_time_utils_test.cc
@@ -0,0 +1,53 @@
+// 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.
+
+#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 "net/third_party/quiche/src/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+TEST(QuicheTimeUtilsTest, Basic) {
+ EXPECT_EQ(1, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 0, 1));
+ EXPECT_EQ(365 * 86400, QuicheUtcDateTimeToUnixSeconds(1971, 1, 1, 0, 0, 0));
+ // Some arbitrary timestamps closer to the present, compared to the output of
+ // "Date(...).getTime()" from the JavaScript console.
+ EXPECT_EQ(1152966896,
+ QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56));
+ EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21));
+
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1));
+ EXPECT_NE(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1));
+}
+
+TEST(QuicheTimeUtilsTest, Bounds) {
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0));
+ EXPECT_EQ(QUICHE_NULLOPT,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0));
+}
+
+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);
+}
+
+} // namespace
+} // namespace quiche
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 344501378b5..2242fea6437 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
@@ -10,6 +10,7 @@
#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"
namespace quiche {
@@ -119,6 +120,15 @@ bool QuicheDataReader::ReadTag(uint32_t* tag) {
return ReadBytes(tag, sizeof(*tag));
}
+bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) {
+ quiche::QuicheStringPiece digits;
+ if (!ReadStringPiece(&digits, num_digits)) {
+ return false;
+ }
+
+ return QuicheTextUtils::StringToUint64(digits, result);
+}
+
quiche::QuicheStringPiece QuicheDataReader::ReadRemainingPayload() {
quiche::QuicheStringPiece payload = PeekRemainingPayload();
pos_ = len_;
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 cf62a164708..f74f90d19e2 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
@@ -87,6 +87,11 @@ class QUICHE_EXPORT_PRIVATE QuicheDataReader {
// endian.
bool ReadTag(uint32_t* tag);
+ // Reads a sequence of a fixed number of decimal digits, parses them as an
+ // unsigned integer and returns them as a uint64_t. Forwards internal
+ // 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.
//
// NOTE: Does not copy but rather references strings in the underlying buffer.
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc
new file mode 100644
index 00000000000..919f76b3b80
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -0,0 +1,177 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h"
+#include <cstdint>
+
+#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_ptr_util.h"
+
+namespace quic {
+
+QuicBatchWriterBase::QuicBatchWriterBase(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer)
+ : write_blocked_(false), batch_buffer_(std::move(batch_buffer)) {}
+
+WriteResult QuicBatchWriterBase::WritePacket(
+ const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options) {
+ const WriteResult result =
+ InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
+ if (result.status == WRITE_STATUS_BLOCKED) {
+ write_blocked_ = true;
+ }
+ return result;
+}
+
+uint64_t QuicBatchWriterBase::GetReleaseTime(
+ const PerPacketOptions* options) const {
+ DCHECK(SupportsReleaseTime());
+
+ if (options == nullptr) {
+ return 0;
+ }
+
+ if ((options->release_time_delay.IsZero() || options->allow_burst) &&
+ !buffered_writes().empty()) {
+ // Send as soon as possible, but no sooner than the last buffered packet.
+ return buffered_writes().back().release_time;
+ }
+
+ // Send according to the release time delay.
+ return NowInNanosForReleaseTime() +
+ options->release_time_delay.ToMicroseconds() * 1000;
+}
+
+WriteResult QuicBatchWriterBase::InternalWritePacket(
+ const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options) {
+ if (buf_len > kMaxOutgoingPacketSize) {
+ return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
+ }
+
+ uint64_t release_time = SupportsReleaseTime() ? GetReleaseTime(options) : 0;
+
+ const CanBatchResult can_batch_result = CanBatch(
+ buffer, buf_len, self_address, peer_address, options, release_time);
+
+ bool buffered = false;
+ bool flush = can_batch_result.must_flush;
+
+ if (can_batch_result.can_batch) {
+ QuicBatchWriterBuffer::PushResult push_result =
+ batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+ peer_address, options, release_time);
+ if (push_result.succeeded) {
+ buffered = true;
+ // If there's no space left after the packet is buffered, force a flush.
+ flush = flush || (batch_buffer_->GetNextWriteLocation() == nullptr);
+ } else {
+ // If there's no space without this packet, force a flush.
+ flush = true;
+ }
+ }
+
+ if (!flush) {
+ return WriteResult(WRITE_STATUS_OK, 0);
+ }
+
+ size_t num_buffered_packets = buffered_writes().size();
+ const FlushImplResult flush_result = CheckedFlush();
+ const WriteResult& result = flush_result.write_result;
+ QUIC_DVLOG(1) << "Internally flushed " << flush_result.num_packets_sent
+ << " out of " << num_buffered_packets
+ << " packets. WriteResult=" << result;
+
+ if (result.status != WRITE_STATUS_OK) {
+ if (IsWriteBlockedStatus(result.status)) {
+ return WriteResult(
+ buffered ? WRITE_STATUS_BLOCKED_DATA_BUFFERED : WRITE_STATUS_BLOCKED,
+ result.error_code);
+ }
+
+ // Drop all packets, including the one being written.
+ size_t dropped_packets =
+ buffered ? buffered_writes().size() : buffered_writes().size() + 1;
+
+ batch_buffer().Clear();
+ WriteResult result_with_dropped = result;
+ result_with_dropped.dropped_packets =
+ dropped_packets > std::numeric_limits<uint16_t>::max()
+ ? std::numeric_limits<uint16_t>::max()
+ : static_cast<uint16_t>(dropped_packets);
+ return result_with_dropped;
+ }
+
+ if (!buffered) {
+ QuicBatchWriterBuffer::PushResult push_result =
+ batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
+ peer_address, options, release_time);
+ buffered = push_result.succeeded;
+
+ // Since buffered_writes has been emptied, this write must have been
+ // buffered successfully.
+ QUIC_BUG_IF(!buffered) << "Failed to push to an empty batch buffer."
+ << " self_addr:" << self_address.ToString()
+ << ", peer_addr:" << peer_address.ToString()
+ << ", buf_len:" << buf_len;
+ }
+
+ return result;
+}
+
+QuicBatchWriterBase::FlushImplResult QuicBatchWriterBase::CheckedFlush() {
+ if (buffered_writes().empty()) {
+ return FlushImplResult{WriteResult(WRITE_STATUS_OK, 0),
+ /*num_packets_sent=*/0, /*bytes_written=*/0};
+ }
+
+ const FlushImplResult flush_result = FlushImpl();
+
+ // Either flush_result.write_result.status is not WRITE_STATUS_OK, or it is
+ // WRITE_STATUS_OK and batch_buffer is empty.
+ DCHECK(flush_result.write_result.status != WRITE_STATUS_OK ||
+ buffered_writes().empty());
+
+ // Flush should never return WRITE_STATUS_BLOCKED_DATA_BUFFERED.
+ DCHECK(flush_result.write_result.status !=
+ WRITE_STATUS_BLOCKED_DATA_BUFFERED);
+
+ return flush_result;
+}
+
+WriteResult QuicBatchWriterBase::Flush() {
+ size_t num_buffered_packets = buffered_writes().size();
+ FlushImplResult flush_result = CheckedFlush();
+ QUIC_DVLOG(1) << "Externally flushed " << flush_result.num_packets_sent
+ << " out of " << num_buffered_packets
+ << " packets. WriteResult=" << flush_result.write_result;
+
+ if (IsWriteError(flush_result.write_result.status)) {
+ if (buffered_writes().size() > std::numeric_limits<uint16_t>::max()) {
+ flush_result.write_result.dropped_packets =
+ std::numeric_limits<uint16_t>::max();
+ } else {
+ flush_result.write_result.dropped_packets =
+ static_cast<uint16_t>(buffered_writes().size());
+ }
+ // Treat all errors as non-retryable fatal errors. Drop all buffered packets
+ // to avoid sending them and getting the same error again.
+ batch_buffer().Clear();
+ }
+
+ if (flush_result.write_result.status == WRITE_STATUS_BLOCKED) {
+ write_blocked_ = true;
+ }
+ return flush_result.write_result;
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h
new file mode 100644
index 00000000000..0213894f227
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h
@@ -0,0 +1,149 @@
+// 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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
+
+#include <cstdint>
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.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_ip_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// QuicBatchWriterBase implements logic common to all derived batch writers,
+// including maintaining write blockage state and a skeleton implemention of
+// WritePacket().
+// A derived batch writer must override the FlushImpl() function to send all
+// buffered writes in a batch. It must also override the CanBatch() function
+// to control whether/when a WritePacket() call should flush.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBase : public QuicPacketWriter {
+ public:
+ explicit QuicBatchWriterBase(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer);
+
+ // ATTENTION: If this write triggered a flush, and the flush failed, all
+ // buffered packets will be dropped to allow the next write to work. The
+ // number of dropped packets can be found in WriteResult.dropped_packets.
+ WriteResult WritePacket(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options) override;
+
+ bool IsWriteBlocked() const final { return write_blocked_; }
+
+ void SetWritable() final { write_blocked_ = false; }
+
+ QuicByteCount GetMaxPacketSize(
+ const QuicSocketAddress& peer_address) const final {
+ return kMaxOutgoingPacketSize;
+ }
+
+ bool SupportsReleaseTime() const { return false; }
+
+ bool IsBatchMode() const final { return true; }
+
+ QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) final {
+ // No need to explicitly delete QuicBatchWriterBuffer.
+ return {batch_buffer_->GetNextWriteLocation(), nullptr};
+ }
+
+ WriteResult Flush() final;
+
+ protected:
+ const QuicBatchWriterBuffer& batch_buffer() const { return *batch_buffer_; }
+ QuicBatchWriterBuffer& batch_buffer() { return *batch_buffer_; }
+
+ const QuicCircularDeque<BufferedWrite>& buffered_writes() const {
+ return batch_buffer_->buffered_writes();
+ }
+
+ // Get the current time in nanos which is understood by the sending api for
+ // releasing packets in the future.
+ virtual uint64_t NowInNanosForReleaseTime() const {
+ DCHECK(false) << "Should not be called since release time is unsupported.";
+ return 0;
+ }
+
+ // Given the release delay in |options| and the state of |batch_buffer_|, get
+ // the absolute release time.
+ uint64_t GetReleaseTime(const PerPacketOptions* options) const;
+
+ struct QUIC_EXPORT_PRIVATE CanBatchResult {
+ CanBatchResult(bool can_batch, bool must_flush)
+ : can_batch(can_batch), must_flush(must_flush) {}
+ // Whether this write can be batched with existing buffered writes.
+ bool can_batch;
+ // If |can_batch|, whether the caller must flush after this packet is
+ // buffered.
+ // Always true if not |can_batch|.
+ bool must_flush;
+ };
+
+ // Given the existing buffered writes(in buffered_writes()), whether a new
+ // write(in the arguments) can be batched.
+ virtual CanBatchResult CanBatch(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) const = 0;
+
+ struct QUIC_EXPORT_PRIVATE FlushImplResult {
+ // The return value of the Flush() interface, which is:
+ // - WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered writes
+ // were sent successfully.
+ // - WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR, if the batch write is
+ // blocked or returned an error while sending. If a portion of buffered
+ // writes were sent successfully, |FlushImplResult.num_packets_sent| and
+ // |FlushImplResult.bytes_written| contain the number of successfully sent
+ // packets and their total bytes.
+ WriteResult write_result;
+ int num_packets_sent;
+ // If write_result.status == WRITE_STATUS_OK, |bytes_written| will be equal
+ // to write_result.bytes_written. Otherwise |bytes_written| will be the
+ // number of bytes written before WRITE_BLOCK or WRITE_ERROR happened.
+ int bytes_written;
+ };
+
+ // Send all buffered writes(in buffered_writes()) in a batch.
+ // buffered_writes() is guaranteed to be non-empty when this function is
+ // called.
+ virtual FlushImplResult FlushImpl() = 0;
+
+ private:
+ WriteResult InternalWritePacket(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options);
+
+ // Calls FlushImpl() and check its post condition.
+ FlushImplResult CheckedFlush();
+
+ bool write_blocked_;
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer_;
+};
+
+// QuicUdpBatchWriter is a batch writer backed by a UDP socket.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriter : public QuicBatchWriterBase {
+ public:
+ QuicUdpBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd)
+ : QuicBatchWriterBase(std::move(batch_buffer)), fd_(fd) {}
+
+ int fd() const { return fd_; }
+
+ private:
+ const int fd_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BASE_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc
new file mode 100644
index 00000000000..62261393256
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.cc
@@ -0,0 +1,154 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h"
+
+#include <sstream>
+
+namespace quic {
+
+QuicBatchWriterBuffer::QuicBatchWriterBuffer() {
+ memset(buffer_, 0, sizeof(buffer_));
+}
+
+void QuicBatchWriterBuffer::Clear() {
+ buffered_writes_.clear();
+}
+
+std::string QuicBatchWriterBuffer::DebugString() const {
+ std::ostringstream os;
+ os << "{ buffer: " << static_cast<const void*>(buffer_)
+ << " buffer_end: " << static_cast<const void*>(buffer_end())
+ << " buffered_writes_.size(): " << buffered_writes_.size()
+ << " next_write_loc: " << static_cast<const void*>(GetNextWriteLocation())
+ << " SizeInUse: " << SizeInUse() << " }";
+ return os.str();
+}
+
+bool QuicBatchWriterBuffer::Invariants() const {
+ // Buffers in buffered_writes_ should not overlap, and collectively they
+ // should cover a continuous prefix of buffer_.
+ const char* next_buffer = buffer_;
+ for (auto iter = buffered_writes_.begin(); iter != buffered_writes_.end();
+ ++iter) {
+ if ((iter->buffer != next_buffer) ||
+ (iter->buffer + iter->buf_len > buffer_end())) {
+ return false;
+ }
+ next_buffer += iter->buf_len;
+ }
+
+ return (next_buffer - buffer_) == SizeInUse();
+}
+
+char* QuicBatchWriterBuffer::GetNextWriteLocation() const {
+ const char* next_loc =
+ buffered_writes_.empty()
+ ? buffer_
+ : buffered_writes_.back().buffer + buffered_writes_.back().buf_len;
+ if (buffer_end() - next_loc < kMaxOutgoingPacketSize) {
+ return nullptr;
+ }
+ return const_cast<char*>(next_loc);
+}
+
+QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
+ const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) {
+ DCHECK(Invariants());
+ DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
+
+ PushResult result = {/*succeeded=*/false, /*buffer_copied=*/false};
+ char* next_write_location = GetNextWriteLocation();
+ if (next_write_location == nullptr) {
+ return result;
+ }
+
+ if (buffer != next_write_location) {
+ if (IsExternalBuffer(buffer, buf_len)) {
+ memcpy(next_write_location, buffer, buf_len);
+ } else if (IsInternalBuffer(buffer, buf_len)) {
+ memmove(next_write_location, buffer, buf_len);
+ } else {
+ QUIC_BUG << "Buffer[" << static_cast<const void*>(buffer) << ", "
+ << static_cast<const void*>(buffer + buf_len)
+ << ") overlaps with internal buffer["
+ << static_cast<const void*>(buffer_) << ", "
+ << static_cast<const void*>(buffer_end()) << ")";
+ return result;
+ }
+ result.buffer_copied = true;
+ } else {
+ // In place push, do nothing.
+ }
+ buffered_writes_.emplace_back(
+ next_write_location, buf_len, self_address, peer_address,
+ options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
+ release_time);
+
+ DCHECK(Invariants());
+
+ result.succeeded = true;
+ return result;
+}
+
+void QuicBatchWriterBuffer::UndoLastPush() {
+ if (!buffered_writes_.empty()) {
+ buffered_writes_.pop_back();
+ }
+}
+
+QuicBatchWriterBuffer::PopResult QuicBatchWriterBuffer::PopBufferedWrite(
+ int32_t num_buffered_writes) {
+ DCHECK(Invariants());
+ DCHECK_GE(num_buffered_writes, 0);
+ DCHECK_LE(num_buffered_writes, buffered_writes_.size());
+
+ PopResult result = {/*num_buffers_popped=*/0,
+ /*moved_remaining_buffers=*/false};
+
+ result.num_buffers_popped = std::max<int32_t>(num_buffered_writes, 0);
+ result.num_buffers_popped =
+ std::min<int32_t>(result.num_buffers_popped, buffered_writes_.size());
+ buffered_writes_.pop_front_n(result.num_buffers_popped);
+
+ if (!buffered_writes_.empty()) {
+ // If not all buffered writes are erased, the remaining ones will not cover
+ // a continuous prefix of buffer_. We'll fix it by moving the remaining
+ // buffers to the beginning of buffer_ and adjust the buffer pointers in all
+ // remaining buffered writes.
+ // This should happen very rarely, about once per write block.
+ result.moved_remaining_buffers = true;
+ const char* buffer_before_move = buffered_writes_.front().buffer;
+ size_t buffer_len_to_move = buffered_writes_.back().buffer +
+ buffered_writes_.back().buf_len -
+ buffer_before_move;
+ memmove(buffer_, buffer_before_move, buffer_len_to_move);
+
+ size_t distance_to_move = buffer_before_move - buffer_;
+ for (BufferedWrite& buffered_write : buffered_writes_) {
+ buffered_write.buffer -= distance_to_move;
+ }
+
+ DCHECK_EQ(buffer_, buffered_writes_.front().buffer);
+ }
+ DCHECK(Invariants());
+
+ return result;
+}
+
+size_t QuicBatchWriterBuffer::SizeInUse() const {
+ if (buffered_writes_.empty()) {
+ return 0;
+ }
+
+ return buffered_writes_.back().buffer + buffered_writes_.back().buf_len -
+ buffer_;
+}
+
+} // namespace quic
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
new file mode 100644
index 00000000000..a441ec3c9d6
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h
@@ -0,0 +1,95 @@
+// 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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_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"
+
+namespace quic {
+
+// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
+// packets. Packet data are placed continuously within the internal buffer such
+// that they can be sent by a QuicGsoBatchWriter.
+// This class can also be used by a QuicBatchWriter which uses sendmmsg,
+// although it is not optimized for that use case.
+class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
+ public:
+ QuicBatchWriterBuffer();
+
+ // Clear all buffered writes, but leave the internal buffer intact.
+ void Clear();
+
+ char* GetNextWriteLocation() const;
+
+ // Push a buffered write to the back.
+ struct QUIC_EXPORT_PRIVATE PushResult {
+ bool succeeded;
+ // True in one of the following cases:
+ // 1) The packet buffer is external and copied to the internal buffer, or
+ // 2) The packet buffer is from the internal buffer and moved within it.
+ // This only happens if PopBufferedWrite is called in the middle of a
+ // in-place push.
+ // Only valid if |succeeded| is true.
+ bool buffer_copied;
+ };
+
+ PushResult PushBufferedWrite(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time);
+
+ void UndoLastPush();
+
+ // Pop |num_buffered_writes| buffered writes from the front.
+ // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
+ // before it is used.
+ struct QUIC_EXPORT_PRIVATE PopResult {
+ int32_t num_buffers_popped;
+ // True if after |num_buffers_popped| buffers are popped from front, the
+ // remaining buffers are moved to the beginning of the internal buffer.
+ // This should normally be false.
+ bool moved_remaining_buffers;
+ };
+ PopResult PopBufferedWrite(int32_t num_buffered_writes);
+
+ const QuicCircularDeque<BufferedWrite>& buffered_writes() const {
+ return buffered_writes_;
+ }
+
+ bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
+ return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
+ }
+ bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
+ return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
+ }
+
+ // Number of bytes used in |buffer_|.
+ // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
+ size_t SizeInUse() const;
+
+ // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
+ // size of a GSO packet.
+ static const size_t kBufferSize = 64 * 1024;
+
+ std::string DebugString() const;
+
+ protected:
+ // Whether the invariants of the buffer are upheld. For debug & test only.
+ bool Invariants() const;
+ const char* const buffer_end() const { return buffer_ + sizeof(buffer_); }
+ QUIC_CACHELINE_ALIGNED char buffer_[kBufferSize];
+ QuicCircularDeque<BufferedWrite> buffered_writes_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
new file mode 100644
index 00000000000..4cdb747ab7c
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
@@ -0,0 +1,281 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h"
+#include <memory>
+#include <string>
+
+#include "net/third_party/quiche/src/quic/core/quic_constants.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"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QUIC_EXPORT_PRIVATE TestQuicBatchWriterBuffer
+ : public QuicBatchWriterBuffer {
+ public:
+ using QuicBatchWriterBuffer::buffer_;
+ using QuicBatchWriterBuffer::buffered_writes_;
+};
+
+static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;
+
+class QuicBatchWriterBufferTest : public QuicTest {
+ public:
+ QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }
+
+ void SwitchToNewBuffer() {
+ batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
+ }
+
+ // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
+ char* FillPacketBuffer(char c) {
+ return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
+ }
+
+ // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
+ char* FillPacketBuffer(char c, char* packet_buffer) {
+ return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
+ }
+
+ // Fill |packet_buffer| with |buf_len| bytes of |c|s.
+ char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
+ memset(packet_buffer, c, buf_len);
+ return packet_buffer;
+ }
+
+ void CheckBufferedWriteContent(int buffered_write_index,
+ char buffer_content,
+ size_t buf_len,
+ const QuicIpAddress& self_addr,
+ const QuicSocketAddress& peer_addr,
+ const PerPacketOptions* options) {
+ const BufferedWrite& buffered_write =
+ batch_buffer_->buffered_writes()[buffered_write_index];
+ EXPECT_EQ(buf_len, buffered_write.buf_len);
+ for (size_t i = 0; i < buf_len; ++i) {
+ EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
+ if (buffer_content != buffered_write.buffer[i]) {
+ break;
+ }
+ }
+ EXPECT_EQ(self_addr, buffered_write.self_address);
+ EXPECT_EQ(peer_addr, buffered_write.peer_address);
+ if (options == nullptr) {
+ EXPECT_EQ(nullptr, buffered_write.options);
+ } else {
+ EXPECT_EQ(options->release_time_delay,
+ buffered_write.options->release_time_delay);
+ }
+ }
+
+ protected:
+ std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
+ QuicIpAddress self_addr_;
+ QuicSocketAddress peer_addr_;
+ uint64_t release_time_ = 0;
+ char packet_buffer_[kMaxOutgoingPacketSize];
+};
+
+class BufferSizeSequence {
+ public:
+ explicit BufferSizeSequence(
+ std::vector<std::pair<std::vector<size_t>, size_t>> stages)
+ : stages_(std::move(stages)),
+ total_buf_len_(0),
+ stage_index_(0),
+ sequence_index_(0) {}
+
+ size_t Next() {
+ const std::vector<size_t>& seq = stages_[stage_index_].first;
+ size_t buf_len = seq[sequence_index_++ % seq.size()];
+ total_buf_len_ += buf_len;
+ if (stages_[stage_index_].second <= total_buf_len_) {
+ stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
+ }
+ return buf_len;
+ }
+
+ private:
+ const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
+ size_t total_buf_len_;
+ size_t stage_index_;
+ size_t sequence_index_;
+};
+
+// Test in-place pushes. A in-place push is a push with a buffer address that is
+// equal to the result of GetNextWriteLocation().
+TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
+ std::vector<BufferSizeSequence> buffer_size_sequences = {
+ // Push large writes until the buffer is near full, then switch to 1-byte
+ // writes. This covers the edge cases when detecting insufficient buffer.
+ BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1e6}}),
+ // A sequence that looks real.
+ BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1e6}}),
+ };
+
+ for (auto& buffer_size_sequence : buffer_size_sequences) {
+ SwitchToNewBuffer();
+ int64_t num_push_failures = 0;
+
+ while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
+ size_t buf_len = buffer_size_sequence.Next();
+ const bool has_enough_space =
+ (kBatchBufferSize - batch_buffer_->SizeInUse() >=
+ kMaxOutgoingPacketSize);
+
+ char* buffer = batch_buffer_->GetNextWriteLocation();
+
+ if (has_enough_space) {
+ EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
+ } else {
+ EXPECT_EQ(nullptr, buffer);
+ }
+
+ SCOPED_TRACE(testing::Message()
+ << "Before Push: buf_len=" << buf_len
+ << ", has_enough_space=" << has_enough_space
+ << ", batch_buffer=" << batch_buffer_->DebugString());
+
+ auto push_result = batch_buffer_->PushBufferedWrite(
+ buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
+ if (!push_result.succeeded) {
+ ++num_push_failures;
+ }
+ EXPECT_EQ(has_enough_space, push_result.succeeded);
+ EXPECT_FALSE(push_result.buffer_copied);
+ if (!has_enough_space) {
+ break;
+ }
+ }
+ // Expect one and only one failure from the final push operation.
+ EXPECT_EQ(1, num_push_failures);
+ }
+}
+
+// Test some in-place pushes mixed with pushes with external buffers.
+TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
+ // First, a in-place push.
+ char* buffer = batch_buffer_->GetNextWriteLocation();
+ auto push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_FALSE(push_result.buffer_copied);
+ CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr);
+
+ // Then a push with external buffer.
+ push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+ nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_TRUE(push_result.buffer_copied);
+ CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr);
+
+ // Then another in-place push.
+ buffer = batch_buffer_->GetNextWriteLocation();
+ push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_FALSE(push_result.buffer_copied);
+ CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr);
+
+ // Then another push with external buffer.
+ push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
+ nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_TRUE(push_result.buffer_copied);
+ CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
+ peer_addr_, nullptr);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopAll) {
+ const int kNumBufferedWrites = 10;
+ for (int i = 0; i < kNumBufferedWrites; ++i) {
+ EXPECT_TRUE(batch_buffer_
+ ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
+ self_addr_, peer_addr_, nullptr,
+ release_time_)
+ .succeeded);
+ }
+ EXPECT_EQ(kNumBufferedWrites, batch_buffer_->buffered_writes().size());
+
+ auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
+ EXPECT_EQ(0, batch_buffer_->buffered_writes().size());
+ EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
+ EXPECT_FALSE(pop_result.moved_remaining_buffers);
+}
+
+TEST_F(QuicBatchWriterBufferTest, PopPartial) {
+ const int kNumBufferedWrites = 10;
+ for (int i = 0; i < kNumBufferedWrites; ++i) {
+ EXPECT_TRUE(batch_buffer_
+ ->PushBufferedWrite(FillPacketBuffer('A' + i),
+ kDefaultMaxPacketSize - i, self_addr_,
+ peer_addr_, nullptr, release_time_)
+ .succeeded);
+ }
+
+ for (int i = 0;
+ i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
+ ++i) {
+ const size_t size_before_pop = batch_buffer_->buffered_writes().size();
+ const size_t expect_size_after_pop =
+ size_before_pop < i ? 0 : size_before_pop - i;
+ batch_buffer_->PopBufferedWrite(i);
+ ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
+ const char first_write_content =
+ 'A' + kNumBufferedWrites - expect_size_after_pop;
+ const size_t first_write_len =
+ kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
+ for (int j = 0; j < expect_size_after_pop; ++j) {
+ CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
+ self_addr_, peer_addr_, nullptr);
+ }
+ }
+}
+
+TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
+ // First, a in-place push.
+ char* buffer = batch_buffer_->GetNextWriteLocation();
+ const size_t first_packet_len = 2;
+ auto push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
+ self_addr_, peer_addr_, nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_FALSE(push_result.buffer_copied);
+ CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
+ nullptr);
+
+ // Simulate the case where the writer wants to do another in-place push, but
+ // can't do so because it can't be batched with the first buffer.
+ buffer = batch_buffer_->GetNextWriteLocation();
+ const size_t second_packet_len = 1350;
+
+ // Flush the first buffer.
+ auto pop_result = batch_buffer_->PopBufferedWrite(1);
+ EXPECT_EQ(1, pop_result.num_buffers_popped);
+ EXPECT_FALSE(pop_result.moved_remaining_buffers);
+
+ // Now the second push.
+ push_result = batch_buffer_->PushBufferedWrite(
+ FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
+ self_addr_, peer_addr_, nullptr, release_time_);
+ EXPECT_TRUE(push_result.succeeded);
+ EXPECT_TRUE(push_result.buffer_copied);
+ CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
+ nullptr);
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc
new file mode 100644
index 00000000000..583b2485c4c
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h"
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h"
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicGsoBatchWriterIOTestDelegate
+ : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+ bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) override {
+ QuicUdpSocketApi socket_api;
+ int fd =
+ socket_api.Create(params.address_family,
+ /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+ /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+ if (fd < 0) {
+ QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+ return false; // Let the test fail rather than skip it.
+ }
+ const bool gso_not_supported =
+ QuicLinuxSocketUtils::GetUDPSegmentSize(fd) < 0;
+ socket_api.Destroy(fd);
+
+ if (gso_not_supported) {
+ QUIC_LOG(WARNING) << "Test skipped since GSO is not supported.";
+ return true;
+ }
+
+ QUIC_LOG(WARNING) << "OK: GSO is supported.";
+ return false;
+ }
+
+ void ResetWriter(int fd) override {
+ writer_ = std::make_unique<QuicGsoBatchWriter>(
+ std::make_unique<QuicBatchWriterBuffer>(), fd);
+ }
+
+ QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+ std::unique_ptr<QuicGsoBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ QuicGsoBatchWriterTest,
+ QuicUdpBatchWriterIOTest,
+ testing::ValuesIn(
+ MakeQuicBatchWriterTestParams<QuicGsoBatchWriterIOTestDelegate>()));
+
+class QuicSendmmsgBatchWriterIOTestDelegate
+ : public QuicUdpBatchWriterIOTestDelegate {
+ public:
+ void ResetWriter(int fd) override {
+ writer_ = std::make_unique<QuicSendmmsgBatchWriter>(
+ std::make_unique<QuicBatchWriterBuffer>(), fd);
+ }
+
+ QuicUdpBatchWriter* GetWriter() override { return writer_.get(); }
+
+ private:
+ std::unique_ptr<QuicSendmmsgBatchWriter> writer_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ QuicSendmmsgBatchWriterTest,
+ QuicUdpBatchWriterIOTest,
+ testing::ValuesIn(MakeQuicBatchWriterTestParams<
+ QuicSendmmsgBatchWriterIOTestDelegate>()));
+
+} // namespace
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h
new file mode 100644
index 00000000000..b4f36b9f3ca
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_test.h
@@ -0,0 +1,284 @@
+// 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_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <iostream>
+#include <utility>
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "net/third_party/quiche/src/quic/core/quic_udp_socket.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+static bool IsAddressFamilySupported(int address_family) {
+ static auto check_function = [](int address_family) {
+ int fd = socket(address_family, SOCK_STREAM, 0);
+ if (fd < 0) {
+ QUIC_LOG(ERROR) << "address_family not supported: " << address_family
+ << ", error: " << strerror(errno);
+ EXPECT_EQ(EAFNOSUPPORT, errno);
+ return false;
+ }
+ close(fd);
+ return true;
+ };
+
+ if (address_family == AF_INET) {
+ static const bool ipv4_supported = check_function(AF_INET);
+ return ipv4_supported;
+ }
+
+ static const bool ipv6_supported = check_function(AF_INET6);
+ return ipv6_supported;
+}
+
+static bool CreateSocket(int family, QuicSocketAddress* address, int* fd) {
+ if (family == AF_INET) {
+ *address = QuicSocketAddress(QuicIpAddress::Loopback4(), 0);
+ } else {
+ DCHECK_EQ(family, AF_INET6);
+ *address = QuicSocketAddress(QuicIpAddress::Loopback6(), 0);
+ }
+
+ QuicUdpSocketApi socket_api;
+ *fd = socket_api.Create(family,
+ /*receive_buffer_size=*/kDefaultSocketReceiveBuffer,
+ /*send_buffer_size=*/kDefaultSocketReceiveBuffer);
+ if (*fd < 0) {
+ QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
+ return false;
+ }
+ socket_api.EnableDroppedPacketCount(*fd);
+
+ if (!socket_api.Bind(*fd, *address)) {
+ QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
+ return false;
+ }
+
+ if (address->FromSocket(*fd) != 0) {
+ QUIC_LOG(ERROR) << "Unable to get self address. Error: "
+ << strerror(errno);
+ return false;
+ }
+ return true;
+}
+
+struct QuicUdpBatchWriterIOTestParams;
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestDelegate {
+ public:
+ virtual ~QuicUdpBatchWriterIOTestDelegate() {}
+
+ virtual bool ShouldSkip(const QuicUdpBatchWriterIOTestParams& params) {
+ return false;
+ }
+
+ virtual void ResetWriter(int fd) = 0;
+
+ virtual QuicUdpBatchWriter* GetWriter() = 0;
+};
+
+struct QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTestParams {
+ // Use shared_ptr because gtest makes copies of test params.
+ std::shared_ptr<QuicUdpBatchWriterIOTestDelegate> delegate;
+ int address_family;
+ int data_size;
+ int packet_size;
+
+ QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os,
+ const QuicUdpBatchWriterIOTestParams& p) {
+ os << "{ address_family: " << p.address_family
+ << " data_size: " << p.data_size << " packet_size: " << p.packet_size
+ << " }";
+ return os;
+ }
+};
+
+template <class QuicUdpBatchWriterIOTestDelegateT>
+static std::vector<QuicUdpBatchWriterIOTestParams>
+MakeQuicBatchWriterTestParams() {
+ static_assert(std::is_base_of<QuicUdpBatchWriterIOTestDelegate,
+ QuicUdpBatchWriterIOTestDelegateT>::value,
+ "<QuicUdpBatchWriterIOTestDelegateT> needs to derive from "
+ "QuicUdpBatchWriterIOTestDelegate");
+
+ std::vector<QuicUdpBatchWriterIOTestParams> params;
+ for (int address_family : {AF_INET, AF_INET6}) {
+ for (int data_size : {1, 150, 1500, 15000, 64000, 512 * 1024}) {
+ for (int packet_size : {1, 50, 1350, 1452}) {
+ if (packet_size <= data_size && (data_size / packet_size < 2000)) {
+ params.push_back(
+ {std::make_unique<QuicUdpBatchWriterIOTestDelegateT>(),
+ address_family, data_size, packet_size});
+ }
+ }
+ }
+ }
+ return params;
+}
+
+// QuicUdpBatchWriterIOTest is a value parameterized test fixture that can be
+// used by tests of derived classes of QuicUdpBatchWriter, to verify basic
+// packet IO capabilities.
+class QUIC_EXPORT_PRIVATE QuicUdpBatchWriterIOTest
+ : public QuicTestWithParam<QuicUdpBatchWriterIOTestParams> {
+ protected:
+ QuicUdpBatchWriterIOTest()
+ : address_family_(GetParam().address_family),
+ data_size_(GetParam().data_size),
+ packet_size_(GetParam().packet_size),
+ self_socket_(-1),
+ peer_socket_(-1) {
+ QUIC_LOG(INFO) << "QuicUdpBatchWriterIOTestParams: " << GetParam();
+ EXPECT_TRUE(address_family_ == AF_INET || address_family_ == AF_INET6);
+ EXPECT_LE(packet_size_, data_size_);
+ EXPECT_LE(packet_size_, sizeof(packet_buffer_));
+ }
+
+ ~QuicUdpBatchWriterIOTest() override {
+ if (self_socket_ > 0) {
+ close(self_socket_);
+ }
+ if (peer_socket_ > 0) {
+ close(peer_socket_);
+ }
+ }
+
+ // Whether this test should be skipped. A test is passed if skipped.
+ // A test can be skipped when e.g. it exercises a kernel feature that is not
+ // available on the system.
+ bool ShouldSkip() {
+ if (!IsAddressFamilySupported(address_family_)) {
+ QUIC_LOG(WARNING)
+ << "Test skipped since address_family is not supported.";
+ return true;
+ }
+
+ return GetParam().delegate->ShouldSkip(GetParam());
+ }
+
+ // Initialize a test.
+ // To fail the test in Initialize, use ASSERT_xx macros.
+ void Initialize() {
+ ASSERT_TRUE(CreateSocket(address_family_, &self_address_, &self_socket_));
+ ASSERT_TRUE(CreateSocket(address_family_, &peer_address_, &peer_socket_));
+
+ QUIC_DLOG(INFO) << "Self address: " << self_address_.ToString() << ", fd "
+ << self_socket_;
+ QUIC_DLOG(INFO) << "Peer address: " << peer_address_.ToString() << ", fd "
+ << peer_socket_;
+ GetParam().delegate->ResetWriter(self_socket_);
+ }
+
+ QuicUdpBatchWriter* GetWriter() { return GetParam().delegate->GetWriter(); }
+
+ void ValidateWrite() {
+ char this_packet_content = '\0';
+ int this_packet_size;
+ int num_writes = 0;
+ int bytes_flushed = 0;
+ WriteResult result;
+
+ for (int bytes_sent = 0; bytes_sent < data_size_;
+ bytes_sent += this_packet_size, ++this_packet_content) {
+ this_packet_size = std::min(packet_size_, data_size_ - bytes_sent);
+ memset(&packet_buffer_[0], this_packet_content, this_packet_size);
+
+ result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
+ self_address_.host(), peer_address_,
+ nullptr);
+
+ ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+ bytes_flushed += result.bytes_written;
+ ++num_writes;
+
+ QUIC_DVLOG(1) << "[write #" << num_writes
+ << "] this_packet_size: " << this_packet_size
+ << ", total_bytes_sent: " << bytes_sent + this_packet_size
+ << ", bytes_flushed: " << bytes_flushed
+ << ", pkt content:" << std::hex << int(this_packet_content);
+ }
+
+ result = GetWriter()->Flush();
+ ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
+ bytes_flushed += result.bytes_written;
+ ASSERT_EQ(data_size_, bytes_flushed);
+
+ QUIC_LOG(INFO) << "Sent " << data_size_ << " bytes in " << num_writes
+ << " writes.";
+ }
+
+ void ValidateRead() {
+ char this_packet_content = '\0';
+ int this_packet_size;
+ int packets_received = 0;
+ for (int bytes_received = 0; bytes_received < data_size_;
+ bytes_received += this_packet_size, ++this_packet_content) {
+ this_packet_size = std::min(packet_size_, data_size_ - bytes_received);
+ SCOPED_TRACE(testing::Message()
+ << "Before ReadPacket: bytes_received=" << bytes_received
+ << ", this_packet_size=" << this_packet_size);
+
+ QuicUdpSocketApi::ReadPacketResult result;
+ result.packet_buffer = {&packet_buffer_[0], sizeof(packet_buffer_)};
+ result.control_buffer = {&control_buffer_[0], sizeof(control_buffer_)};
+ QuicUdpSocketApi().ReadPacket(
+ peer_socket_,
+ quic::BitMask64(QuicUdpPacketInfoBit::V4_SELF_IP,
+ QuicUdpPacketInfoBit::V6_SELF_IP,
+ QuicUdpPacketInfoBit::PEER_ADDRESS),
+ &result);
+ ASSERT_TRUE(result.ok);
+ ASSERT_TRUE(
+ result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+ QuicSocketAddress read_peer_address = result.packet_info.peer_address();
+ QuicIpAddress read_self_address = read_peer_address.host().IsIPv6()
+ ? result.packet_info.self_v6_ip()
+ : result.packet_info.self_v4_ip();
+
+ EXPECT_EQ(read_self_address, peer_address_.host());
+ EXPECT_EQ(read_peer_address, self_address_);
+ for (int i = 0; i < this_packet_size; ++i) {
+ EXPECT_EQ(this_packet_content, packet_buffer_[i]);
+ }
+ packets_received += this_packet_size;
+ }
+
+ QUIC_LOG(INFO) << "Received " << data_size_ << " bytes in "
+ << packets_received << " packets.";
+ }
+
+ QuicSocketAddress self_address_;
+ QuicSocketAddress peer_address_;
+ char packet_buffer_[1500];
+ char control_buffer_[kDefaultUdpPacketControlBufferSize];
+ int address_family_;
+ const int data_size_;
+ const int packet_size_;
+ int self_socket_;
+ int peer_socket_;
+};
+
+TEST_P(QuicUdpBatchWriterIOTest, WriteAndRead) {
+ if (ShouldSkip()) {
+ return;
+ }
+
+ Initialize();
+
+ ValidateWrite();
+ ValidateRead();
+}
+
+} // namespace test
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_TEST_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc
new file mode 100644
index 00000000000..56c0e10171f
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -0,0 +1,122 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <time.h>
+#include <ctime>
+
+#include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
+
+namespace quic {
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd)
+ : QuicGsoBatchWriter(std::move(batch_buffer), fd, CLOCK_MONOTONIC) {}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd,
+ clockid_t clockid_for_release_time)
+ : QuicUdpBatchWriter(std::move(batch_buffer), fd),
+ clockid_for_release_time_(clockid_for_release_time),
+ supports_release_time_(
+ GetQuicRestartFlag(quic_support_release_time_for_gso) &&
+ QuicLinuxSocketUtils::EnableReleaseTime(fd,
+ clockid_for_release_time)) {
+ if (supports_release_time_) {
+ QUIC_RESTART_FLAG_COUNT(quic_support_release_time_for_gso);
+ QUIC_LOG_FIRST_N(INFO, 5) << "Release time is enabled.";
+ } else {
+ QUIC_LOG_FIRST_N(INFO, 5) << "Release time is not enabled.";
+ }
+}
+
+QuicGsoBatchWriter::QuicGsoBatchWriter(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd,
+ clockid_t clockid_for_release_time,
+ ReleaseTimeForceEnabler enabler)
+ : QuicUdpBatchWriter(std::move(batch_buffer), fd),
+ clockid_for_release_time_(clockid_for_release_time),
+ supports_release_time_(true) {
+ QUIC_DLOG(INFO) << "Release time forcefully enabled.";
+}
+
+QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
+ const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) const {
+ // If there is nothing buffered already, this write will be included in this
+ // batch.
+ if (buffered_writes().empty()) {
+ return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+ }
+
+ // The new write can be batched if all of the following are true:
+ // [0] The total number of the GSO segments(one write=one segment, including
+ // the new write) must not exceed |max_segments|.
+ // [1] It has the same source and destination addresses as already buffered
+ // writes.
+ // [2] It won't cause this batch to exceed kMaxGsoPacketSize.
+ // [3] Already buffered writes all have the same length.
+ // [4] Length of already buffered writes must >= length of the new write.
+ // [5] The new packet has the same release time as buffered writes.
+ const BufferedWrite& first = buffered_writes().front();
+ const BufferedWrite& last = buffered_writes().back();
+ size_t max_segments = MaxSegments(first.buf_len);
+ bool can_batch =
+ buffered_writes().size() < max_segments && // [0]
+ last.self_address == self_address && // [1]
+ last.peer_address == peer_address && // [1]
+ batch_buffer().SizeInUse() + buf_len <= kMaxGsoPacketSize && // [2]
+ first.buf_len == last.buf_len && // [3]
+ first.buf_len >= buf_len && // [4]
+ (!SupportsReleaseTime() || first.release_time == release_time); // [5]
+
+ // A flush is required if any of the following is true:
+ // [a] The new write can't be batched.
+ // [b] Length of the new write is different from the length of already
+ // buffered writes.
+ // [c] The total number of the GSO segments, including the new write, reaches
+ // |max_segments|.
+ bool must_flush = (!can_batch) || // [a]
+ (last.buf_len != buf_len) || // [b]
+ (buffered_writes().size() + 1 == max_segments); // [c]
+ return CanBatchResult(can_batch, must_flush);
+}
+
+uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const {
+ struct timespec ts;
+
+ if (clock_gettime(clockid_for_release_time_, &ts) != 0) {
+ return 0;
+ }
+
+ return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
+}
+
+// static
+void QuicGsoBatchWriter::BuildCmsg(QuicMsgHdr* hdr,
+ const QuicIpAddress& self_address,
+ uint16_t gso_size,
+ uint64_t release_time) {
+ hdr->SetIpInNextCmsg(self_address);
+ if (gso_size > 0) {
+ *hdr->GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = gso_size;
+ }
+ if (release_time != 0) {
+ *hdr->GetNextCmsgData<uint64_t>(SOL_SOCKET, SO_TXTIME) = release_time;
+ }
+}
+
+QuicGsoBatchWriter::FlushImplResult QuicGsoBatchWriter::FlushImpl() {
+ return InternalFlushImpl<kCmsgSpace>(BuildCmsg);
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h
new file mode 100644
index 00000000000..64c7e02fdd4
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -0,0 +1,114 @@
+// 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_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h"
+
+namespace quic {
+
+// QuicGsoBatchWriter sends QUIC packets in batches, using UDP socket's generic
+// segmentation offload(GSO) capability.
+class QUIC_EXPORT_PRIVATE QuicGsoBatchWriter : public QuicUdpBatchWriter {
+ public:
+ QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd);
+
+ // |clockid_for_release_time|: FQ qdisc requires CLOCK_MONOTONIC, EDF requires
+ // CLOCK_TAI.
+ QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd,
+ clockid_t clockid_for_release_time);
+
+ bool SupportsReleaseTime() const final { return supports_release_time_; }
+
+ CanBatchResult CanBatch(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) const override;
+
+ FlushImplResult FlushImpl() override;
+
+ protected:
+ // Test only constructor to forcefully enable release time.
+ struct QUIC_EXPORT_PRIVATE ReleaseTimeForceEnabler {};
+ QuicGsoBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd,
+ clockid_t clockid_for_release_time,
+ ReleaseTimeForceEnabler enabler);
+
+ uint64_t NowInNanosForReleaseTime() const override;
+
+ static size_t MaxSegments(size_t gso_size) {
+ // Max segments should be the min of UDP_MAX_SEGMENTS(64) and
+ // (((64KB - sizeof(ip hdr) - sizeof(udp hdr)) / MSS) + 1), in the typical
+ // case of IPv6 packets with 1500-byte MTU, the result is
+ // ((64KB - 40 - 8) / (1500 - 48)) + 1 = 46
+ // However, due a kernel bug, the limit is much lower for tiny gso_sizes.
+ return gso_size <= 2 ? 16 : 45;
+ }
+
+ static const int kCmsgSpace =
+ kCmsgSpaceForIp + kCmsgSpaceForSegmentSize + kCmsgSpaceForTxTime;
+ static void BuildCmsg(QuicMsgHdr* hdr,
+ const QuicIpAddress& self_address,
+ uint16_t gso_size,
+ uint64_t release_time);
+
+ template <size_t CmsgSpace, typename CmsgBuilderT>
+ FlushImplResult InternalFlushImpl(CmsgBuilderT cmsg_builder) {
+ DCHECK(!IsWriteBlocked());
+ DCHECK(!buffered_writes().empty());
+
+ FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+ /*num_packets_sent=*/0, /*bytes_written=*/0};
+ WriteResult& write_result = result.write_result;
+
+ int total_bytes = batch_buffer().SizeInUse();
+ const BufferedWrite& first = buffered_writes().front();
+ char cbuf[CmsgSpace];
+ QuicMsgHdr hdr(first.buffer, total_bytes, first.peer_address, cbuf,
+ sizeof(cbuf));
+
+ uint16_t gso_size = buffered_writes().size() > 1 ? first.buf_len : 0;
+ cmsg_builder(&hdr, first.self_address, gso_size, first.release_time);
+
+ write_result = QuicLinuxSocketUtils::WritePacket(fd(), hdr);
+ QUIC_DVLOG(1) << "Write GSO packet result: " << write_result
+ << ", fd: " << fd()
+ << ", self_address: " << first.self_address.ToString()
+ << ", peer_address: " << first.peer_address.ToString()
+ << ", num_segments: " << buffered_writes().size()
+ << ", total_bytes: " << total_bytes
+ << ", gso_size: " << gso_size;
+
+ // All segments in a GSO packet share the same fate - if the write failed,
+ // none of them are sent, and it's not needed to call PopBufferedWrite().
+ if (write_result.status != WRITE_STATUS_OK) {
+ return result;
+ }
+
+ result.num_packets_sent = buffered_writes().size();
+
+ write_result.bytes_written = total_bytes;
+ result.bytes_written = total_bytes;
+
+ batch_buffer().PopBufferedWrite(buffered_writes().size());
+
+ QUIC_BUG_IF(!buffered_writes().empty())
+ << "All packets should have been written on a successful return";
+ return result;
+ }
+
+ private:
+ const clockid_t clockid_for_release_time_;
+ const bool supports_release_time_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_GSO_BATCH_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc
new file mode 100644
index 00000000000..c7d695ab4f5
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer_test.cc
@@ -0,0 +1,461 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_gso_batch_writer.h"
+
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <utility>
+
+#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_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::StrictMock;
+
+namespace quic {
+namespace test {
+namespace {
+
+size_t PacketLength(const msghdr* msg) {
+ size_t length = 0;
+ for (size_t i = 0; i < msg->msg_iovlen; ++i) {
+ length += msg->msg_iov[i].iov_len;
+ }
+ return length;
+}
+
+uint64_t MillisToNanos(uint64_t milliseconds) {
+ return milliseconds * 1000000;
+}
+
+class QUIC_EXPORT_PRIVATE TestQuicGsoBatchWriter : public QuicGsoBatchWriter {
+ public:
+ using QuicGsoBatchWriter::batch_buffer;
+ using QuicGsoBatchWriter::buffered_writes;
+ using QuicGsoBatchWriter::CanBatch;
+ using QuicGsoBatchWriter::CanBatchResult;
+ using QuicGsoBatchWriter::GetReleaseTime;
+ using QuicGsoBatchWriter::MaxSegments;
+ using QuicGsoBatchWriter::QuicGsoBatchWriter;
+
+ static std::unique_ptr<TestQuicGsoBatchWriter>
+ NewInstanceWithReleaseTimeSupport() {
+ return std::unique_ptr<TestQuicGsoBatchWriter>(new TestQuicGsoBatchWriter(
+ std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1, CLOCK_MONOTONIC, ReleaseTimeForceEnabler()));
+ }
+
+ uint64_t NowInNanosForReleaseTime() const override {
+ return MillisToNanos(forced_release_time_ms_);
+ }
+
+ void ForceReleaseTimeMs(uint64_t forced_release_time_ms) {
+ forced_release_time_ms_ = forced_release_time_ms;
+ }
+
+ private:
+ uint64_t forced_release_time_ms_ = 1;
+};
+
+struct QUIC_EXPORT_PRIVATE TestPerPacketOptions : public PerPacketOptions {
+ std::unique_ptr<quic::PerPacketOptions> Clone() const override {
+ return std::make_unique<TestPerPacketOptions>(*this);
+ }
+};
+
+// TestBufferedWrite is a copy-constructible BufferedWrite.
+struct QUIC_EXPORT_PRIVATE TestBufferedWrite : public BufferedWrite {
+ using BufferedWrite::BufferedWrite;
+ TestBufferedWrite(const TestBufferedWrite& other)
+ : BufferedWrite(other.buffer,
+ other.buf_len,
+ other.self_address,
+ other.peer_address,
+ other.options ? other.options->Clone()
+ : std::unique_ptr<PerPacketOptions>(),
+ other.release_time) {}
+};
+
+// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
+static char unused_packet_buffer[kMaxOutgoingPacketSize];
+
+struct QUIC_EXPORT_PRIVATE BatchCriteriaTestData {
+ BatchCriteriaTestData(size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ uint64_t release_time,
+ bool can_batch,
+ bool must_flush)
+ : buffered_write(unused_packet_buffer,
+ buf_len,
+ self_address,
+ peer_address,
+ std::unique_ptr<PerPacketOptions>(),
+ release_time),
+ can_batch(can_batch),
+ must_flush(must_flush) {}
+
+ TestBufferedWrite buffered_write;
+ // Expected value of CanBatchResult.can_batch when batching |buffered_write|.
+ bool can_batch;
+ // Expected value of CanBatchResult.must_flush when batching |buffered_write|.
+ bool must_flush;
+};
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeDecrease() {
+ const QuicIpAddress self_addr;
+ const QuicSocketAddress peer_addr;
+ std::vector<BatchCriteriaTestData> test_data_table = {
+ // clang-format off
+ // buf_len self_addr peer_addr t_rel can_batch must_flush
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {39, self_addr, peer_addr, 0, true, true},
+ {39, self_addr, peer_addr, 0, false, true},
+ {1350, self_addr, peer_addr, 0, false, true},
+ // clang-format on
+ };
+ return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_SizeIncrease() {
+ const QuicIpAddress self_addr;
+ const QuicSocketAddress peer_addr;
+ std::vector<BatchCriteriaTestData> test_data_table = {
+ // clang-format off
+ // buf_len self_addr peer_addr t_rel can_batch must_flush
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1351, self_addr, peer_addr, 0, false, true},
+ // clang-format on
+ };
+ return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_AddressChange() {
+ const QuicIpAddress self_addr1 = QuicIpAddress::Loopback4();
+ const QuicIpAddress self_addr2 = QuicIpAddress::Loopback6();
+ const QuicSocketAddress peer_addr1(self_addr1, 666);
+ const QuicSocketAddress peer_addr2(self_addr1, 777);
+ const QuicSocketAddress peer_addr3(self_addr2, 666);
+ const QuicSocketAddress peer_addr4(self_addr2, 777);
+ std::vector<BatchCriteriaTestData> test_data_table = {
+ // clang-format off
+ // buf_len self_addr peer_addr t_rel can_batch must_flush
+ {1350, self_addr1, peer_addr1, 0, true, false},
+ {1350, self_addr1, peer_addr1, 0, true, false},
+ {1350, self_addr1, peer_addr1, 0, true, false},
+ {1350, self_addr2, peer_addr1, 0, false, true},
+ {1350, self_addr1, peer_addr2, 0, false, true},
+ {1350, self_addr1, peer_addr3, 0, false, true},
+ {1350, self_addr1, peer_addr4, 0, false, true},
+ {1350, self_addr1, peer_addr4, 0, false, true},
+ // clang-format on
+ };
+ return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime1() {
+ const QuicIpAddress self_addr;
+ const QuicSocketAddress peer_addr;
+ std::vector<BatchCriteriaTestData> test_data_table = {
+ // clang-format off
+ // buf_len self_addr peer_addr t_rel can_batch must_flush
+ {1350, self_addr, peer_addr, 5, true, false},
+ {1350, self_addr, peer_addr, 5, true, false},
+ {1350, self_addr, peer_addr, 5, true, false},
+ {1350, self_addr, peer_addr, 9, false, true},
+ // clang-format on
+ };
+ return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_ReleaseTime2() {
+ const QuicIpAddress self_addr;
+ const QuicSocketAddress peer_addr;
+ std::vector<BatchCriteriaTestData> test_data_table = {
+ // clang-format off
+ // buf_len self_addr peer_addr t_rel can_batch must_flush
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 0, true, false},
+ {1350, self_addr, peer_addr, 9, false, true},
+ // clang-format on
+ };
+ return test_data_table;
+}
+
+std::vector<BatchCriteriaTestData> BatchCriteriaTestData_MaxSegments(
+ size_t gso_size) {
+ const QuicIpAddress self_addr;
+ const QuicSocketAddress peer_addr;
+ std::vector<BatchCriteriaTestData> test_data_table;
+ size_t max_segments = TestQuicGsoBatchWriter::MaxSegments(gso_size);
+ for (int i = 0; i < max_segments; ++i) {
+ bool is_last_in_batch = (i + 1 == max_segments);
+ test_data_table.push_back({gso_size, self_addr, peer_addr,
+ /*release_time=*/0, true, is_last_in_batch});
+ }
+ test_data_table.push_back(
+ {gso_size, self_addr, peer_addr, /*release_time=*/0, false, true});
+ return test_data_table;
+}
+
+class QuicGsoBatchWriterTest : public QuicTest {
+ protected:
+ WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
+ return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
+ peer_address_, nullptr);
+ }
+
+ WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
+ PerPacketOptions* options) {
+ return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
+ peer_address_, options);
+ }
+
+ QuicIpAddress self_address_ = QuicIpAddress::Any4();
+ QuicSocketAddress peer_address_{QuicIpAddress::Any4(), 443};
+ char packet_buffer_[1500];
+ StrictMock<MockQuicSyscallWrapper> mock_syscalls_;
+ ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+TEST_F(QuicGsoBatchWriterTest, BatchCriteria) {
+ std::unique_ptr<TestQuicGsoBatchWriter> writer;
+
+ std::vector<std::vector<BatchCriteriaTestData>> test_data_tables;
+ test_data_tables.emplace_back(BatchCriteriaTestData_SizeDecrease());
+ test_data_tables.emplace_back(BatchCriteriaTestData_SizeIncrease());
+ test_data_tables.emplace_back(BatchCriteriaTestData_AddressChange());
+ test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime1());
+ test_data_tables.emplace_back(BatchCriteriaTestData_ReleaseTime2());
+ test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1));
+ test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(2));
+ test_data_tables.emplace_back(BatchCriteriaTestData_MaxSegments(1350));
+
+ for (size_t i = 0; i < test_data_tables.size(); ++i) {
+ writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+ const auto& test_data_table = test_data_tables[i];
+ for (size_t j = 0; j < test_data_table.size(); ++j) {
+ const BatchCriteriaTestData& test_data = test_data_table[j];
+ SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
+ TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
+ test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
+ test_data.buffered_write.self_address,
+ test_data.buffered_write.peer_address,
+ /*options=*/nullptr, test_data.buffered_write.release_time);
+
+ ASSERT_EQ(test_data.can_batch, result.can_batch);
+ ASSERT_EQ(test_data.must_flush, result.must_flush);
+
+ if (result.can_batch) {
+ ASSERT_TRUE(
+ writer->batch_buffer()
+ .PushBufferedWrite(test_data.buffered_write.buffer,
+ test_data.buffered_write.buf_len,
+ test_data.buffered_write.self_address,
+ test_data.buffered_write.peer_address,
+ /*options=*/nullptr,
+ test_data.buffered_write.release_time)
+ .succeeded);
+ }
+ }
+ }
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteSuccess) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 1000));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(1100u, PacketLength(msg));
+ return 1100;
+ }));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 1100), WritePacket(&writer, 100));
+ ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataNotBuffered) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(200u, PacketLength(msg));
+ errno = EWOULDBLOCK;
+ return -1;
+ }));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+ WritePacket(&writer, 150));
+ ASSERT_EQ(200u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(2u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteBlockDataBuffered) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(250u, PacketLength(msg));
+ errno = EWOULDBLOCK;
+ return -1;
+ }));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_BLOCKED_DATA_BUFFERED, EWOULDBLOCK),
+ WritePacket(&writer, 50));
+ ASSERT_EQ(250u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(3u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorWithoutDataBuffered) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(200u, PacketLength(msg));
+ errno = EPERM;
+ return -1;
+ }));
+ WriteResult error_result = WritePacket(&writer, 150);
+ ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+ ASSERT_EQ(3u, error_result.dropped_packets);
+ ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, WriteErrorAfterDataBuffered) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(250u, PacketLength(msg));
+ errno = EPERM;
+ return -1;
+ }));
+ WriteResult error_result = WritePacket(&writer, 50);
+ ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM), error_result);
+
+ ASSERT_EQ(3u, error_result.dropped_packets);
+ ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, FlushError) {
+ TestQuicGsoBatchWriter writer(std::make_unique<QuicBatchWriterBuffer>(),
+ /*fd=*/-1);
+
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 0), WritePacket(&writer, 100));
+
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(200u, PacketLength(msg));
+ errno = EINVAL;
+ return -1;
+ }));
+ WriteResult error_result = writer.Flush();
+ ASSERT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL), error_result);
+
+ ASSERT_EQ(2u, error_result.dropped_packets);
+ ASSERT_EQ(0u, writer.batch_buffer().SizeInUse());
+ ASSERT_EQ(0u, writer.buffered_writes().size());
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
+ auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+ EXPECT_EQ(0, writer->GetReleaseTime(nullptr));
+}
+
+TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
+ const WriteResult write_buffered(WRITE_STATUS_OK, 0);
+
+ auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
+
+ TestPerPacketOptions options;
+ EXPECT_TRUE(options.release_time_delay.IsZero());
+ EXPECT_FALSE(options.allow_burst);
+ EXPECT_EQ(MillisToNanos(1), writer->GetReleaseTime(&options));
+
+ // The 1st packet has no delay.
+ ASSERT_EQ(write_buffered, WritePacketWithOptions(writer.get(), &options));
+ EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+
+ // The 2nd packet has some delay, but allows burst.
+ options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
+ options.allow_burst = true;
+ ASSERT_EQ(write_buffered, WritePacketWithOptions(writer.get(), &options));
+ EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
+
+ // The 3rd packet has more delay and does not allow burst.
+ // The first 2 packets are flushed due to different release time.
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(2700u, PacketLength(msg));
+ errno = 0;
+ return 0;
+ }));
+ options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
+ options.allow_burst = false;
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700),
+ WritePacketWithOptions(writer.get(), &options));
+ EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+
+ // The 4th packet has same delay, but allows burst.
+ options.allow_burst = true;
+ ASSERT_EQ(write_buffered, WritePacketWithOptions(writer.get(), &options));
+ EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+
+ // The 5th packet has same delay, allows burst, but is shorter.
+ // Packets 3,4 and 5 are flushed.
+ EXPECT_CALL(mock_syscalls_, Sendmsg(_, _, _))
+ .WillOnce(Invoke([](int sockfd, const msghdr* msg, int flags) {
+ EXPECT_EQ(3000u, PacketLength(msg));
+ errno = 0;
+ return 0;
+ }));
+ options.allow_burst = true;
+ EXPECT_EQ(MillisToNanos(6), writer->GetReleaseTime(&options));
+ ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
+ writer->WritePacket(&packet_buffer_[0], 300, self_address_,
+ peer_address_, &options));
+ EXPECT_TRUE(writer->buffered_writes().empty());
+
+ // Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
+ // words, the release time should still be the same as packets 3-5.
+ writer->ForceReleaseTimeMs(2);
+ options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
+ ASSERT_EQ(write_buffered, WritePacketWithOptions(writer.get(), &options));
+ EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
new file mode 100644
index 00000000000..efd21791c4d
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
@@ -0,0 +1,83 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+
+QuicSendmmsgBatchWriter::QuicSendmmsgBatchWriter(
+ std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd)
+ : QuicUdpBatchWriter(std::move(batch_buffer), fd) {}
+
+QuicSendmmsgBatchWriter::CanBatchResult QuicSendmmsgBatchWriter::CanBatch(
+ const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) const {
+ return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult QuicSendmmsgBatchWriter::FlushImpl() {
+ return InternalFlushImpl(
+ kCmsgSpaceForIp,
+ [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+ mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+ });
+}
+
+QuicSendmmsgBatchWriter::FlushImplResult
+QuicSendmmsgBatchWriter::InternalFlushImpl(size_t cmsg_space,
+ const CmsgBuilder& cmsg_builder) {
+ DCHECK(!IsWriteBlocked());
+ DCHECK(!buffered_writes().empty());
+
+ FlushImplResult result = {WriteResult(WRITE_STATUS_OK, 0),
+ /*num_packets_sent=*/0, /*bytes_written=*/0};
+ WriteResult& write_result = result.write_result;
+
+ auto first = buffered_writes().cbegin();
+ const auto last = buffered_writes().cend();
+ while (first != last) {
+ QuicMMsgHdr mhdr(first, last, cmsg_space, cmsg_builder);
+
+ int num_packets_sent;
+ write_result = QuicLinuxSocketUtils::WriteMultiplePackets(
+ fd(), &mhdr, &num_packets_sent);
+ QUIC_DVLOG(1) << "WriteMultiplePackets sent " << num_packets_sent
+ << " out of " << mhdr.num_msgs()
+ << " packets. WriteResult=" << write_result;
+
+ if (write_result.status != WRITE_STATUS_OK) {
+ DCHECK_EQ(0, num_packets_sent);
+ break;
+ } else if (num_packets_sent == 0) {
+ QUIC_BUG << "WriteMultiplePackets returned OK, but no packets were sent.";
+ write_result = WriteResult(WRITE_STATUS_ERROR, EIO);
+ break;
+ }
+
+ first += num_packets_sent;
+
+ result.num_packets_sent += num_packets_sent;
+ result.bytes_written += write_result.bytes_written;
+ }
+
+ // Call PopBufferedWrite() even if write_result.status is not WRITE_STATUS_OK,
+ // to deal with partial writes.
+ batch_buffer().PopBufferedWrite(result.num_packets_sent);
+
+ if (write_result.status != WRITE_STATUS_OK) {
+ return result;
+ }
+
+ QUIC_BUG_IF(!buffered_writes().empty())
+ << "All packets should have been written on a successful return";
+ write_result.bytes_written = result.bytes_written;
+ return result;
+}
+
+} // namespace quic
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
new file mode 100644
index 00000000000..26a728e676a
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
@@ -0,0 +1,35 @@
+// 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_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_base.h"
+#include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
+
+namespace quic {
+
+class QUIC_EXPORT_PRIVATE QuicSendmmsgBatchWriter : public QuicUdpBatchWriter {
+ public:
+ QuicSendmmsgBatchWriter(std::unique_ptr<QuicBatchWriterBuffer> batch_buffer,
+ int fd);
+
+ CanBatchResult CanBatch(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ const PerPacketOptions* options,
+ uint64_t release_time) const override;
+
+ FlushImplResult FlushImpl() override;
+
+ protected:
+ typedef QuicMMsgHdr::ControlBufferInitializer CmsgBuilder;
+ FlushImplResult InternalFlushImpl(size_t cmsg_space,
+ const CmsgBuilder& cmsg_builder);
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SENDMMSG_BATCH_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
new file mode 100644
index 00000000000..4dcc33c91d3
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer_test.cc
@@ -0,0 +1,15 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/batch_writer/quic_sendmmsg_batch_writer.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+// Add tests here.
+
+} // namespace
+} // namespace test
+} // namespace quic
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 b4907d4a020..1605b264c63 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
@@ -11,6 +11,7 @@
#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.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_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"
@@ -77,6 +78,7 @@ class ChloFramerVisitor : public QuicFramerVisitorInterface,
bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
bool OnMessageFrame(const QuicMessageFrame& frame) override;
bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& farme) override;
void OnPacketComplete() override {}
bool IsValidStatelessResetToken(QuicUint128 token) const override;
void OnAuthenticatedIetfStatelessResetPacket(
@@ -289,6 +291,11 @@ bool ChloFramerVisitor::OnHandshakeDoneFrame(
return true;
}
+bool ChloFramerVisitor::OnAckFrequencyFrame(
+ const QuicAckFrequencyFrame& /*frame*/) {
+ return true;
+}
+
bool ChloFramerVisitor::IsValidStatelessResetToken(
QuicUint128 /*token*/) const {
return false;
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc
index f885c94794c..6eacef38e2e 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler.cc
@@ -87,7 +87,7 @@ BandwidthSampler::BandwidthSampler(
total_bytes_sent_at_last_acked_packet_(0),
last_acked_packet_sent_time_(QuicTime::Zero()),
last_acked_packet_ack_time_(QuicTime::Zero()),
- is_app_limited_(started_as_app_limited_),
+ is_app_limited_(true),
connection_state_map_(),
max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
unacked_packet_map_(unacked_packet_map),
@@ -105,7 +105,6 @@ BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
last_sent_packet_(other.last_sent_packet_),
- started_as_app_limited_(other.started_as_app_limited_),
is_app_limited_(other.is_app_limited_),
end_of_app_limited_phase_(other.end_of_app_limited_phase_),
connection_state_map_(other.connection_state_map_),
@@ -321,23 +320,13 @@ BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
recent_ack_points_.Update(ack_time, total_bytes_acked_);
}
- if (started_as_app_limited_) {
- if (is_app_limited_) {
- // Exit app-limited phase in two cases:
- // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
- // packets are sent while there are buffered packets or pending data.
- // (2) The current acked packet is after the sent packet marked as the end
- // of the app limit phase.
- if (!end_of_app_limited_phase_.IsInitialized() ||
- packet_number > end_of_app_limited_phase_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_bw_sampler_app_limited_starting_value);
- is_app_limited_ = false;
- }
- }
- } else {
- // Exit app-limited phase once a packet that was sent while the connection
- // is not app-limited is acknowledged.
- if (is_app_limited_ && end_of_app_limited_phase_.IsInitialized() &&
+ if (is_app_limited_) {
+ // Exit app-limited phase in two cases:
+ // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
+ // packets are sent while there are buffered packets or pending data.
+ // (2) The current acked packet is after the sent packet marked as the end
+ // of the app limit phase.
+ if (!end_of_app_limited_phase_.IsInitialized() ||
packet_number > end_of_app_limited_phase_) {
is_app_limited_ = false;
}
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 b3c07364705..f32eabf0694 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
@@ -528,10 +528,6 @@ class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
// The most recently sent packet.
QuicPacketNumber last_sent_packet_;
- // Indicates whether the bandwidth sampler is started in app-limited phase.
- const bool started_as_app_limited_ =
- GetQuicReloadableFlag(quic_bw_sampler_app_limited_starting_value);
-
// Indicates whether the bandwidth sampler is currently in an app-limited
// phase.
bool is_app_limited_;
@@ -565,8 +561,7 @@ class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
MaxAckHeightTracker max_ack_height_tracker_;
QuicByteCount total_bytes_acked_after_last_ack_event_;
- // True if --quic_avoid_overestimate_bandwidth_with_aggregation=true and
- // connection option 'BSAO' is set.
+ // True if connection option 'BSAO' is set.
bool overestimate_avoidance_;
};
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc
index 5dda9986965..f689553bc5b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -34,8 +34,18 @@ const QuicByteCount kRegularPacketSize = 1280;
static_assert((kRegularPacketSize & 31) == 0,
"kRegularPacketSize has to be five times divisible by 2");
+struct TestParameters {
+ bool overestimate_avoidance;
+};
+
+// Used by ::testing::PrintToStringParamName().
+std::string PrintToString(const TestParameters& p) {
+ return p.overestimate_avoidance ? "enable_overestimate_avoidance"
+ : "no_enable_overestimate_avoidance";
+}
+
// A test fixture with utility methods for BandwidthSampler tests.
-class BandwidthSamplerTest : public QuicTest {
+class BandwidthSamplerTest : public QuicTestWithParam<TestParameters> {
protected:
BandwidthSamplerTest()
: sampler_(nullptr, /*max_height_tracker_window_length=*/0),
@@ -46,8 +56,7 @@ class BandwidthSamplerTest : public QuicTest {
round_trip_count_(0) {
// Ensure that the clock does not start at zero.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
+ if (GetParam().overestimate_avoidance) {
sampler_.EnableOverestimateAvoidance();
}
}
@@ -170,8 +179,15 @@ class BandwidthSamplerTest : public QuicTest {
}
};
+INSTANTIATE_TEST_SUITE_P(
+ BandwidthSamplerTests,
+ BandwidthSamplerTest,
+ testing::Values(TestParameters{/*overestimate_avoidance=*/false},
+ TestParameters{/*overestimate_avoidance=*/true}),
+ testing::PrintToStringParamName());
+
// Test the sampler in a simple stop-and-wait sender setting.
-TEST_F(BandwidthSamplerTest, SendAndWait) {
+TEST_P(BandwidthSamplerTest, SendAndWait) {
QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
QuicBandwidth expected_bandwidth =
QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
@@ -200,7 +216,7 @@ TEST_F(BandwidthSamplerTest, SendAndWait) {
EXPECT_EQ(0u, bytes_in_flight_);
}
-TEST_F(BandwidthSamplerTest, SendTimeState) {
+TEST_P(BandwidthSamplerTest, SendTimeState) {
QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
// Send packets 1-5.
@@ -266,7 +282,7 @@ TEST_F(BandwidthSamplerTest, SendTimeState) {
// Test the sampler during regular windowed sender scenario with fixed
// CWND of 20.
-TEST_F(BandwidthSamplerTest, SendPaced) {
+TEST_P(BandwidthSamplerTest, SendPaced) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -288,7 +304,7 @@ TEST_F(BandwidthSamplerTest, SendPaced) {
}
// Test the sampler in a scenario where 50% of packets is consistently lost.
-TEST_F(BandwidthSamplerTest, SendWithLosses) {
+TEST_P(BandwidthSamplerTest, SendWithLosses) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -333,7 +349,7 @@ TEST_F(BandwidthSamplerTest, SendWithLosses) {
// congestion controlled (specifically, non-retransmittable data is not
// congestion controlled). Should be functionally consistent in behavior with
// the SendWithLosses test.
-TEST_F(BandwidthSamplerTest, NotCongestionControlled) {
+TEST_P(BandwidthSamplerTest, NotCongestionControlled) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -382,7 +398,7 @@ TEST_F(BandwidthSamplerTest, NotCongestionControlled) {
// Simulate a situation where ACKs arrive in burst and earlier than usual, thus
// producing an ACK rate which is higher than the original send rate.
-TEST_F(BandwidthSamplerTest, CompressedAck) {
+TEST_P(BandwidthSamplerTest, CompressedAck) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -410,7 +426,7 @@ TEST_F(BandwidthSamplerTest, CompressedAck) {
}
// Tests receiving ACK packets in the reverse order.
-TEST_F(BandwidthSamplerTest, ReorderedAck) {
+TEST_P(BandwidthSamplerTest, ReorderedAck) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -441,7 +457,7 @@ TEST_F(BandwidthSamplerTest, ReorderedAck) {
}
// Test the app-limited logic.
-TEST_F(BandwidthSamplerTest, AppLimited) {
+TEST_P(BandwidthSamplerTest, AppLimited) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
QuicBandwidth expected_bandwidth =
@@ -508,7 +524,7 @@ TEST_F(BandwidthSamplerTest, AppLimited) {
}
// Test the samples taken at the first flight of packets sent.
-TEST_F(BandwidthSamplerTest, FirstRoundTrip) {
+TEST_P(BandwidthSamplerTest, FirstRoundTrip) {
const QuicTime::Delta time_between_packets =
QuicTime::Delta::FromMilliseconds(1);
const QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(800);
@@ -543,7 +559,7 @@ TEST_F(BandwidthSamplerTest, FirstRoundTrip) {
}
// Test sampler's ability to remove obsolete packets.
-TEST_F(BandwidthSamplerTest, RemoveObsoletePackets) {
+TEST_P(BandwidthSamplerTest, RemoveObsoletePackets) {
SendPacket(1);
SendPacket(2);
SendPacket(3);
@@ -566,7 +582,7 @@ TEST_F(BandwidthSamplerTest, RemoveObsoletePackets) {
EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
}
-TEST_F(BandwidthSamplerTest, NeuterPacket) {
+TEST_P(BandwidthSamplerTest, NeuterPacket) {
SendPacket(1);
EXPECT_EQ(0u, sampler_.total_bytes_neutered());
@@ -589,7 +605,7 @@ TEST_F(BandwidthSamplerTest, NeuterPacket) {
EXPECT_EQ(0u, sample.extra_acked);
}
-TEST_F(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
+TEST_P(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
// Make sure a default constructed CongestionEventSample has the correct
// initial values for BandwidthSampler::OnCongestionEvent() to work.
BandwidthSampler::CongestionEventSample sample;
@@ -602,7 +618,7 @@ TEST_F(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
}
// 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
-TEST_F(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
+TEST_P(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
kRegularPacketSize, time_between_packets);
@@ -631,7 +647,7 @@ TEST_F(BandwidthSamplerTest, TwoAckedPacketsPerEvent) {
}
}
-TEST_F(BandwidthSamplerTest, LoseEveryOtherPacket) {
+TEST_P(BandwidthSamplerTest, LoseEveryOtherPacket) {
QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
QuicBandwidth sending_rate = QuicBandwidth::FromBytesAndTimeDelta(
kRegularPacketSize, time_between_packets);
@@ -663,7 +679,7 @@ TEST_F(BandwidthSamplerTest, LoseEveryOtherPacket) {
}
}
-TEST_F(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
+TEST_P(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
QuicTime::Delta time_between_packets = QuicTime::Delta::FromMilliseconds(10);
QuicBandwidth first_packet_sending_rate =
QuicBandwidth::FromBytesAndTimeDelta(kRegularPacketSize,
@@ -693,10 +709,7 @@ TEST_F(BandwidthSamplerTest, AckHeightRespectBandwidthEstimateUpperBound) {
class MaxAckHeightTrackerTest : public QuicTest {
protected:
MaxAckHeightTrackerTest() : tracker_(/*initial_filter_window=*/10) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- tracker_.SetAckAggregationBandwidthThreshold(1.8);
- }
+ tracker_.SetAckAggregationBandwidthThreshold(1.8);
}
// Run a full aggregation episode, which is one or more aggregated acks,
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 90df9a0c0da..cdd0cb54c16 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
@@ -110,7 +110,7 @@ void Bbr2NetworkModel::OnCongestionEventStart(
// b) all packets in |acked_packets| did not generate valid samples. (e.g. ack
// of ack-only packets). In both cases, total_bytes_acked() will not change.
if (prior_bytes_acked != total_bytes_acked()) {
- QUIC_BUG_IF(sample.sample_max_bandwidth.IsZero())
+ QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
<< total_bytes_acked() - prior_bytes_acked << " bytes from "
<< acked_packets.size()
<< " packets have been acked, but sample_max_bandwidth is zero.";
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 e110a4c3297..ddef7722939 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
@@ -184,6 +184,9 @@ 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;
};
class QUIC_EXPORT_PRIVATE RoundTripCounter {
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 6fb7eee8059..f6a09388604 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
@@ -198,9 +198,9 @@ Bbr2ProbeBwMode::AdaptUpperBoundsResult Bbr2ProbeBwMode::MaybeAdaptUpperBounds(
cycle_.is_sample_from_probing = false;
if (!send_state.is_app_limited) {
- QuicByteCount inflight_at_send = BytesInFlight(send_state);
+ const QuicByteCount inflight_at_send = BytesInFlight(send_state);
- QuicByteCount inflight_target =
+ const QuicByteCount inflight_target =
sender_->GetTargetBytesInflight() * (1.0 - Params().beta);
if (inflight_at_send >= inflight_target) {
// The new code does not change behavior.
@@ -209,7 +209,20 @@ 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);
}
- model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+ 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);
+ } else {
+ // The new code actually cuts inflight_hi slower than before.
+ QUIC_CODE_COUNT(quic_bbr2_cut_inflight_hi_cwnd_in_effect);
+ }
+ model_->set_inflight_hi(std::max(inflight_at_send, cwnd_target));
+ } else {
+ model_->set_inflight_hi(std::max(inflight_at_send, inflight_target));
+ }
}
QUIC_DVLOG(3) << sender_ << " " << cycle_.phase
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 8c0171bc9bf..d1b3159f271 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
@@ -95,11 +95,7 @@ void Bbr2Sender::SetFromConfig(const QuicConfig& config,
if (config.HasClientRequestedIndependentOption(kBBR9, perspective)) {
params_.flexible_app_limited = true;
}
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation) &&
- config.HasClientRequestedIndependentOption(kBSAO, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_avoid_overestimate_bandwidth_with_aggregation, 4, 4);
+ if (config.HasClientRequestedIndependentOption(kBSAO, perspective)) {
model_.EnableOverestimateAvoidance();
}
if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
@@ -127,14 +123,18 @@ void Bbr2Sender::SetFromConfig(const QuicConfig& config,
QUIC_RELOADABLE_FLAG_COUNT(quic_bbr2_ignore_inflight_lo);
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;
+ }
ApplyConnectionOptions(config.ClientRequestedIndependentOptions(perspective));
}
void Bbr2Sender::ApplyConnectionOptions(
const QuicTagVector& connection_options) {
- if (GetQuicReloadableFlag(quic_bbr2_lower_startup_cwnd_gain) &&
- ContainsQuicTag(connection_options, kBBQ2)) {
+ if (ContainsQuicTag(connection_options, kBBQ2)) {
// 2 is the lower, derived gain for CWND.
params_.startup_cwnd_gain = 2;
params_.drain_cwnd_gain = 2;
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 f803ab68cdf..205d3563f90 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
@@ -427,10 +427,7 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
}
TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
DefaultTopologyParams params;
CreateNetwork(params);
// 2 RTTs of aggregation, with a max of 10kb.
@@ -440,17 +437,9 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- } else {
- EXPECT_LE(params.BottleneckBandwidth() * 0.99f,
- sender_->ExportDebugState().bandwidth_hi);
- // TODO(b/36022633): Bandwidth sampler overestimates with aggregation.
- EXPECT_GE(params.BottleneckBandwidth() * 1.5f,
- sender_->ExportDebugState().bandwidth_hi);
- }
+ 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.
@@ -459,10 +448,7 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
}
TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
// Enable Ack Decimation on the receiver.
QuicConnectionPeer::SetAckMode(receiver_endpoint_.connection(),
AckMode::ACK_DECIMATION);
@@ -473,17 +459,9 @@ TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
- sender_->ExportDebugState().bandwidth_hi, 0.01f);
- } else {
- EXPECT_LE(params.BottleneckBandwidth() * 0.99f,
- sender_->ExportDebugState().bandwidth_hi);
- // TODO(b/36022633): Bandwidth sampler overestimates with aggregation.
- EXPECT_GE(params.BottleneckBandwidth() * 1.1f,
- sender_->ExportDebugState().bandwidth_hi);
- }
+ EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
+ sender_->ExportDebugState().bandwidth_hi, 0.01f);
+
EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
// The margin here is high, because the aggregation greatly increases
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 f150ec14787..6c6f3efd2ad 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
@@ -32,10 +32,6 @@ const float kDefaultHighGain = 2.885f;
const float kDerivedHighGain = 2.773f;
// The newly derived CWND gain for STARTUP, 2.
const float kDerivedHighCWNDGain = 2.0f;
-// The gain used in STARTUP after loss has been detected.
-// 1.5 is enough to allow for 25% exogenous loss and still observe a 25% growth
-// in measured bandwidth.
-const float kStartupAfterLossGain = 1.5f;
// The cycle of gains used during the PROBE_BW stage.
const float kPacingGain[] = {1.25, 0.75, 1, 1, 1, 1, 1, 1};
@@ -106,8 +102,6 @@ BbrSender::BbrSender(QuicTime now,
congestion_window_gain_constant_(
static_cast<float>(GetQuicFlag(FLAGS_quic_bbr_cwnd_gain))),
num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
- exit_startup_on_loss_(
- GetQuicReloadableFlag(quic_bbr_default_exit_startup_on_loss)),
cycle_current_offset_(0),
last_cycle_start_(QuicTime::Zero()),
is_at_full_bandwidth_(false),
@@ -138,10 +132,7 @@ BbrSender::BbrSender(QuicTime now,
stats_->slowstart_duration = QuicTimeAccumulator();
}
EnterStartupMode(now);
- if (exit_startup_on_loss_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_bbr_default_exit_startup_on_loss);
- set_high_cwnd_gain(kDerivedHighCWNDGain);
- }
+ set_high_cwnd_gain(kDerivedHighCWNDGain);
}
BbrSender::~BbrSender() {}
@@ -203,14 +194,8 @@ QuicByteCount BbrSender::GetCongestionWindow() const {
return ProbeRttCongestionWindow();
}
- if (exit_startup_on_loss_) {
- if (InRecovery()) {
- return std::min(congestion_window_, recovery_window_);
- }
- } else {
- if (InRecovery() && !(rate_based_startup_ && mode_ == STARTUP)) {
- return std::min(congestion_window_, recovery_window_);
- }
+ if (InRecovery()) {
+ return std::min(congestion_window_, recovery_window_);
}
return congestion_window_;
@@ -265,17 +250,9 @@ void BbrSender::SetFromConfig(const QuicConfig& config,
if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
num_startup_rtts_ = 2;
}
- if (!exit_startup_on_loss_ &&
- config.HasClientRequestedIndependentOption(kBBRS, perspective)) {
- slower_startup_ = true;
- }
if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
drain_to_target_ = true;
}
- if (!exit_startup_on_loss_ &&
- config.HasClientRequestedIndependentOption(kBBS1, perspective)) {
- rate_based_startup_ = true;
- }
if (GetQuicReloadableFlag(quic_bbr_mitigate_overly_large_bandwidth_sample)) {
if (config.HasClientRequestedIndependentOption(kBWM3, perspective)) {
bytes_lost_multiplier_with_network_parameters_adjusted_ = 3;
@@ -313,11 +290,7 @@ void BbrSender::SetFromConfig(const QuicConfig& config,
max_congestion_window_with_network_parameters_adjusted_ =
100 * kDefaultTCPMSS;
}
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation) &&
- config.HasClientRequestedIndependentOption(kBSAO, perspective)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_avoid_overestimate_bandwidth_with_aggregation, 3, 4);
+ if (config.HasClientRequestedIndependentOption(kBSAO, perspective)) {
sampler_.EnableOverestimateAvoidance();
}
@@ -325,14 +298,7 @@ void BbrSender::SetFromConfig(const QuicConfig& config,
}
void BbrSender::ApplyConnectionOptions(
- const QuicTagVector& connection_options) {
- if (ContainsQuicTag(connection_options, kLRTT)) {
- exit_startup_on_loss_ = true;
- }
- if (ContainsQuicTag(connection_options, kBBQ2)) {
- set_high_cwnd_gain(kDerivedHighCWNDGain);
- }
-}
+ const QuicTagVector& /*connection_options*/) {}
void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
const QuicBandwidth& bandwidth = params.bandwidth;
@@ -352,12 +318,16 @@ void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
// Ignore bad bandwidth samples.
return;
}
+
+ auto cwnd_bootstrapping_rtt = params.quic_bbr_donot_inject_bandwidth
+ ? GetMinRtt()
+ : rtt_stats_->SmoothedOrInitialRtt();
const QuicByteCount new_cwnd = std::max(
kMinInitialCongestionWindow * kDefaultTCPMSS,
std::min(max_congestion_window_with_network_parameters_adjusted_,
- bandwidth * (params.quic_bbr_donot_inject_bandwidth
- ? GetMinRtt()
- : rtt_stats_->SmoothedOrInitialRtt())));
+ bandwidth * cwnd_bootstrapping_rtt));
+
+ stats_->cwnd_bootstrapping_rtt_us = cwnd_bootstrapping_rtt.ToMicroseconds();
if (!rtt_stats_->smoothed_rtt().IsZero()) {
QUIC_CODE_COUNT(quic_smoothed_rtt_available);
} else if (rtt_stats_->initial_rtt() !=
@@ -434,7 +404,7 @@ void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
// ack-only packets). In both cases, sampler_.total_bytes_acked() will not
// change.
if (total_bytes_acked_before != sampler_.total_bytes_acked()) {
- QUIC_BUG_IF(sample.sample_max_bandwidth.IsZero())
+ QUIC_LOG_IF(WARNING, sample.sample_max_bandwidth.IsZero())
<< sampler_.total_bytes_acked() - total_bytes_acked_before
<< " bytes from " << acked_packets.size()
<< " packets have been acked, but sample_max_bandwidth is zero.";
@@ -502,13 +472,10 @@ QuicTime::Delta BbrSender::GetMinRtt() const {
if (!min_rtt_.IsZero()) {
return min_rtt_;
}
- if (GetQuicReloadableFlag(quic_bbr_use_available_min_rtt)) {
- // min_rtt could be available if the handshake packet gets neutered then
- // gets acknowledged. This could only happen for QUIC crypto where we do not
- // drop keys.
- return rtt_stats_->MinOrInitialRtt();
- }
- return rtt_stats_->initial_rtt();
+ // min_rtt could be available if the handshake packet gets neutered then
+ // gets acknowledged. This could only happen for QUIC crypto where we do not
+ // drop keys.
+ return rtt_stats_->MinOrInitialRtt();
}
QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
@@ -675,10 +642,6 @@ void BbrSender::OnExitStartup(QuicTime now) {
bool BbrSender::ShouldExitStartupDueToLoss(
const SendTimeState& last_packet_send_state) const {
- if (!exit_startup_on_loss_) {
- return false;
- }
-
if (num_loss_events_in_round_ <
GetQuicFlag(FLAGS_quic_bbr2_default_startup_full_loss_count) ||
!last_packet_send_state.is_valid) {
@@ -749,7 +712,7 @@ void BbrSender::UpdateRecoveryState(QuicPacketNumber last_acked_packet,
bool has_losses,
bool is_round_start) {
// Disable recovery in startup, if loss-based exit is enabled.
- if (exit_startup_on_loss_ && !is_at_full_bandwidth_) {
+ if (!is_at_full_bandwidth_) {
return;
}
@@ -843,16 +806,6 @@ void BbrSender::CalculatePacingRate(QuicByteCount bytes_lost) {
}
}
- if (!exit_startup_on_loss_) {
- // Slow the pacing rate in STARTUP once loss has ever been detected.
- const bool has_ever_detected_loss = end_recovery_at_.IsInitialized();
- if (slower_startup_ && has_ever_detected_loss &&
- has_non_app_limited_sample_) {
- pacing_rate_ = kStartupAfterLossGain * BandwidthEstimate();
- return;
- }
- }
-
// Do not decrease the pacing rate during startup.
pacing_rate_ = std::max(pacing_rate_, target_rate);
}
@@ -898,10 +851,6 @@ void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked,
void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
QuicByteCount bytes_lost) {
- if (!exit_startup_on_loss_ && rate_based_startup_ && mode_ == STARTUP) {
- return;
- }
-
if (recovery_state_ == NOT_IN_RECOVERY) {
return;
}
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 c7285d76f24..446f0ddff8d 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
@@ -326,13 +326,6 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
// The number of RTTs to stay in STARTUP mode. Defaults to 3.
QuicRoundTripCount num_startup_rtts_;
- // Latched value of --quic_bbr_default_exit_startup_on_loss.
- // If true, exit startup if all of the following conditions are met:
- // - 1RTT has passed with no bandwidth increase,
- // - Some number of congestion events happened with loss, in the last round.
- // - Some amount of inflight bytes (at the start of the last round) are lost.
- bool exit_startup_on_loss_;
-
// Number of round-trips in PROBE_BW mode, used for determining the current
// pacing gain cycle.
int cycle_current_offset_;
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 e50a7c04c61..88559185087 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
@@ -115,6 +115,9 @@ class BbrSenderTest : public QuicTest {
}
void SetUp() override {
+ SetQuicReloadableFlag(quic_fix_bbr_cwnd_in_bandwidth_resumption, true);
+ SetQuicReloadableFlag(quic_bbr_fix_pacing_rate, true);
+ SetQuicReloadableFlag(quic_bbr_donot_inject_bandwidth, true);
if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
SendAlgorithmTestResult expected;
ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
@@ -389,10 +392,7 @@ TEST_F(BbrSenderTest, RemoveBytesLostInRecovery) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
CreateDefaultSetup();
// 2 RTTs of aggregation, with a max of 10kb.
EnableAggregation(10 * 1024, 2 * kTestRtt);
@@ -401,20 +401,10 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- } else {
- // It's possible to read a bandwidth as much as 50% too high with
- // aggregation.
- EXPECT_LE(kTestLinkBandwidth * 0.93f,
- sender_->ExportDebugState().max_bandwidth);
- // TODO(ianswett): Tighten this bound once we understand why BBR is
- // overestimating bandwidth with aggregation. b/36022633
- EXPECT_GE(kTestLinkBandwidth * 1.5f,
- sender_->ExportDebugState().max_bandwidth);
- }
+
+ EXPECT_APPROX_EQ(kTestLinkBandwidth,
+ sender_->ExportDebugState().max_bandwidth, 0.01f);
+
// The margin here is high, because the aggregation greatly increases
// smoothed rtt.
EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt());
@@ -423,10 +413,7 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
// Decrease the CWND gain so extra CWND is required with stretch acks.
SetQuicFlag(FLAGS_quic_bbr_cwnd_gain, 1.0);
sender_ = new BbrSender(
@@ -446,20 +433,9 @@ TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- } else {
- // It's possible to read a bandwidth as much as 50% too high with
- // aggregation.
- EXPECT_LE(kTestLinkBandwidth * 0.93f,
- sender_->ExportDebugState().max_bandwidth);
- // TODO(ianswett): Tighten this bound once we understand why BBR is
- // overestimating bandwidth with aggregation. b/36022633
- EXPECT_GE(kTestLinkBandwidth * 1.5f,
- sender_->ExportDebugState().max_bandwidth);
- }
+ EXPECT_APPROX_EQ(kTestLinkBandwidth,
+ sender_->ExportDebugState().max_bandwidth, 0.01f);
+
// TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
// bandwidth higher than the link rate.
EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
@@ -471,10 +447,7 @@ TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
// Disable Ack Decimation on the receiver, because it can increase srtt.
QuicConnectionPeer::SetAckMode(receiver_.connection(), AckMode::TCP_ACKING);
CreateDefaultSetup();
@@ -486,20 +459,10 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- } else {
- // It's possible to read a bandwidth as much as 50% too high with
- // aggregation.
- EXPECT_LE(kTestLinkBandwidth * 0.93f,
- sender_->ExportDebugState().max_bandwidth);
- // TODO(ianswett): Tighten this bound once we understand why BBR is
- // overestimating bandwidth with aggregation. b/36022633
- EXPECT_GE(kTestLinkBandwidth * 1.5f,
- sender_->ExportDebugState().max_bandwidth);
- }
+
+ EXPECT_APPROX_EQ(kTestLinkBandwidth,
+ sender_->ExportDebugState().max_bandwidth, 0.01f);
+
// TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
// bandwidth higher than the link rate.
// The margin here is high, because the aggregation greatly increases
@@ -510,10 +473,7 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- SetConnectionOption(kBSAO);
- }
+ SetConnectionOption(kBSAO);
// Disable Ack Decimation on the receiver, because it can increase srtt.
QuicConnectionPeer::SetAckMode(receiver_.connection(), AckMode::TCP_ACKING);
CreateDefaultSetup();
@@ -525,20 +485,10 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
EXPECT_TRUE(sender_->ExportDebugState().mode == BbrSender::PROBE_BW ||
sender_->ExportDebugState().mode == BbrSender::PROBE_RTT);
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_APPROX_EQ(kTestLinkBandwidth,
- sender_->ExportDebugState().max_bandwidth, 0.01f);
- } else {
- // It's possible to read a bandwidth as much as 50% too high with
- // aggregation.
- EXPECT_LE(kTestLinkBandwidth * 0.93f,
- sender_->ExportDebugState().max_bandwidth);
- // TODO(ianswett): Tighten this bound once we understand why BBR is
- // overestimating bandwidth with aggregation. b/36022633
- EXPECT_GE(kTestLinkBandwidth * 1.5f,
- sender_->ExportDebugState().max_bandwidth);
- }
+
+ EXPECT_APPROX_EQ(kTestLinkBandwidth,
+ sender_->ExportDebugState().max_bandwidth, 0.01f);
+
// TODO(ianswett): Expect 0 packets are lost once BBR no longer measures
// bandwidth higher than the link rate.
// The margin here is high, because the aggregation greatly increases
@@ -667,17 +617,10 @@ TEST_F(BbrSenderTest, Drain) {
EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
sender_->PacingRate(0), 0.01f);
- if (!GetQuicReloadableFlag(quic_bbr_default_exit_startup_on_loss)) {
- // 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 * kTestBdp);
- } else {
- // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
- // with approximately 1 BDP. Here, we use 0.8 to give some margin for
- // error.
- EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
- }
+ // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer
+ // with approximately 1 BDP. Here, we use 0.8 to give some margin for
+ // error.
+ EXPECT_GE(queue->bytes_queued(), 0.8 * kTestBdp);
// Observe increased RTT due to bufferbloat.
const QuicTime::Delta queueing_delay =
@@ -935,9 +878,6 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
CreateDefaultSetup();
- if (!GetQuicReloadableFlag(quic_bbr_default_exit_startup_on_loss)) {
- SetConnectionOption(kLRTT);
- }
EXPECT_EQ(3u, sender_->num_startup_rtts());
// Run until the full bandwidth is reached and check how many rounds it was.
@@ -965,9 +905,6 @@ TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLoss) {
TEST_F(BbrSenderTest, SimpleTransferExitStartupOnLossSmallBuffer) {
CreateSmallBufferSetup();
- if (!GetQuicReloadableFlag(quic_bbr_default_exit_startup_on_loss)) {
- SetConnectionOption(kLRTT);
- }
EXPECT_EQ(3u, sender_->num_startup_rtts());
// Run until the full bandwidth is reached and check how many rounds it was.
@@ -1021,9 +958,6 @@ TEST_F(BbrSenderTest, DerivedPacingGainStartup) {
TEST_F(BbrSenderTest, DerivedCWNDGainStartup) {
CreateSmallBufferSetup();
- if (!GetQuicReloadableFlag(quic_bbr_default_exit_startup_on_loss)) {
- SetConnectionOption(kBBQ2);
- }
EXPECT_EQ(3u, sender_->num_startup_rtts());
// Verify that Sender is in slow start.
EXPECT_TRUE(sender_->InSlowStart());
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc
index f00045e7b8e..666e7ea7c5a 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.cc
@@ -12,6 +12,20 @@
namespace quic {
+namespace {
+float DetectionResponseTime(QuicTime::Delta rtt,
+ QuicTime send_time,
+ QuicTime detection_time) {
+ if (detection_time <= send_time || rtt.IsZero()) {
+ // Time skewed, assume a very fast detection where |detection_time| is
+ // |send_time| + |rtt|.
+ return 1.0;
+ }
+ float send_to_detection_us = (detection_time - send_time).ToMicroseconds();
+ return send_to_detection_us / rtt.ToMicroseconds();
+}
+} // namespace
+
GeneralLossAlgorithm::GeneralLossAlgorithm()
: loss_detection_timeout_(QuicTime::Zero()),
reordering_shift_(kDefaultLossDelayShift),
@@ -56,7 +70,7 @@ LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
QuicTime::Delta max_rtt =
std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
max_rtt = std::max(kAlarmGranularity, max_rtt);
- QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
+ const QuicTime::Delta loss_delay = max_rtt + (max_rtt >> reordering_shift_);
QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
auto it = unacked_packets.begin();
if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
@@ -100,12 +114,18 @@ LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
if (!skip_packet_threshold_detection &&
largest_newly_acked - packet_number >= reordering_threshold_) {
packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+ detection_stats.total_loss_detection_response_time +=
+ DetectionResponseTime(max_rtt, it->sent_time, time);
continue;
}
// Time threshold loss detection.
QuicTime when_lost = it->sent_time + loss_delay;
if (time < when_lost) {
+ if (time >=
+ it->sent_time + max_rtt + (max_rtt >> (reordering_shift_ + 1))) {
+ ++detection_stats.sent_packets_num_borderline_time_reorderings;
+ }
loss_detection_timeout_ = when_lost;
if (!least_in_flight_.IsInitialized()) {
// At this point, packet_number is in flight and not detected as lost.
@@ -114,6 +134,8 @@ LossDetectionInterface::DetectionStats GeneralLossAlgorithm::DetectLosses(
break;
}
packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
+ detection_stats.total_loss_detection_response_time +=
+ DetectionResponseTime(max_rtt, it->sent_time, time);
}
if (!least_in_flight_.IsInitialized()) {
// There is no in flight packet.
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h
index ee8ba64c2d7..950831e4594 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h
@@ -58,6 +58,11 @@ class QUIC_EXPORT_PRIVATE GeneralLossAlgorithm : public LossDetectionInterface {
<< "Unexpected call to GeneralLossAlgorithm::OnMinRttAvailable";
}
+ void OnUserAgentIdKnown() override {
+ DCHECK(false)
+ << "Unexpected call to GeneralLossAlgorithm::OnUserAgentIdKnown";
+ }
+
void OnConnectionClosed() override {
DCHECK(false)
<< "Unexpected call to GeneralLossAlgorithm::OnConnectionClosed";
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 1a58ade2695..be33c25857c 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,14 +62,17 @@ 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>());
}
- 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,
+ quiche::QuicheOptional<QuicPacketCount> max_sequence_reordering_expected,
+ quiche::QuicheOptional<QuicPacketCount>
+ num_borderline_time_reorderings_expected) {
unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
LostPacketVector lost_packets;
@@ -80,6 +83,10 @@ class GeneralLossAlgorithmTest : public QuicTest {
EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
max_sequence_reordering_expected.value());
}
+ if (num_borderline_time_reorderings_expected.has_value()) {
+ EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
+ num_borderline_time_reorderings_expected.value());
+ }
ASSERT_EQ(losses_expected.size(), lost_packets.size());
for (size_t i = 0; i < losses_expected.size(); ++i) {
EXPECT_EQ(lost_packets[i].packet_number,
@@ -104,19 +111,19 @@ TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
packets_acked.push_back(AckedPacket(
QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1);
+ VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
packets_acked.clear();
// No loss on two acks.
unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
packets_acked.push_back(AckedPacket(
QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2);
+ VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
packets_acked.clear();
// Loss on three acks.
unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
packets_acked.push_back(AckedPacket(
QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
- VerifyLosses(4, packets_acked, {1}, 3);
+ VerifyLosses(4, packets_acked, {1}, 3, 0);
EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
}
@@ -176,7 +183,12 @@ TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
loss_algorithm_.GetLossTimeout());
- clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
+ clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
+ // If reordering_shift increases by one we should have detected a loss.
+ VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
+ /*num_borderline_time_reorderings_expected=*/1);
+
+ clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
VerifyLosses(2, packets_acked, {1});
EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h b/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h
index 8d91976de45..6799de97ae5 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h
@@ -29,6 +29,10 @@ class QUIC_EXPORT_PRIVATE LossDetectionInterface {
struct QUIC_NO_EXPORT DetectionStats {
// Maximum sequence reordering observed in newly acked packets.
QuicPacketCount sent_packets_max_sequence_reordering = 0;
+ QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
+ // Total detection response time for lost packets from this detection.
+ // See QuicConnectionStats for the definition of detection response time.
+ float total_loss_detection_response_time = 0.0;
};
// Called when a new ack arrives or the loss alarm fires.
@@ -56,6 +60,8 @@ class QUIC_EXPORT_PRIVATE LossDetectionInterface {
virtual void OnMinRttAvailable() = 0;
+ virtual void OnUserAgentIdKnown() = 0;
+
virtual void OnConnectionClosed() = 0;
};
diff --git a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc
index 0f294d6b94e..5debad62c6b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.cc
@@ -54,6 +54,10 @@ LossDetectionInterface::DetectionStats UberLossAlgorithm::DetectLosses(
overall_stats.sent_packets_max_sequence_reordering =
std::max(overall_stats.sent_packets_max_sequence_reordering,
stats.sent_packets_max_sequence_reordering);
+ overall_stats.sent_packets_num_borderline_time_reorderings +=
+ stats.sent_packets_num_borderline_time_reorderings;
+ overall_stats.total_loss_detection_response_time +=
+ stats.total_loss_detection_response_time;
}
return overall_stats;
@@ -96,11 +100,27 @@ void UberLossAlgorithm::SetLossDetectionTuner(
}
void UberLossAlgorithm::MaybeStartTuning() {
- if (tuner_started_ || !tuning_enabled_ || !min_rtt_available_) {
+ if (tuner_started_ || !tuning_enabled_ || !min_rtt_available_ ||
+ !user_agent_known_) {
return;
}
tuner_started_ = tuner_->Start(&tuned_parameters_);
+ if (!tuner_started_) {
+ return;
+ }
+
+ if (tuned_parameters_.reordering_shift.has_value() &&
+ tuned_parameters_.reordering_threshold.has_value()) {
+ QUIC_DLOG(INFO) << "Setting reordering shift to "
+ << *tuned_parameters_.reordering_shift
+ << ", and reordering threshold to "
+ << *tuned_parameters_.reordering_threshold;
+ SetReorderingShift(*tuned_parameters_.reordering_shift);
+ SetReorderingThreshold(*tuned_parameters_.reordering_threshold);
+ } else {
+ QUIC_BUG << "Tuner started but some parameters are missing";
+ }
}
void UberLossAlgorithm::OnConfigNegotiated() {}
@@ -110,6 +130,11 @@ void UberLossAlgorithm::OnMinRttAvailable() {
MaybeStartTuning();
}
+void UberLossAlgorithm::OnUserAgentIdKnown() {
+ user_agent_known_ = true;
+ MaybeStartTuning();
+}
+
void UberLossAlgorithm::OnConnectionClosed() {
if (tuner_ != nullptr && tuner_started_) {
tuner_->Finish(tuned_parameters_);
@@ -151,6 +176,10 @@ QuicPacketCount UberLossAlgorithm::GetPacketReorderingThreshold() const {
return general_loss_algorithms_[APPLICATION_DATA].reordering_threshold();
}
+int UberLossAlgorithm::GetPacketReorderingShift() const {
+ return general_loss_algorithms_[APPLICATION_DATA].reordering_shift();
+}
+
void UberLossAlgorithm::DisablePacketThresholdForRuntPackets() {
for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
general_loss_algorithms_[i].disable_packet_threshold_for_runt_packets();
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 86b652572b7..0d1453c07b3 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
@@ -7,6 +7,7 @@
#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 {
@@ -72,6 +73,7 @@ class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
std::unique_ptr<LossDetectionTunerInterface> tuner);
void OnConfigNegotiated() override;
void OnMinRttAvailable() override;
+ void OnUserAgentIdKnown() override;
void OnConnectionClosed() override;
// Sets reordering_shift for all packet number spaces.
@@ -93,12 +95,25 @@ class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
// Always 3 when adaptive reordering is not enabled.
QuicPacketCount GetPacketReorderingThreshold() const;
+ // Get the packet reordering shift from the APPLICATION_DATA PN space.
+ int GetPacketReorderingShift() const;
+
// Disable packet threshold loss detection for *runt* packets.
void DisablePacketThresholdForRuntPackets();
// Called to reset loss detection of |space|.
void ResetLossDetection(PacketNumberSpace space);
+ bool use_adaptive_reordering_threshold() const {
+ return general_loss_algorithms_[APPLICATION_DATA]
+ .use_adaptive_reordering_threshold();
+ }
+
+ bool use_adaptive_time_threshold() const {
+ return general_loss_algorithms_[APPLICATION_DATA]
+ .use_adaptive_time_threshold();
+ }
+
private:
friend class test::QuicSentPacketManagerPeer;
@@ -112,6 +127,10 @@ class QUIC_EXPORT_PRIVATE UberLossAlgorithm : public LossDetectionInterface {
LossDetectionParameters tuned_parameters_;
bool tuner_started_ = false;
bool min_rtt_available_ = false;
+ // If flag is false, set |user_agent_known_| to true, so loss detection tuner
+ // will start once SetFromConfig is called and min rtt is available.
+ bool user_agent_known_ =
+ !GetQuicReloadableFlag(quic_save_user_agent_in_quic_session);
bool tuning_enabled_ = false; // Whether tuning is enabled by config.
};
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 6fd949f317a..e6635402d68 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
@@ -4,9 +4,12 @@
#include "net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h"
+#include <memory>
#include <utility>
#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"
#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"
@@ -204,6 +207,143 @@ TEST_F(UberLossAlgorithmTest, PacketInLimbo) {
VerifyLosses(6, packets_acked_, std::vector<uint64_t>{2});
}
+class TestLossTuner : public LossDetectionTunerInterface {
+ public:
+ TestLossTuner(bool forced_start_result,
+ LossDetectionParameters forced_parameters)
+ : forced_start_result_(forced_start_result),
+ forced_parameters_(std::move(forced_parameters)) {}
+
+ ~TestLossTuner() override = default;
+
+ bool Start(LossDetectionParameters* params) override {
+ start_called_ = true;
+ *params = forced_parameters_;
+ return forced_start_result_;
+ }
+
+ void Finish(const LossDetectionParameters& /*params*/) override {}
+
+ bool start_called() const { return start_called_; }
+
+ private:
+ bool forced_start_result_;
+ LossDetectionParameters forced_parameters_;
+ bool start_called_ = false;
+};
+
+// Verify the parameters are changed if first call SetFromConfig(), then call
+// OnMinRttAvailable().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_SetFromConfigFirst) {
+ const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+ const QuicPacketCount old_reordering_threshold =
+ loss_algorithm_.GetPacketReorderingThreshold();
+
+ loss_algorithm_.OnUserAgentIdKnown();
+
+ // Not owned.
+ TestLossTuner* test_tuner = new TestLossTuner(
+ /*forced_start_result=*/true,
+ LossDetectionParameters{
+ /*reordering_shift=*/old_reordering_shift + 1,
+ /*reordering_threshold=*/old_reordering_threshold * 2});
+ loss_algorithm_.SetLossDetectionTuner(
+ std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kELDT);
+ config.SetInitialReceivedConnectionOptions(connection_options);
+ loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+ // MinRtt was not available when SetFromConfig was called.
+ EXPECT_FALSE(test_tuner->start_called());
+ EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_EQ(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+
+ // Tuning should start when MinRtt becomes available.
+ loss_algorithm_.OnMinRttAvailable();
+ EXPECT_TRUE(test_tuner->start_called());
+ EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_NE(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are changed if first call OnMinRttAvailable(), then
+// call SetFromConfig().
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_OnMinRttAvailableFirst) {
+ const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+ const QuicPacketCount old_reordering_threshold =
+ loss_algorithm_.GetPacketReorderingThreshold();
+
+ loss_algorithm_.OnUserAgentIdKnown();
+
+ // Not owned.
+ TestLossTuner* test_tuner = new TestLossTuner(
+ /*forced_start_result=*/true,
+ LossDetectionParameters{
+ /*reordering_shift=*/old_reordering_shift + 1,
+ /*reordering_threshold=*/old_reordering_threshold * 2});
+ loss_algorithm_.SetLossDetectionTuner(
+ std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+ loss_algorithm_.OnMinRttAvailable();
+ EXPECT_FALSE(test_tuner->start_called());
+ EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_EQ(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kELDT);
+ config.SetInitialReceivedConnectionOptions(connection_options);
+ // Should start tuning since MinRtt is available.
+ loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+ EXPECT_TRUE(test_tuner->start_called());
+ EXPECT_NE(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_NE(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+}
+
+// Verify the parameters are not changed if Tuner.Start() returns false.
+TEST_F(UberLossAlgorithmTest, LossDetectionTuning_StartFailed) {
+ const int old_reordering_shift = loss_algorithm_.GetPacketReorderingShift();
+ const QuicPacketCount old_reordering_threshold =
+ loss_algorithm_.GetPacketReorderingThreshold();
+
+ loss_algorithm_.OnUserAgentIdKnown();
+
+ // Not owned.
+ TestLossTuner* test_tuner = new TestLossTuner(
+ /*forced_start_result=*/false,
+ LossDetectionParameters{
+ /*reordering_shift=*/old_reordering_shift + 1,
+ /*reordering_threshold=*/old_reordering_threshold * 2});
+ loss_algorithm_.SetLossDetectionTuner(
+ std::unique_ptr<LossDetectionTunerInterface>(test_tuner));
+
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kELDT);
+ config.SetInitialReceivedConnectionOptions(connection_options);
+ loss_algorithm_.SetFromConfig(config, Perspective::IS_SERVER);
+
+ // MinRtt was not available when SetFromConfig was called.
+ EXPECT_FALSE(test_tuner->start_called());
+ EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_EQ(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+
+ // Parameters should not change since test_tuner->Start() returns false.
+ loss_algorithm_.OnMinRttAvailable();
+ EXPECT_TRUE(test_tuner->start_called());
+ EXPECT_EQ(old_reordering_shift, loss_algorithm_.GetPacketReorderingShift());
+ EXPECT_EQ(old_reordering_threshold,
+ loss_algorithm_.GetPacketReorderingThreshold());
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc b/chromium/net/third_party/quiche/src/quic/core/crypto/certificate_view.cc
index 0f17d121ca0..af6b54c5863 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
@@ -4,6 +4,7 @@
#include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h"
+#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
@@ -17,6 +18,8 @@
#include "third_party/boringssl/src/include/openssl/rsa.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/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_ip_address.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -24,10 +27,17 @@
#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 {
+
+using ::quiche::QuicheOptional;
+using ::quiche::QuicheStringPiece;
+using ::quiche::QuicheTextUtils;
// The literals below were encoded using `ascii2der | xxd -i`. The comments
// above the literals are the contents in the der2ascii syntax.
-namespace {
// X.509 version 3 (version numbering starts with zero).
// INTEGER { 2 }
@@ -94,22 +104,54 @@ PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
namespace quic {
+QuicheOptional<quic::QuicWallTime> ParseDerTime(unsigned tag,
+ QuicheStringPiece payload) {
+ if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) {
+ QUIC_BUG << "Invalid tag supplied for a DER timestamp";
+ return QUICHE_NULLOPT;
+ }
+
+ const size_t year_length = tag == CBS_ASN1_GENERALIZEDTIME ? 4 : 2;
+ uint64_t year, month, day, hour, minute, second;
+ quiche::QuicheDataReader reader(payload);
+ if (!reader.ReadDecimal64(year_length, &year) ||
+ !reader.ReadDecimal64(2, &month) || !reader.ReadDecimal64(2, &day) ||
+ !reader.ReadDecimal64(2, &hour) || !reader.ReadDecimal64(2, &minute) ||
+ !reader.ReadDecimal64(2, &second) ||
+ reader.ReadRemainingPayload() != "Z") {
+ QUIC_DLOG(WARNING) << "Failed to parse the DER timestamp";
+ return QUICHE_NULLOPT;
+ }
+
+ if (tag == CBS_ASN1_UTCTIME) {
+ DCHECK_LE(year, 100u);
+ year += (year >= 50) ? 1900 : 2000;
+ }
+
+ const QuicheOptional<int64_t> unix_time =
+ quiche::QuicheUtcDateTimeToUnixSeconds(year, month, day, hour, minute,
+ second);
+ if (!unix_time.has_value() || *unix_time < 0) {
+ return QUICHE_NULLOPT;
+ }
+ return QuicWallTime::FromUNIXSeconds(*unix_time);
+}
+
PemReadResult ReadNextPemMessage(std::istream* input) {
- constexpr quiche::QuicheStringPiece kPemBegin = "-----BEGIN ";
- constexpr quiche::QuicheStringPiece kPemEnd = "-----END ";
- constexpr quiche::QuicheStringPiece kPemDashes = "-----";
+ constexpr QuicheStringPiece kPemBegin = "-----BEGIN ";
+ constexpr QuicheStringPiece kPemEnd = "-----END ";
+ constexpr QuicheStringPiece kPemDashes = "-----";
std::string line_buffer, encoded_message_contents, expected_end;
bool pending_message = false;
PemReadResult result;
while (std::getline(*input, line_buffer)) {
- quiche::QuicheStringPiece line(line_buffer);
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
+ QuicheStringPiece line(line_buffer);
+ QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&line);
// Handle BEGIN lines.
- if (!pending_message &&
- quiche::QuicheTextUtils::StartsWith(line, kPemBegin) &&
- quiche::QuicheTextUtils::EndsWith(line, kPemDashes)) {
+ if (!pending_message && QuicheTextUtils::StartsWith(line, kPemBegin) &&
+ QuicheTextUtils::EndsWith(line, kPemDashes)) {
result.type = std::string(
line.substr(kPemBegin.size(),
line.size() - kPemDashes.size() - kPemBegin.size()));
@@ -120,8 +162,8 @@ PemReadResult ReadNextPemMessage(std::istream* input) {
// Handle END lines.
if (pending_message && line == expected_end) {
- quiche::QuicheOptional<std::string> data =
- quiche::QuicheTextUtils::Base64Decode(encoded_message_contents);
+ QuicheOptional<std::string> data =
+ QuicheTextUtils::Base64Decode(encoded_message_contents);
if (data.has_value()) {
result.status = PemReadResult::kOk;
result.contents = data.value();
@@ -137,11 +179,11 @@ PemReadResult ReadNextPemMessage(std::istream* input) {
}
bool eof_reached = input->eof() && !pending_message;
return PemReadResult{
- .status = (eof_reached ? PemReadResult::kEof : PemReadResult::kError)};
+ (eof_reached ? PemReadResult::kEof : PemReadResult::kError), "", ""};
}
std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
- quiche::QuicheStringPiece certificate) {
+ QuicheStringPiece certificate) {
std::unique_ptr<CertificateView> result(new CertificateView());
CBS top = StringPieceToCbs(certificate);
@@ -215,6 +257,25 @@ std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
return nullptr;
}
+ unsigned not_before_tag, not_after_tag;
+ CBS not_before, not_after;
+ if (!CBS_get_any_asn1(&validity, &not_before, &not_before_tag) ||
+ !CBS_get_any_asn1(&validity, &not_after, &not_after_tag) ||
+ CBS_len(&validity) != 0) {
+ QUIC_DLOG(WARNING) << "Failed to extract the validity dates";
+ return nullptr;
+ }
+ QuicheOptional<QuicWallTime> not_before_parsed =
+ ParseDerTime(not_before_tag, CbsToStringPiece(not_before));
+ QuicheOptional<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";
+ return nullptr;
+ }
+ result->validity_start_ = *not_before_parsed;
+ result->validity_end_ = *not_after_parsed;
+
result->public_key_.reset(EVP_parse_public_key(&spki));
if (result->public_key_ == nullptr) {
QUIC_DLOG(WARNING) << "Failed to parse the public key";
@@ -286,7 +347,7 @@ bool CertificateView::ParseExtensions(CBS extensions) {
return false;
}
- quiche::QuicheStringPiece alt_name = CbsToStringPiece(alt_name_cbs);
+ QuicheStringPiece alt_name = CbsToStringPiece(alt_name_cbs);
QuicIpAddress ip_address;
// GeneralName ::= CHOICE {
switch (alt_name_tag) {
@@ -306,8 +367,8 @@ bool CertificateView::ParseExtensions(CBS extensions) {
break;
default:
- QUIC_DLOG(WARNING) << "Invalid subjectAltName tag";
- return false;
+ QUIC_DLOG(INFO) << "Unknown subjectAltName tag " << alt_name_tag;
+ continue;
}
}
}
@@ -355,8 +416,8 @@ bool CertificateView::ValidatePublicKeyParameters() {
}
}
-bool CertificateView::VerifySignature(quiche::QuicheStringPiece data,
- quiche::QuicheStringPiece signature,
+bool CertificateView::VerifySignature(QuicheStringPiece data,
+ QuicheStringPiece signature,
uint16_t signature_algorithm) const {
if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
PublicKeyTypeFromKey(public_key_.get())) {
@@ -386,7 +447,7 @@ bool CertificateView::VerifySignature(quiche::QuicheStringPiece data,
}
std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadFromDer(
- quiche::QuicheStringPiece private_key) {
+ QuicheStringPiece 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));
@@ -423,7 +484,7 @@ std::unique_ptr<CertificatePrivateKey> CertificatePrivateKey::LoadPemFromStream(
return nullptr;
}
-std::string CertificatePrivateKey::Sign(quiche::QuicheStringPiece input,
+std::string CertificatePrivateKey::Sign(QuicheStringPiece input,
uint16_t signature_algorithm) {
if (PublicKeyTypeFromSignatureAlgorithm(signature_algorithm) !=
PublicKeyTypeFromKey(private_key_.get())) {
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 286226d7e20..13bb5ff14ae 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
@@ -13,8 +13,11 @@
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/evp.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/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 {
@@ -46,6 +49,8 @@ class QUIC_EXPORT_PRIVATE CertificateView {
// without parsing them. Returns an empty vector if any parsing error occurs.
static std::vector<std::string> LoadPemFromStream(std::istream* input);
+ QuicWallTime validity_start() const { return validity_start_; }
+ 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()
@@ -64,6 +69,9 @@ class QUIC_EXPORT_PRIVATE CertificateView {
private:
CertificateView() = default;
+ QuicWallTime validity_start_ = QuicWallTime::Zero();
+ QuicWallTime validity_end_ = QuicWallTime::Zero();
+
// Public key parsed from SPKI.
bssl::UniquePtr<EVP_PKEY> public_key_;
@@ -103,6 +111,12 @@ class QUIC_EXPORT_PRIVATE CertificatePrivateKey {
bssl::UniquePtr<EVP_PKEY> private_key_;
};
+// Parses a DER time based on the specified ASN.1 tag. Exposed primarily for
+// testing.
+QUIC_EXPORT_PRIVATE quiche::QuicheOptional<quic::QuicWallTime> ParseDerTime(
+ unsigned tag,
+ quiche::QuicheStringPiece payload);
+
} // namespace quic
#endif // QUICHE_QUIC_CORE_CRYPTO_CERTIFICATE_VIEW_H_
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 b0b52f14f3b..ad512143243 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
@@ -8,19 +8,23 @@
#include <sstream>
#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/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 {
namespace test {
namespace {
-using testing::ElementsAre;
-using testing::HasSubstr;
+using ::testing::ElementsAre;
+using ::testing::HasSubstr;
+using ::testing::Optional;
TEST(CertificateViewTest, PemParser) {
std::stringstream stream(kTestCertificatePem);
@@ -45,6 +49,24 @@ TEST(CertificateViewTest, Parse) {
EXPECT_THAT(view->subject_alt_name_ips(),
ElementsAre(QuicIpAddress::Loopback4()));
EXPECT_EQ(EVP_PKEY_id(view->public_key()), EVP_PKEY_RSA);
+
+ const QuicWallTime validity_start = QuicWallTime::FromUNIXSeconds(
+ *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 1, 30, 18, 13, 59));
+ EXPECT_EQ(view->validity_start(), validity_start);
+ const QuicWallTime validity_end = QuicWallTime::FromUNIXSeconds(
+ *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59));
+ EXPECT_EQ(view->validity_end(), validity_end);
+}
+
+TEST(CertificateViewTest, ParseCertWithUnknownSanType) {
+ std::stringstream stream(kTestCertWithUnknownSanTypePem);
+ PemReadResult result = ReadNextPemMessage(&stream);
+ EXPECT_EQ(result.status, PemReadResult::kOk);
+ EXPECT_EQ(result.type, "CERTIFICATE");
+
+ std::unique_ptr<CertificateView> view =
+ CertificateView::ParseSingleCertificate(result.contents);
+ EXPECT_TRUE(view != nullptr);
}
TEST(CertificateViewTest, PemSingleCertificate) {
@@ -109,6 +131,47 @@ TEST(CertificateViewTest, PrivateKeyPem) {
EXPECT_TRUE(legacy_key->MatchesPublicKey(*view));
}
+TEST(CertificateViewTest, DerTime) {
+ EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Z"),
+ Optional(QuicWallTime::FromUNIXSeconds(24)));
+ EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19710101000024Z"),
+ Optional(QuicWallTime::FromUNIXSeconds(365 * 86400 + 24)));
+ EXPECT_THAT(ParseDerTime(CBS_ASN1_UTCTIME, "700101000024Z"),
+ 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, "19700101000024.001Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024Q"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024-0500"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "700101000024ZZ"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.00Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "197O0101000024Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101000024.0O1Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "-9700101000024Z"),
+ QUICHE_NULLOPT);
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "1970-101000024Z"),
+ QUICHE_NULLOPT);
+
+ EXPECT_TRUE(ParseDerTime(CBS_ASN1_UTCTIME, "490101000024Z").has_value());
+ // This should parse as 1950, which predates UNIX epoch.
+ EXPECT_FALSE(ParseDerTime(CBS_ASN1_UTCTIME, "500101000024Z").has_value());
+
+ EXPECT_THAT(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101230000Z"),
+ Optional(QuicWallTime::FromUNIXSeconds(23 * 3600)));
+ EXPECT_EQ(ParseDerTime(CBS_ASN1_GENERALIZEDTIME, "19700101240000Z"),
+ QUICHE_NULLOPT);
+}
+
} // namespace
} // namespace test
} // namespace quic
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 172fd822d0b..4beec0bdf90 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
@@ -125,6 +125,8 @@ 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 kBSAO = TAG('B', 'S', 'A', 'O'); // Avoid Overestimation in
// Bandwidth Sampler with ack
// aggregation
@@ -160,7 +162,13 @@ const QuicTag kACKQ = TAG('A', 'C', 'K', 'Q'); // Send an immediate ack after
// 1 RTT of not receiving.
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
+const QuicTag k3RTO = TAG('3', 'R', 'T', 'O'); // Close connection on 3 RTOs
+const QuicTag k4RTO = TAG('4', 'R', 'T', 'O'); // Close connection on 4 RTOs
const QuicTag k5RTO = TAG('5', 'R', 'T', 'O'); // Close connection on 5 RTOs
+const QuicTag k6RTO = TAG('6', 'R', 'T', 'O'); // Close connection on 6 RTOs
+const QuicTag kCBHD = TAG('C', 'B', 'H', 'D'); // Client only blackhole
+ // detection.
const QuicTag kCONH = TAG('C', 'O', 'N', 'H'); // Conservative Handshake
// Retransmissions.
const QuicTag kLFAK = TAG('L', 'F', 'A', 'K'); // Don't invoke FACK on the
@@ -225,6 +233,8 @@ const QuicTag kPLE2 = TAG('P', 'L', 'E', '2'); // Arm the 1st PTO with
// earliest in flight sent time
// and at least 1.5*srtt from
// last sent packet.
+const QuicTag kAPTO = TAG('A', 'P', 'T', 'O'); // Use 1.5 * initial RTT before
+ // any RTT sample is available.
const QuicTag kELDT = TAG('E', 'L', 'D', 'T'); // Enable Loss Detection Tuning
@@ -329,6 +339,9 @@ const QuicTag kCFCW = TAG('C', 'F', 'C', 'W'); // Initial session/connection
// flow control receive window.
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 kMAD = TAG('M', 'A', 'D', 0); // Max Ack Delay (IETF QUIC)
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 ee9dc53cf64..58d39b8f7d6 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
@@ -508,6 +508,12 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
}
TEST_P(CryptoServerTest, TooSmall) {
+ if (GetQuicReloadableFlag(quic_dont_pad_chlo)) {
+ // This test validates that non-padded CHLOs are rejected, it cannot pass
+ // when the padding is no longer required.
+ // TODO(dschinazi) remove this test when we deprecate quic_dont_pad_chlo.
+ return;
+ }
ShouldFailMentioning(
"too small", crypto_test_utils::CreateCHLO(
{{"PDMD", "X509"}, {"VER\0", client_version_string_}}));
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 b6c6b7ae434..3127edec87b 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
@@ -117,10 +117,16 @@ namespace {
// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-25#section-5.2
// and https://tools.ietf.org/html/draft-ietf-quic-tls-27#section-5.2
+// and https://tools.ietf.org/html/draft-ietf-quic-tls-28#section-5.2
const uint8_t kDraft25InitialSalt[] = {0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb,
0x5a, 0x11, 0xa7, 0xd2, 0x43, 0x2b, 0xb4,
0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02};
+// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
+const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
+ 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
+ 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
+
// Salts used by deployed versions of QUIC. When introducing a new version,
// generate a new salt by running `openssl rand -hex 20`.
@@ -135,7 +141,7 @@ const uint8_t kT050Salt[] = {0x7f, 0xf5, 0x79, 0xe5, 0xac, 0xd0, 0x72,
const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
size_t* out_len) {
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync with initial encryption salts");
switch (version.handshake_protocol) {
case PROTOCOL_QUIC_CRYPTO:
@@ -166,6 +172,9 @@ const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
// draft-27 uses the same salt as draft-25.
*out_len = QUICHE_ARRAYSIZE(kDraft25InitialSalt);
return kDraft25InitialSalt;
+ case QUIC_VERSION_IETF_DRAFT_29:
+ *out_len = QUICHE_ARRAYSIZE(kDraft29InitialSalt);
+ return kDraft29InitialSalt;
default:
QUIC_BUG << "No initial obfuscation salt for version " << version;
}
@@ -183,11 +192,20 @@ const char kPreSharedKeyLabel[] = "QUIC PSK";
// Retry Integrity Protection Keys and Nonces.
// https://tools.ietf.org/html/draft-ietf-quic-tls-25#section-5.8
// https://tools.ietf.org/html/draft-ietf-quic-tls-27#section-5.8
+// https://tools.ietf.org/html/draft-ietf-quic-tls-28#section-5.8
const uint8_t kDraft25RetryIntegrityKey[] = {0x4d, 0x32, 0xec, 0xdb, 0x2a, 0x21,
0x33, 0xc8, 0x41, 0xe4, 0x04, 0x3d,
0xf2, 0x7d, 0x44, 0x30};
const uint8_t kDraft25RetryIntegrityNonce[] = {
0x4d, 0x16, 0x11, 0xd0, 0x55, 0x13, 0xa5, 0x52, 0xc5, 0x87, 0xd5, 0x75};
+
+// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
+const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
+ 0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
+ 0x6c, 0xb9, 0x6b, 0xe1};
+const uint8_t kDraft29RetryIntegrityNonce[] = {
+ 0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
+
// Keys used by Google versions of QUIC. When introducing a new version,
// generate a new key by running `openssl rand -hex 16`.
const uint8_t kT050RetryIntegrityKey[] = {0xc9, 0x2d, 0x32, 0x3d, 0x9c, 0xe3,
@@ -227,6 +245,15 @@ bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
QUICHE_ARRAYSIZE(kDraft25RetryIntegrityNonce));
return true;
}
+ if (version == ParsedQuicVersion::Draft29()) {
+ *key = quiche::QuicheStringPiece(
+ reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
+ QUICHE_ARRAYSIZE(kDraft29RetryIntegrityKey));
+ *nonce = quiche::QuicheStringPiece(
+ reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
+ QUICHE_ARRAYSIZE(kDraft29RetryIntegrityNonce));
+ return true;
+ }
QUIC_BUG << "Attempted to get retry integrity keys for version " << version;
return false;
}
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 6afc65f557a..e432682bddd 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
@@ -104,8 +104,8 @@ bool ProofSourceX509::AddCertificateChain(
}
certificates_.push_front(Certificate{
- .chain = chain,
- .key = std::move(key),
+ chain,
+ std::move(key),
});
Certificate* certificate = &certificates_.front();
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 7f8edc22cfe..9314e99f293 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
@@ -67,7 +67,10 @@ QuicCryptoClientConfig::QuicCryptoClientConfig(
std::unique_ptr<SessionCache> session_cache)
: proof_verifier_(std::move(proof_verifier)),
session_cache_(std::move(session_cache)),
- ssl_ctx_(TlsClientConnection::CreateSslCtx()) {
+ enable_zero_rtt_for_tls_(
+ GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls)),
+ ssl_ctx_(TlsClientConnection::CreateSslCtx(enable_zero_rtt_for_tls_)),
+ disable_chlo_padding_(GetQuicReloadableFlag(quic_dont_pad_chlo)) {
DCHECK(proof_verifier_.get());
SetDefaults();
}
@@ -132,16 +135,6 @@ QuicCryptoClientConfig::CachedState::GetServerConfig() const {
return scfg_.get();
}
-void QuicCryptoClientConfig::CachedState::add_server_designated_connection_id(
- QuicConnectionId connection_id) {
- server_designated_connection_ids_.push(connection_id);
-}
-
-bool QuicCryptoClientConfig::CachedState::has_server_designated_connection_id()
- const {
- return !server_designated_connection_ids_.empty();
-}
-
void QuicCryptoClientConfig::CachedState::add_server_nonce(
const std::string& server_nonce) {
server_nonces_.push(server_nonce);
@@ -204,9 +197,6 @@ void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
server_config_.clear();
scfg_.reset();
SetProofInvalid();
- QuicQueue<QuicConnectionId> empty_queue;
- using std::swap;
- swap(server_designated_connection_ids_, empty_queue);
}
void QuicCryptoClientConfig::CachedState::SetProof(
@@ -249,9 +239,6 @@ void QuicCryptoClientConfig::CachedState::Clear() {
proof_verify_details_.reset();
scfg_.reset();
++generation_counter_;
- QuicQueue<QuicConnectionId> empty_queue;
- using std::swap;
- swap(server_designated_connection_ids_, empty_queue);
}
void QuicCryptoClientConfig::CachedState::ClearProof() {
@@ -370,7 +357,6 @@ void QuicCryptoClientConfig::CachedState::InitializeFrom(
chlo_hash_ = other.chlo_hash_;
server_config_sig_ = other.server_config_sig_;
server_config_valid_ = other.server_config_valid_;
- server_designated_connection_ids_ = other.server_designated_connection_ids_;
expiration_time_ = other.expiration_time_;
if (other.proof_verify_details_ != nullptr) {
proof_verify_details_.reset(other.proof_verify_details_->Clone());
@@ -378,18 +364,6 @@ void QuicCryptoClientConfig::CachedState::InitializeFrom(
++generation_counter_;
}
-QuicConnectionId
-QuicCryptoClientConfig::CachedState::GetNextServerDesignatedConnectionId() {
- if (server_designated_connection_ids_.empty()) {
- QUIC_BUG
- << "Attempting to consume a connection id that was never designated.";
- return EmptyQuicConnectionId();
- }
- const QuicConnectionId next_id = server_designated_connection_ids_.front();
- server_designated_connection_ids_.pop();
- return next_id;
-}
-
std::string QuicCryptoClientConfig::CachedState::GetNextServerNonce() {
if (server_nonces_.empty()) {
QUIC_BUG
@@ -447,7 +421,7 @@ void QuicCryptoClientConfig::FillInchoateClientHello(
CryptoHandshakeMessage* out) const {
out->set_tag(kCHLO);
// TODO(rch): Remove this when we remove quic_use_chlo_packet_size flag.
- if (pad_inchoate_hello_) {
+ if (pad_inchoate_hello_ && !disable_chlo_padding_) {
out->set_minimum_size(kClientHelloMinimumSize);
} else {
out->set_minimum_size(1);
@@ -536,7 +510,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
FillInchoateClientHello(server_id, preferred_version, cached, rand,
/* demand_x509_proof= */ true, out_params, out);
- if (pad_full_hello_) {
+ if (pad_full_hello_ && !disable_chlo_padding_) {
out->set_minimum_size(kClientHelloMinimumSize);
} else {
out->set_minimum_size(1);
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 e3867c8e7b2..ce0efe530c7 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
@@ -76,6 +76,10 @@ class QUIC_EXPORT_PRIVATE SessionCache {
virtual std::unique_ptr<QuicResumptionState> Lookup(
const QuicServerId& server_id,
const SSL_CTX* ctx) = 0;
+
+ // Called when 0-RTT is rejected. Disables early data for all the TLS tickets
+ // associated with |server_id|.
+ virtual void ClearEarlyData(const QuicServerId& server_id) = 0;
};
// QuicCryptoClientConfig contains crypto-related configuration settings for a
@@ -171,20 +175,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
void set_cert_sct(quiche::QuicheStringPiece cert_sct);
- // Adds the connection ID to the queue of server-designated connection-ids.
- void add_server_designated_connection_id(QuicConnectionId connection_id);
-
- // If true, the crypto config contains at least one connection ID specified
- // by the server, and the client should use one of these IDs when initiating
- // the next connection.
- bool has_server_designated_connection_id() const;
-
- // This function should only be called when
- // has_server_designated_connection_id is true. Returns the next
- // connection_id specified by the server and removes it from the
- // queue of ids.
- QuicConnectionId GetNextServerDesignatedConnectionId();
-
// Adds the servernonce to the queue of server nonces.
void add_server_nonce(const std::string& server_nonce);
@@ -238,10 +228,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// scfg contains the cached, parsed value of |server_config|.
mutable std::unique_ptr<CryptoHandshakeMessage> scfg_;
- // TODO(jokulik): Consider using a hash-set as extra book-keeping to ensure
- // that no connection-id is added twice. Also, consider keeping the server
- // nonces and connection_ids together in one queue.
- QuicQueue<QuicConnectionId> server_designated_connection_ids_;
QuicQueue<std::string> server_nonces_;
};
@@ -368,6 +354,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
void set_proof_source(std::unique_ptr<ProofSource> proof_source);
SSL_CTX* ssl_ctx() const;
+ bool early_data_enabled_for_tls() const { return enable_zero_rtt_for_tls_; }
+
// Initialize the CachedState from |canonical_crypto_config| for the
// |canonical_server_id| as the initial CachedState for |server_id|. We will
// copy config data only if |canonical_crypto_config| has valid proof.
@@ -409,6 +397,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
bool pad_full_hello() const { return pad_full_hello_; }
void set_pad_full_hello(bool new_value) { pad_full_hello_ = new_value; }
+ void set_disable_chlo_padding(bool disabled) {
+ disable_chlo_padding_ = disabled;
+ }
+
private:
// Sets the members to reasonable, default values.
void SetDefaults();
@@ -450,6 +442,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
std::unique_ptr<ProofVerifier> proof_verifier_;
std::unique_ptr<SessionCache> session_cache_;
std::unique_ptr<ProofSource> proof_source_;
+
+ // Latched value of reloadable flag quic_enable_zero_rtt_for_tls
+ bool enable_zero_rtt_for_tls_;
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
// The |user_agent_id_| passed in QUIC's CHLO message.
@@ -475,6 +470,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// other means of verifying the client.
bool pad_inchoate_hello_ = true;
bool pad_full_hello_ = true;
+ bool disable_chlo_padding_;
};
} // namespace quic
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 4b6dcd71bcb..c995e8a87c0 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
@@ -81,46 +81,6 @@ TEST_F(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) {
EXPECT_EQ(details, state.proof_verify_details());
}
-TEST_F(QuicCryptoClientConfigTest, CachedState_ServerDesignatedConnectionId) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_FALSE(state.has_server_designated_connection_id());
-
- uint64_t conn_id = 1234;
- QuicConnectionId connection_id = TestConnectionId(conn_id);
- state.add_server_designated_connection_id(connection_id);
- EXPECT_TRUE(state.has_server_designated_connection_id());
- EXPECT_EQ(connection_id, state.GetNextServerDesignatedConnectionId());
- EXPECT_FALSE(state.has_server_designated_connection_id());
-
- // Allow the ID to be set multiple times. It's unusual that this would
- // happen, but not impossible.
- connection_id = TestConnectionId(++conn_id);
- state.add_server_designated_connection_id(connection_id);
- EXPECT_TRUE(state.has_server_designated_connection_id());
- EXPECT_EQ(connection_id, state.GetNextServerDesignatedConnectionId());
- connection_id = TestConnectionId(++conn_id);
- state.add_server_designated_connection_id(connection_id);
- EXPECT_EQ(connection_id, state.GetNextServerDesignatedConnectionId());
- EXPECT_FALSE(state.has_server_designated_connection_id());
-
- // Test FIFO behavior.
- const QuicConnectionId first_cid = TestConnectionId(0xdeadbeef);
- const QuicConnectionId second_cid = TestConnectionId(0xfeedbead);
- state.add_server_designated_connection_id(first_cid);
- state.add_server_designated_connection_id(second_cid);
- EXPECT_TRUE(state.has_server_designated_connection_id());
- EXPECT_EQ(first_cid, state.GetNextServerDesignatedConnectionId());
- EXPECT_EQ(second_cid, state.GetNextServerDesignatedConnectionId());
-}
-
-TEST_F(QuicCryptoClientConfigTest, CachedState_ServerIdConsumedBeforeSet) {
- QuicCryptoClientConfig::CachedState state;
- EXPECT_FALSE(state.has_server_designated_connection_id());
- EXPECT_QUIC_BUG(state.GetNextServerDesignatedConnectionId(),
- "Attempting to consume a connection id "
- "that was never designated.");
-}
-
TEST_F(QuicCryptoClientConfigTest, CachedState_ServerNonce) {
QuicCryptoClientConfig::CachedState state;
EXPECT_FALSE(state.has_server_nonce());
@@ -170,7 +130,6 @@ TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
EXPECT_EQ(state.source_address_token(), other.source_address_token());
EXPECT_EQ(state.certs(), other.certs());
EXPECT_EQ(1u, other.generation_counter());
- EXPECT_FALSE(state.has_server_designated_connection_id());
EXPECT_FALSE(state.has_server_nonce());
}
@@ -200,7 +159,11 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
EXPECT_TRUE(msg.GetStringPiece(kALPN, &alpn));
EXPECT_EQ("hq", alpn);
- EXPECT_EQ(msg.minimum_size(), 1024u);
+ if (GetQuicReloadableFlag(quic_dont_pad_chlo)) {
+ EXPECT_EQ(msg.minimum_size(), 1u);
+ } else {
+ EXPECT_EQ(msg.minimum_size(), 1024u);
+ }
}
TEST_F(QuicCryptoClientConfigTest, InchoateChloIsNotPadded) {
@@ -532,7 +495,6 @@ TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
AllSupportedTransportVersions().front(),
"", &cached, out_params, &error),
IsQuicNoError());
- EXPECT_FALSE(cached.has_server_designated_connection_id());
EXPECT_FALSE(cached.has_server_nonce());
}
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 9cb089bf0e8..c07b8d3bf11 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
@@ -1211,10 +1211,14 @@ void QuicCryptoServerConfig::EvaluateClientHello(
const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello;
ClientHelloInfo* info = &(client_hello_state->info);
- if (validate_chlo_size_ && client_hello.size() < kClientHelloMinimumSize) {
- helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH,
- "Client hello too small", nullptr);
- return;
+ if (GetQuicReloadableFlag(quic_dont_pad_chlo)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_dont_pad_chlo, 1, 2);
+ } else {
+ if (validate_chlo_size_ && client_hello.size() < kClientHelloMinimumSize) {
+ helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH,
+ "Client hello too small", nullptr);
+ return;
+ }
}
if (client_hello.GetStringPiece(kSNI, &info->sni) &&
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 7d112245b3c..79088473bbc 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
@@ -11,7 +11,8 @@ TlsClientConnection::TlsClientConnection(SSL_CTX* ssl_ctx, Delegate* delegate)
delegate_(delegate) {}
// static
-bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx() {
+bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx(
+ bool enable_early_data) {
bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
// Configure certificate verification.
SSL_CTX_set_custom_verify(ssl_ctx.get(), SSL_VERIFY_PEER, &VerifyCallback);
@@ -22,6 +23,8 @@ bssl::UniquePtr<SSL_CTX> TlsClientConnection::CreateSslCtx() {
SSL_CTX_set_session_cache_mode(
ssl_ctx.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+ SSL_CTX_set_early_data_enabled(ssl_ctx.get(), enable_early_data);
return ssl_ctx;
}
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 035f420a835..a7ef209792f 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
@@ -39,7 +39,7 @@ class QUIC_EXPORT_PRIVATE TlsClientConnection : public TlsConnection {
TlsClientConnection(SSL_CTX* ssl_ctx, Delegate* delegate);
// Creates and configures an SSL_CTX that is appropriate for clients to use.
- static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+ static bssl::UniquePtr<SSL_CTX> CreateSslCtx(bool enable_early_data);
private:
// Registered as the callback for SSL_CTX_set_custom_verify. The
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 75d28c55d60..8e4d391db4b 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
@@ -114,28 +114,6 @@ const SSL_QUIC_METHOD TlsConnection::kSslQuicMethod{
TlsConnection::SendAlertCallback};
// static
-int TlsConnection::SetEncryptionSecretCallback(
- SSL* ssl,
- enum ssl_encryption_level_t level,
- const uint8_t* read_key,
- const uint8_t* write_key,
- size_t key_length) {
- // TODO(nharper): replace these vectors and memcpys with spans (which
- // unfortunately doesn't yet exist in quic/platform/api).
- std::vector<uint8_t> read_secret(key_length), write_secret(key_length);
- memcpy(read_secret.data(), read_key, key_length);
- memcpy(write_secret.data(), write_key, key_length);
- TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
- const SSL_CIPHER* cipher = SSL_get_pending_cipher(ssl);
- delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher, write_secret);
- if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
- read_secret)) {
- return 0;
- }
- return 1;
-}
-
-// static
int TlsConnection::SetReadSecretCallback(SSL* ssl,
enum ssl_encryption_level_t level,
const SSL_CIPHER* cipher,
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 d65f63c68e5..15a4f4f9a3a 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
@@ -101,11 +101,6 @@ class QUIC_EXPORT_PRIVATE TlsConnection {
static const SSL_QUIC_METHOD kSslQuicMethod;
// The following static functions make up the members of kSslQuicMethod:
- static int SetEncryptionSecretCallback(SSL* ssl,
- enum ssl_encryption_level_t level,
- const uint8_t* read_key,
- const uint8_t* write_key,
- size_t key_length);
static int SetReadSecretCallback(SSL* ssl,
enum ssl_encryption_level_t level,
const SSL_CIPHER* cipher,
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 3e286adc84b..330a14d5ea2 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 "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/crypto/crypto_framer.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
@@ -31,8 +33,8 @@ namespace quic {
// which parameter is encoded. The supported draft version is noted in
// transport_parameters.h.
enum TransportParameters::TransportParameterId : uint64_t {
- kOriginalConnectionId = 0,
- kIdleTimeout = 1,
+ kOriginalDestinationConnectionId = 0,
+ kMaxIdleTimeout = 1,
kStatelessResetToken = 2,
kMaxPacketSize = 3,
kInitialMaxData = 4,
@@ -43,15 +45,18 @@ enum TransportParameters::TransportParameterId : uint64_t {
kInitialMaxStreamsUni = 9,
kAckDelayExponent = 0xa,
kMaxAckDelay = 0xb,
- kDisableMigration = 0xc,
+ kDisableActiveMigration = 0xc,
kPreferredAddress = 0xd,
kActiveConnectionIdLimit = 0xe,
+ kInitialSourceConnectionId = 0xf,
+ kRetrySourceConnectionId = 0x10,
kMaxDatagramFrameSize = 0x20,
kInitialRoundTripTime = 0x3127,
kGoogleConnectionOptions = 0x3128,
kGoogleUserAgentId = 0x3129,
+ kGoogleSupportHandshakeDone = 0x312A, // Only used in T050.
kGoogleQuicParam = 18257, // Used for non-standard Google-specific params.
kGoogleQuicVersion =
18258, // Used to transmit version and supported_versions.
@@ -74,14 +79,14 @@ constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;
std::string TransportParameterIdToString(
TransportParameters::TransportParameterId param_id) {
switch (param_id) {
- case TransportParameters::kOriginalConnectionId:
- return "original_connection_id";
- case TransportParameters::kIdleTimeout:
- return "idle_timeout";
+ case TransportParameters::kOriginalDestinationConnectionId:
+ return "original_destination_connection_id";
+ case TransportParameters::kMaxIdleTimeout:
+ return "max_idle_timeout";
case TransportParameters::kStatelessResetToken:
return "stateless_reset_token";
case TransportParameters::kMaxPacketSize:
- return "max_packet_size";
+ return "max_udp_payload_size";
case TransportParameters::kInitialMaxData:
return "initial_max_data";
case TransportParameters::kInitialMaxStreamDataBidiLocal:
@@ -98,12 +103,16 @@ std::string TransportParameterIdToString(
return "ack_delay_exponent";
case TransportParameters::kMaxAckDelay:
return "max_ack_delay";
- case TransportParameters::kDisableMigration:
- return "disable_migration";
+ case TransportParameters::kDisableActiveMigration:
+ return "disable_active_migration";
case TransportParameters::kPreferredAddress:
return "preferred_address";
case TransportParameters::kActiveConnectionIdLimit:
return "active_connection_id_limit";
+ case TransportParameters::kInitialSourceConnectionId:
+ return "initial_source_connection_id";
+ case TransportParameters::kRetrySourceConnectionId:
+ return "retry_source_connection_id";
case TransportParameters::kMaxDatagramFrameSize:
return "max_datagram_frame_size";
case TransportParameters::kInitialRoundTripTime:
@@ -112,6 +121,8 @@ std::string TransportParameterIdToString(
return "google_connection_options";
case TransportParameters::kGoogleUserAgentId:
return "user_agent_id";
+ case TransportParameters::kGoogleSupportHandshakeDone:
+ return "support_handshake_done";
case TransportParameters::kGoogleQuicParam:
return "google";
case TransportParameters::kGoogleQuicVersion:
@@ -123,8 +134,8 @@ std::string TransportParameterIdToString(
bool TransportParameterIdIsKnown(
TransportParameters::TransportParameterId param_id) {
switch (param_id) {
- case TransportParameters::kOriginalConnectionId:
- case TransportParameters::kIdleTimeout:
+ case TransportParameters::kOriginalDestinationConnectionId:
+ case TransportParameters::kMaxIdleTimeout:
case TransportParameters::kStatelessResetToken:
case TransportParameters::kMaxPacketSize:
case TransportParameters::kInitialMaxData:
@@ -135,13 +146,16 @@ bool TransportParameterIdIsKnown(
case TransportParameters::kInitialMaxStreamsUni:
case TransportParameters::kAckDelayExponent:
case TransportParameters::kMaxAckDelay:
- case TransportParameters::kDisableMigration:
+ case TransportParameters::kDisableActiveMigration:
case TransportParameters::kPreferredAddress:
case TransportParameters::kActiveConnectionIdLimit:
+ case TransportParameters::kInitialSourceConnectionId:
+ case TransportParameters::kRetrySourceConnectionId:
case TransportParameters::kMaxDatagramFrameSize:
case TransportParameters::kInitialRoundTripTime:
case TransportParameters::kGoogleConnectionOptions:
case TransportParameters::kGoogleUserAgentId:
+ case TransportParameters::kGoogleSupportHandshakeDone:
case TransportParameters::kGoogleQuicParam:
case TransportParameters::kGoogleQuicVersion:
return true;
@@ -401,18 +415,18 @@ std::string TransportParameters::ToString() const {
rv += " supported_versions " +
QuicVersionLabelVectorToString(supported_versions);
}
- if (original_connection_id.has_value()) {
- rv += " " + TransportParameterIdToString(kOriginalConnectionId) + " " +
- original_connection_id.value().ToString();
+ if (original_destination_connection_id.has_value()) {
+ rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
+ " " + original_destination_connection_id.value().ToString();
}
- rv += idle_timeout_milliseconds.ToString(/*for_use_in_list=*/true);
+ rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
if (!stateless_reset_token.empty()) {
rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
quiche::QuicheTextUtils::HexEncode(
reinterpret_cast<const char*>(stateless_reset_token.data()),
stateless_reset_token.size());
}
- rv += max_packet_size.ToString(/*for_use_in_list=*/true);
+ rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
rv += initial_max_data.ToString(/*for_use_in_list=*/true);
rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
@@ -421,14 +435,22 @@ std::string TransportParameters::ToString() const {
rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
- if (disable_migration) {
- rv += " " + TransportParameterIdToString(kDisableMigration);
+ if (disable_active_migration) {
+ rv += " " + TransportParameterIdToString(kDisableActiveMigration);
}
if (preferred_address) {
rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
preferred_address->ToString();
}
rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
+ if (initial_source_connection_id.has_value()) {
+ rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
+ initial_source_connection_id.value().ToString();
+ }
+ if (retry_source_connection_id.has_value()) {
+ rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
+ retry_source_connection_id.value().ToString();
+ }
rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
if (google_connection_options.has_value()) {
@@ -447,12 +469,24 @@ std::string TransportParameters::ToString() const {
rv += " " + TransportParameterIdToString(kGoogleUserAgentId) + " \"" +
user_agent_id.value() + "\"";
}
+ if (support_handshake_done) {
+ rv += " " + TransportParameterIdToString(kGoogleSupportHandshakeDone);
+ }
if (google_quic_params) {
rv += " " + TransportParameterIdToString(kGoogleQuicParam);
}
for (const auto& kv : custom_parameters) {
rv += " 0x" + quiche::QuicheTextUtils::Hex(static_cast<uint32_t>(kv.first));
- rv += "=" + quiche::QuicheTextUtils::HexEncode(kv.second);
+ rv += "=";
+ static constexpr size_t kMaxPrintableLength = 32;
+ if (kv.second.length() <= kMaxPrintableLength) {
+ rv += quiche::QuicheTextUtils::HexEncode(kv.second);
+ } else {
+ quiche::QuicheStringPiece truncated(kv.second.data(),
+ kMaxPrintableLength);
+ rv += quiche::QuicheStrCat(quiche::QuicheTextUtils::HexEncode(truncated),
+ "...(length ", kv.second.length(), ")");
+ }
}
rv += "]";
return rv;
@@ -460,11 +494,11 @@ std::string TransportParameters::ToString() const {
TransportParameters::TransportParameters()
: version(0),
- idle_timeout_milliseconds(kIdleTimeout),
- max_packet_size(kMaxPacketSize,
- kDefaultMaxPacketSizeTransportParam,
- kMinMaxPacketSizeTransportParam,
- kVarInt62MaxValue),
+ max_idle_timeout_ms(kMaxIdleTimeout),
+ max_udp_payload_size(kMaxPacketSize,
+ kDefaultMaxPacketSizeTransportParam,
+ kMinMaxPacketSizeTransportParam,
+ kVarInt62MaxValue),
initial_max_data(kInitialMaxData),
initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
@@ -479,13 +513,14 @@ TransportParameters::TransportParameters()
kDefaultMaxAckDelayTransportParam,
0,
kMaxMaxAckDelayTransportParam),
- disable_migration(false),
+ disable_active_migration(false),
active_connection_id_limit(kActiveConnectionIdLimit,
kDefaultActiveConnectionIdLimitTransportParam,
kMinActiveConnectionIdLimitTransportParam,
kVarInt62MaxValue),
max_datagram_frame_size(kMaxDatagramFrameSize),
- initial_round_trip_time_us(kInitialRoundTripTime)
+ initial_round_trip_time_us(kInitialRoundTripTime),
+ support_handshake_done(false)
// Important note: any new transport parameters must be added
// to TransportParameters::AreValid, SerializeTransportParameters and
// ParseTransportParameters, TransportParameters's custom copy constructor, the
@@ -496,10 +531,11 @@ TransportParameters::TransportParameters(const TransportParameters& other)
: perspective(other.perspective),
version(other.version),
supported_versions(other.supported_versions),
- original_connection_id(other.original_connection_id),
- idle_timeout_milliseconds(other.idle_timeout_milliseconds),
+ original_destination_connection_id(
+ other.original_destination_connection_id),
+ max_idle_timeout_ms(other.max_idle_timeout_ms),
stateless_reset_token(other.stateless_reset_token),
- max_packet_size(other.max_packet_size),
+ max_udp_payload_size(other.max_udp_payload_size),
initial_max_data(other.initial_max_data),
initial_max_stream_data_bidi_local(
other.initial_max_stream_data_bidi_local),
@@ -510,12 +546,15 @@ TransportParameters::TransportParameters(const TransportParameters& other)
initial_max_streams_uni(other.initial_max_streams_uni),
ack_delay_exponent(other.ack_delay_exponent),
max_ack_delay(other.max_ack_delay),
- disable_migration(other.disable_migration),
+ disable_active_migration(other.disable_active_migration),
active_connection_id_limit(other.active_connection_id_limit),
+ initial_source_connection_id(other.initial_source_connection_id),
+ retry_source_connection_id(other.retry_source_connection_id),
max_datagram_frame_size(other.max_datagram_frame_size),
initial_round_trip_time_us(other.initial_round_trip_time_us),
google_connection_options(other.google_connection_options),
user_agent_id(other.user_agent_id),
+ support_handshake_done(other.support_handshake_done),
custom_parameters(other.custom_parameters) {
if (other.preferred_address) {
preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
@@ -530,11 +569,11 @@ TransportParameters::TransportParameters(const TransportParameters& other)
bool TransportParameters::operator==(const TransportParameters& rhs) const {
if (!(perspective == rhs.perspective && version == rhs.version &&
supported_versions == rhs.supported_versions &&
- original_connection_id == rhs.original_connection_id &&
- idle_timeout_milliseconds.value() ==
- rhs.idle_timeout_milliseconds.value() &&
+ original_destination_connection_id ==
+ rhs.original_destination_connection_id &&
+ max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
stateless_reset_token == rhs.stateless_reset_token &&
- max_packet_size.value() == rhs.max_packet_size.value() &&
+ max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
initial_max_data.value() == rhs.initial_max_data.value() &&
initial_max_stream_data_bidi_local.value() ==
rhs.initial_max_stream_data_bidi_local.value() &&
@@ -548,15 +587,18 @@ bool TransportParameters::operator==(const TransportParameters& rhs) const {
rhs.initial_max_streams_uni.value() &&
ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
max_ack_delay.value() == rhs.max_ack_delay.value() &&
- disable_migration == rhs.disable_migration &&
+ disable_active_migration == rhs.disable_active_migration &&
active_connection_id_limit.value() ==
rhs.active_connection_id_limit.value() &&
+ initial_source_connection_id == rhs.initial_source_connection_id &&
+ retry_source_connection_id == rhs.retry_source_connection_id &&
max_datagram_frame_size.value() ==
rhs.max_datagram_frame_size.value() &&
initial_round_trip_time_us.value() ==
rhs.initial_round_trip_time_us.value() &&
google_connection_options == rhs.google_connection_options &&
user_agent_id == rhs.user_agent_id &&
+ support_handshake_done == rhs.support_handshake_done &&
custom_parameters == rhs.custom_parameters)) {
return false;
}
@@ -591,8 +633,8 @@ bool TransportParameters::AreValid(std::string* error_details) const {
return false;
}
if (perspective == Perspective::IS_CLIENT &&
- original_connection_id.has_value()) {
- *error_details = "Client cannot send original connection ID";
+ original_destination_connection_id.has_value()) {
+ *error_details = "Client cannot send original_destination_connection_id";
return false;
}
if (!stateless_reset_token.empty() &&
@@ -619,6 +661,11 @@ bool TransportParameters::AreValid(std::string* error_details) const {
*error_details = "Internal preferred address family failure";
return false;
}
+ if (perspective == Perspective::IS_CLIENT &&
+ retry_source_connection_id.has_value()) {
+ *error_details = "Client cannot send retry_source_connection_id";
+ return false;
+ }
for (const auto& kv : custom_parameters) {
if (TransportParameterIdIsKnown(kv.first)) {
*error_details = quiche::QuicheStrCat(
@@ -637,7 +684,7 @@ bool TransportParameters::AreValid(std::string* error_details) const {
return false;
}
const bool ok =
- idle_timeout_milliseconds.IsValid() && max_packet_size.IsValid() &&
+ max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
initial_max_data.IsValid() &&
initial_max_stream_data_bidi_local.IsValid() &&
initial_max_stream_data_bidi_remote.IsValid() &&
@@ -669,11 +716,78 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
return false;
}
- // Empirically transport parameters generally fit within 128 bytes.
- // For now we hope this will be enough.
- // TODO(dschinazi) make this grow if needed.
- static const size_t kMaxTransportParametersLength = 4096;
- out->resize(kMaxTransportParametersLength);
+ // Maximum length of the GREASE transport parameter (see below).
+ static constexpr size_t kMaxGreaseLength = 16;
+
+ // Empirically transport parameters generally fit within 128 bytes, but we
+ // need to allocate the size up front. Integer transport parameters
+ // have a maximum encoded length of 24 bytes (3 variable length integers),
+ // other transport parameters have a length of 16 + the maximum value length.
+ static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
+ static constexpr size_t kIntegerParameterLength =
+ kTypeAndValueLength + sizeof(uint64_t);
+ static constexpr size_t kStatelessResetParameterLength =
+ kTypeAndValueLength + 16 /* stateless reset token length */;
+ static constexpr size_t kConnectionIdParameterLength =
+ kTypeAndValueLength + 255 /* maximum connection ID length */;
+ static constexpr size_t kPreferredAddressParameterLength =
+ kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
+ 16 /* IPv6 address */ + 1 /* Connection ID length */ +
+ 255 /* maximum connection ID length */ + 16 /* stateless reset token */;
+ static constexpr size_t kGreaseParameterLength =
+ kTypeAndValueLength + kMaxGreaseLength;
+ static constexpr size_t kKnownTransportParamLength =
+ kConnectionIdParameterLength + // original_destination_connection_id
+ kIntegerParameterLength + // max_idle_timeout
+ kStatelessResetParameterLength + // stateless_reset_token
+ kIntegerParameterLength + // max_udp_payload_size
+ kIntegerParameterLength + // initial_max_data
+ kIntegerParameterLength + // initial_max_stream_data_bidi_local
+ kIntegerParameterLength + // initial_max_stream_data_bidi_remote
+ kIntegerParameterLength + // initial_max_stream_data_uni
+ kIntegerParameterLength + // initial_max_streams_bidi
+ kIntegerParameterLength + // initial_max_streams_uni
+ kIntegerParameterLength + // ack_delay_exponent
+ kIntegerParameterLength + // max_ack_delay
+ kTypeAndValueLength + // disable_active_migration
+ kPreferredAddressParameterLength + // preferred_address
+ kIntegerParameterLength + // active_connection_id_limit
+ kConnectionIdParameterLength + // initial_source_connection_id
+ kConnectionIdParameterLength + // retry_source_connection_id
+ kIntegerParameterLength + // max_datagram_frame_size
+ kIntegerParameterLength + // initial_round_trip_time_us
+ kTypeAndValueLength + // google_connection_options
+ kTypeAndValueLength + // user_agent_id
+ kTypeAndValueLength + // support_handshake_done
+ kTypeAndValueLength + // google
+ kTypeAndValueLength + // google-version
+ kGreaseParameterLength; // GREASE
+
+ size_t max_transport_param_length = kKnownTransportParamLength;
+ // google_connection_options.
+ if (in.google_connection_options.has_value()) {
+ max_transport_param_length +=
+ in.google_connection_options.value().size() * sizeof(QuicTag);
+ }
+ // user_agent_id.
+ if (in.user_agent_id.has_value()) {
+ max_transport_param_length += in.user_agent_id.value().length();
+ }
+ // Google-specific version extension.
+ max_transport_param_length +=
+ sizeof(in.version) + 1 /* versions length */ +
+ in.supported_versions.size() * sizeof(QuicVersionLabel);
+ // Custom parameters.
+ for (const auto& kv : in.custom_parameters) {
+ max_transport_param_length += kTypeAndValueLength + kv.second.length();
+ }
+ // Google-specific non-standard parameter.
+ if (in.google_quic_params) {
+ max_transport_param_length +=
+ in.google_quic_params->GetSerialized().length();
+ }
+
+ out->resize(max_transport_param_length);
QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));
if (!version.HasVarIntTransportParams()) {
@@ -688,24 +802,27 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
}
}
- // original_connection_id
- if (in.original_connection_id.has_value()) {
+ // original_destination_connection_id
+ if (in.original_destination_connection_id.has_value()) {
DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
- QuicConnectionId original_connection_id = in.original_connection_id.value();
+ QuicConnectionId original_destination_connection_id =
+ in.original_destination_connection_id.value();
if (!WriteTransportParameterId(
- &writer, TransportParameters::kOriginalConnectionId, version) ||
+ &writer, TransportParameters::kOriginalDestinationConnectionId,
+ version) ||
!WriteTransportParameterStringPiece(
&writer,
- quiche::QuicheStringPiece(original_connection_id.data(),
- original_connection_id.length()),
+ quiche::QuicheStringPiece(
+ original_destination_connection_id.data(),
+ original_destination_connection_id.length()),
version)) {
- QUIC_BUG << "Failed to write original_connection_id "
- << in.original_connection_id.value() << " for " << in;
+ QUIC_BUG << "Failed to write original_destination_connection_id "
+ << original_destination_connection_id << " for " << in;
return false;
}
}
- if (!in.idle_timeout_milliseconds.Write(&writer, version)) {
+ if (!in.max_idle_timeout_ms.Write(&writer, version)) {
QUIC_BUG << "Failed to write idle_timeout for " << in;
return false;
}
@@ -728,7 +845,7 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
}
}
- if (!in.max_packet_size.Write(&writer, version) ||
+ if (!in.max_udp_payload_size.Write(&writer, version) ||
!in.initial_max_data.Write(&writer, version) ||
!in.initial_max_stream_data_bidi_local.Write(&writer, version) ||
!in.initial_max_stream_data_bidi_remote.Write(&writer, version) ||
@@ -744,12 +861,12 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
return false;
}
- // disable_migration
- if (in.disable_migration) {
+ // disable_active_migration
+ if (in.disable_active_migration) {
if (!WriteTransportParameterId(
- &writer, TransportParameters::kDisableMigration, version) ||
+ &writer, TransportParameters::kDisableActiveMigration, version) ||
!WriteTransportParameterLength(&writer, /*length=*/0, version)) {
- QUIC_BUG << "Failed to write disable_migration for " << in;
+ QUIC_BUG << "Failed to write disable_active_migration for " << in;
return false;
}
}
@@ -791,6 +908,42 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
}
}
+ // initial_source_connection_id
+ if (in.initial_source_connection_id.has_value()) {
+ QuicConnectionId initial_source_connection_id =
+ in.initial_source_connection_id.value();
+ if (!WriteTransportParameterId(
+ &writer, TransportParameters::kInitialSourceConnectionId,
+ version) ||
+ !WriteTransportParameterStringPiece(
+ &writer,
+ quiche::QuicheStringPiece(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;
+ return false;
+ }
+ }
+
+ // retry_source_connection_id
+ if (in.retry_source_connection_id.has_value()) {
+ DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
+ QuicConnectionId retry_source_connection_id =
+ in.retry_source_connection_id.value();
+ if (!WriteTransportParameterId(
+ &writer, TransportParameters::kRetrySourceConnectionId, version) ||
+ !WriteTransportParameterStringPiece(
+ &writer,
+ quiche::QuicheStringPiece(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;
+ return false;
+ }
+ }
+
// Google-specific connection options.
if (in.google_connection_options.has_value()) {
static_assert(sizeof(in.google_connection_options.value().front()) == 4,
@@ -827,6 +980,17 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
}
}
+ // Google-specific support handshake done.
+ if (in.support_handshake_done) {
+ if (!WriteTransportParameterId(
+ &writer, TransportParameters::kGoogleSupportHandshakeDone,
+ version) ||
+ !WriteTransportParameterLength(&writer, /*length=*/0, version)) {
+ QUIC_BUG << "Failed to write support_handshake_done for " << in;
+ return false;
+ }
+ }
+
// Google-specific non-standard parameter.
if (in.google_quic_params) {
const QuicData& serialized_google_quic_params =
@@ -910,7 +1074,6 @@ bool SerializeTransportParameters(ParsedQuicVersion version,
<< grease_id64 << " invalid for " << version;
TransportParameters::TransportParameterId grease_id =
static_cast<TransportParameters::TransportParameterId>(grease_id64);
- const size_t kMaxGreaseLength = 16;
const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
DCHECK_GE(kMaxGreaseLength, grease_length);
char grease_contents[kMaxGreaseLength];
@@ -989,41 +1152,43 @@ bool ParseTransportParameters(ParsedQuicVersion version,
QuicDataReader value_reader(value);
bool parse_success = true;
switch (param_id) {
- case TransportParameters::kOriginalConnectionId: {
- if (out->original_connection_id.has_value()) {
- *error_details = "Received a second original connection ID";
+ case TransportParameters::kOriginalDestinationConnectionId: {
+ if (out->original_destination_connection_id.has_value()) {
+ *error_details =
+ "Received a second original_destination_connection_id";
return false;
}
const size_t connection_id_length = value_reader.BytesRemaining();
if (!QuicUtils::IsConnectionIdLengthValidForVersion(
connection_id_length, version.transport_version)) {
*error_details = quiche::QuicheStrCat(
- "Received original connection ID of invalid length ",
+ "Received original_destination_connection_id of invalid length ",
connection_id_length);
return false;
}
- QuicConnectionId original_connection_id;
- if (!value_reader.ReadConnectionId(&original_connection_id,
+ QuicConnectionId original_destination_connection_id;
+ if (!value_reader.ReadConnectionId(&original_destination_connection_id,
connection_id_length)) {
- *error_details = "Failed to read original connection ID";
+ *error_details = "Failed to read original_destination_connection_id";
return false;
}
- out->original_connection_id = original_connection_id;
+ out->original_destination_connection_id =
+ original_destination_connection_id;
} break;
- case TransportParameters::kIdleTimeout:
+ case TransportParameters::kMaxIdleTimeout:
parse_success =
- out->idle_timeout_milliseconds.Read(&value_reader, error_details);
+ out->max_idle_timeout_ms.Read(&value_reader, error_details);
break;
case TransportParameters::kStatelessResetToken: {
if (!out->stateless_reset_token.empty()) {
- *error_details = "Received a second stateless reset token";
+ *error_details = "Received a second stateless_reset_token";
return false;
}
quiche::QuicheStringPiece stateless_reset_token =
value_reader.ReadRemainingPayload();
if (stateless_reset_token.length() != kStatelessResetTokenLength) {
*error_details = quiche::QuicheStrCat(
- "Received stateless reset token of invalid length ",
+ "Received stateless_reset_token of invalid length ",
stateless_reset_token.length());
return false;
}
@@ -1032,7 +1197,8 @@ bool ParseTransportParameters(ParsedQuicVersion version,
stateless_reset_token.data() + stateless_reset_token.length());
} break;
case TransportParameters::kMaxPacketSize:
- parse_success = out->max_packet_size.Read(&value_reader, error_details);
+ parse_success =
+ out->max_udp_payload_size.Read(&value_reader, error_details);
break;
case TransportParameters::kInitialMaxData:
parse_success =
@@ -1065,12 +1231,12 @@ bool ParseTransportParameters(ParsedQuicVersion version,
case TransportParameters::kMaxAckDelay:
parse_success = out->max_ack_delay.Read(&value_reader, error_details);
break;
- case TransportParameters::kDisableMigration:
- if (out->disable_migration) {
- *error_details = "Received a second disable migration";
+ case TransportParameters::kDisableActiveMigration:
+ if (out->disable_active_migration) {
+ *error_details = "Received a second disable_active_migration";
return false;
}
- out->disable_migration = true;
+ out->disable_active_migration = true;
break;
case TransportParameters::kPreferredAddress: {
TransportParameters::PreferredAddress preferred_address;
@@ -1087,7 +1253,7 @@ bool ParseTransportParameters(ParsedQuicVersion version,
&preferred_address.connection_id) ||
!value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
kStatelessResetTokenLength)) {
- *error_details = "Failed to read preferred address";
+ *error_details = "Failed to read preferred_address";
return false;
}
preferred_address.ipv4_socket_address =
@@ -1096,13 +1262,13 @@ bool ParseTransportParameters(ParsedQuicVersion version,
QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
!preferred_address.ipv6_socket_address.host().IsIPv6()) {
- *error_details = "Received preferred addresses of bad families " +
+ *error_details = "Received preferred_address of bad families " +
preferred_address.ToString();
return false;
}
if (!QuicUtils::IsConnectionIdValidForVersion(
preferred_address.connection_id, version.transport_version)) {
- *error_details = "Received invalid preferred address connection ID " +
+ *error_details = "Received invalid preferred_address connection ID " +
preferred_address.ToString();
return false;
}
@@ -1114,6 +1280,48 @@ bool ParseTransportParameters(ParsedQuicVersion version,
parse_success =
out->active_connection_id_limit.Read(&value_reader, error_details);
break;
+ case TransportParameters::kInitialSourceConnectionId: {
+ if (out->initial_source_connection_id.has_value()) {
+ *error_details = "Received a second initial_source_connection_id";
+ return false;
+ }
+ const size_t connection_id_length = value_reader.BytesRemaining();
+ if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+ connection_id_length, version.transport_version)) {
+ *error_details = quiche::QuicheStrCat(
+ "Received initial_source_connection_id of invalid length ",
+ connection_id_length);
+ return false;
+ }
+ QuicConnectionId initial_source_connection_id;
+ if (!value_reader.ReadConnectionId(&initial_source_connection_id,
+ connection_id_length)) {
+ *error_details = "Failed to read initial_source_connection_id";
+ return false;
+ }
+ out->initial_source_connection_id = initial_source_connection_id;
+ } break;
+ case TransportParameters::kRetrySourceConnectionId: {
+ if (out->retry_source_connection_id.has_value()) {
+ *error_details = "Received a second retry_source_connection_id";
+ return false;
+ }
+ const size_t connection_id_length = value_reader.BytesRemaining();
+ if (!QuicUtils::IsConnectionIdLengthValidForVersion(
+ connection_id_length, version.transport_version)) {
+ *error_details = quiche::QuicheStrCat(
+ "Received retry_source_connection_id of invalid length ",
+ connection_id_length);
+ return false;
+ }
+ QuicConnectionId retry_source_connection_id;
+ if (!value_reader.ReadConnectionId(&retry_source_connection_id,
+ connection_id_length)) {
+ *error_details = "Failed to read retry_source_connection_id";
+ return false;
+ }
+ out->retry_source_connection_id = retry_source_connection_id;
+ } break;
case TransportParameters::kMaxDatagramFrameSize:
parse_success =
out->max_datagram_frame_size.Read(&value_reader, error_details);
@@ -1124,14 +1332,14 @@ bool ParseTransportParameters(ParsedQuicVersion version,
break;
case TransportParameters::kGoogleConnectionOptions: {
if (out->google_connection_options.has_value()) {
- *error_details = "Received a second Google connection options";
+ *error_details = "Received a second google_connection_options";
return false;
}
out->google_connection_options = QuicTagVector{};
while (!value_reader.IsDoneReading()) {
QuicTag connection_option;
if (!value_reader.ReadTag(&connection_option)) {
- *error_details = "Failed to read a Google connection option";
+ *error_details = "Failed to read a google_connection_options";
return false;
}
out->google_connection_options.value().push_back(connection_option);
@@ -1139,11 +1347,18 @@ bool ParseTransportParameters(ParsedQuicVersion version,
} break;
case TransportParameters::kGoogleUserAgentId:
if (out->user_agent_id.has_value()) {
- *error_details = "Received a second user agent ID";
+ *error_details = "Received a second user_agent_id";
return false;
}
out->user_agent_id = std::string(value_reader.ReadRemainingPayload());
break;
+ case TransportParameters::kGoogleSupportHandshakeDone:
+ if (out->support_handshake_done) {
+ *error_details = "Received a second support_handshake_done";
+ return false;
+ }
+ out->support_handshake_done = true;
+ break;
case TransportParameters::kGoogleQuicParam: {
if (out->google_quic_params) {
*error_details = "Received a second Google parameter";
@@ -1208,4 +1423,87 @@ bool ParseTransportParameters(ParsedQuicVersion version,
return true;
}
+namespace {
+
+bool DigestUpdateIntegerParam(
+ EVP_MD_CTX* hash_ctx,
+ const TransportParameters::IntegerParameter& param) {
+ uint64_t value = param.value();
+ return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
+}
+
+} // namespace
+
+bool SerializeTransportParametersForTicket(
+ const TransportParameters& in,
+ const std::vector<uint8_t>& application_data,
+ std::vector<uint8_t>* out) {
+ std::string error_details;
+ if (!in.AreValid(&error_details)) {
+ QUIC_BUG << "Not serializing invalid transport parameters: "
+ << error_details;
+ return false;
+ }
+
+ out->resize(SHA256_DIGEST_LENGTH + 1);
+ const uint8_t serialization_version = 0;
+ (*out)[0] = serialization_version;
+
+ bssl::ScopedEVP_MD_CTX hash_ctx;
+ // Write application data:
+ uint64_t app_data_len = application_data.size();
+ const uint64_t parameter_version = 0;
+ // The format of the input to the hash function is as follows:
+ // - The application data, prefixed with a 64-bit length field.
+ // - Transport parameters:
+ // - A 64-bit version field indicating which version of encoding is used
+ // for transport parameters.
+ // - A list of 64-bit integers representing the relevant parameters.
+ //
+ // When changing which parameters are included, additional parameters can be
+ // added to the end of the list without changing the version field. New
+ // parameters that are variable length must be length prefixed. If
+ // parameters are removed from the list, the version field must be
+ // incremented.
+ //
+ // Integers happen to be written in host byte order, not network byte order.
+ if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
+ !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
+ !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
+ application_data.size()) ||
+ !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
+ sizeof(parameter_version))) {
+ QUIC_BUG << "Unexpected failure of EVP_Digest functions when hashing "
+ "Transport Parameters for ticket";
+ return false;
+ }
+
+ // Write transport parameters specified by draft-ietf-quic-transport-28,
+ // section 7.4.1, that are remembered for 0-RTT.
+ if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(),
+ in.initial_max_stream_data_bidi_local) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(),
+ in.initial_max_stream_data_bidi_remote) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(),
+ in.initial_max_stream_data_uni) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
+ !DigestUpdateIntegerParam(hash_ctx.get(),
+ in.active_connection_id_limit)) {
+ QUIC_BUG << "Unexpected failure of EVP_Digest functions when hashing "
+ "Transport Parameters for ticket";
+ return false;
+ }
+ uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
+ if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
+ sizeof(disable_active_migration)) ||
+ !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
+ QUIC_BUG << "Unexpected failure of EVP_Digest functions when hashing "
+ "Transport Parameters for ticket";
+ return false;
+ }
+ return true;
+}
+
} // namespace quic
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 9dec484a552..093bb09de2a 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
@@ -28,7 +28,7 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
// The identifier used to differentiate transport parameters.
enum TransportParameterId : uint64_t;
// A map used to specify custom parameters.
- using ParameterMap = QuicUnorderedMap<TransportParameterId, std::string>;
+ using ParameterMap = QuicHashMap<TransportParameterId, std::string>;
// Represents an individual QUIC transport parameter that only encodes a
// variable length integer. Can only be created inside the constructor for
// TransportParameters.
@@ -132,17 +132,17 @@ 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_connection_id;
+ quiche::QuicheOptional<QuicConnectionId> original_destination_connection_id;
- // Idle timeout expressed in milliseconds.
- IntegerParameter idle_timeout_milliseconds;
+ // Maximum idle timeout expressed in milliseconds.
+ IntegerParameter max_idle_timeout_ms;
// Stateless reset token used in verifying stateless resets.
std::vector<uint8_t> stateless_reset_token;
// Limits the size of packets that the endpoint is willing to receive.
// This indicates that packets larger than this limit will be dropped.
- IntegerParameter max_packet_size;
+ IntegerParameter max_udp_payload_size;
// Contains the initial value for the maximum amount of data that can
// be sent on the connection.
@@ -171,7 +171,7 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
IntegerParameter max_ack_delay;
// Indicates lack of support for connection migration.
- bool disable_migration;
+ bool disable_active_migration;
// Used to effect a change in server address at the end of the handshake.
std::unique_ptr<PreferredAddress> preferred_address;
@@ -180,6 +180,14 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
// to store.
IntegerParameter active_connection_id_limit;
+ // 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;
+
+ // 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;
+
// Indicates support for the DATAGRAM frame and the maximum frame size that
// the sender accepts. See draft-ietf-quic-datagram.
IntegerParameter max_datagram_frame_size;
@@ -194,6 +202,9 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
// Google-specific user agent identifier.
quiche::QuicheOptional<std::string> user_agent_id;
+ // Google-specific handshake done support. This is only used for T050.
+ bool support_handshake_done;
+
// Transport parameters used by Google QUIC but not IETF QUIC. This is
// serialized into a TransportParameter struct with a TransportParameterId of
// kGoogleQuicParamId.
@@ -235,6 +246,19 @@ QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
TransportParameters* out,
std::string* error_details);
+// Serializes |in| and |application_data| in a deterministic format so that
+// multiple calls to SerializeTransportParametersForTicket with the same inputs
+// will generate the same output, and if the inputs differ, then the output will
+// differ. The output of this function is used by the server in
+// SSL_set_quic_early_data_context to determine whether early data should be
+// accepted: Early data will only be accepted if the inputs to this function
+// match what they were on the connection that issued an early data capable
+// ticket.
+QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
+ const TransportParameters& in,
+ const std::vector<uint8_t>& application_data,
+ std::vector<uint8_t>* out);
+
} // namespace quic
#endif // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
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 1fc1f5c5c93..39919532dc6 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
@@ -44,6 +44,7 @@ const uint64_t kFakeInitialRoundTripTime = 53;
const uint8_t kFakePreferredStatelessResetTokenData[16] = {
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
+const bool kFakeSupportHandshakeDone = true;
const auto kCustomParameter1 =
static_cast<TransportParameters::TransportParameterId>(0xffcd);
@@ -52,10 +53,18 @@ const auto kCustomParameter2 =
static_cast<TransportParameters::TransportParameterId>(0xff34);
const char* kCustomParameter2Value = "bar";
-QuicConnectionId CreateFakeOriginalConnectionId() {
+QuicConnectionId CreateFakeOriginalDestinationConnectionId() {
return TestConnectionId(0x1337);
}
+QuicConnectionId CreateFakeInitialSourceConnectionId() {
+ return TestConnectionId(0x2345);
+}
+
+QuicConnectionId CreateFakeRetrySourceConnectionId() {
+ return TestConnectionId(0x9876);
+}
+
QuicConnectionId CreateFakePreferredConnectionId() {
return TestConnectionId(0xBEEF);
}
@@ -151,8 +160,8 @@ TEST_P(TransportParametersTest, Comparator) {
new_params.perspective = Perspective::IS_CLIENT;
orig_params.version = kFakeVersionLabel;
new_params.version = kFakeVersionLabel;
- orig_params.disable_migration = true;
- new_params.disable_migration = true;
+ orig_params.disable_active_migration = true;
+ new_params.disable_active_migration = true;
EXPECT_EQ(orig_params, new_params);
EXPECT_TRUE(orig_params == new_params);
EXPECT_FALSE(orig_params != new_params);
@@ -172,12 +181,12 @@ TEST_P(TransportParametersTest, Comparator) {
EXPECT_FALSE(orig_params != new_params);
// Test comparison on IntegerParameters.
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
- new_params.max_packet_size.set_value(kFakeMaxPacketSize + 1);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
+ new_params.max_udp_payload_size.set_value(kFakeMaxPacketSize + 1);
EXPECT_NE(orig_params, new_params);
EXPECT_FALSE(orig_params == new_params);
EXPECT_TRUE(orig_params != new_params);
- new_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ new_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
EXPECT_EQ(orig_params, new_params);
EXPECT_TRUE(orig_params == new_params);
EXPECT_FALSE(orig_params != new_params);
@@ -222,6 +231,23 @@ TEST_P(TransportParametersTest, Comparator) {
EXPECT_EQ(orig_params, new_params);
EXPECT_TRUE(orig_params == new_params);
EXPECT_FALSE(orig_params != new_params);
+
+ // Test comparison on connection IDs.
+ orig_params.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
+ new_params.initial_source_connection_id = QUICHE_NULLOPT;
+ EXPECT_NE(orig_params, new_params);
+ EXPECT_FALSE(orig_params == new_params);
+ EXPECT_TRUE(orig_params != new_params);
+ new_params.initial_source_connection_id = TestConnectionId(0xbadbad);
+ EXPECT_NE(orig_params, new_params);
+ EXPECT_FALSE(orig_params == new_params);
+ EXPECT_TRUE(orig_params != new_params);
+ new_params.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
+ EXPECT_EQ(orig_params, new_params);
+ EXPECT_TRUE(orig_params == new_params);
+ EXPECT_FALSE(orig_params != new_params);
}
TEST_P(TransportParametersTest, CopyConstructor) {
@@ -230,10 +256,11 @@ TEST_P(TransportParametersTest, CopyConstructor) {
orig_params.version = kFakeVersionLabel;
orig_params.supported_versions.push_back(kFakeVersionLabel);
orig_params.supported_versions.push_back(kFakeVersionLabel2);
- orig_params.original_connection_id = CreateFakeOriginalConnectionId();
- orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+ orig_params.original_destination_connection_id =
+ CreateFakeOriginalDestinationConnectionId();
+ orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
orig_params.initial_max_data.set_value(kFakeInitialMaxData);
orig_params.initial_max_stream_data_bidi_local.set_value(
kFakeInitialMaxStreamDataBidiLocal);
@@ -245,13 +272,17 @@ TEST_P(TransportParametersTest, CopyConstructor) {
orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
- orig_params.disable_migration = kFakeDisableMigration;
+ orig_params.disable_active_migration = kFakeDisableMigration;
orig_params.preferred_address = CreateFakePreferredAddress();
orig_params.active_connection_id_limit.set_value(
kFakeActiveConnectionIdLimit);
+ orig_params.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
+ orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
orig_params.user_agent_id = CreateFakeUserAgentId();
+ orig_params.support_handshake_done = kFakeSupportHandshakeDone;
orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
@@ -263,8 +294,8 @@ TEST_P(TransportParametersTest, RoundTripClient) {
TransportParameters orig_params;
orig_params.perspective = Perspective::IS_CLIENT;
orig_params.version = kFakeVersionLabel;
- orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
orig_params.initial_max_data.set_value(kFakeInitialMaxData);
orig_params.initial_max_stream_data_bidi_local.set_value(
kFakeInitialMaxStreamDataBidiLocal);
@@ -276,12 +307,15 @@ TEST_P(TransportParametersTest, RoundTripClient) {
orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
- orig_params.disable_migration = kFakeDisableMigration;
+ orig_params.disable_active_migration = kFakeDisableMigration;
orig_params.active_connection_id_limit.set_value(
kFakeActiveConnectionIdLimit);
+ orig_params.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
orig_params.initial_round_trip_time_us.set_value(kFakeInitialRoundTripTime);
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
orig_params.user_agent_id = CreateFakeUserAgentId();
+ orig_params.support_handshake_done = kFakeSupportHandshakeDone;
orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
@@ -305,10 +339,11 @@ TEST_P(TransportParametersTest, RoundTripServer) {
orig_params.version = kFakeVersionLabel;
orig_params.supported_versions.push_back(kFakeVersionLabel);
orig_params.supported_versions.push_back(kFakeVersionLabel2);
- orig_params.original_connection_id = CreateFakeOriginalConnectionId();
- orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+ orig_params.original_destination_connection_id =
+ CreateFakeOriginalDestinationConnectionId();
+ orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
orig_params.initial_max_data.set_value(kFakeInitialMaxData);
orig_params.initial_max_stream_data_bidi_local.set_value(
kFakeInitialMaxStreamDataBidiLocal);
@@ -320,10 +355,13 @@ TEST_P(TransportParametersTest, RoundTripServer) {
orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
- orig_params.disable_migration = kFakeDisableMigration;
+ orig_params.disable_active_migration = kFakeDisableMigration;
orig_params.preferred_address = CreateFakePreferredAddress();
orig_params.active_connection_id_limit.set_value(
kFakeActiveConnectionIdLimit);
+ orig_params.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
+ orig_params.retry_source_connection_id = CreateFakeRetrySourceConnectionId();
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
std::vector<uint8_t> serialized;
@@ -354,10 +392,10 @@ TEST_P(TransportParametersTest, AreValid) {
params.perspective = Perspective::IS_CLIENT;
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+ params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.idle_timeout_milliseconds.set_value(601000);
+ params.max_idle_timeout_ms.set_value(601000);
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
}
@@ -367,27 +405,27 @@ TEST_P(TransportParametersTest, AreValid) {
params.perspective = Perspective::IS_CLIENT;
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.max_packet_size.set_value(1200);
+ params.max_udp_payload_size.set_value(1200);
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.max_packet_size.set_value(65535);
+ params.max_udp_payload_size.set_value(65535);
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.max_packet_size.set_value(9999999);
+ params.max_udp_payload_size.set_value(9999999);
EXPECT_TRUE(params.AreValid(&error_details));
EXPECT_TRUE(error_details.empty());
- params.max_packet_size.set_value(0);
+ params.max_udp_payload_size.set_value(0);
error_details = "";
EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(
- error_details,
- "Invalid transport parameters [Client max_packet_size 0 (Invalid)]");
- params.max_packet_size.set_value(1199);
+ EXPECT_EQ(error_details,
+ "Invalid transport parameters [Client max_udp_payload_size 0 "
+ "(Invalid)]");
+ params.max_udp_payload_size.set_value(1199);
error_details = "";
EXPECT_FALSE(params.AreValid(&error_details));
- EXPECT_EQ(
- error_details,
- "Invalid transport parameters [Client max_packet_size 1199 (Invalid)]");
+ EXPECT_EQ(error_details,
+ "Invalid transport parameters [Client max_udp_payload_size 1199 "
+ "(Invalid)]");
}
{
TransportParameters params;
@@ -436,9 +474,9 @@ TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
TransportParameters orig_params;
orig_params.perspective = Perspective::IS_CLIENT;
orig_params.version = kFakeVersionLabel;
- orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
+ orig_params.max_idle_timeout_ms.set_value(kFakeIdleTimeoutMilliseconds);
orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
std::vector<uint8_t> out;
bool ok;
@@ -452,12 +490,12 @@ TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
TEST_P(TransportParametersTest, ParseClientParams) {
// clang-format off
const uint8_t kClientParamsOld[] = {
- 0x00, 0x6a, // length of the parameters array that follows
- // idle_timeout
+ 0x00, 0x7A, // length of the parameters array that follows
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
- // max_packet_size
+ // max_udp_payload_size
0x00, 0x03, // parameter id
0x00, 0x02, // length
0x63, 0x29, // value
@@ -493,13 +531,17 @@ TEST_P(TransportParametersTest, ParseClientParams) {
0x00, 0x0b, // parameter id
0x00, 0x01, // length
0x33, // value
- // disable_migration
+ // disable_active_migration
0x00, 0x0c, // parameter id
0x00, 0x00, // length
// active_connection_id_limit
0x00, 0x0e, // parameter id
0x00, 0x01, // length
0x34, // value
+ // initial_source_connection_id
+ 0x00, 0x0f, // parameter id
+ 0x00, 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
// initial_round_trip_time_us
0x31, 0x27, // parameter id
0x00, 0x01, // length
@@ -514,17 +556,20 @@ TEST_P(TransportParametersTest, ParseClientParams) {
0x31, 0x29, // parameter id
0x00, 0x08, // length
'F', 'a', 'k', 'e', 'U', 'A', 'I', 'D', // value
+ // support_handshake_done
+ 0x31, 0x2A, // parameter id
+ 0x00, 0x00, // value
// Google version extension
0x47, 0x52, // parameter id
0x00, 0x04, // length
0x01, 0x23, 0x45, 0x67, // initial version
};
const uint8_t kClientParams[] = {
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
- // max_packet_size
+ // max_udp_payload_size
0x03, // parameter id
0x02, // length
0x63, 0x29, // value
@@ -560,13 +605,17 @@ TEST_P(TransportParametersTest, ParseClientParams) {
0x0b, // parameter id
0x01, // length
0x33, // value
- // disable_migration
+ // disable_active_migration
0x0c, // parameter id
0x00, // length
// active_connection_id_limit
0x0e, // parameter id
0x01, // length
0x34, // value
+ // initial_source_connection_id
+ 0x0f, // parameter id
+ 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
// initial_round_trip_time_us
0x71, 0x27, // parameter id
0x01, // length
@@ -581,6 +630,9 @@ TEST_P(TransportParametersTest, ParseClientParams) {
0x71, 0x29, // parameter id
0x08, // length
'F', 'a', 'k', 'e', 'U', 'A', 'I', 'D', // value
+ // support_handshake_done
+ 0x71, 0x2A, // parameter id
+ 0x00, // length
// Google version extension
0x80, 0x00, 0x47, 0x52, // parameter id
0x04, // length
@@ -604,11 +656,11 @@ TEST_P(TransportParametersTest, ParseClientParams) {
EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
EXPECT_EQ(kFakeVersionLabel, new_params.version);
EXPECT_TRUE(new_params.supported_versions.empty());
- EXPECT_FALSE(new_params.original_connection_id.has_value());
+ EXPECT_FALSE(new_params.original_destination_connection_id.has_value());
EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
- new_params.idle_timeout_milliseconds.value());
+ new_params.max_idle_timeout_ms.value());
EXPECT_TRUE(new_params.stateless_reset_token.empty());
- EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
+ EXPECT_EQ(kFakeMaxPacketSize, new_params.max_udp_payload_size.value());
EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
new_params.initial_max_stream_data_bidi_local.value());
@@ -622,9 +674,13 @@ TEST_P(TransportParametersTest, ParseClientParams) {
new_params.initial_max_streams_uni.value());
EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
- EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
+ EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
EXPECT_EQ(kFakeActiveConnectionIdLimit,
new_params.active_connection_id_limit.value());
+ ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+ EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+ new_params.initial_source_connection_id.value());
+ EXPECT_FALSE(new_params.retry_source_connection_id.has_value());
EXPECT_EQ(kFakeInitialRoundTripTime,
new_params.initial_round_trip_time_us.value());
ASSERT_TRUE(new_params.google_connection_options.has_value());
@@ -632,6 +688,7 @@ TEST_P(TransportParametersTest, ParseClientParams) {
new_params.google_connection_options.value());
ASSERT_TRUE(new_params.user_agent_id.has_value());
EXPECT_EQ(CreateFakeUserAgentId(), new_params.user_agent_id.value());
+ EXPECT_TRUE(new_params.support_handshake_done);
}
TEST_P(TransportParametersTest,
@@ -639,7 +696,7 @@ TEST_P(TransportParametersTest,
// clang-format off
const uint8_t kClientParamsWithFullTokenOld[] = {
0x00, 0x26, // length parameters array that follows
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
@@ -648,7 +705,7 @@ TEST_P(TransportParametersTest,
0x00, 0x10, // length
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_packet_size
+ // max_udp_payload_size
0x00, 0x03, // parameter id
0x00, 0x02, // length
0x63, 0x29, // value
@@ -658,7 +715,7 @@ TEST_P(TransportParametersTest,
0x40, 0x65, // value
};
const uint8_t kClientParamsWithFullToken[] = {
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -667,7 +724,7 @@ TEST_P(TransportParametersTest,
0x10, // length
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_packet_size
+ // max_udp_payload_size
0x03, // parameter id
0x02, // length
0x63, 0x29, // value
@@ -698,14 +755,14 @@ TEST_P(TransportParametersTest,
// clang-format off
const uint8_t kClientParamsWithEmptyTokenOld[] = {
0x00, 0x16, // length parameters array that follows
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
// stateless_reset_token
0x00, 0x02, // parameter id
0x00, 0x00,
- // max_packet_size
+ // max_udp_payload_size
0x00, 0x03, // parameter id
0x00, 0x02, // length
0x63, 0x29, // value
@@ -715,14 +772,14 @@ TEST_P(TransportParametersTest,
0x40, 0x65, // value
};
const uint8_t kClientParamsWithEmptyToken[] = {
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
// stateless_reset_token
0x02, // parameter id
0x00, // length
- // max_packet_size
+ // max_udp_payload_size
0x03, // parameter id
0x02, // length
0x63, 0x29, // value
@@ -746,36 +803,36 @@ TEST_P(TransportParametersTest,
client_params, client_params_length,
&out_params, &error_details));
EXPECT_EQ(error_details,
- "Received stateless reset token of invalid length 0");
+ "Received stateless_reset_token of invalid length 0");
}
TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
// clang-format off
const uint8_t kClientParamsRepeatedOld[] = {
0x00, 0x12, // length parameters array that follows
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
- // max_packet_size
+ // max_udp_payload_size
0x00, 0x03, // parameter id
0x00, 0x02, // length
0x63, 0x29, // value
- // idle_timeout (repeated)
+ // max_idle_timeout (repeated)
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
};
const uint8_t kClientParamsRepeated[] = {
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
- // max_packet_size
+ // max_udp_payload_size
0x03, // parameter id
0x02, // length
0x63, 0x29, // value
- // idle_timeout (repeated)
+ // max_idle_timeout (repeated)
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -793,18 +850,18 @@ TEST_P(TransportParametersTest, ParseClientParametersRepeated) {
EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
client_params, client_params_length,
&out_params, &error_details));
- EXPECT_EQ(error_details, "Received a second idle_timeout");
+ EXPECT_EQ(error_details, "Received a second max_idle_timeout");
}
TEST_P(TransportParametersTest, ParseServerParams) {
// clang-format off
const uint8_t kServerParamsOld[] = {
- 0x00, 0xb7, // length of parameters array that follows
- // original_connection_id
+ 0x00, 0xd3, // length of parameters array that follows
+ // original_destination_connection_id
0x00, 0x00, // parameter id
0x00, 0x08, // length
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
@@ -813,7 +870,7 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x00, 0x10, // length
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_packet_size
+ // max_udp_payload_size
0x00, 0x03, // parameter id
0x00, 0x02, // length
0x63, 0x29, // value
@@ -849,7 +906,7 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x00, 0x0b, // parameter id
0x00, 0x01, // length
0x33, // value
- // disable_migration
+ // disable_active_migration
0x00, 0x0c, // parameter id
0x00, 0x00, // length
// preferred_address
@@ -868,12 +925,23 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x00, 0x0e, // parameter id
0x00, 0x01, // length
0x34, // value
+ // initial_source_connection_id
+ 0x00, 0x0f, // parameter id
+ 0x00, 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+ // retry_source_connection_id
+ 0x00, 0x10, // parameter id
+ 0x00, 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
// google_connection_options
0x31, 0x28, // parameter id
0x00, 0x0c, // length
'A', 'L', 'P', 'N', // value
'E', 'F', 'G', 0x00,
'H', 'I', 'J', 0xff,
+ // support_handshake_done
+ 0x31, 0x2A, // parameter id
+ 0x00, 0x00, // value
// Google version extension
0x47, 0x52, // parameter id
0x00, 0x0d, // length
@@ -883,11 +951,11 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x89, 0xab, 0xcd, 0xef,
};
const uint8_t kServerParams[] = {
- // original_connection_id
+ // original_destination_connection_id
0x00, // parameter id
0x08, // length
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -896,7 +964,7 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x10, // length
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
- // max_packet_size
+ // max_udp_payload_size
0x03, // parameter id
0x02, // length
0x63, 0x29, // value
@@ -932,7 +1000,7 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x0b, // parameter id
0x01, // length
0x33, // value
- // disable_migration
+ // disable_active_migration
0x0c, // parameter id
0x00, // length
// preferred_address
@@ -951,12 +1019,23 @@ TEST_P(TransportParametersTest, ParseServerParams) {
0x0e, // parameter id
0x01, // length
0x34, // value
+ // initial_source_connection_id
+ 0x0f, // parameter id
+ 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45,
+ // retry_source_connection_id
+ 0x10, // parameter id
+ 0x08, // length
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x76,
// google_connection_options
0x71, 0x28, // parameter id
0x0c, // length
'A', 'L', 'P', 'N', // value
'E', 'F', 'G', 0x00,
'H', 'I', 'J', 0xff,
+ // support_handshake_done
+ 0x71, 0x2A, // parameter id
+ 0x00, // length
// Google version extension
0x80, 0x00, 0x47, 0x52, // parameter id
0x0d, // length
@@ -985,13 +1064,13 @@ TEST_P(TransportParametersTest, ParseServerParams) {
EXPECT_EQ(2u, new_params.supported_versions.size());
EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]);
EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]);
- ASSERT_TRUE(new_params.original_connection_id.has_value());
- EXPECT_EQ(CreateFakeOriginalConnectionId(),
- new_params.original_connection_id.value());
+ ASSERT_TRUE(new_params.original_destination_connection_id.has_value());
+ EXPECT_EQ(CreateFakeOriginalDestinationConnectionId(),
+ new_params.original_destination_connection_id.value());
EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
- new_params.idle_timeout_milliseconds.value());
+ new_params.max_idle_timeout_ms.value());
EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token);
- EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
+ EXPECT_EQ(kFakeMaxPacketSize, new_params.max_udp_payload_size.value());
EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
new_params.initial_max_stream_data_bidi_local.value());
@@ -1005,7 +1084,7 @@ TEST_P(TransportParametersTest, ParseServerParams) {
new_params.initial_max_streams_uni.value());
EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
- EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
+ EXPECT_EQ(kFakeDisableMigration, new_params.disable_active_migration);
ASSERT_NE(nullptr, new_params.preferred_address.get());
EXPECT_EQ(CreateFakeV4SocketAddress(),
new_params.preferred_address->ipv4_socket_address);
@@ -1017,21 +1096,28 @@ TEST_P(TransportParametersTest, ParseServerParams) {
new_params.preferred_address->stateless_reset_token);
EXPECT_EQ(kFakeActiveConnectionIdLimit,
new_params.active_connection_id_limit.value());
+ ASSERT_TRUE(new_params.initial_source_connection_id.has_value());
+ EXPECT_EQ(CreateFakeInitialSourceConnectionId(),
+ new_params.initial_source_connection_id.value());
+ ASSERT_TRUE(new_params.retry_source_connection_id.has_value());
+ EXPECT_EQ(CreateFakeRetrySourceConnectionId(),
+ new_params.retry_source_connection_id.value());
ASSERT_TRUE(new_params.google_connection_options.has_value());
EXPECT_EQ(CreateFakeGoogleConnectionOptions(),
new_params.google_connection_options.value());
EXPECT_FALSE(new_params.user_agent_id.has_value());
+ EXPECT_TRUE(new_params.support_handshake_done);
}
TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
// clang-format off
const uint8_t kServerParamsRepeatedOld[] = {
0x00, 0x2c, // length of parameters array that follows
- // original_connection_id
+ // original_destination_connection_id
0x00, 0x00, // parameter id
0x00, 0x08, // length
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
@@ -1040,17 +1126,17 @@ TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
0x00, 0x10, // length
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- // idle_timeout (repeated)
+ // max_idle_timeout (repeated)
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
};
const uint8_t kServerParamsRepeated[] = {
- // original_connection_id
+ // original_destination_connection_id
0x00, // parameter id
0x08, // length
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -1059,7 +1145,7 @@ TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
0x10, // length
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- // idle_timeout (repeated)
+ // max_idle_timeout (repeated)
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -1077,7 +1163,7 @@ TEST_P(TransportParametersTest, ParseServerParametersRepeated) {
EXPECT_FALSE(ParseTransportParameters(version_, Perspective::IS_SERVER,
server_params, server_params_length,
&out_params, &error_details));
- EXPECT_EQ(error_details, "Received a second idle_timeout");
+ EXPECT_EQ(error_details, "Received a second max_idle_timeout");
}
TEST_P(TransportParametersTest,
@@ -1085,10 +1171,10 @@ TEST_P(TransportParametersTest,
// clang-format off
const uint8_t kServerParamsEmptyOriginalConnectionIdOld[] = {
0x00, 0x1e, // length of parameters array that follows
- // original_connection_id
+ // original_destination_connection_id
0x00, 0x00, // parameter id
0x00, 0x00, // length
- // idle_timeout
+ // max_idle_timeout
0x00, 0x01, // parameter id
0x00, 0x02, // length
0x6e, 0xec, // value
@@ -1099,10 +1185,10 @@ TEST_P(TransportParametersTest,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
};
const uint8_t kServerParamsEmptyOriginalConnectionId[] = {
- // original_connection_id
+ // original_destination_connection_id
0x00, // parameter id
0x00, // length
- // idle_timeout
+ // max_idle_timeout
0x01, // parameter id
0x02, // length
0x6e, 0xec, // value
@@ -1129,15 +1215,16 @@ TEST_P(TransportParametersTest,
server_params, server_params_length,
&out_params, &error_details))
<< error_details;
- ASSERT_TRUE(out_params.original_connection_id.has_value());
- EXPECT_EQ(out_params.original_connection_id.value(), EmptyQuicConnectionId());
+ ASSERT_TRUE(out_params.original_destination_connection_id.has_value());
+ EXPECT_EQ(out_params.original_destination_connection_id.value(),
+ EmptyQuicConnectionId());
}
TEST_P(TransportParametersTest, CryptoHandshakeMessageRoundtrip) {
TransportParameters orig_params;
orig_params.perspective = Perspective::IS_CLIENT;
orig_params.version = kFakeVersionLabel;
- orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
+ orig_params.max_udp_payload_size.set_value(kFakeMaxPacketSize);
orig_params.google_quic_params = std::make_unique<CryptoHandshakeMessage>();
const std::string kTestString = "test string";
@@ -1166,7 +1253,132 @@ TEST_P(TransportParametersTest, CryptoHandshakeMessageRoundtrip) {
IsQuicNoError());
EXPECT_EQ(test_value, kTestValue);
EXPECT_EQ(kFakeVersionLabel, new_params.version);
- EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
+ EXPECT_EQ(kFakeMaxPacketSize, new_params.max_udp_payload_size.value());
+}
+
+TEST_P(TransportParametersTest, VeryLongCustomParameter) {
+ // Ensure we can handle a 70KB custom parameter on both send and receive.
+ size_t custom_value_length = 70000;
+ if (!version_.HasVarIntTransportParams()) {
+ // These versions encode lengths as uint16 so they cannot send as much.
+ custom_value_length = 65000;
+ }
+ std::string custom_value(custom_value_length, '?');
+ TransportParameters orig_params;
+ orig_params.perspective = Perspective::IS_CLIENT;
+ orig_params.version = kFakeVersionLabel;
+ orig_params.custom_parameters[kCustomParameter1] = custom_value;
+
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+
+ TransportParameters new_params;
+ std::string error_details;
+ ASSERT_TRUE(ParseTransportParameters(version_, Perspective::IS_CLIENT,
+ serialized.data(), serialized.size(),
+ &new_params, &error_details))
+ << error_details;
+ EXPECT_TRUE(error_details.empty());
+ RemoveGreaseParameters(&new_params);
+ EXPECT_EQ(new_params, orig_params);
+}
+
+class TransportParametersTicketSerializationTest : public QuicTest {
+ protected:
+ void SetUp() override {
+ original_params_.perspective = Perspective::IS_SERVER;
+ original_params_.version = kFakeVersionLabel;
+ original_params_.supported_versions.push_back(kFakeVersionLabel);
+ original_params_.supported_versions.push_back(kFakeVersionLabel2);
+ original_params_.original_destination_connection_id =
+ CreateFakeOriginalDestinationConnectionId();
+ original_params_.max_idle_timeout_ms.set_value(
+ kFakeIdleTimeoutMilliseconds);
+ original_params_.stateless_reset_token = CreateFakeStatelessResetToken();
+ original_params_.max_udp_payload_size.set_value(kFakeMaxPacketSize);
+ original_params_.initial_max_data.set_value(kFakeInitialMaxData);
+ original_params_.initial_max_stream_data_bidi_local.set_value(
+ kFakeInitialMaxStreamDataBidiLocal);
+ original_params_.initial_max_stream_data_bidi_remote.set_value(
+ kFakeInitialMaxStreamDataBidiRemote);
+ original_params_.initial_max_stream_data_uni.set_value(
+ kFakeInitialMaxStreamDataUni);
+ original_params_.initial_max_streams_bidi.set_value(
+ kFakeInitialMaxStreamsBidi);
+ original_params_.initial_max_streams_uni.set_value(
+ kFakeInitialMaxStreamsUni);
+ original_params_.ack_delay_exponent.set_value(kFakeAckDelayExponent);
+ original_params_.max_ack_delay.set_value(kFakeMaxAckDelay);
+ original_params_.disable_active_migration = kFakeDisableMigration;
+ original_params_.preferred_address = CreateFakePreferredAddress();
+ original_params_.active_connection_id_limit.set_value(
+ kFakeActiveConnectionIdLimit);
+ original_params_.initial_source_connection_id =
+ CreateFakeInitialSourceConnectionId();
+ original_params_.retry_source_connection_id =
+ CreateFakeRetrySourceConnectionId();
+ original_params_.google_connection_options =
+ CreateFakeGoogleConnectionOptions();
+
+ ASSERT_TRUE(SerializeTransportParametersForTicket(
+ original_params_, application_state_, &original_serialized_params_));
+ }
+
+ TransportParameters original_params_;
+ std::vector<uint8_t> application_state_ = {0, 1};
+ std::vector<uint8_t> original_serialized_params_;
+};
+
+TEST_F(TransportParametersTicketSerializationTest,
+ StatelessResetTokenDoesntChangeOutput) {
+ // Test that changing the stateless reset token doesn't change the ticket
+ // serialization.
+ TransportParameters new_params = original_params_;
+ new_params.stateless_reset_token = CreateFakePreferredStatelessResetToken();
+ EXPECT_NE(new_params, original_params_);
+
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(SerializeTransportParametersForTicket(
+ new_params, application_state_, &serialized));
+ EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+ ConnectionIDDoesntChangeOutput) {
+ // Changing original destination CID doesn't change serialization.
+ TransportParameters new_params = original_params_;
+ new_params.original_destination_connection_id = TestConnectionId(0xCAFE);
+ EXPECT_NE(new_params, original_params_);
+
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(SerializeTransportParametersForTicket(
+ new_params, application_state_, &serialized));
+ EXPECT_EQ(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest, StreamLimitChangesOutput) {
+ // Changing a stream limit does change the serialization.
+ TransportParameters new_params = original_params_;
+ new_params.initial_max_stream_data_bidi_local.set_value(
+ kFakeInitialMaxStreamDataBidiLocal + 1);
+ EXPECT_NE(new_params, original_params_);
+
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(SerializeTransportParametersForTicket(
+ new_params, application_state_, &serialized));
+ EXPECT_NE(original_serialized_params_, serialized);
+}
+
+TEST_F(TransportParametersTicketSerializationTest,
+ ApplicationStateChangesOutput) {
+ // Changing the application state changes the serialization.
+ std::vector<uint8_t> new_application_state = {0};
+ EXPECT_NE(new_application_state, application_state_);
+
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(SerializeTransportParametersForTicket(
+ original_params_, new_application_state, &serialized));
+ EXPECT_NE(original_serialized_params_, serialized);
}
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc
new file mode 100644
index 00000000000..b8c7efafa98
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.cc
@@ -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.
+
+#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h"
+#include <cstdint>
+#include <limits>
+
+namespace quic {
+
+std::ostream& operator<<(std::ostream& os, const QuicAckFrequencyFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", sequence_number: " << frame.sequence_number
+ << ", packet_tolerance: " << frame.packet_tolerance
+ << ", max_ack_delay_ms: " << frame.max_ack_delay.ToMilliseconds()
+ << ", ignore_order: " << frame.ignore_order << " }\n";
+ return os;
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h
new file mode 100644
index 00000000000..52b70daff2e
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h
@@ -0,0 +1,45 @@
+// 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_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
+
+#include <cstdint>
+#include <ostream>
+
+#include "net/third_party/quiche/src/quic/core/quic_constants.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_export.h"
+
+namespace quic {
+
+// A frame that allows sender control of acknowledgement delays.
+struct QUIC_EXPORT_PRIVATE QuicAckFrequencyFrame {
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicAckFrequencyFrame& ack_frequency_frame);
+
+ // A unique identifier of this control frame. 0 when this frame is received,
+ // and non-zero when sent.
+ QuicControlFrameId control_frame_id = kInvalidControlFrameId;
+
+ // If true, do not ack immediately upon observeation of packet reordering.
+ bool ignore_order = false;
+
+ // Sequence number assigned to the ACK_FREQUENCY frame by the sender to allow
+ // receivers to ignore obsolete frames.
+ uint64_t sequence_number = 0;
+
+ // The maximum number of ack-eliciting packets after which the receiver sends
+ // an acknowledgement. Invald if == 0.
+ uint64_t packet_tolerance = 0;
+
+ // The maximum time that ack packets can be delayed.
+ QuicTime::Delta max_ack_delay = QuicTime::Delta::Zero();
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FREQUENCY_FRAME_H_
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 81b3e18a6b2..bef5f286d23 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
@@ -32,8 +32,7 @@ QuicCryptoFrame::~QuicCryptoFrame() {}
std::ostream& operator<<(std::ostream& os,
const QuicCryptoFrame& stream_frame) {
- os << "{ level: " << EncryptionLevelToString(stream_frame.level)
- << ", offset: " << stream_frame.offset
+ os << "{ level: " << stream_frame.level << ", offset: " << stream_frame.offset
<< ", length: " << stream_frame.data_length << " }\n";
return os;
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc
index d40202f1930..99b0963a2dc 100644
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frame.cc
@@ -6,6 +6,7 @@
#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.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_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -75,6 +76,9 @@ QuicFrame::QuicFrame(QuicMessageFrame* frame)
QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
: type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
+QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
+ : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
+
void DeleteFrames(QuicFrames* frames) {
for (QuicFrame& frame : *frames) {
DeleteFrame(&frame);
@@ -136,7 +140,9 @@ void DeleteFrame(QuicFrame* frame) {
case NEW_TOKEN_FRAME:
delete frame->new_token_frame;
break;
-
+ case ACK_FREQUENCY_FRAME:
+ delete frame->ack_frequency_frame;
+ break;
case NUM_FRAME_TYPES:
DCHECK(false) << "Cannot delete type: " << frame->type;
}
@@ -164,6 +170,7 @@ bool IsControlFrame(QuicFrameType type) {
case PING_FRAME:
case STOP_SENDING_FRAME:
case HANDSHAKE_DONE_FRAME:
+ case ACK_FREQUENCY_FRAME:
return true;
default:
return false;
@@ -190,6 +197,8 @@ QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
return frame.stop_sending_frame->control_frame_id;
case HANDSHAKE_DONE_FRAME:
return frame.handshake_done_frame.control_frame_id;
+ case ACK_FREQUENCY_FRAME:
+ return frame.ack_frequency_frame->control_frame_id;
default:
return kInvalidControlFrameId;
}
@@ -224,6 +233,9 @@ void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
case HANDSHAKE_DONE_FRAME:
frame->handshake_done_frame.control_frame_id = control_frame_id;
return;
+ case ACK_FREQUENCY_FRAME:
+ frame->ack_frequency_frame->control_frame_id = control_frame_id;
+ return;
default:
QUIC_BUG
<< "Try to set control frame id of a frame without control frame id";
@@ -261,6 +273,9 @@ QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
copy = QuicFrame(
QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
break;
+ case ACK_FREQUENCY_FRAME:
+ copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+ break;
default:
QUIC_BUG << "Try to copy a non-retransmittable control frame: " << frame;
copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
@@ -352,6 +367,9 @@ QuicFrame CopyQuicFrame(QuicBufferAllocator* allocator,
copy = QuicFrame(
QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
break;
+ case ACK_FREQUENCY_FRAME:
+ copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
+ break;
default:
QUIC_BUG << "Cannot copy frame: " << frame;
copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
@@ -451,6 +469,9 @@ std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
case HANDSHAKE_DONE_FRAME:
os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
break;
+ case ACK_FREQUENCY_FRAME:
+ os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
+ break;
default: {
QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
break;
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 756b69f1db0..a8aabfc4ca5 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
@@ -9,6 +9,7 @@
#include <vector>
#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frame.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_blocked_frame.h"
#include "net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h"
#include "net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h"
@@ -62,6 +63,7 @@ struct QUIC_EXPORT_PRIVATE QuicFrame {
explicit QuicFrame(QuicStopSendingFrame* frame);
explicit QuicFrame(QuicMessageFrame* message_frame);
explicit QuicFrame(QuicCryptoFrame* crypto_frame);
+ explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
const QuicFrame& frame);
@@ -102,6 +104,7 @@ struct QUIC_EXPORT_PRIVATE QuicFrame {
QuicStopSendingFrame* stop_sending_frame;
QuicMessageFrame* message_frame;
QuicCryptoFrame* crypto_frame;
+ QuicAckFrequencyFrame* ack_frequency_frame;
QuicNewTokenFrame* new_token_frame;
};
};
diff --git a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc
index 22322ed8ee2..3f04c8c0704 100644
--- a/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/frames/quic_frames_test.cc
@@ -15,6 +15,7 @@
#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
#include "net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.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_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"
@@ -243,6 +244,25 @@ TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
EXPECT_TRUE(IsControlFrame(frame.type));
}
+TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
+ QuicAckFrequencyFrame ack_frequency_frame;
+ ack_frequency_frame.sequence_number = 1;
+ ack_frequency_frame.packet_tolerance = 2;
+ ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
+ ack_frequency_frame.ignore_order = false;
+ QuicFrame frame(&ack_frequency_frame);
+ ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
+ SetControlFrameId(6, &frame);
+ EXPECT_EQ(6u, GetControlFrameId(frame));
+ std::ostringstream stream;
+ stream << *frame.ack_frequency_frame;
+ EXPECT_EQ(
+ "{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
+ "max_ack_delay_ms: 25, ignore_order: 0 }\n",
+ stream.str());
+ EXPECT_TRUE(IsControlFrame(frame.type));
+}
+
TEST_F(QuicFramesTest, StreamFrameToString) {
QuicStreamFrame frame;
frame.stream_id = 1;
@@ -558,6 +578,9 @@ TEST_F(QuicFramesTest, CopyQuicFrames) {
case HANDSHAKE_DONE_FRAME:
frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
break;
+ case ACK_FREQUENCY_FRAME:
+ frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
+ break;
default:
ASSERT_TRUE(false)
<< "Please fix CopyQuicFrames if a new frame type is added.";
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 0e8e0454483..bfc87610fd4 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
@@ -5,6 +5,7 @@
#ifndef QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
#define QUICHE_QUIC_CORE_HANDSHAKER_DELEGATE_INTERFACE_H_
+#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
namespace quic {
@@ -54,6 +55,22 @@ class QUIC_EXPORT_PRIVATE HandshakerDelegateInterface {
// encryption level and 2) a server successfully processes a forward secure
// packet.
virtual void NeuterHandshakeData() = 0;
+
+ // Called when 0-RTT data is rejected by the server. This is only called in
+ // TLS handshakes and only called on clients.
+ virtual void OnZeroRttRejected() = 0;
+
+ // Fills in |params| with values from the delegate's QuicConfig.
+ // Returns whether the operation succeeded.
+ virtual bool FillTransportParameters(TransportParameters* params) = 0;
+
+ // Read |params| and apply the values to the delegate's QuicConfig.
+ // On failure, returns a QuicErrorCode and saves a detailed error in
+ // |error_details|.
+ virtual QuicErrorCode ProcessTransportParameters(
+ const TransportParameters& params,
+ bool is_resumption,
+ std::string* error_details) = 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 782394427f4..8d274d03739 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
@@ -37,7 +37,9 @@
#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h"
#include "net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.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/quic/test_tools/quic_client_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
@@ -55,6 +57,7 @@
#include "net/third_party/quiche/src/quic/test_tools/quic_test_server.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
#include "net/third_party/quiche/src/quic/tools/quic_client.h"
#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
@@ -70,6 +73,9 @@ using spdy::SpdyFramer;
using spdy::SpdyHeaderBlock;
using spdy::SpdySerializedFrame;
using spdy::SpdySettingsIR;
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::NiceMock;
namespace quic {
namespace test {
@@ -77,6 +83,7 @@ namespace {
const char kFooResponseBody[] = "Artichoke hearts make me happy.";
const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
+const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
const float kSessionToStreamRatio = 1.5;
// Run all tests with the cross products of all versions.
@@ -191,6 +198,16 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
AddToCache("/foo", 200, kFooResponseBody);
AddToCache("/bar", 200, kBarResponseBody);
+ // Enable fixes for bugs found in tests and prod.
+ SetQuicReloadableFlag(quic_donot_change_queued_ack, true);
+ SetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time, true);
+ SetQuicReloadableFlag(quic_fix_server_pto_timeout, true);
+ SetQuicReloadableFlag(quic_do_not_retransmit_immediately_on_zero_rtt_reject,
+ true);
+
+ SetQuicReloadableFlag(quic_support_handshake_done_in_t050, true);
+ SetQuicReloadableFlag(quic_enable_tls_resumption, true);
+ SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
}
~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
@@ -203,7 +220,9 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
QuicTestClient* client =
new QuicTestClient(server_address_, server_hostname_, client_config_,
client_supported_versions_,
- crypto_test_utils::ProofVerifierForTesting());
+ crypto_test_utils::ProofVerifierForTesting(),
+ std::make_unique<SimpleSessionCache>());
+ client->SetUserAgentID(kTestUserAgentId);
client->UseWriter(writer);
if (!pre_shared_key_client_.empty()) {
client->client()->SetPreSharedKey(pre_shared_key_client_);
@@ -441,6 +460,13 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
EXPECT_EQ(0u, server_stats.packets_lost);
}
EXPECT_EQ(0u, server_stats.packets_discarded);
+ if (GetQuicReloadableFlag(quic_save_user_agent_in_quic_session)) {
+ EXPECT_EQ(
+ GetServerSession()->user_agent_id().value_or("MissingUserAgent"),
+ kTestUserAgentId);
+ } else {
+ EXPECT_FALSE(GetServerSession()->user_agent_id().has_value());
+ }
// TODO(ianswett): Restore the check for packets_dropped equals 0.
// The expect for packets received is equal to packets processed fails
// due to version negotiation packets.
@@ -529,7 +555,7 @@ INSTANTIATE_TEST_SUITE_P(EndToEndTests,
TEST_P(EndToEndTest, HandshakeSuccessful) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
QuicCryptoStream* crypto_stream =
QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
@@ -568,7 +594,7 @@ TEST_P(EndToEndTest, SimpleRequestResponse) {
TEST_P(EndToEndTest, HandshakeConfirmed) {
ASSERT_TRUE(Initialize());
- if (!version_.HasHandshakeDone()) {
+ if (!version_.UsesTls()) {
return;
}
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -599,44 +625,27 @@ TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
// Simple transaction, but set a non-default ack delay at the client
// and ensure it gets to the server.
TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
// Force the ACK delay to be something other than the default.
- // Note that it is sent only if doing IETF QUIC.
- client_config_.SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs + 100u);
+ constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
+ client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
ASSERT_TRUE(Initialize());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
EXPECT_FALSE(client_->client()->EarlyDataAccepted());
EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- EXPECT_EQ(kDefaultDelayedAckTimeMs + 100u,
- GetSentPacketManagerFromFirstServerSession()
- ->peer_max_ack_delay()
- .ToMilliseconds());
- } else {
- EXPECT_EQ(kDefaultDelayedAckTimeMs,
- GetSentPacketManagerFromFirstServerSession()
- ->peer_max_ack_delay()
- .ToMilliseconds());
- }
+ EXPECT_EQ(kClientMaxAckDelay, GetSentPacketManagerFromFirstServerSession()
+ ->peer_max_ack_delay()
+ .ToMilliseconds());
}
// Simple transaction, but set a non-default ack exponent at the client
// and ensure it gets to the server.
TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
- const uint32_t kClientAckDelayExponent = kDefaultAckDelayExponent + 100u;
+ const uint32_t kClientAckDelayExponent = 19;
+ EXPECT_NE(kClientAckDelayExponent, kDefaultAckDelayExponent);
// Force the ACK exponent to be something other than the default.
- // Note that it is sent only if doing IETF QUIC.
+ // Note that it is sent only with QUIC+TLS.
client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
ASSERT_TRUE(Initialize());
@@ -645,12 +654,12 @@ TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
EXPECT_FALSE(client_->client()->EarlyDataAccepted());
EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
- if (VersionHasIetfQuicFrames(version_.transport_version)) {
- // Should be only for IETF QUIC.
+ if (version_.UsesTls()) {
+ // Should be only sent with QUIC+TLS.
EXPECT_EQ(kClientAckDelayExponent,
GetServerConnection()->framer().peer_ack_delay_exponent());
} else {
- // No change for Google QUIC.
+ // No change for QUIC_CRYPTO.
EXPECT_EQ(kDefaultAckDelayExponent,
GetServerConnection()->framer().peer_ack_delay_exponent());
}
@@ -662,9 +671,9 @@ TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
client_supported_versions_.insert(client_supported_versions_.begin(),
QuicVersionReservedForNegotiation());
- testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
+ NiceMock<MockQuicConnectionDebugVisitor> visitor;
connection_debug_visitor_ = &visitor;
- EXPECT_CALL(visitor, OnVersionNegotiationPacket(testing::_)).Times(1);
+ EXPECT_CALL(visitor, OnVersionNegotiationPacket(_)).Times(1);
ASSERT_TRUE(Initialize());
ASSERT_TRUE(ServerSendsVersionNegotiation());
@@ -1103,7 +1112,7 @@ TEST_P(EndToEndTest, PostMissingBytes) {
TEST_P(EndToEndTest, LargePostNoPacketLoss) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// 1 MB body.
std::string body(1024 * 1024, 'a');
@@ -1124,7 +1133,7 @@ TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
ASSERT_TRUE(Initialize());
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// 100 KB body.
std::string body(100 * 1024, 'a');
@@ -1145,9 +1154,7 @@ TEST_P(EndToEndTest, LargePostWithPacketLoss) {
// brutal.
SetPacketLossPercentage(5);
ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
SetPacketLossPercentage(30);
// 10 KB body.
@@ -1166,9 +1173,7 @@ TEST_P(EndToEndTest, LargePostWithPacketLoss) {
// Regression test for b/80090281.
TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Normally server only bundles a retransmittable frame once every other
@@ -1199,9 +1204,7 @@ TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
// b/10126687 is fixed, losing handshake packets is pretty brutal.
SetPacketLossPercentage(5);
ASSERT_TRUE(Initialize());
-
- // Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
SetPacketLossPercentage(10);
client_writer_->set_fake_blocked_socket_percentage(10);
@@ -1219,8 +1222,7 @@ TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
ASSERT_TRUE(Initialize());
-
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
// Both of these must be called when the writer is not actively used.
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
SetReorderPercentage(30);
@@ -1238,11 +1240,6 @@ TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
}
TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
- if (version_.UsesTls()) {
- // TODO(b/152551499): Re-enable this test when TLS supports 0-RTT.
- Initialize();
- return;
- }
// Send a request and then disconnect. This prepares the client to attempt
// a 0-RTT handshake for the next request.
ASSERT_TRUE(Initialize());
@@ -1265,7 +1262,7 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
// The 0-RTT handshake should succeed.
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody,
client_->SendCustomSynchronousRequest(headers, body));
@@ -1281,7 +1278,7 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
StartServer();
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody,
client_->SendCustomSynchronousRequest(headers, body));
@@ -1294,11 +1291,6 @@ TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
}
TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
- if (version_.UsesTls()) {
- // TODO(b/152551499): Re-enable this test when TLS supports 0-RTT.
- Initialize();
- return;
- }
// Send a request and then disconnect. This prepares the client to attempt
// a 0-RTT handshake for the next request.
ASSERT_TRUE(Initialize());
@@ -1313,7 +1305,7 @@ TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
// The 0-RTT handshake should succeed.
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -1328,7 +1320,7 @@ TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
StartServer();
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
@@ -1360,14 +1352,10 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
client_->Disconnect();
- if (version_.UsesTls()) {
- // TODO(b/152551499): remove this when TLS supports 0-RTT.
- return;
- }
// The 0-RTT handshake should succeed.
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody,
client_->SendCustomSynchronousRequest(headers, body));
@@ -1383,7 +1371,7 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
StartServer();
client_->Connect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
EXPECT_EQ(kFooResponseBody,
client_->SendCustomSynchronousRequest(headers, body));
@@ -1413,7 +1401,7 @@ TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
initial_received_options));
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
@@ -1438,7 +1426,7 @@ TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
server_writer_->set_max_bandwidth_and_buffer_size(
QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// 1 MB body.
std::string body(1024 * 1024, 'a');
@@ -1462,7 +1450,7 @@ TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
// an infinite loop in the EpollServer, as the alarm fires and is immediately
// rescheduled.
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Ensure both stream and connection level are flow control blocked by setting
// the send window offset to 0.
@@ -1498,7 +1486,7 @@ TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
TEST_P(EndToEndTest, InvalidStream) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
std::string body(kMaxOutgoingPacketSize, 'a');
SpdyHeaderBlock headers;
@@ -1523,7 +1511,7 @@ TEST_P(EndToEndTest, InvalidStream) {
// with overly large headers.
TEST_P(EndToEndTest, LargeHeaders) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
std::string body(kMaxOutgoingPacketSize, 'a');
SpdyHeaderBlock headers;
@@ -1552,7 +1540,7 @@ TEST_P(EndToEndTest, LargeHeaders) {
TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
std::string large_body(1024 * 1024, 'a');
SpdyHeaderBlock headers;
@@ -1618,7 +1606,7 @@ TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
// not properly set up.
return;
}
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Make the client misbehave after negotiation.
const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
@@ -1654,7 +1642,7 @@ TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// The client has received the server's limit and vice versa.
QuicSpdyClientSession* client_session = GetClientSession();
@@ -1711,7 +1699,7 @@ TEST_P(EndToEndTest, SetIndependentMaxDynamicStreamsLimits) {
TEST_P(EndToEndTest, NegotiateCongestionControl) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
CongestionControlType expected_congestion_control_type = kRenoBytes;
switch (GetParam().congestion_control_tag) {
@@ -1745,7 +1733,7 @@ TEST_P(EndToEndTest, ClientSuggestsRTT) {
client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Pause the server so we can access the server's internals without races.
@@ -1774,7 +1762,7 @@ TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
client_config_.SetConnectionOptionsToSend(options);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Pause the server so we can access the server's internals without races.
@@ -1801,7 +1789,7 @@ TEST_P(EndToEndTest, MaxInitialRTT) {
kMaxInitialRoundTripTimeUs);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Pause the server so we can access the server's internals without races.
@@ -1827,7 +1815,7 @@ TEST_P(EndToEndTest, MinInitialRTT) {
client_config_.SetInitialRoundTripTimeUsToSend(0);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Pause the server so we can access the server's internals without races.
@@ -1908,7 +1896,7 @@ TEST_P(EndToEndTest, ResetConnection) {
EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
client_->ResetConnection();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
}
@@ -1923,7 +1911,7 @@ TEST_P(EndToEndTest, MaxStreamsUberTest) {
AddToCache("/large_response", 200, large_body);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
SetPacketLossPercentage(10);
for (int i = 0; i < max_streams; ++i) {
@@ -1942,7 +1930,7 @@ TEST_P(EndToEndTest, StreamCancelErrorTest) {
AddToCache("/small_response", 200, small_body);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicSession* session = GetClientSession();
// Lose the request.
@@ -1952,11 +1940,7 @@ TEST_P(EndToEndTest, StreamCancelErrorTest) {
// Transmit the cancel, and ensure the connection is torn down properly.
SetPacketLossPercentage(0);
QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
- if (session->break_close_loop()) {
- session->ResetStream(stream_id, QUIC_STREAM_CANCELLED, 0);
- } else {
- session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
- }
+ session->ResetStream(stream_id, QUIC_STREAM_CANCELLED, 0);
// WaitForEvents waits 50ms and returns true if there are outstanding
// requests.
@@ -2050,7 +2034,7 @@ TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
ASSERT_TRUE(Initialize());
// Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
server_thread_->Pause();
@@ -2060,11 +2044,6 @@ TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
}
TEST_P(EndToEndTest, DifferentFlowControlWindows) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
// Client and server can set different initial flow control receive windows.
// These are sent in CHLO/SHLO. Tests that these values are exchanged properly
// in the crypto handshake.
@@ -2081,7 +2060,7 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
ASSERT_TRUE(Initialize());
// Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Open a data stream to make sure the stream level flow control is updated.
@@ -2089,17 +2068,28 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
WriteHeadersOnStream(stream);
stream->WriteOrBufferBody("hello", false);
- // Client should have the right values for server's receive window.
- EXPECT_EQ(kServerStreamIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kServerSessionIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
+ if (!version_.UsesTls()) {
+ // IFWA only exists with QUIC_CRYPTO.
+ // Client should have the right values for server's receive window.
+ ASSERT_TRUE(client_->client()
+ ->client_session()
+ ->config()
+ ->HasReceivedInitialStreamFlowControlWindowBytes());
+ EXPECT_EQ(kServerStreamIFCW,
+ client_->client()
+ ->client_session()
+ ->config()
+ ->ReceivedInitialStreamFlowControlWindowBytes());
+ ASSERT_TRUE(client_->client()
+ ->client_session()
+ ->config()
+ ->HasReceivedInitialSessionFlowControlWindowBytes());
+ EXPECT_EQ(kServerSessionIFCW,
+ client_->client()
+ ->client_session()
+ ->config()
+ ->ReceivedInitialSessionFlowControlWindowBytes());
+ }
EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
stream->flow_controller()));
EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
@@ -2107,23 +2097,24 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
// Server should have the right values for client's receive window.
server_thread_->Pause();
- QuicSession* session = GetServerSession();
- EXPECT_EQ(kClientStreamIFCW,
- session->config()->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kClientSessionIFCW,
- session->config()->ReceivedInitialSessionFlowControlWindowBytes());
+ QuicConfig server_config = *GetServerSession()->config();
EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
- session->flow_controller()));
+ GetServerSession()->flow_controller()));
server_thread_->Resume();
+ if (version_.UsesTls()) {
+ // IFWA only exists with QUIC_CRYPTO.
+ return;
+ }
+ ASSERT_TRUE(server_config.HasReceivedInitialStreamFlowControlWindowBytes());
+ EXPECT_EQ(kClientStreamIFCW,
+ server_config.ReceivedInitialStreamFlowControlWindowBytes());
+ ASSERT_TRUE(server_config.HasReceivedInitialSessionFlowControlWindowBytes());
+ EXPECT_EQ(kClientSessionIFCW,
+ server_config.ReceivedInitialSessionFlowControlWindowBytes());
}
// Test negotiation of IFWA connection option.
TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
const uint32_t kClientStreamIFCW = 123456;
const uint32_t kClientSessionIFCW = 234567;
set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
@@ -2142,7 +2133,7 @@ TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
ASSERT_TRUE(Initialize());
// Values are exchanged during crypto handshake, so wait for that to finish.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
// Open a data stream to make sure the stream level flow control is updated.
@@ -2150,17 +2141,28 @@ TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
WriteHeadersOnStream(stream);
stream->WriteOrBufferBody("hello", false);
- // Client should have the right values for server's receive window.
- EXPECT_EQ(kExpectedStreamIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialStreamFlowControlWindowBytes());
- EXPECT_EQ(kExpectedSessionIFCW,
- client_->client()
- ->client_session()
- ->config()
- ->ReceivedInitialSessionFlowControlWindowBytes());
+ if (!version_.UsesTls()) {
+ // IFWA only exists with QUIC_CRYPTO.
+ // Client should have the right values for server's receive window.
+ ASSERT_TRUE(client_->client()
+ ->client_session()
+ ->config()
+ ->HasReceivedInitialStreamFlowControlWindowBytes());
+ EXPECT_EQ(kExpectedStreamIFCW,
+ client_->client()
+ ->client_session()
+ ->config()
+ ->ReceivedInitialStreamFlowControlWindowBytes());
+ ASSERT_TRUE(client_->client()
+ ->client_session()
+ ->config()
+ ->HasReceivedInitialSessionFlowControlWindowBytes());
+ EXPECT_EQ(kExpectedSessionIFCW,
+ client_->client()
+ ->client_session()
+ ->config()
+ ->ReceivedInitialSessionFlowControlWindowBytes());
+ }
EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
stream->flow_controller()));
EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
@@ -2182,7 +2184,7 @@ TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
// Wait for crypto handshake to finish. This should have contributed to the
// crypto stream flow control window, but not affected the session flow
// control window.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
QuicCryptoStream* crypto_stream =
@@ -2236,7 +2238,7 @@ TEST_P(EndToEndTest, FlowControlsSynced) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
server_thread_->WaitForCryptoHandshakeConfirmed();
QuicSpdySession* const client_session = GetClientSession();
@@ -2353,28 +2355,26 @@ TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
server_thread_->Resume();
}
-// A TestAckListener verifies that exactly |bytes_to_ack| bytes are acked during
-// its lifetime.
+// TestAckListener counts how many bytes are acked during its lifetime.
class TestAckListener : public QuicAckListenerInterface {
public:
- explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
+ TestAckListener() {}
void OnPacketAcked(int acked_bytes,
QuicTime::Delta /*delta_largest_observed*/) override {
- ASSERT_LE(acked_bytes, bytes_to_ack_);
- bytes_to_ack_ -= acked_bytes;
+ total_bytes_acked_ += acked_bytes;
}
void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
- bool has_been_notified() const { return bytes_to_ack_ == 0; }
+ int total_bytes_acked() const { return total_bytes_acked_; }
protected:
// Object is ref counted.
- ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
+ ~TestAckListener() override {}
private:
- int bytes_to_ack_;
+ int total_bytes_acked_ = 0;
};
class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
@@ -2388,22 +2388,35 @@ class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
}
};
-// TODO(dschinazi) Fix this test's flakiness in Chrome.
-TEST_P(
- EndToEndTest,
- QUIC_TEST_DISABLED_IN_CHROME(AckNotifierWithPacketLossAndBlockedSocket)) {
+TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
// Verify that even in the presence of packet loss and occasionally blocked
// socket, an AckNotifierDelegate will get informed that the data it is
// interested in has been ACKed. This tests end-to-end ACK notification, and
// demonstrates that retransmissions do not break this functionality.
SetPacketLossPercentage(5);
ASSERT_TRUE(Initialize());
-
// Wait for the server SHLO before upping the packet loss.
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
SetPacketLossPercentage(30);
client_writer_->set_fake_blocked_socket_percentage(10);
+ // Wait for SETTINGS frame from server that sets QPACK dynamic table capacity
+ // to make sure request headers will be compressed using the dynamic table.
+ if (version_.UsesHttp3()) {
+ while (true) {
+ // Waits for up to 50 ms.
+ client_->client()->WaitForEvents();
+ if (!GetClientSession() || !GetClientSession()->qpack_encoder()) {
+ continue;
+ }
+ QpackHeaderTable* header_table =
+ QpackEncoderPeer::header_table(GetClientSession()->qpack_encoder());
+ if (QpackHeaderTablePeer::dynamic_table_capacity(header_table) > 0) {
+ break;
+ }
+ }
+ }
+
// Create a POST request and send the headers only.
SpdyHeaderBlock headers;
headers[":method"] = "POST";
@@ -2413,14 +2426,11 @@ TEST_P(
client_->SendMessage(headers, "", /*fin=*/false);
- // Size of headers on the request stream. Zero if headers are sent on the
- // header stream.
+ // Size of headers on the request stream. This is zero if headers are sent on
+ // the header stream.
size_t header_size = 0;
- if (VersionUsesHttp3(client_->client()
- ->client_session()
- ->connection()
- ->transport_version())) {
- // Determine size of compressed headers.
+ if (version_.UsesHttp3()) {
+ // Determine size of headers after QPACK compression in both scenarios.
NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
@@ -2432,8 +2442,8 @@ TEST_P(
qpack_encoder.SetDynamicTableCapacity(kDefaultQpackMaxDynamicTableCapacity);
qpack_encoder.SetMaximumBlockedStreams(kDefaultMaximumBlockedStreams);
- std::string encoded_headers =
- qpack_encoder.EncodeHeaderList(/* stream_id = */ 0, headers, nullptr);
+ std::string encoded_headers = qpack_encoder.EncodeHeaderList(
+ /* stream_id = */ 0, headers, nullptr);
header_size = encoded_headers.size();
}
@@ -2442,9 +2452,11 @@ TEST_P(
std::string request_string = "a request body bigger than one packet" +
std::string(kMaxOutgoingPacketSize, '.');
+ const int expected_bytes_acked = header_size + request_string.length();
+
// The TestAckListener will cause a failure if not notified.
QuicReferenceCountedPointer<TestAckListener> ack_listener(
- new TestAckListener(header_size + request_string.length()));
+ new TestAckListener());
// Send the request, and register the delegate for ACKs.
client_->SendData(request_string, true, ack_listener);
@@ -2456,17 +2468,20 @@ TEST_P(
client_->SendSynchronousRequest("/bar");
// Make sure the delegate does get the notification it expects.
- while (!ack_listener->has_been_notified()) {
+ while (ack_listener->total_bytes_acked() < expected_bytes_acked) {
// Waits for up to 50 ms.
client_->client()->WaitForEvents();
}
+ EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked)
+ << " header_size " << header_size << " request length "
+ << request_string.length();
}
// Send a public reset from the server.
TEST_P(EndToEndTest, ServerSendPublicReset) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicConnection* client_connection = GetClientConnection();
QuicConfig* config = client_->client()->session()->config();
EXPECT_TRUE(config->HasReceivedStatelessResetToken());
@@ -2504,7 +2519,7 @@ TEST_P(EndToEndTest, ServerSendPublicReset) {
TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicConnection* client_connection = GetClientConnection();
QuicConfig* config = client_->client()->session()->config();
EXPECT_TRUE(config->HasReceivedStatelessResetToken());
@@ -2517,7 +2532,7 @@ TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
std::unique_ptr<QuicEncryptedPacket> packet;
- testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
+ NiceMock<MockQuicConnectionDebugVisitor> visitor;
GetClientConnection()->set_debug_visitor(&visitor);
if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
@@ -2581,7 +2596,7 @@ TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Send the version negotiation packet.
QuicConnection* client_connection = GetClientConnection();
@@ -2593,7 +2608,7 @@ TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
VersionHasIetfInvariantHeader(client_connection->transport_version()),
client_connection->version().HasLengthPrefixedConnectionIds(),
server_supported_versions_));
- testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
+ NiceMock<MockQuicConnectionDebugVisitor> visitor;
client_connection->set_debug_visitor(&visitor);
EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
.Times(1);
@@ -2733,7 +2748,7 @@ TEST_P(EndToEndTest, BadEncryptedData) {
TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Lose the request.
SetPacketLossPercentage(100);
SpdyHeaderBlock headers;
@@ -2934,7 +2949,7 @@ TEST_P(EndToEndTest, EarlyResponseFinRecording) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// A POST that gets an early error response, after the headers are received
// and before the body is received, due to invalid content-length.
@@ -2982,7 +2997,7 @@ TEST_P(EndToEndTest, EarlyResponseFinRecording) {
TEST_P(EndToEndTest, Trailers) {
// Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Set reordering to ensure that Trailers arriving before body is ok.
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
@@ -3014,6 +3029,7 @@ class EndToEndTestServerPush : public EndToEndTest {
const size_t kNumMaxStreams = 10;
EndToEndTestServerPush() : EndToEndTest() {
+ SetQuicFlag(FLAGS_quic_enable_http3_server_push, true);
client_config_.SetMaxBidirectionalStreamsToSend(kNumMaxStreams);
server_config_.SetMaxBidirectionalStreamsToSend(kNumMaxStreams);
client_config_.SetMaxUnidirectionalStreamsToSend(kNumMaxStreams);
@@ -3068,7 +3084,7 @@ INSTANTIATE_TEST_SUITE_P(EndToEndTestsServerPush,
TEST_P(EndToEndTestServerPush, ServerPush) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
// Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
@@ -3092,10 +3108,7 @@ TEST_P(EndToEndTestServerPush, ServerPush) {
EXPECT_EQ(kBody, client_->SendSynchronousRequest(
"https://example.com/push_example"));
QuicStreamSequencer* sequencer;
- if (!VersionUsesHttp3(client_->client()
- ->client_session()
- ->connection()
- ->transport_version())) {
+ if (!version_.UsesHttp3()) {
QuicHeadersStream* headers_stream =
QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
sequencer = QuicStreamPeer::sequencer(headers_stream);
@@ -3113,27 +3126,23 @@ TEST_P(EndToEndTestServerPush, ServerPush) {
QUIC_DVLOG(1) << "response body " << response_body;
EXPECT_EQ(expected_body, response_body);
}
- if (!VersionUsesHttp3(client_->client()
- ->client_session()
- ->connection()
- ->transport_version())) {
+ if (!version_.UsesHttp3()) {
EXPECT_FALSE(
QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
}
}
TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
// Tests that sending a request which has 4 push resources will trigger server
// to push those 4 resources and client can handle pushed resources and match
// them with requests later.
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+ if (version_.UsesHttp3()) {
+ static_cast<QuicSpdySession*>(client_->client()->session())
+ ->SetMaxPushId(kMaxQuicStreamId);
+ }
// Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
@@ -3177,9 +3186,10 @@ TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
}
TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
+ if (version_.UsesHttp3()) {
+ // TODO(b/142504641): Re-enable this test when we support push streams
+ // arriving before the corresponding promises.
+ ASSERT_TRUE(Initialize());
return;
}
// Tests that when streams are not blocked by flow control or congestion
@@ -3187,15 +3197,10 @@ TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
// streams should still work because all response streams get closed
// immediately after pushing resources.
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
-
- if (VersionUsesHttp3(client_->client()
- ->client_session()
- ->connection()
- ->transport_version())) {
- // TODO(b/142504641): Re-enable this test when we support push streams
- // arriving before the corresponding promises.
- return;
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+ if (version_.UsesHttp3()) {
+ static_cast<QuicSpdySession*>(client_->client()->session())
+ ->SetMaxPushId(kMaxQuicStreamId);
}
// Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
@@ -3240,11 +3245,6 @@ TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
}
TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
- if (version_.UsesTls()) {
- // TODO(b/155316241): Enable this test for TLS.
- Initialize();
- return;
- }
// Tests that when server tries to send more large resources(large enough to
// be blocked by flow control window or congestion control window) than max
// open outgoing streams , server can open upto max number of outgoing
@@ -3261,7 +3261,11 @@ TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
kBodySize * kNumMaxStreams + 1024);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+ if (version_.UsesHttp3()) {
+ static_cast<QuicSpdySession*>(client_->client()->session())
+ ->SetMaxPushId(kMaxQuicStreamId);
+ }
// Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
@@ -3293,9 +3297,13 @@ TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
// Check server session to see if it has max number of outgoing streams opened
// though more resources need to be pushed.
- server_thread_->Pause();
- EXPECT_EQ(kNumMaxStreams, GetServerSession()->GetNumOpenOutgoingStreams());
- server_thread_->Resume();
+ if (!version_.HasIetfQuicFrames()) {
+ server_thread_->Pause();
+ EXPECT_EQ(kNumMaxStreams,
+ QuicSessionPeer::GetStreamIdManager(GetServerSession())
+ ->num_open_outgoing_streams());
+ server_thread_->Resume();
+ }
EXPECT_EQ(1u, client_->num_requests());
EXPECT_EQ(1u, client_->num_responses());
@@ -3334,7 +3342,7 @@ TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
// within a short time.
client_->epoll_server()->set_timeout_in_us(0);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
SetPacketLossPercentage(1);
// To avoid storing the whole request body in memory, use a loop to repeatedly
// send body size of kSizeBytes until the whole request body size is reached.
@@ -3392,7 +3400,7 @@ TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
initialized_ = true;
ASSERT_TRUE(client_->client()->connected());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
SetPacketLossPercentage(1);
client_->SendRequest("/huge_response");
client_->WaitForResponse();
@@ -3402,7 +3410,7 @@ TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
// Regression test for b/111515567
TEST_P(EndToEndTest, AgreeOnStopWaiting) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicConnection* client_connection = GetClientConnection();
server_thread_->Pause();
@@ -3420,7 +3428,7 @@ TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
options.push_back(kNSTP);
client_config_.SetConnectionOptionsToSend(options);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicConnection* client_connection = GetClientConnection();
server_thread_->Pause();
@@ -3451,6 +3459,13 @@ TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
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";
@@ -3493,7 +3508,7 @@ class WindowUpdateObserver : public QuicConnectionDebugVisitor {
TEST_P(EndToEndTest, WindowUpdateInAck) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
WindowUpdateObserver observer;
QuicConnection* client_connection = GetClientConnection();
client_connection->set_debug_visitor(&observer);
@@ -3514,7 +3529,7 @@ TEST_P(EndToEndTest, WindowUpdateInAck) {
TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicConfig* config = client_->client()->session()->config();
EXPECT_TRUE(config->HasReceivedStatelessResetToken());
EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
@@ -3526,10 +3541,6 @@ TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
// Regression test for b/116200989.
TEST_P(EndToEndTest,
SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
- if (!GetQuicReloadableFlag(quic_notify_handshaker_on_connection_close)) {
- ASSERT_TRUE(Initialize());
- return;
- }
connect_to_server_on_initialize_ = false;
ASSERT_TRUE(Initialize());
@@ -3674,8 +3685,7 @@ TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
// 2. Crypto handshake has not completed, Initialize() returns true. The call
// to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
// return whether it is successful.
- ASSERT_FALSE(Initialize() &&
- client_->client()->WaitForCryptoHandshakeConfirmed());
+ ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
}
@@ -3696,8 +3706,7 @@ TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
return;
}
- ASSERT_FALSE(Initialize() &&
- client_->client()->WaitForCryptoHandshakeConfirmed());
+ ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
}
@@ -3718,8 +3727,7 @@ TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
return;
}
- ASSERT_FALSE(Initialize() &&
- client_->client()->WaitForCryptoHandshakeConfirmed());
+ ASSERT_FALSE(Initialize() && client_->client()->WaitForOneRttKeysAvailable());
EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
}
@@ -3738,7 +3746,7 @@ TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
server_hostname_, "/test_url", std::move(response_headers), response_body,
QuicBackendResponse::INCOMPLETE_RESPONSE);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
client_->WaitForDelayedAcks();
QuicSession* session = GetClientSession();
@@ -3760,7 +3768,7 @@ TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForHandshakeConfirmed());
SetPacketLossPercentage(30);
QuicSpdyClientStream* stream = client_->GetOrCreateStream();
@@ -3781,7 +3789,7 @@ TEST_P(EndToEndTest, SendMessages) {
return;
}
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
QuicSession* client_session = GetClientSession();
QuicConnection* client_connection = client_session->connection();
@@ -3911,16 +3919,14 @@ TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
server_connection->GetStats().num_connectivity_probing_received);
server_thread_->Resume();
- EXPECT_EQ(
+ // Server definitely responded to the connectivity probing. Sometime it also
+ // sends a padded ping that is not a connectivity probing, which is recognized
+ // as connectivity probing because client's self address is ANY.
+ EXPECT_LE(
1u, GetClientConnection()->GetStats().num_connectivity_probing_received);
}
TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
- if (version_.UsesTls()) {
- // TODO(b/152551499): Re-enable this test when TLS supports 0-RTT.
- Initialize();
- return;
- }
ASSERT_TRUE(Initialize());
// Finish one request to make sure handshake established.
client_->SendSynchronousRequest("/foo");
@@ -3933,7 +3939,7 @@ TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
// Only send out a CHLO.
client_->client()->Initialize();
client_->client()->StartConnect();
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(client_->client()->connected());
// Send a request before handshake finishes.
@@ -3947,14 +3953,10 @@ TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
client_->WaitForResponse();
EXPECT_EQ(kBarResponseBody, client_->response_body());
QuicConnectionStats client_stats = GetClientConnection()->GetStats();
- if (GetQuicReloadableFlag(quic_advance_ack_timeout_update)) {
- // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
- // the delay, server processes packet 2 and later drops packet 1. ACK is
- // bundled with SHLO, such that 1 can be detected loss by time threshold.
- EXPECT_LE(0u, client_stats.packets_lost);
- } else {
- EXPECT_EQ(0u, client_stats.packets_lost);
- }
+ // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
+ // the delay, server processes packet 2 and later drops packet 1. ACK is
+ // bundled with SHLO, such that 1 can be detected loss by time threshold.
+ EXPECT_LE(0u, client_stats.packets_lost);
EXPECT_TRUE(client_->client()->EarlyDataAccepted());
}
@@ -4010,7 +4012,7 @@ TEST_P(EndToEndTest, SimpleStopSendingTest) {
server_hostname_, "/test_url", std::move(response_headers), response_body,
kStopSendingTestCode);
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
client_->WaitForDelayedAcks();
QuicSession* session = GetClientSession();
@@ -4188,7 +4190,7 @@ TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
// Only runs for IETF QUIC.
return;
}
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
std::string body(kMaxOutgoingPacketSize, 'a');
SpdyHeaderBlock headers;
@@ -4216,17 +4218,15 @@ TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
}
TEST_P(EndToEndTest, TestMaxPushId) {
- if (version_.UsesTls() ||
- !VersionHasIetfQuicFrames(version_.transport_version)) {
- // TODO(b/155316241): Enable this test for TLS.
- // Only runs for IETF QUIC.
+ if (!version_.HasIetfQuicFrames()) {
+ // MaxPushId is only implemented for IETF QUIC.
Initialize();
return;
}
- // Has to be before version test, see EndToEndTest::TearDown()
+ SetQuicFlag(FLAGS_quic_enable_http3_server_push, true);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
static_cast<QuicSpdySession*>(client_->client()->session())
->SetMaxPushId(kMaxQuicStreamId);
@@ -4239,18 +4239,135 @@ TEST_P(EndToEndTest, TestMaxPushId) {
->CanCreatePushStreamWithId(kMaxQuicStreamId));
}
-TEST_P(EndToEndTest, DISABLED_CustomTransportParameters) {
- // TODO(b/155316241): Enable this test.
+TEST_P(EndToEndTest, CustomTransportParameters) {
+ if (!version_.UsesTls()) {
+ // Custom transport parameters are only supported with TLS.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
constexpr auto kCustomParameter =
static_cast<TransportParameters::TransportParameterId>(0xff34);
client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
"test";
+ NiceMock<MockQuicConnectionDebugVisitor> visitor;
+ connection_debug_visitor_ = &visitor;
+ EXPECT_CALL(visitor, OnTransportParametersSent(_))
+ .WillOnce(Invoke([kCustomParameter](
+ const TransportParameters& transport_parameters) {
+ ASSERT_NE(transport_parameters.custom_parameters.find(kCustomParameter),
+ transport_parameters.custom_parameters.end());
+ EXPECT_EQ(transport_parameters.custom_parameters.at(kCustomParameter),
+ "test");
+ }));
+ EXPECT_CALL(visitor, OnTransportParametersReceived(_)).Times(1);
ASSERT_TRUE(Initialize());
- EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
- EXPECT_EQ(server_config_.received_custom_transport_parameters().at(
+ EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
+
+ server_thread_->Pause();
+ QuicConfig server_config = *GetServerSession()->config();
+ if (GetQuicReloadableFlag(quic_save_user_agent_in_quic_session)) {
+ EXPECT_EQ(GetServerSession()->user_agent_id().value_or("MissingUserAgent"),
+ kTestUserAgentId);
+ } else {
+ EXPECT_FALSE(GetServerSession()->user_agent_id().has_value());
+ }
+ server_thread_->Resume();
+ ASSERT_NE(server_config.received_custom_transport_parameters().find(
kCustomParameter),
- "test");
+ server_config.received_custom_transport_parameters().end());
+ EXPECT_EQ(
+ server_config.received_custom_transport_parameters().at(kCustomParameter),
+ "test");
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
+ if (!version_.HasLongHeaderLengths()) {
+ // Decapsulating Legacy Version Encapsulation packets from these versions
+ // is not currently supported in QuicDispatcher.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ SetQuicReloadableFlag(quic_dont_pad_chlo, true);
+ SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
+ client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+ ASSERT_TRUE(Initialize());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_GT(GetClientConnection()
+ ->GetStats()
+ .sent_legacy_version_encapsulated_packets,
+ 0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
+ if (!version_.HasLongHeaderLengths()) {
+ // Decapsulating Legacy Version Encapsulation packets from these versions
+ // is not currently supported in QuicDispatcher.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ if (!version_.UsesTls()) {
+ // This test uses custom transport parameters to increase the size of the
+ // CHLO, and those are only supported with TLS.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ SetQuicReloadableFlag(quic_dont_pad_chlo, true);
+ SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
+ client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+ constexpr auto kCustomParameter =
+ static_cast<TransportParameters::TransportParameterId>(0xff34);
+ client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
+ std::string(2000, '?');
+ ASSERT_TRUE(Initialize());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_GT(GetClientConnection()
+ ->GetStats()
+ .sent_legacy_version_encapsulated_packets,
+ 0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
+ if (!version_.HasLongHeaderLengths()) {
+ // Decapsulating Legacy Version Encapsulation packets from these versions
+ // is not currently supported in QuicDispatcher.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ client_supported_versions_.insert(client_supported_versions_.begin(),
+ QuicVersionReservedForNegotiation());
+ SetQuicReloadableFlag(quic_dont_pad_chlo, true);
+ SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
+ client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+ ASSERT_TRUE(Initialize());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_GT(GetClientConnection()
+ ->GetStats()
+ .sent_legacy_version_encapsulated_packets,
+ 0u);
+}
+
+TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
+ if (!version_.HasLongHeaderLengths()) {
+ // Decapsulating Legacy Version Encapsulation packets from these versions
+ // is not currently supported in QuicDispatcher.
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ SetPacketLossPercentage(30);
+ SetQuicReloadableFlag(quic_dont_pad_chlo, true);
+ SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
+ client_config_.SetClientConnectionOptions(QuicTagVector{kQLVE});
+ ASSERT_TRUE(Initialize());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_GT(GetClientConnection()
+ ->GetStats()
+ .sent_legacy_version_encapsulated_packets,
+ 0u);
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h b/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h
index 17afe1bea19..285d3792d7a 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/http_constants.h
@@ -42,6 +42,7 @@ const QuicByteCount kDefaultQpackMaxDynamicTableCapacity = 64 * 1024; // 64 KB
// SETTINGS_QPACK_BLOCKED_STREAMS.
const uint64_t kDefaultMaximumBlockedStreams = 100;
+const char kUserAgentHeaderName[] = "user-agent";
} // namespace quic
#endif // QUICHE_QUIC_CORE_HTTP_HTTP_CONSTANTS_H_
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 a5996260d23..0836f9a0d56 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
@@ -227,9 +227,6 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
- if (!session_.break_close_loop()) {
- EXPECT_CALL(session_, CloseStream(promise_id_));
- }
promised->HandleClientRequest(client_request_, &delegate);
}
@@ -305,9 +302,6 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
session_.GetOrCreateStream(promise_id_);
// Cancel the promised stream.
- if (!session_.break_close_loop()) {
- EXPECT_CALL(session_, CloseStream(promise_id_));
- }
EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
promised->Cancel();
@@ -331,17 +325,10 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
promise_stream->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
headers);
- if (!session_.break_close_loop()) {
- EXPECT_CALL(session_, CloseStream(promise_id_));
- }
EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*connection_,
OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
- if (session_.break_close_loop()) {
- session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
- } else {
- session_.SendRstStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
- }
+ session_.ResetStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
// Now initiate rendezvous.
TestPushPromiseDelegate delegate(/*match=*/true);
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 d24e3ddaa88..27de70d3fa4 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
@@ -131,8 +131,7 @@ bool QuicReceiveControlStream::OnSettingsFrameStart(
bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
QUIC_DVLOG(1) << "Control Stream " << id()
<< " received settings frame: " << frame;
- spdy_session_->OnSettingsFrame(frame);
- return true;
+ return spdy_session_->OnSettingsFrame(frame);
}
bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
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 64c306a4431..59574a146b9 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
@@ -18,18 +18,12 @@
namespace quic {
-QuicSendControlStream::QuicSendControlStream(
- QuicStreamId id,
- QuicSpdySession* spdy_session,
- uint64_t qpack_maximum_dynamic_table_capacity,
- uint64_t qpack_maximum_blocked_streams,
- uint64_t max_inbound_header_list_size)
+QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
+ QuicSpdySession* spdy_session,
+ const SettingsFrame& settings)
: QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
settings_sent_(false),
- qpack_maximum_dynamic_table_capacity_(
- qpack_maximum_dynamic_table_capacity),
- qpack_maximum_blocked_streams_(qpack_maximum_blocked_streams),
- max_inbound_header_list_size_(max_inbound_header_list_size),
+ settings_(settings),
spdy_session_(spdy_session) {}
void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
@@ -56,13 +50,7 @@ void QuicSendControlStream::MaybeSendSettingsFrame() {
WriteOrBufferData(quiche::QuicheStringPiece(writer.data(), writer.length()),
false, nullptr);
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
- qpack_maximum_dynamic_table_capacity_;
- settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
- qpack_maximum_blocked_streams_;
- settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] =
- max_inbound_header_list_size_;
+ SettingsFrame settings = settings_;
// https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
// specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
// greasing should be attempted.
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h
index 03bd1f747aa..c14254f4cb7 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h
@@ -23,9 +23,7 @@ class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
// only be accessed through the session.
QuicSendControlStream(QuicStreamId id,
QuicSpdySession* session,
- uint64_t qpack_maximum_dynamic_table_capacity,
- uint64_t qpack_maximum_blocked_streams,
- uint64_t max_inbound_header_list_size);
+ const SettingsFrame& settings);
QuicSendControlStream(const QuicSendControlStream&) = delete;
QuicSendControlStream& operator=(const QuicSendControlStream&) = delete;
~QuicSendControlStream() override = default;
@@ -59,12 +57,8 @@ class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
// Track if a settings frame is already sent.
bool settings_sent_;
- // SETTINGS_QPACK_MAX_TABLE_CAPACITY value to send.
- const uint64_t qpack_maximum_dynamic_table_capacity_;
- // SETTINGS_QPACK_BLOCKED_STREAMS value to send.
- const uint64_t qpack_maximum_blocked_streams_;
- // SETTINGS_MAX_HEADER_LIST_SIZE value to send.
- const uint64_t max_inbound_header_list_size_;
+ // SETTINGS values to send.
+ const SettingsFrame settings_;
QuicSpdySession* const spdy_session_;
};
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc
index 27db719fccd..ef367d98cb5 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.cc
@@ -39,6 +39,9 @@ void QuicServerSessionBase::Initialize() {
crypto_stream_ =
CreateQuicCryptoServerStream(crypto_config_, compressed_certs_cache_);
QuicSpdySession::Initialize();
+ if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls)) {
+ SendSettingsToCryptoStream();
+ }
}
void QuicServerSessionBase::OnConfigNegotiated() {
@@ -260,4 +263,19 @@ int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
}
+void QuicServerSessionBase::SendSettingsToCryptoStream() {
+ if (!version().UsesTls()) {
+ return;
+ }
+ std::unique_ptr<char[]> buffer;
+ QuicByteCount buffer_size =
+ HttpEncoder::SerializeSettingsFrame(settings(), &buffer);
+
+ std::unique_ptr<ApplicationState> serialized_settings =
+ std::make_unique<ApplicationState>(buffer.get(),
+ buffer.get() + buffer_size);
+ GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+ std::move(serialized_settings));
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h
index bf7a5bbb693..b4a467fedff 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_server_session_base.h
@@ -99,6 +99,11 @@ class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
friend class test::QuicServerSessionBasePeer;
friend class test::QuicSimpleServerSessionPeer;
+ // Informs the QuicCryptoStream of the SETTINGS that will be used on this
+ // connection, so that the server crypto stream knows whether to accept 0-RTT
+ // data.
+ void SendSettingsToCryptoStream();
+
const QuicCryptoServerConfig* crypto_config_;
// The cache which contains most recently compressed certs.
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 c482856b61b..6af67a656f4 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
@@ -157,6 +157,9 @@ class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
session_->config(), kMinimumFlowControlSendWindow);
session_->OnConfigNegotiated();
+ if (connection_->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(connection_);
+ }
}
QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
@@ -349,6 +352,7 @@ TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
// more than the negotiated stream limit to deal with rare cases where a
// client FIN/RST is lost.
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
if (!VersionHasIetfQuicFrames(transport_version())) {
// The slightly increased stream limit is set during config negotiation. It
@@ -401,6 +405,7 @@ TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
// 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_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
const size_t kAvailableStreamLimit =
session_->MaxAvailableBidirectionalStreams();
@@ -506,6 +511,7 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
QuicTagVector copt;
copt.push_back(kBWRE);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_TRUE(
QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
@@ -696,6 +702,7 @@ TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
QuicTagVector copt;
copt.push_back(kBWMX);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_TRUE(
QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
@@ -704,6 +711,7 @@ TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
EXPECT_FALSE(
QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
EXPECT_FALSE(
QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc
index 6127e1b682e..066adb9f859 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.cc
@@ -39,6 +39,13 @@ QuicSpdyClientSession::~QuicSpdyClientSession() = default;
void QuicSpdyClientSession::Initialize() {
crypto_stream_ = CreateQuicCryptoStream();
+ if (config()->HasClientRequestedIndependentOption(kQLVE,
+ Perspective::IS_CLIENT)) {
+ connection()->EnableLegacyVersionEncapsulation(server_id_.host());
+ // Legacy Version Encapsulation needs CHLO padding to be disabled.
+ // TODO(dschinazi) remove this line once we deprecate quic_dont_pad_chlo.
+ crypto_config_->set_disable_chlo_padding(true);
+ }
QuicSpdyClientSessionBase::Initialize();
}
@@ -152,7 +159,7 @@ bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
}
if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::IsBidirectionalStreamId(id)) {
+ QuicUtils::IsBidirectionalStreamId(id, version())) {
connection()->CloseConnection(
QUIC_HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM,
"Server created bidirectional stream.",
@@ -186,7 +193,7 @@ QuicSpdyClientSession::CreateQuicCryptoStream() {
return std::make_unique<QuicCryptoClientStream>(
server_id_, this,
crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
- this, /*has_application_state = */ true);
+ this, /*has_application_state = */ version().UsesHttp3());
}
bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc
index 63de57c31bc..b433c56f687 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.cc
@@ -204,26 +204,20 @@ void QuicSpdyClientSessionBase::ResetPromised(
QuicStreamId id,
QuicRstStreamErrorCode error_code) {
DCHECK(QuicUtils::IsServerInitiatedStreamId(transport_version(), id));
- if (break_close_loop()) {
- ResetStream(id, error_code, 0);
- } else {
- SendRstStream(id, error_code, 0);
- }
+ ResetStream(id, error_code, 0);
if (!IsOpenStream(id) && !IsClosedStream(id)) {
MaybeIncreaseLargestPeerStreamId(id);
}
}
-void QuicSpdyClientSessionBase::CloseStreamInner(QuicStreamId stream_id,
- bool rst_sent) {
- QuicSpdySession::CloseStreamInner(stream_id, rst_sent);
+void QuicSpdyClientSessionBase::CloseStream(QuicStreamId stream_id) {
+ QuicSpdySession::CloseStream(stream_id);
if (!VersionUsesHttp3(transport_version())) {
headers_stream()->MaybeReleaseSequencerBuffer();
}
}
void QuicSpdyClientSessionBase::OnStreamClosed(QuicStreamId stream_id) {
- DCHECK(break_close_loop());
QuicSpdySession::OnStreamClosed(stream_id);
if (!VersionUsesHttp3(transport_version())) {
headers_stream()->MaybeReleaseSequencerBuffer();
@@ -234,15 +228,55 @@ bool QuicSpdyClientSessionBase::ShouldReleaseHeadersStreamSequencerBuffer() {
return !HasActiveRequestStreams() && promised_by_id_.empty();
}
-void QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
- QuicSpdySession::OnSettingsFrame(frame);
+bool QuicSpdyClientSessionBase::ShouldKeepConnectionAlive() const {
+ return QuicSpdySession::ShouldKeepConnectionAlive() ||
+ num_outgoing_draining_streams() > 0;
+}
+
+bool QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
+ if (!was_zero_rtt_rejected()) {
+ if (max_outbound_header_list_size() != std::numeric_limits<size_t>::max() &&
+ frame.values.find(SETTINGS_MAX_HEADER_LIST_SIZE) ==
+ frame.values.end()) {
+ CloseConnectionWithDetails(
+ QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ "Server accepted 0-RTT but omitted non-default "
+ "SETTINGS_MAX_HEADER_LIST_SIZE");
+ return false;
+ }
+
+ if (qpack_encoder()->maximum_blocked_streams() != 0 &&
+ frame.values.find(SETTINGS_QPACK_BLOCKED_STREAMS) ==
+ frame.values.end()) {
+ CloseConnectionWithDetails(
+ QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ "Server accepted 0-RTT but omitted non-default "
+ "SETTINGS_QPACK_BLOCKED_STREAMS");
+ return false;
+ }
+
+ if (qpack_encoder()->MaximumDynamicTableCapacity() != 0 &&
+ frame.values.find(SETTINGS_QPACK_MAX_TABLE_CAPACITY) ==
+ frame.values.end()) {
+ CloseConnectionWithDetails(
+ QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ "Server accepted 0-RTT but omitted non-default "
+ "SETTINGS_QPACK_MAX_TABLE_CAPACITY");
+ return false;
+ }
+ }
+
+ if (!QuicSpdySession::OnSettingsFrame(frame)) {
+ return false;
+ }
std::unique_ptr<char[]> buffer;
QuicByteCount frame_length =
HttpEncoder::SerializeSettingsFrame(frame, &buffer);
auto serialized_data = std::make_unique<ApplicationState>(
buffer.get(), buffer.get() + frame_length);
- static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
- ->OnApplicationState(std::move(serialized_data));
+ GetMutableCryptoStream()->SetServerApplicationStateForResumption(
+ std::move(serialized_data));
+ return true;
}
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h
index a109d185a46..31924793f6b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h
+++ b/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h
@@ -102,7 +102,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
void ResetPromised(QuicStreamId id, QuicRstStreamErrorCode error_code);
// Release headers stream's sequencer buffer if it's empty.
- void CloseStreamInner(QuicStreamId stream_id, bool rst_sent) override;
+ void CloseStream(QuicStreamId stream_id) override;
// Release headers stream's sequencer buffer if it's empty.
void OnStreamClosed(QuicStreamId stream_id) override;
@@ -110,6 +110,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
// Returns true if there are no active requests and no promised streams.
bool ShouldReleaseHeadersStreamSequencerBuffer() override;
+ // Override to wait for all received responses to be consumed by application.
+ bool ShouldKeepConnectionAlive() const override;
+
size_t get_max_promises() const {
return max_open_incoming_unidirectional_streams() *
kMaxPromisedStreamsMultiplier;
@@ -120,7 +123,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyClientSessionBase
}
// Override to serialize the settings and pass it down to the handshaker.
- void OnSettingsFrame(const SettingsFrame& frame) override;
+ bool OnSettingsFrame(const SettingsFrame& frame) override;
private:
// For QuicSpdyClientStream to detect that a response corresponds to a
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 7d4ae810115..3464a7eda90 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
@@ -16,10 +16,12 @@
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.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_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.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_ptr_util.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"
@@ -38,12 +40,13 @@
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
using spdy::SpdyHeaderBlock;
-using testing::_;
-using testing::AnyNumber;
-using testing::AtLeast;
-using testing::AtMost;
-using testing::Invoke;
-using testing::Truly;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::AtLeast;
+using ::testing::AtMost;
+using ::testing::Invoke;
+using ::testing::StrictMock;
+using ::testing::Truly;
namespace quic {
namespace test {
@@ -93,8 +96,12 @@ class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
auto client_cache = std::make_unique<test::SimpleSessionCache>();
client_session_cache_ = client_cache.get();
- crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+ SetQuicReloadableFlag(quic_enable_tls_resumption, true);
+ SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
+ SetQuicReloadableFlag(quic_fix_gquic_stream_type, true);
+ client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
+ server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
Initialize();
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -107,14 +114,16 @@ class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
void Initialize() {
session_.reset();
- connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
- Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
+ connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+ &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+ SupportedVersions(GetParam()));
session_ = std::make_unique<TestQuicSpdyClientSession>(
DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
- QuicServerId(kServerHostname, kPort, false), crypto_config_.get(),
- &push_promise_index_);
+ QuicServerId(kServerHostname, kPort, false),
+ client_crypto_config_.get(), &push_promise_index_);
session_->Initialize();
+ crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+ session_->GetMutableCryptoStream());
push_promise_[":path"] = "/bar";
push_promise_[":authority"] = "www.google.com";
push_promise_[":method"] = "GET";
@@ -157,13 +166,11 @@ class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
void CompleteCryptoHandshake(uint32_t server_max_incoming_streams) {
if (VersionHasIetfQuicFrames(connection_->transport_version())) {
EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(testing::AnyNumber())
+ .Times(::testing::AnyNumber())
.WillRepeatedly(Invoke(
this, &QuicSpdyClientSessionTest::ClearMaxStreamsControlFrame));
}
session_->CryptoConnect();
- QuicCryptoClientStream* stream = static_cast<QuicCryptoClientStream*>(
- session_->GetMutableCryptoStream());
QuicConfig config = DefaultQuicConfig();
if (VersionHasIetfQuicFrames(connection_->transport_version())) {
config.SetMaxUnidirectionalStreamsToSend(server_max_incoming_streams);
@@ -171,32 +178,45 @@ class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
} else {
config.SetMaxBidirectionalStreamsToSend(server_max_incoming_streams);
}
- SetQuicReloadableFlag(quic_enable_tls_resumption, true);
- SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
- std::unique_ptr<QuicCryptoServerConfig> crypto_config =
- crypto_test_utils::CryptoServerConfigForTesting();
crypto_test_utils::HandshakeWithFakeServer(
- &config, crypto_config.get(), &helper_, &alarm_factory_, connection_,
- stream, AlpnForVersion(connection_->version()));
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
}
void CreateConnection() {
- connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
- Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
+ connection_ = new ::testing::NiceMock<PacketSavingConnection>(
+ &helper_, &alarm_factory_, Perspective::IS_CLIENT,
+ SupportedVersions(GetParam()));
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
session_ = std::make_unique<TestQuicSpdyClientSession>(
DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
- QuicServerId(kServerHostname, kPort, false), crypto_config_.get(),
- &push_promise_index_);
+ QuicServerId(kServerHostname, kPort, false),
+ client_crypto_config_.get(), &push_promise_index_);
session_->Initialize();
+ crypto_stream_ = static_cast<QuicCryptoClientStream*>(
+ session_->GetMutableCryptoStream());
}
- std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
+ void CompleteFirstConnection() {
+ CompleteCryptoHandshake();
+ EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
+ if (session_->version().UsesHttp3()) {
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+ settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+ settings.values[256] = 4; // unknown setting
+ session_->OnSettingsFrame(settings);
+ }
+ }
+
+ // Owned by |session_|.
+ QuicCryptoClientStream* crypto_stream_;
+ std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
+ std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
- PacketSavingConnection* connection_;
+ ::testing::NiceMock<PacketSavingConnection>* connection_;
std::unique_ptr<TestQuicSpdyClientSession> session_;
QuicClientPushPromiseIndex push_promise_index_;
SpdyHeaderBlock push_promise_;
@@ -219,8 +239,6 @@ TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
// This test relies on resumption and is QUIC crypto specific, so it is
// disabled for TLS.
- // TODO(nharper): Add support for resumption to the TLS handshake, and fix
- // this test to not rely on QUIC crypto.
return;
}
// Complete a handshake in order to prime the crypto config for 0-RTT.
@@ -229,7 +247,6 @@ TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
// Now create a second session using the same crypto config.
Initialize();
- EXPECT_CALL(*connection_, OnCanWrite());
// Starting the handshake should move immediately to encryption
// established and will allow streams to be created.
session_->CryptoConnect();
@@ -257,7 +274,7 @@ TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
char data[] = "hello world";
EXPECT_QUIC_BUG(
session_->WritevData(stream->id(), QUICHE_ARRAYSIZE(data), 0, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt),
+ NOT_RETRANSMISSION, QUICHE_NULLOPT),
"Client: Try to send data of stream");
}
@@ -343,11 +360,7 @@ TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&ClearControlFrame));
EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- if (session_->break_close_loop()) {
- session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
- } else {
- session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
- }
+ session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
// A new stream cannot be created as the reset stream still counts as an open
// outgoing stream until closed by the server.
@@ -399,11 +412,7 @@ TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&ClearControlFrame));
EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- if (session_->break_close_loop()) {
- session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
- } else {
- session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
- }
+ session_->ResetStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
// The stream receives trailers with final byte offset, but the header value
// is non-numeric and should be treated as malformed.
@@ -853,12 +862,7 @@ TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*connection_,
OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
- if (session_->break_close_loop()) {
- session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
- } else {
- session_->SendRstStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY,
- 0);
- }
+ session_->ResetStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
QuicClientPromisedInfo* promised =
session_->GetPromisedById(promised_stream_id_);
EXPECT_NE(promised, nullptr);
@@ -983,44 +987,50 @@ TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
}
TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
- // This feature is HTTP/3 only
- if (!VersionUsesHttp3(session_->transport_version())) {
+ // This feature is TLS-only.
+ if (session_->version().UsesQuicCrypto()) {
return;
}
- CompleteCryptoHandshake();
- EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
- SettingsFrame settings;
- settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
- settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
- settings.values[256] = 4; // unknown setting
- session_->OnSettingsFrame(settings);
+
+ CompleteFirstConnection();
CreateConnection();
// Session configs should be in initial state.
- EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
- EXPECT_EQ(std::numeric_limits<size_t>::max(),
- session_->max_outbound_header_list_size());
+ if (session_->version().UsesHttp3()) {
+ EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
+ EXPECT_EQ(std::numeric_limits<size_t>::max(),
+ session_->max_outbound_header_list_size());
+ } else {
+ EXPECT_EQ(kMinimumFlowControlSendWindow,
+ session_->flow_controller()->send_window_offset());
+ }
session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
// The client session should have a basic setup ready before the handshake
// succeeds.
EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
session_->flow_controller()->send_window_offset());
- auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection,
- id_manager->max_outgoing_bidirectional_streams());
- EXPECT_EQ(
- kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
- id_manager->max_outgoing_unidirectional_streams());
- auto* control_stream =
- QuicSpdySessionPeer::GetSendControlStream(session_.get());
- EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
- control_stream->flow_controller()->send_window_offset());
- EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+ if (session_->version().UsesHttp3()) {
+ auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+ id_manager->max_outgoing_bidirectional_streams());
+ EXPECT_EQ(
+ kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
+ id_manager->max_outgoing_unidirectional_streams());
+ auto* control_stream =
+ QuicSpdySessionPeer::GetSendControlStream(session_.get());
+ EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
+ control_stream->flow_controller()->send_window_offset());
+ EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+ } else {
+ auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+ id_manager->max_open_outgoing_streams());
+ }
// Complete the handshake with a different config.
- QuicCryptoClientStream* stream =
- static_cast<QuicCryptoClientStream*>(session_->GetMutableCryptoStream());
QuicConfig config = DefaultQuicConfig();
config.SetInitialMaxStreamDataBytesUnidirectionalToSend(
kInitialStreamFlowControlWindowForTest + 1);
@@ -1028,23 +1038,415 @@ TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
kInitialSessionFlowControlWindowForTest + 1);
config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection + 1);
- SetQuicReloadableFlag(quic_enable_tls_resumption, true);
- std::unique_ptr<QuicCryptoServerConfig> crypto_config =
- crypto_test_utils::CryptoServerConfigForTesting();
crypto_test_utils::HandshakeWithFakeServer(
- &config, crypto_config.get(), &helper_, &alarm_factory_, connection_,
- stream, AlpnForVersion(connection_->version()));
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
session_->flow_controller()->send_window_offset());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
- id_manager->max_outgoing_bidirectional_streams());
- EXPECT_EQ(kDefaultMaxStreamsPerConnection +
- kHttp3StaticUnidirectionalStreamCount + 1,
- id_manager->max_outgoing_unidirectional_streams());
- EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
- control_stream->flow_controller()->send_window_offset());
+ if (session_->version().UsesHttp3()) {
+ auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
+ auto* control_stream =
+ QuicSpdySessionPeer::GetSendControlStream(session_.get());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+ id_manager->max_outgoing_bidirectional_streams());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection +
+ kHttp3StaticUnidirectionalStreamCount + 1,
+ id_manager->max_outgoing_unidirectional_streams());
+ EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
+ control_stream->flow_controller()->send_window_offset());
+ } else {
+ auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+ EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+ id_manager->max_open_outgoing_streams());
+ }
+
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+ // Let the session receive a new SETTINGS frame to complete the second
+ // connection.
+ if (session_->version().UsesHttp3()) {
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+ settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+ settings.values[256] = 4; // unknown setting
+ session_->OnSettingsFrame(settings);
+ }
+}
+
+// Regression test for b/159168475
+TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
+ SetQuicReloadableFlag(quic_do_not_retransmit_immediately_on_zero_rtt_reject,
+ true);
+ // This feature is TLS-only.
+ if (session_->version().UsesQuicCrypto()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ // Create a second connection, but disable 0-RTT on the server.
+ CreateConnection();
+ ON_CALL(*connection_, OnCanWrite())
+ .WillByDefault(
+ testing::Invoke(connection_, &MockQuicConnection::ReallyOnCanWrite));
+ EXPECT_CALL(*connection_, OnCanWrite()).Times(0);
+
+ QuicConfig config = DefaultQuicConfig();
+ config.SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+ config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+
+ // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
+ // data.
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
+ .Times(session_->version().UsesHttp3() ? 2 : 1);
+ session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+ QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+ ASSERT_TRUE(stream);
+ stream->WriteOrBufferData("hello", true, nullptr);
+
+ // When handshake is done, the client sends 2 packet: HANDSHAKE FINISHED, and
+ // coalesced retransmission of HTTP/3 SETTINGS and request data.
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+ // TODO(b/158027651): change transmission type to ALL_ZERO_RTT_RETRANSMISSION.
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+ EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+}
+
+// When IETF QUIC 0-RTT is rejected, a server-sent fresh transport params is
+// available. If the new transport params reduces stream/flow control limit to
+// lower than what the client has already used, connection will be closed.
+TEST_P(QuicSpdyClientSessionTest, ZeroRttRejectReducesStreamLimitTooMuch) {
+ // This feature is TLS-only.
+ if (session_->version().UsesQuicCrypto()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ // Create a second connection, but disable 0-RTT on the server.
+ CreateConnection();
+ QuicConfig config = DefaultQuicConfig();
+ // Server doesn't allow any bidirectional streams.
+ config.SetMaxBidirectionalStreamsToSend(0);
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+ session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+ ASSERT_TRUE(stream);
+
+ if (session_->version().UsesHttp3()) {
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(
+ QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+ "Server rejected 0-RTT, aborting because new bidirectional initial "
+ "stream limit 0 is less than current open streams: 1",
+ _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ } else {
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_INTERNAL_ERROR,
+ "Server rejected 0-RTT, aborting because new stream "
+ "limit 0 is less than current open streams: 1",
+ _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ }
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+ ZeroRttRejectReducesStreamFlowControlTooMuch) {
+ // This feature is TLS-only.
+ if (session_->version().UsesQuicCrypto()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ // Create a second connection, but disable 0-RTT on the server.
+ CreateConnection();
+ QuicConfig config = DefaultQuicConfig();
+ // Server doesn't allow any outgoing streams.
+ config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(2);
+ config.SetInitialMaxStreamDataBytesUnidirectionalToSend(1);
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+ session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+ ASSERT_TRUE(stream);
+ // Let the stream write more than 1 byte of data.
+ stream->WriteOrBufferData("hello", true, nullptr);
+
+ if (session_->version().UsesHttp3()) {
+ // Both control stream and the request stream will report errors.
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+ .Times(2)
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ } else {
+ EXPECT_CALL(*connection_,
+ CloseConnection(
+ QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+ "Server rejected 0-RTT, aborting because new stream max "
+ "data 2 for stream 3 is less than currently used: 5",
+ _))
+ .Times(1)
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ }
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest,
+ ZeroRttRejectReducesSessionFlowControlTooMuch) {
+ // This feature is TLS-only.
+ if (session_->version().UsesQuicCrypto()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ // Create a second connection, but disable 0-RTT on the server.
+ CreateConnection();
+ QuicConfig config = DefaultQuicConfig();
+ // Server doesn't allow minimum data in session.
+ config.SetInitialSessionFlowControlWindowToSend(
+ kMinimumFlowControlSendWindow);
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+ session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ QuicSpdyClientStream* stream = session_->CreateOutgoingBidirectionalStream();
+ ASSERT_TRUE(stream);
+ std::string data_to_send(kMinimumFlowControlSendWindow + 1, 'x');
+ // Let the stream write some data.
+ stream->WriteOrBufferData(data_to_send, true, nullptr);
+
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_ZERO_RTT_UNRETRANSMITTABLE, _, _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
+
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+}
+
+TEST_P(QuicSpdyClientSessionTest, SetMaxPushIdBeforeEncryptionEstablished) {
+ // 0-RTT is TLS-only, MAX_PUSH_ID frame is HTTP/3-only.
+ if (!session_->version().UsesTls() || !session_->version().UsesHttp3()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ CreateConnection();
+ StrictMock<MockHttp3DebugVisitor> debug_visitor;
+ session_->set_debug_visitor(&debug_visitor);
+
+ // No MAX_PUSH_ID frame is sent before encryption is established.
+ session_->SetMaxPushId(5);
+
+ EXPECT_FALSE(session_->IsEncryptionEstablished());
+ EXPECT_FALSE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_INITIAL, session_->connection()->encryption_level());
+
+ // MAX_PUSH_ID frame is sent upon encryption establishment with the value set
+ // by the earlier SetMaxPushId() call.
+ EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+ EXPECT_CALL(debug_visitor, OnMaxPushIdFrameSent(_))
+ .WillOnce(Invoke(
+ [](const MaxPushIdFrame& frame) { EXPECT_EQ(5u, frame.push_id); }));
+ session_->CryptoConnect();
+ testing::Mock::VerifyAndClearExpectations(&debug_visitor);
+
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_FALSE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+
+ // Another SetMaxPushId() call with the same value does not trigger sending
+ // another MAX_PUSH_ID frame.
+ session_->SetMaxPushId(5);
+
+ // Calling SetMaxPushId() with a different value results in sending another
+ // MAX_PUSH_ID frame.
+ EXPECT_CALL(debug_visitor, OnMaxPushIdFrameSent(_))
+ .WillOnce(Invoke(
+ [](const MaxPushIdFrame& frame) { EXPECT_EQ(10u, frame.push_id); }));
+ session_->SetMaxPushId(10);
+ testing::Mock::VerifyAndClearExpectations(&debug_visitor);
+
+ QuicConfig config = DefaultQuicConfig();
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_TRUE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
+ session_->connection()->encryption_level());
+ EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+}
+
+TEST_P(QuicSpdyClientSessionTest, SetMaxPushIdAfterEncryptionEstablished) {
+ // 0-RTT is TLS-only, MAX_PUSH_ID frame is HTTP/3-only.
+ if (!session_->version().UsesTls() || !session_->version().UsesHttp3()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ CreateConnection();
+ StrictMock<MockHttp3DebugVisitor> debug_visitor;
+ session_->set_debug_visitor(&debug_visitor);
+
+ EXPECT_FALSE(session_->IsEncryptionEstablished());
+ EXPECT_FALSE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_INITIAL, session_->connection()->encryption_level());
+
+ // No MAX_PUSH_ID frame is sent if SetMaxPushId() has not been called.
+ EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
+ session_->CryptoConnect();
+ testing::Mock::VerifyAndClearExpectations(&debug_visitor);
+
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_FALSE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
+
+ // Calling SetMaxPushId() for the first time after encryption is established
+ // results in sending a MAX_PUSH_ID frame.
+ EXPECT_CALL(debug_visitor, OnMaxPushIdFrameSent(_))
+ .WillOnce(Invoke(
+ [](const MaxPushIdFrame& frame) { EXPECT_EQ(5u, frame.push_id); }));
+ session_->SetMaxPushId(5);
+ testing::Mock::VerifyAndClearExpectations(&debug_visitor);
+
+ // Another SetMaxPushId() call with the same value does not trigger sending
+ // another MAX_PUSH_ID frame.
+ session_->SetMaxPushId(5);
+
+ // Calling SetMaxPushId() with a different value results in sending another
+ // MAX_PUSH_ID frame.
+ EXPECT_CALL(debug_visitor, OnMaxPushIdFrameSent(_))
+ .WillOnce(Invoke(
+ [](const MaxPushIdFrame& frame) { EXPECT_EQ(10u, frame.push_id); }));
+ session_->SetMaxPushId(10);
+ testing::Mock::VerifyAndClearExpectations(&debug_visitor);
+
+ QuicConfig config = DefaultQuicConfig();
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ EXPECT_TRUE(session_->OneRttKeysAvailable());
+ EXPECT_EQ(ENCRYPTION_FORWARD_SECURE,
+ session_->connection()->encryption_level());
+ EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttResumption) {
+ if (!session_->version().UsesHttp3()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ CreateConnection();
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ // Let the session receive a different SETTINGS frame.
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+ settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+ settings.values[256] = 4; // unknown setting
+ session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, BadSettingsInZeroRttRejection) {
+ if (!session_->version().UsesHttp3()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ CreateConnection();
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+ session_->CryptoConnect();
+ EXPECT_TRUE(session_->IsEncryptionEstablished());
+ QuicConfig config = DefaultQuicConfig();
+ crypto_test_utils::HandshakeWithFakeServer(
+ &config, server_crypto_config_.get(), &helper_, &alarm_factory_,
+ connection_, crypto_stream_, AlpnForVersion(connection_->version()));
+ EXPECT_FALSE(session_->GetCryptoStream()->EarlyDataAccepted());
+
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH, _, _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ // Let the session receive a different SETTINGS frame.
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+ // setting on SETTINGS_MAX_HEADER_LIST_SIZE is reduced.
+ settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 4;
+ settings.values[256] = 4; // unknown setting
+ session_->OnSettingsFrame(settings);
+}
+
+TEST_P(QuicSpdyClientSessionTest, ServerAcceptsZeroRttButOmitSetting) {
+ if (!session_->version().UsesHttp3()) {
+ return;
+ }
+
+ CompleteFirstConnection();
+
+ CreateConnection();
+ CompleteCryptoHandshake();
+ EXPECT_TRUE(session_->GetMutableCryptoStream()->EarlyDataAccepted());
+
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH, _, _))
+ .WillOnce(testing::Invoke(connection_,
+ &MockQuicConnection::ReallyCloseConnection));
+ // Let the session receive a different SETTINGS frame.
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1;
+ // Intentionally omit SETTINGS_MAX_HEADER_LIST_SIZE which was previously sent
+ // with a non-zero value.
+ settings.values[256] = 4; // unknown setting
+ session_->OnSettingsFrame(settings);
}
} // namespace
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 7232f76c755..f50e756d1b3 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
@@ -53,24 +53,41 @@ void QuicSpdyClientStream::OnInitialHeadersComplete(
if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
&response_headers_)) {
QUIC_DLOG(ERROR) << "Failed to parse header list: "
- << header_list.DebugString();
+ << header_list.DebugString() << " on stream " << id();
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
return;
}
if (!ParseHeaderStatusCode(response_headers_, &response_code_)) {
QUIC_DLOG(ERROR) << "Received invalid response code: "
- << response_headers_[":status"].as_string();
+ << response_headers_[":status"].as_string()
+ << " on stream " << id();
+ Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+ return;
+ }
+
+ if (response_code_ == 101) {
+ // 101 "Switching Protocols" is forbidden in HTTP/3 as per the
+ // "HTTP Upgrade" section of draft-ietf-quic-http.
+ QUIC_DLOG(ERROR) << "Received forbidden 101 response code"
+ << " on stream " << id();
Reset(QUIC_BAD_APPLICATION_PAYLOAD);
return;
}
- if (response_code_ == 100 && !has_preliminary_headers_) {
- // These are preliminary 100 Continue headers, not the actual response
- // headers.
+ if (response_code_ >= 100 && response_code_ < 200) {
+ // These are Informational 1xx headers, not the actual response headers.
+ QUIC_DLOG(INFO) << "Received informational response code: "
+ << response_headers_[":status"].as_string() << " on stream "
+ << id();
set_headers_decompressed(false);
- has_preliminary_headers_ = true;
- preliminary_headers_ = std::move(response_headers_);
+ if (response_code_ == 100 && !has_preliminary_headers_) {
+ // This is 100 Continue, save it to enable "Expect: 100-continue".
+ has_preliminary_headers_ = true;
+ preliminary_headers_ = std::move(response_headers_);
+ } else {
+ response_headers_.clear();
+ }
}
ConsumeHeaderList();
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 fdc0e298371..1aba0005981 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
@@ -133,17 +133,77 @@ TEST_P(QuicSpdyClientStreamTest, TestFraming) {
EXPECT_EQ(body_, stream_->data());
}
-TEST_P(QuicSpdyClientStreamTest, TestFraming100Continue) {
+TEST_P(QuicSpdyClientStreamTest, Test100ContinueBeforeSuccessful) {
+ // First send 100 Continue.
headers_[":status"] = "100";
auto headers = AsHeaderList(headers_);
stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
headers);
- stream_->OnStreamFrame(
- QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
EXPECT_EQ(0u, stream_->response_headers().size());
EXPECT_EQ(100, stream_->response_code());
EXPECT_EQ("", stream_->data());
+ // Then send 200 OK.
+ headers_[":status"] = "200";
+ headers = AsHeaderList(headers_);
+ stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+ headers);
+ std::unique_ptr<char[]> buffer;
+ QuicByteCount header_length =
+ HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
+ std::string header = std::string(buffer.get(), header_length);
+ std::string data =
+ connection_->version().UsesHttp3() ? header + body_ : body_;
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+ // Make sure the 200 response got parsed correctly.
+ EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+ EXPECT_EQ(200, stream_->response_code());
+ EXPECT_EQ(body_, stream_->data());
+ // Make sure the 100 response is still available.
+ EXPECT_EQ("100", stream_->preliminary_headers().find(":status")->second);
+}
+
+TEST_P(QuicSpdyClientStreamTest, TestUnknownInformationalBeforeSuccessful) {
+ // First send 199, an unknown Informational (1XX).
+ headers_[":status"] = "199";
+ auto headers = AsHeaderList(headers_);
+ stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+ headers);
+ EXPECT_EQ(0u, stream_->response_headers().size());
+ EXPECT_EQ(199, stream_->response_code());
+ EXPECT_EQ("", stream_->data());
+ // Then send 200 OK.
+ headers_[":status"] = "200";
+ headers = AsHeaderList(headers_);
+ stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+ headers);
+ std::unique_ptr<char[]> buffer;
+ QuicByteCount header_length =
+ HttpEncoder::SerializeDataFrameHeader(body_.length(), &buffer);
+ std::string header = std::string(buffer.get(), header_length);
+ std::string data =
+ connection_->version().UsesHttp3() ? header + body_ : body_;
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
+ // Make sure the 200 response got parsed correctly.
+ EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
+ EXPECT_EQ(200, stream_->response_code());
+ EXPECT_EQ(body_, stream_->data());
+}
+
+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(*connection_,
+ OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
+ auto headers = AsHeaderList(headers_);
+ stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
+ headers);
+ EXPECT_THAT(stream_->stream_error(),
+ IsStreamError(QUIC_BAD_APPLICATION_PAYLOAD));
}
TEST_P(QuicSpdyClientStreamTest, TestFramingOnePacket) {
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 27643c87294..d6b5a0e7629 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
@@ -434,6 +434,7 @@ QuicSpdySession::~QuicSpdySession() {
void QuicSpdySession::Initialize() {
QuicSession::Initialize();
+ FillSettingsFrame();
if (!VersionUsesHttp3(transport_version())) {
if (perspective() == Perspective::IS_SERVER) {
set_largest_peer_created_stream_id(
@@ -464,6 +465,15 @@ void QuicSpdySession::Initialize() {
2 * max_inbound_header_list_size_);
}
+void QuicSpdySession::FillSettingsFrame() {
+ settings_.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+ qpack_maximum_dynamic_table_capacity_;
+ settings_.values[SETTINGS_QPACK_BLOCKED_STREAMS] =
+ qpack_maximum_blocked_streams_;
+ settings_.values[SETTINGS_MAX_HEADER_LIST_SIZE] =
+ max_inbound_header_list_size_;
+}
+
void QuicSpdySession::OnDecoderStreamError(
quiche::QuicheStringPiece error_message) {
DCHECK(VersionUsesHttp3(transport_version()));
@@ -548,7 +558,7 @@ void QuicSpdySession::OnPriorityFrame(
bool QuicSpdySession::OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
int urgency) {
if (perspective() == Perspective::IS_CLIENT ||
- !QuicUtils::IsBidirectionalStreamId(stream_id) ||
+ !QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
!QuicUtils::IsClientInitiatedStreamId(transport_version(), stream_id)) {
return true;
}
@@ -647,7 +657,7 @@ void QuicSpdySession::WriteHttp3PriorityUpdate(
void QuicSpdySession::OnHttp3GoAway(QuicStreamId stream_id) {
DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
- if (!QuicUtils::IsBidirectionalStreamId(stream_id) ||
+ if (!QuicUtils::IsBidirectionalStreamId(stream_id, version()) ||
IsIncomingStream(stream_id)) {
CloseConnectionWithDetails(
QUIC_INVALID_STREAM_ID,
@@ -736,9 +746,9 @@ void QuicSpdySession::SendInitialData() {
}
QuicConnection::ScopedPacketFlusher flusher(connection());
send_control_stream_->MaybeSendSettingsFrame();
- if (perspective() == Perspective::IS_CLIENT && !http3_max_push_id_sent_) {
+ if (perspective() == Perspective::IS_CLIENT && max_push_id_.has_value() &&
+ !http3_max_push_id_sent_) {
SendMaxPushId();
- http3_max_push_id_sent_ = true;
}
}
@@ -856,7 +866,7 @@ void QuicSpdySession::OnPromiseHeaderList(
ConnectionCloseBehavior::SILENT_CLOSE);
}
-bool QuicSpdySession::SetApplicationState(ApplicationState* cached_state) {
+bool QuicSpdySession::ResumeApplicationState(ApplicationState* cached_state) {
DCHECK_EQ(perspective(), Perspective::IS_CLIENT);
DCHECK(VersionUsesHttp3(transport_version()));
@@ -874,52 +884,102 @@ bool QuicSpdySession::SetApplicationState(ApplicationState* cached_state) {
return true;
}
-void QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
+bool QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
DCHECK(VersionUsesHttp3(transport_version()));
if (debug_visitor_ != nullptr) {
debug_visitor_->OnSettingsFrameReceived(frame);
}
for (const auto& setting : frame.values) {
- OnSetting(setting.first, setting.second);
+ if (!OnSetting(setting.first, setting.second)) {
+ return false;
+ }
}
+ return true;
}
-void QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
+bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
if (VersionUsesHttp3(transport_version())) {
// SETTINGS frame received on the control stream.
switch (id) {
- case SETTINGS_QPACK_MAX_TABLE_CAPACITY:
+ case SETTINGS_QPACK_MAX_TABLE_CAPACITY: {
QUIC_DVLOG(1)
<< ENDPOINT
<< "SETTINGS_QPACK_MAX_TABLE_CAPACITY received with value "
<< value;
// Communicate |value| to encoder, because it is used for encoding
// Required Insert Count.
- qpack_encoder_->SetMaximumDynamicTableCapacity(value);
+ bool success = qpack_encoder_->SetMaximumDynamicTableCapacity(value);
+ if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) && !success) {
+ CloseConnectionWithDetails(
+ was_zero_rtt_rejected()
+ ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+ : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ quiche::QuicheStrCat(
+ was_zero_rtt_rejected()
+ ? "Server rejected 0-RTT, aborting because "
+ : "",
+ "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: ", value,
+ "while current value is: ",
+ qpack_encoder_->MaximumDynamicTableCapacity()));
+ return false;
+ }
// However, limit the dynamic table capacity to
// |qpack_maximum_dynamic_table_capacity_|.
qpack_encoder_->SetDynamicTableCapacity(
std::min(value, qpack_maximum_dynamic_table_capacity_));
break;
+ }
case SETTINGS_MAX_HEADER_LIST_SIZE:
QUIC_DVLOG(1) << ENDPOINT
<< "SETTINGS_MAX_HEADER_LIST_SIZE received with value "
<< value;
+ if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) &&
+ max_outbound_header_list_size_ !=
+ std::numeric_limits<size_t>::max() &&
+ max_outbound_header_list_size_ > value) {
+ CloseConnectionWithDetails(
+ was_zero_rtt_rejected()
+ ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+ : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ quiche::QuicheStrCat(
+ was_zero_rtt_rejected()
+ ? "Server rejected 0-RTT, aborting because "
+ : "",
+ "Server sent an SETTINGS_MAX_HEADER_LIST_SIZE: ", value,
+ "which reduces current value: ",
+ max_outbound_header_list_size_));
+ return false;
+ }
max_outbound_header_list_size_ = value;
break;
- case SETTINGS_QPACK_BLOCKED_STREAMS:
+ case SETTINGS_QPACK_BLOCKED_STREAMS: {
QUIC_DVLOG(1) << ENDPOINT
<< "SETTINGS_QPACK_BLOCKED_STREAMS received with value "
<< value;
- qpack_encoder_->SetMaximumBlockedStreams(value);
+ bool success = qpack_encoder_->SetMaximumBlockedStreams(value);
+ if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) && !success) {
+ CloseConnectionWithDetails(
+ was_zero_rtt_rejected()
+ ? QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH
+ : QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
+ quiche::QuicheStrCat(
+ was_zero_rtt_rejected()
+ ? "Server rejected 0-RTT, aborting because "
+ : "",
+ "Server sent an SETTINGS_QPACK_BLOCKED_STREAMS: ", value,
+ "which reduces current value: ",
+ qpack_encoder_->maximum_blocked_streams()));
+ return false;
+ }
break;
+ }
default:
QUIC_DVLOG(1) << ENDPOINT << "Unknown setting identifier " << id
<< " received with value " << value;
// Ignore unknown settings.
break;
}
- return;
+ return true;
}
// SETTINGS frame received on the headers stream.
@@ -942,7 +1002,7 @@ void QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
quiche::QuicheStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ",
value));
}
- return;
+ return true;
}
QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_ENABLE_PUSH received with value "
<< value;
@@ -977,6 +1037,7 @@ void QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
id));
}
}
+ return true;
}
bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() {
@@ -1076,11 +1137,8 @@ void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error,
}
bool QuicSpdySession::HasActiveRequestStreams() const {
- DCHECK_GE(static_cast<size_t>(stream_map().size()),
- num_incoming_static_streams() + num_outgoing_static_streams());
- return stream_map().size() - num_incoming_static_streams() -
- num_outgoing_static_streams() >
- 0;
+ DCHECK_GE(static_cast<size_t>(stream_map().size()), num_static_streams());
+ return stream_map().size() - num_static_streams() > 0;
}
bool QuicSpdySession::ProcessPendingStream(PendingStream* pending) {
@@ -1176,9 +1234,7 @@ void QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams() {
DCHECK(VersionUsesHttp3(transport_version()));
if (!send_control_stream_ && CanOpenNextOutgoingUnidirectionalStream()) {
auto send_control = std::make_unique<QuicSendControlStream>(
- GetNextOutgoingUnidirectionalStreamId(), this,
- qpack_maximum_dynamic_table_capacity_, qpack_maximum_blocked_streams_,
- max_inbound_header_list_size_);
+ GetNextOutgoingUnidirectionalStreamId(), this, settings_);
send_control_stream_ = send_control.get();
ActivateStream(std::move(send_control));
if (debug_visitor_) {
@@ -1231,15 +1287,19 @@ void QuicSpdySession::SetMaxPushId(PushId max_push_id) {
ietf_server_push_enabled_ = true;
if (max_push_id_.has_value()) {
- QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id
+ if (max_push_id == max_push_id_.value()) {
+ QUIC_DVLOG(1) << "Not changing max_push_id: " << max_push_id;
+ return;
+ }
+
+ QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id
<< " from: " << max_push_id_.value();
} else {
- QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id
- << " from unset";
+ QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id << " from unset";
}
max_push_id_ = max_push_id;
- if (OneRttKeysAvailable()) {
+ if (IsEncryptionEstablished()) {
SendMaxPushId();
}
}
@@ -1281,9 +1341,8 @@ void QuicSpdySession::SendMaxPushId() {
DCHECK(VersionUsesHttp3(transport_version()));
DCHECK_EQ(Perspective::IS_CLIENT, perspective());
- if (max_push_id_.has_value()) {
- send_control_stream_->SendMaxPushIdFrame(max_push_id_.value());
- }
+ send_control_stream_->SendMaxPushIdFrame(max_push_id_.value());
+ http3_max_push_id_sent_ = true;
}
void QuicSpdySession::EnableServerPush() {
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 703dffaf41e..4d6ee6370e3 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
@@ -247,10 +247,14 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
bool server_push_enabled() const;
// Called when the control stream receives HTTP/3 SETTINGS.
- virtual void OnSettingsFrame(const SettingsFrame& frame);
+ // Returns false in case of 0-RTT if received settings are incompatible with
+ // cached values, true otherwise.
+ virtual bool OnSettingsFrame(const SettingsFrame& frame);
- // Called when a setting is parsed from an incoming SETTINGS frame.
- void OnSetting(uint64_t id, uint64_t value);
+ // Called when a SETTINGS is parsed from an incoming SETTINGS frame.
+ // Returns false in case of 0-RTT if received SETTINGS is incompatible with
+ // cached value, true otherwise.
+ bool OnSetting(uint64_t id, uint64_t value);
// Return true if this session wants to release headers stream's buffer
// aggressively.
@@ -378,7 +382,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
void OnStreamCreated(QuicSpdyStream* stream);
// Decode SETTINGS from |cached_state| and apply it to the session.
- bool SetApplicationState(ApplicationState* cached_state) override;
+ bool ResumeApplicationState(ApplicationState* cached_state) override;
protected:
// Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
@@ -443,11 +447,11 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
return receive_control_stream_;
}
+ const SettingsFrame& settings() const { return settings_; }
+
// Initializes HTTP/3 unidirectional streams if not yet initialzed.
virtual void MaybeInitializeHttp3UnidirectionalStreams();
- void SendMaxPushId();
-
private:
friend class test::QuicSpdySessionPeer;
@@ -468,10 +472,18 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
quiche::QuicheStringPiece type);
- // Sends any data which should be sent at the start of a connection,
- // including the initial SETTINGS frame, etc.
+ // 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
+ // frame if SetMaxPushId() had been called before encryption was established.
+ // When using 0-RTT, this method is called twice: once when encryption is
+ // established, and again when 1-RTT keys are available.
void SendInitialData();
+ // Send a MAX_PUSH_ID frame. Used in IETF QUIC only.
+ void SendMaxPushId();
+
+ void FillSettingsFrame();
+
std::unique_ptr<QpackEncoder> qpack_encoder_;
std::unique_ptr<QpackDecoder> qpack_decoder_;
@@ -489,6 +501,8 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
QpackSendStream* qpack_encoder_send_stream_;
QpackSendStream* qpack_decoder_send_stream_;
+ SettingsFrame settings_;
+
// Maximum dynamic table capacity as defined at
// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
// for the decoding context. Value will be sent via
@@ -533,12 +547,17 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
// Server push is enabled for a client by calling SetMaxPushId().
bool ietf_server_push_enabled_;
- // Used in IETF QUIC only. Unset until a MAX_PUSH_ID frame is received/sent.
- // For a server, the push ID in the most recently received MAX_PUSH_ID frame.
- // For a client before 1-RTT keys are available, the push ID to be sent in the
- // initial MAX_PUSH_ID frame.
- // For a client after 1-RTT keys are available, the push ID in the most
- // recently sent MAX_PUSH_ID frame.
+ // Used in IETF QUIC only.
+ // For a server:
+ // the push ID in the most recently received MAX_PUSH_ID frame,
+ // or unset if no MAX_PUSH_ID frame has been received.
+ // For a client:
+ // unset until SetMaxPushId() is called;
+ // before encryption is established, the push ID to be sent in the initial
+ // MAX_PUSH_ID frame;
+ // 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_;
// An integer used for live check. The indicator is assigned a value in
@@ -554,14 +573,14 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
// If the endpoint has sent HTTP/3 GOAWAY frame.
bool http3_goaway_sent_;
- // If SendMaxPushId() has been called from SendInitialData(). Note that a
- // MAX_PUSH_ID frame is only sent if SetMaxPushId() had been called
- // beforehand.
+ // 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
+ // recent MAX_PUSH_ID frame. Once true, never goes back to false.
bool http3_max_push_id_sent_;
// Priority values received in PRIORITY_UPDATE frames for streams that are not
// open yet.
- QuicUnorderedMap<QuicStreamId, int> buffered_stream_priorities_;
+ QuicHashMap<QuicStreamId, int> buffered_stream_priorities_;
};
} // 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 8b78d7f0883..b2bcaa3bf28 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
@@ -91,6 +91,17 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
kInitialStreamFlowControlWindowForTest);
session()->config()->SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
+ if (session()->version().AuthenticatesHandshakeConnectionIds()) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ session()->config()->SetOriginalConnectionIdToSend(
+ session()->connection()->connection_id());
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->connection_id());
+ } else {
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->client_connection_id());
+ }
+ }
if (session()->connection()->version().handshake_protocol ==
PROTOCOL_TLS1_3) {
TransportParameters transport_parameters;
@@ -129,6 +140,8 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
HandshakeState GetHandshakeState() const override {
return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
}
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
const override {
return *params_;
@@ -197,6 +210,9 @@ class TestSession : public QuicSpdySession {
this->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(connection->perspective()));
+ if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(this->connection());
+ }
}
~TestSession() override { DeleteConnection(); }
@@ -226,7 +242,7 @@ class TestSession : public QuicSpdySession {
TestStream* CreateIncomingStream(QuicStreamId id) override {
// Enforce the limit on the number of open streams.
if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
- GetNumOpenIncomingStreams() + 1 >
+ stream_id_manager().num_open_incoming_streams() + 1 >
max_open_incoming_bidirectional_streams()) {
connection()->CloseConnection(
QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
@@ -235,9 +251,8 @@ class TestSession : public QuicSpdySession {
} else {
TestStream* stream = new TestStream(
id, this,
- DetermineStreamType(id, connection()->transport_version(),
- perspective(), /*is_incoming=*/true,
- BIDIRECTIONAL));
+ DetermineStreamType(id, connection()->version(), perspective(),
+ /*is_incoming=*/true, BIDIRECTIONAL));
ActivateStream(QuicWrapUnique(stream));
return stream;
}
@@ -245,11 +260,10 @@ class TestSession : public QuicSpdySession {
TestStream* CreateIncomingStream(PendingStream* pending) override {
QuicStreamId id = pending->id();
- TestStream* stream =
- new TestStream(pending, this,
- DetermineStreamType(
- id, connection()->transport_version(), perspective(),
- /*is_incoming=*/true, BIDIRECTIONAL));
+ TestStream* stream = new TestStream(
+ pending, this,
+ DetermineStreamType(id, connection()->version(), perspective(),
+ /*is_incoming=*/true, BIDIRECTIONAL));
ActivateStream(QuicWrapUnique(stream));
return stream;
}
@@ -299,7 +313,7 @@ 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, QuicheNullOpt);
+ WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, QUICHE_NULLOPT);
QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
consumed.bytes_consumed);
return consumed;
@@ -308,7 +322,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,
- QuicheNullOpt);
+ QUICHE_NULLOPT);
}
using QuicSession::closed_streams;
@@ -1599,6 +1613,7 @@ TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
return;
}
QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
EXPECT_CALL(
*connection_,
@@ -1613,6 +1628,7 @@ TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
copt.push_back(kIFW7);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
session_.flow_controller()));
@@ -2985,6 +3001,26 @@ TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
}
}
+TEST_P(QuicSpdySessionTestServer,
+ H3ControlStreamsLimitedByConnectionFlowControl) {
+ if (!VersionUsesHttp3(transport_version())) {
+ return;
+ }
+ // Ensure connection level flow control blockage.
+ QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+ EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+
+ QuicSendControlStream* send_control_stream =
+ QuicSpdySessionPeer::GetSendControlStream(&session_);
+ // Mark send_control stream write blocked.
+ session_.MarkConnectionLevelWriteBlocked(send_control_stream->id());
+ if (GetQuicReloadableFlag(quic_fix_willing_and_able_to_write)) {
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+ } else {
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+ }
+}
+
TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
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 51f7c5c9525..4c979c1784f 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
@@ -529,6 +529,21 @@ void QuicSpdyStream::OnStreamHeadersPriority(
void QuicSpdyStream::OnStreamHeaderList(bool fin,
size_t frame_len,
const QuicHeaderList& header_list) {
+ if (GetQuicReloadableFlag(quic_save_user_agent_in_quic_session)) {
+ if (!spdy_session()->user_agent_id().has_value()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_save_user_agent_in_quic_session, 3, 3);
+ std::string uaid;
+ for (const auto& kv : header_list) {
+ if (quiche::QuicheTextUtils::ToLower(kv.first) ==
+ kUserAgentHeaderName) {
+ uaid = kv.second;
+ break;
+ }
+ }
+ spdy_session()->SetUserAgentId(std::move(uaid));
+ }
+ }
+
// TODO(b/134706391): remove |fin| argument.
// When using Google QUIC, an empty header list indicates that the size limit
// has been exceeded.
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 bafb0f282f0..e769a9d6027 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
@@ -78,6 +78,17 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
kInitialStreamFlowControlWindowForTest);
session()->config()->SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
+ if (session()->version().AuthenticatesHandshakeConnectionIds()) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ session()->config()->SetOriginalConnectionIdToSend(
+ session()->connection()->connection_id());
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->connection_id());
+ } else {
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->client_connection_id());
+ }
+ }
if (session()->connection()->version().handshake_protocol ==
PROTOCOL_TLS1_3) {
TransportParameters transport_parameters;
@@ -116,6 +127,8 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
HandshakeState GetHandshakeState() const override {
return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
}
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
const override {
return *params_;
@@ -324,6 +337,9 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
&helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
session_ = std::make_unique<StrictMock<TestSession>>(connection_);
session_->Initialize();
+ if (connection_->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(connection_);
+ }
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
ON_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillByDefault(
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc
index 6120f850bbc..af4de8b1c8c 100644
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.cc
@@ -31,42 +31,20 @@ LegacyQuicStreamIdManager::LegacyQuicStreamIdManager(
: QuicUtils::GetCryptoStreamId(transport_version_))
: QuicUtils::GetInvalidStreamId(transport_version_)),
num_open_incoming_streams_(0),
- num_open_outgoing_streams_(0),
- handles_accounting_(
- GetQuicReloadableFlag(quic_stream_id_manager_handles_accounting)) {
- if (handles_accounting_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_stream_id_manager_handles_accounting);
- }
-}
+ num_open_outgoing_streams_(0) {}
LegacyQuicStreamIdManager::~LegacyQuicStreamIdManager() {}
-bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream(
- size_t current_num_open_outgoing_streams) const {
- if (handles_accounting_) {
- DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
- QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
- << "Failed to create a new outgoing stream. "
- << "Already " << num_open_outgoing_streams_ << " open.";
- return num_open_outgoing_streams_ < max_open_outgoing_streams_;
- }
- if (current_num_open_outgoing_streams >= max_open_outgoing_streams_) {
- QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
- << "Already " << current_num_open_outgoing_streams
- << " open.";
- return false;
- }
- return true;
+bool LegacyQuicStreamIdManager::CanOpenNextOutgoingStream() const {
+ DCHECK_LE(num_open_outgoing_streams_, max_open_outgoing_streams_);
+ QUIC_DLOG_IF(INFO, num_open_outgoing_streams_ == max_open_outgoing_streams_)
+ << "Failed to create a new outgoing stream. "
+ << "Already " << num_open_outgoing_streams_ << " open.";
+ return num_open_outgoing_streams_ < max_open_outgoing_streams_;
}
-bool LegacyQuicStreamIdManager::CanOpenIncomingStream(
- size_t current_num_open_incoming_streams) const {
- if (handles_accounting_) {
- return num_open_incoming_streams_ < max_open_incoming_streams_;
- }
- // Check if the new number of open streams would cause the number of
- // open streams to exceed the limit.
- return current_num_open_incoming_streams < max_open_incoming_streams_;
+bool LegacyQuicStreamIdManager::CanOpenIncomingStream() const {
+ return num_open_incoming_streams_ < max_open_incoming_streams_;
}
bool LegacyQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
@@ -121,7 +99,6 @@ QuicStreamId LegacyQuicStreamIdManager::GetNextOutgoingStreamId() {
}
void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
- DCHECK(handles_accounting_);
if (is_incoming) {
++num_open_incoming_streams_;
return;
@@ -130,7 +107,6 @@ void LegacyQuicStreamIdManager::ActivateStream(bool is_incoming) {
}
void LegacyQuicStreamIdManager::OnStreamClosed(bool is_incoming) {
- DCHECK(handles_accounting_);
if (is_incoming) {
QUIC_BUG_IF(num_open_incoming_streams_ == 0);
--num_open_incoming_streams_;
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h
index 6c1309ebbc9..01315872fb8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h
@@ -29,11 +29,10 @@ class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
~LegacyQuicStreamIdManager();
// Returns true if the next outgoing stream ID can be allocated.
- bool CanOpenNextOutgoingStream(
- size_t current_num_open_outgoing_streams) const;
+ bool CanOpenNextOutgoingStream() const;
// Returns true if a new incoming stream can be opened.
- bool CanOpenIncomingStream(size_t current_num_open_incoming_streams) const;
+ bool CanOpenIncomingStream() const;
// Returns false when increasing the largest created stream id to |id| would
// violate the limit, so the connection should be closed.
@@ -95,8 +94,6 @@ class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
return num_open_outgoing_streams_;
}
- bool handles_accounting() const { return handles_accounting_; }
-
private:
friend class test::QuicSessionPeer;
@@ -118,16 +115,11 @@ class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
QuicStreamId largest_peer_created_stream_id_;
- // A counter for peer initiated open streams. Used when handles_accounting_ is
- // true.
+ // A counter for peer initiated open streams.
size_t num_open_incoming_streams_;
- // A counter for self initiated open streams. Used when handles_accounting_ is
- // true.
+ // A counter for self initiated open streams.
size_t num_open_outgoing_streams_;
-
- // Latched value of quic_stream_id_manager_handles_accounting.
- const bool handles_accounting_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc
index 00654b48c45..b7ba1d27035 100644
--- a/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager_test.cc
@@ -78,33 +78,21 @@ INSTANTIATE_TEST_SUITE_P(Tests,
::testing::PrintToStringParamName());
TEST_P(LegacyQuicStreamIdManagerTest, CanOpenNextOutgoingStream) {
- if (GetQuicReloadableFlag(quic_stream_id_manager_handles_accounting)) {
- for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
- manager_.ActivateStream(/*is_incoming=*/false);
- }
- }
- EXPECT_TRUE(manager_.CanOpenNextOutgoingStream(
- manager_.max_open_outgoing_streams() - 1));
- if (GetQuicReloadableFlag(quic_stream_id_manager_handles_accounting)) {
+ for (size_t i = 0; i < manager_.max_open_outgoing_streams() - 1; ++i) {
manager_.ActivateStream(/*is_incoming=*/false);
}
- EXPECT_FALSE(
- manager_.CanOpenNextOutgoingStream(manager_.max_open_outgoing_streams()));
+ EXPECT_TRUE(manager_.CanOpenNextOutgoingStream());
+ manager_.ActivateStream(/*is_incoming=*/false);
+ EXPECT_FALSE(manager_.CanOpenNextOutgoingStream());
}
TEST_P(LegacyQuicStreamIdManagerTest, CanOpenIncomingStream) {
- if (GetQuicReloadableFlag(quic_stream_id_manager_handles_accounting)) {
- for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
- manager_.ActivateStream(/*is_incoming=*/true);
- }
- }
- EXPECT_TRUE(
- manager_.CanOpenIncomingStream(manager_.max_open_incoming_streams() - 1));
- if (GetQuicReloadableFlag(quic_stream_id_manager_handles_accounting)) {
+ for (size_t i = 0; i < manager_.max_open_incoming_streams() - 1; ++i) {
manager_.ActivateStream(/*is_incoming=*/true);
}
- EXPECT_FALSE(
- manager_.CanOpenIncomingStream(manager_.max_open_incoming_streams()));
+ EXPECT_TRUE(manager_.CanOpenIncomingStream());
+ manager_.ActivateStream(/*is_incoming=*/true);
+ EXPECT_FALSE(manager_.CanOpenIncomingStream());
}
TEST_P(LegacyQuicStreamIdManagerTest, AvailableStreams) {
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h
index f1659a64fc9..ecb56993381 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h
@@ -77,7 +77,7 @@ class QUIC_EXPORT_PRIVATE QpackBlockingManager {
// same time. Use std::list instead of QuicCircularDeque because it has lower
// memory footprint when holding few elements.
using HeaderBlocksForStream = std::list<IndexSet>;
- using HeaderBlocks = QuicUnorderedMap<QuicStreamId, HeaderBlocksForStream>;
+ using HeaderBlocks = QuicHashMap<QuicStreamId, HeaderBlocksForStream>;
// Increase or decrease the reference count for each index in |indices|.
void IncreaseReferenceCounts(const IndexSet& indices);
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 db7ec794268..67adf1268eb 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
@@ -378,9 +378,10 @@ std::string QpackEncoder::EncodeHeaderList(
return SecondPassEncode(std::move(instructions), required_insert_count);
}
-void QpackEncoder::SetMaximumDynamicTableCapacity(
+bool QpackEncoder::SetMaximumDynamicTableCapacity(
uint64_t maximum_dynamic_table_capacity) {
- header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
+ return header_table_.SetMaximumDynamicTableCapacity(
+ maximum_dynamic_table_capacity);
}
void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
@@ -392,8 +393,12 @@ void QpackEncoder::SetDynamicTableCapacity(uint64_t dynamic_table_capacity) {
DCHECK(success);
}
-void QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
+bool QpackEncoder::SetMaximumBlockedStreams(uint64_t maximum_blocked_streams) {
+ if (maximum_blocked_streams < maximum_blocked_streams_) {
+ return false;
+ }
maximum_blocked_streams_ = maximum_blocked_streams;
+ return true;
}
void QpackEncoder::OnInsertCountIncrement(uint64_t increment) {
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 0f1d14ca539..202fc6d8ef1 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
@@ -63,7 +63,10 @@ class QUIC_EXPORT_PRIVATE QpackEncoder
// measured in bytes. Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
// received. Encoder needs to know this value so that it can calculate
// MaxEntries, used as a modulus to encode Required Insert Count.
- void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+ // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+ // or if it doesn't change current value. The setting is not changed when
+ // returning false.
+ bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
// Set dynamic table capacity to |dynamic_table_capacity|.
// |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
@@ -72,7 +75,9 @@ class QUIC_EXPORT_PRIVATE QpackEncoder
// Set maximum number of blocked streams.
// Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
- void SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
+ // Returns true if |maximum_blocked_streams| doesn't decrease current value.
+ // The setting is not changed when returning false.
+ bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);
// QpackDecoderStreamReceiver::Delegate implementation
void OnInsertCountIncrement(uint64_t increment) override;
@@ -94,6 +99,12 @@ class QUIC_EXPORT_PRIVATE QpackEncoder
return header_table_.dynamic_table_entry_referenced();
}
+ uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }
+
+ uint64_t MaximumDynamicTableCapacity() const {
+ return header_table_.maximum_dynamic_table_capacity();
+ }
+
private:
friend class test::QpackEncoderPeer;
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 472db893540..29e71488bda 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
@@ -186,16 +186,15 @@ bool QpackHeaderTable::SetDynamicTableCapacity(uint64_t capacity) {
return true;
}
-void QpackHeaderTable::SetMaximumDynamicTableCapacity(
+bool QpackHeaderTable::SetMaximumDynamicTableCapacity(
uint64_t maximum_dynamic_table_capacity) {
- // This method can only be called once: in the decoding context, shortly after
- // construction; in the encoding context, upon receiving the SETTINGS frame.
- DCHECK_EQ(0u, dynamic_table_capacity_);
- DCHECK_EQ(0u, maximum_dynamic_table_capacity_);
- DCHECK_EQ(0u, max_entries_);
-
- maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
- max_entries_ = maximum_dynamic_table_capacity / 32;
+ if (maximum_dynamic_table_capacity_ == 0) {
+ maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
+ max_entries_ = maximum_dynamic_table_capacity / 32;
+ return true;
+ }
+ // If the value is already set, it should not be changed.
+ return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
}
void QpackHeaderTable::RegisterObserver(uint64_t required_insert_count,
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 e3fb97504b3..bed1cc84afa 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
@@ -97,7 +97,10 @@ class QUIC_EXPORT_PRIVATE QpackHeaderTable {
// value can be set upon connection establishment, whereas in the encoding
// context it can be set when the SETTINGS frame is received.
// This method must only be called at most once.
- void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+ // Returns true if |maximum_dynamic_table_capacity| is set for the first time
+ // or if it doesn't change current value. The setting is not changed when
+ // returning false.
+ bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
// Get |maximum_dynamic_table_capacity_|.
uint64_t maximum_dynamic_table_capacity() const {
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 c77a6218bca..63e0f12e3cc 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
@@ -7,6 +7,7 @@
#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"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_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_str_cat.h"
@@ -66,6 +67,9 @@ class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
SupportedVersions(GetParam().version))),
session_(connection_) {
session_.Initialize();
+ if (connection_->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(connection_);
+ }
QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
session_.config(), kMinimumFlowControlSendWindow);
QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc b/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc
index c18369eac9b..3b22180750d 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_coalesced_packet.cc
@@ -61,7 +61,7 @@ bool QuicCoalescedPacket::MaybeCoalescePacket(
return false;
}
QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
- << EncryptionLevelToString(packet.encryption_level)
+ << packet.encryption_level
<< ", encrypted_length: " << packet.encrypted_length
<< ", current length: " << length_
<< ", max_packet_length: " << max_packet_length_;
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 7c781f4def0..30a5e2ba568 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
@@ -434,7 +434,7 @@ QuicConfig::QuicConfig()
max_undecryptable_packets_(0),
connection_options_(kCOPT, PRESENCE_OPTIONAL),
client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
- idle_timeout_to_send_(QuicTime::Delta::Infinite()),
+ max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
@@ -447,12 +447,13 @@ QuicConfig::QuicConfig()
initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
+ support_handshake_done_(0, PRESENCE_OPTIONAL),
alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
- max_packet_size_(0, PRESENCE_OPTIONAL),
+ max_udp_payload_size_(0, PRESENCE_OPTIONAL),
max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
SetDefaults();
@@ -543,17 +544,17 @@ void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
QUIC_BUG << "Invalid idle network timeout " << idle_network_timeout;
return;
}
- idle_timeout_to_send_ = idle_network_timeout;
+ max_idle_timeout_to_send_ = idle_network_timeout;
}
QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
// TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
// received the peer's values. This is true in production code but not in all
// of our tests that use a fake QuicConfig.
- if (!received_idle_timeout_.has_value()) {
- return idle_timeout_to_send_;
+ if (!received_max_idle_timeout_.has_value()) {
+ return max_idle_timeout_to_send_;
}
- return received_idle_timeout_.value();
+ return received_max_idle_timeout_.value();
}
void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
@@ -592,7 +593,7 @@ void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
return max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
}
-uint32_t QuicConfig::GetMaxAckDelayToToSendMs() const {
+uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
return max_ack_delay_ms_.GetSendValue();
}
@@ -620,20 +621,20 @@ uint32_t QuicConfig::ReceivedAckDelayExponent() const {
return ack_delay_exponent_.GetReceivedValue();
}
-void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_packet_size) {
- max_packet_size_.SetSendValue(max_packet_size);
+void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
+ max_udp_payload_size_.SetSendValue(max_udp_payload_size);
}
uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
- return max_packet_size_.GetSendValue();
+ return max_udp_payload_size_.GetSendValue();
}
bool QuicConfig::HasReceivedMaxPacketSize() const {
- return max_packet_size_.HasReceivedValue();
+ return max_udp_payload_size_.HasReceivedValue();
}
uint64_t QuicConfig::ReceivedMaxPacketSize() const {
- return max_packet_size_.GetReceivedValue();
+ return max_udp_payload_size_.GetReceivedValue();
}
void QuicConfig::SetMaxDatagramFrameSizeToSend(
@@ -832,6 +833,19 @@ bool QuicConfig::DisableConnectionMigration() const {
return connection_migration_disabled_.HasReceivedValue();
}
+void QuicConfig::SetSupportHandshakeDone() {
+ support_handshake_done_.SetSendValue(1);
+}
+
+bool QuicConfig::HandshakeDoneSupported() const {
+ return support_handshake_done_.HasSendValue() &&
+ support_handshake_done_.GetSendValue() > 0;
+}
+
+bool QuicConfig::PeerSupportsHandshakeDone() const {
+ return support_handshake_done_.HasReceivedValue();
+}
+
void QuicConfig::SetIPv6AlternateServerAddressToSend(
const QuicSocketAddress& alternate_server_address_ipv6) {
if (!alternate_server_address_ipv6.host().IsIPv6()) {
@@ -871,12 +885,13 @@ const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
}
void QuicConfig::SetOriginalConnectionIdToSend(
- const QuicConnectionId& original_connection_id) {
- original_connection_id_to_send_ = original_connection_id;
+ const QuicConnectionId& original_destination_connection_id) {
+ original_destination_connection_id_to_send_ =
+ original_destination_connection_id;
}
bool QuicConfig::HasReceivedOriginalConnectionId() const {
- return received_original_connection_id_.has_value();
+ return received_original_destination_connection_id_.has_value();
}
QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
@@ -884,7 +899,41 @@ QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
QUIC_BUG << "No received original connection ID";
return EmptyQuicConnectionId();
}
- return received_original_connection_id_.value();
+ return received_original_destination_connection_id_.value();
+}
+
+void QuicConfig::SetInitialSourceConnectionIdToSend(
+ const QuicConnectionId& initial_source_connection_id) {
+ initial_source_connection_id_to_send_ = initial_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
+ return received_initial_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
+ if (!HasReceivedInitialSourceConnectionId()) {
+ QUIC_BUG << "No received initial source connection ID";
+ return EmptyQuicConnectionId();
+ }
+ return received_initial_source_connection_id_.value();
+}
+
+void QuicConfig::SetRetrySourceConnectionIdToSend(
+ const QuicConnectionId& retry_source_connection_id) {
+ retry_source_connection_id_to_send_ = retry_source_connection_id;
+}
+
+bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
+ return received_retry_source_connection_id_.has_value();
+}
+
+QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
+ if (!HasReceivedRetrySourceConnectionId()) {
+ QUIC_BUG << "No received retry source connection ID";
+ return EmptyQuicConnectionId();
+ }
+ return received_retry_source_connection_id_.value();
}
void QuicConfig::SetStatelessResetTokenToSend(
@@ -938,14 +987,16 @@ void QuicConfig::ToHandshakeMessage(
// the one received. Additionally, when QUIC_CRYPTO is used, the server
// MUST send an idle timeout no greater than the idle timeout it received
// from the client. We therefore send the received value if it is lower.
- QuicFixedUint32 idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
- uint32_t idle_timeout_to_send_seconds = idle_timeout_to_send_.ToSeconds();
- if (received_idle_timeout_.has_value() &&
- received_idle_timeout_->ToSeconds() < idle_timeout_to_send_seconds) {
- idle_timeout_to_send_seconds = received_idle_timeout_->ToSeconds();
+ QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+ uint32_t max_idle_timeout_to_send_seconds =
+ max_idle_timeout_to_send_.ToSeconds();
+ if (received_max_idle_timeout_.has_value() &&
+ received_max_idle_timeout_->ToSeconds() <
+ max_idle_timeout_to_send_seconds) {
+ max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
}
- idle_timeout_seconds.SetSendValue(idle_timeout_to_send_seconds);
- idle_timeout_seconds.ToHandshakeMessage(out);
+ max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
+ max_idle_timeout_seconds.ToHandshakeMessage(out);
// Do not need a version check here, max...bi... will encode
// as "MIDS" -- the max initial dynamic streams tag -- if
@@ -955,8 +1006,15 @@ void QuicConfig::ToHandshakeMessage(
max_unidirectional_streams_.ToHandshakeMessage(out);
ack_delay_exponent_.ToHandshakeMessage(out);
}
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 1, 4);
+ if (GetQuicReloadableFlag(quic_dont_send_max_ack_delay_if_default)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_dont_send_max_ack_delay_if_default);
+ if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
+ // Only send max ack delay if it is using a non-default value, because
+ // the default value is used by QuicSentPacketManager if it is not
+ // sent during the handshake, and we want to save bytes.
+ max_ack_delay_ms_.ToHandshakeMessage(out);
+ }
+ } else {
max_ack_delay_ms_.ToHandshakeMessage(out);
}
bytes_for_connection_id_.ToHandshakeMessage(out);
@@ -986,12 +1044,12 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
// the one received. Additionally, when QUIC_CRYPTO is used, the server
// MUST send an idle timeout no greater than the idle timeout it received
// from the client.
- QuicFixedUint32 idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
- error = idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
- error_details);
+ QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
+ error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
+ error_details);
if (error == QUIC_NO_ERROR) {
- if (idle_timeout_seconds.GetReceivedValue() >
- idle_timeout_to_send_.ToSeconds()) {
+ if (max_idle_timeout_seconds.GetReceivedValue() >
+ max_idle_timeout_to_send_.ToSeconds()) {
// The received value is higher than ours, ignore it if from the client
// and raise an error if from the server.
if (hello_type == SERVER) {
@@ -1000,8 +1058,8 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
"Invalid value received for " + QuicTagToString(kICSL);
}
} else {
- received_idle_timeout_ = QuicTime::Delta::FromSeconds(
- idle_timeout_seconds.GetReceivedValue());
+ received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
+ max_idle_timeout_seconds.GetReceivedValue());
}
}
}
@@ -1056,9 +1114,7 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
error_details);
}
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time) &&
- error == QUIC_NO_ERROR) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 2, 4);
+ if (error == QUIC_NO_ERROR) {
error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
error_details);
}
@@ -1073,12 +1129,13 @@ QuicErrorCode QuicConfig::ProcessPeerHello(
}
bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
- if (original_connection_id_to_send_.has_value()) {
- params->original_connection_id = original_connection_id_to_send_.value();
+ if (original_destination_connection_id_to_send_.has_value()) {
+ params->original_destination_connection_id =
+ original_destination_connection_id_to_send_.value();
}
- params->idle_timeout_milliseconds.set_value(
- idle_timeout_to_send_.ToMilliseconds());
+ params->max_idle_timeout_ms.set_value(
+ max_idle_timeout_to_send_.ToMilliseconds());
if (stateless_reset_token_.HasSendValue()) {
QuicUint128 stateless_reset_token = stateless_reset_token_.GetSendValue();
@@ -1088,7 +1145,7 @@ bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
sizeof(stateless_reset_token));
}
- params->max_packet_size.set_value(GetMaxPacketSizeToSend());
+ params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
params->initial_max_data.set_value(
GetInitialSessionFlowControlWindowToSend());
@@ -1108,14 +1165,12 @@ bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
GetMaxBidirectionalStreamsToSend());
params->initial_max_streams_uni.set_value(
GetMaxUnidirectionalStreamsToSend());
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 3, 4);
- params->max_ack_delay.set_value(kDefaultDelayedAckTimeMs);
- }
+ params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
- params->disable_migration =
+ params->disable_active_migration =
connection_migration_disabled_.HasSendValue() &&
connection_migration_disabled_.GetSendValue() != 0;
+ params->support_handshake_done = HandshakeDoneSupported();
if (alternate_server_address_ipv6_.HasSendValue() ||
alternate_server_address_ipv4_.HasSendValue()) {
@@ -1138,6 +1193,16 @@ bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
active_connection_id_limit_.GetSendValue());
}
+ if (initial_source_connection_id_to_send_.has_value()) {
+ params->initial_source_connection_id =
+ initial_source_connection_id_to_send_.value();
+ }
+
+ if (retry_source_connection_id_to_send_.has_value()) {
+ params->retry_source_connection_id =
+ retry_source_connection_id_to_send_.value();
+ }
+
if (GetQuicRestartFlag(quic_google_transport_param_send_new)) {
QUIC_RESTART_FLAG_COUNT_N(quic_google_transport_param_send_new, 1, 3);
if (initial_round_trip_time_us_.HasSendValue()) {
@@ -1171,18 +1236,19 @@ QuicErrorCode QuicConfig::ProcessTransportParameters(
HelloType hello_type,
bool is_resumption,
std::string* error_details) {
- if (!is_resumption && params.original_connection_id.has_value()) {
- received_original_connection_id_ = params.original_connection_id.value();
+ if (!is_resumption && params.original_destination_connection_id.has_value()) {
+ received_original_destination_connection_id_ =
+ params.original_destination_connection_id.value();
}
- if (params.idle_timeout_milliseconds.value() > 0 &&
- params.idle_timeout_milliseconds.value() <
- static_cast<uint64_t>(idle_timeout_to_send_.ToMilliseconds())) {
+ if (params.max_idle_timeout_ms.value() > 0 &&
+ params.max_idle_timeout_ms.value() <
+ static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
// An idle timeout of zero indicates it is disabled.
// We also ignore values higher than ours which will cause us to use the
// smallest value between ours and our peer's.
- received_idle_timeout_ = QuicTime::Delta::FromMilliseconds(
- params.idle_timeout_milliseconds.value());
+ received_max_idle_timeout_ =
+ QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
}
if (!is_resumption && !params.stateless_reset_token.empty()) {
@@ -1198,8 +1264,8 @@ QuicErrorCode QuicConfig::ProcessTransportParameters(
stateless_reset_token_.SetReceivedValue(stateless_reset_token);
}
- if (params.max_packet_size.IsValid()) {
- max_packet_size_.SetReceivedValue(params.max_packet_size.value());
+ if (params.max_udp_payload_size.IsValid()) {
+ max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
}
if (params.max_datagram_frame_size.IsValid()) {
@@ -1233,10 +1299,7 @@ QuicErrorCode QuicConfig::ProcessTransportParameters(
params.initial_max_stream_data_uni.value());
if (!is_resumption) {
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 4, 4);
- max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
- }
+ max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
if (params.ack_delay_exponent.IsValid()) {
ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
}
@@ -1252,13 +1315,27 @@ QuicErrorCode QuicConfig::ProcessTransportParameters(
}
}
- if (params.disable_migration) {
+ if (params.disable_active_migration) {
connection_migration_disabled_.SetReceivedValue(1u);
}
+ if (params.support_handshake_done) {
+ support_handshake_done_.SetReceivedValue(1u);
+ }
active_connection_id_limit_.SetReceivedValue(
params.active_connection_id_limit.value());
+ if (!is_resumption) {
+ if (params.initial_source_connection_id.has_value()) {
+ received_initial_source_connection_id_ =
+ params.initial_source_connection_id.value();
+ }
+ if (params.retry_source_connection_id.has_value()) {
+ received_retry_source_connection_id_ =
+ params.retry_source_connection_id.value();
+ }
+ }
+
bool google_params_already_parsed = false;
if (GetQuicRestartFlag(quic_google_transport_param_send_new)) {
QUIC_RESTART_FLAG_COUNT_N(quic_google_transport_param_send_new, 2, 3);
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 4d2bacce383..6f041b82f45 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
@@ -382,6 +382,11 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
void SetDisableConnectionMigration();
bool DisableConnectionMigration() const;
+ // Support handshake done.
+ void SetSupportHandshakeDone();
+ bool HandshakeDoneSupported() const;
+ bool PeerSupportsHandshakeDone() const;
+
// IPv6 alternate server address.
void SetIPv6AlternateServerAddressToSend(
const QuicSocketAddress& alternate_server_address_ipv6);
@@ -394,9 +399,9 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
bool HasReceivedIPv4AlternateServerAddress() const;
const QuicSocketAddress& ReceivedIPv4AlternateServerAddress() const;
- // Original connection ID.
+ // Original destination connection ID.
void SetOriginalConnectionIdToSend(
- const QuicConnectionId& original_connection_id);
+ const QuicConnectionId& original_destination_connection_id);
bool HasReceivedOriginalConnectionId() const;
QuicConnectionId ReceivedOriginalConnectionId() const;
@@ -411,7 +416,7 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
// The received delay is the value received from
// the peer (QuicSentPacketManager::peer_max_ack_delay_).
void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
- uint32_t GetMaxAckDelayToToSendMs() const;
+ uint32_t GetMaxAckDelayToSendMs() const;
bool HasReceivedMaxAckDelayMs() const;
uint32_t ReceivedMaxAckDelayMs() const;
@@ -420,8 +425,8 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
bool HasReceivedAckDelayExponent() const;
uint32_t ReceivedAckDelayExponent() const;
- // IETF QUIC max_packet_size transport parameter.
- void SetMaxPacketSizeToSend(uint64_t max_packet_size);
+ // IETF QUIC max_udp_payload_size transport parameter.
+ void SetMaxPacketSizeToSend(uint64_t max_udp_payload_size);
uint64_t GetMaxPacketSizeToSend() const;
bool HasReceivedMaxPacketSize() const;
uint64_t ReceivedMaxPacketSize() const;
@@ -438,6 +443,18 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
bool HasReceivedActiveConnectionIdLimit() const;
uint64_t ReceivedActiveConnectionIdLimit() const;
+ // Initial source connection ID.
+ void SetInitialSourceConnectionIdToSend(
+ const QuicConnectionId& initial_source_connection_id);
+ bool HasReceivedInitialSourceConnectionId() const;
+ QuicConnectionId ReceivedInitialSourceConnectionId() const;
+
+ // Retry source connection ID.
+ void SetRetrySourceConnectionIdToSend(
+ const QuicConnectionId& retry_source_connection_id);
+ bool HasReceivedRetrySourceConnectionId() const;
+ QuicConnectionId ReceivedRetrySourceConnectionId() const;
+
bool negotiated() const;
void SetCreateSessionTagIndicators(QuicTagVector tags);
@@ -501,12 +518,12 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
QuicFixedTagVector connection_options_;
// Connection options which only affect the client side.
QuicFixedTagVector client_connection_options_;
- // Idle network timeout.
+ // Maximum idle network timeout.
// Uses the max_idle_timeout transport parameter in IETF QUIC.
- // Note that received_idle_timeout_ is only populated if we receive the
+ // 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 idle_timeout_to_send_;
- quiche::QuicheOptional<QuicTime::Delta> received_idle_timeout_;
+ QuicTime::Delta max_idle_timeout_to_send_;
+ quiche::QuicheOptional<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.
@@ -554,6 +571,10 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
// Uses the disable_active_migration transport parameter in IETF QUIC.
QuicFixedUint32 connection_migration_disabled_;
+ // Whether handshake done is supported. Only used in T050.
+ // Uses the support_handshake_done transport parameter in IETF QUIC.
+ QuicFixedUint32 support_handshake_done_;
+
// 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.
@@ -583,8 +604,8 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
QuicFixedUint32 ack_delay_exponent_;
// Maximum packet size in bytes.
- // Uses the max_packet_size transport parameter in IETF QUIC.
- QuicFixedUint62 max_packet_size_;
+ // Uses the max_udp_payload_size transport parameter in IETF QUIC.
+ QuicFixedUint62 max_udp_payload_size_;
// Maximum DATAGRAM/MESSAGE frame size in bytes.
// Uses the max_datagram_frame_size transport parameter in IETF QUIC.
@@ -594,10 +615,28 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
// Uses the active_connection_id_limit transport parameter in IETF QUIC.
QuicFixedUint62 active_connection_id_limit_;
- // Sent by the server when it has previously sent a RETRY packet.
- // Uses the original_connection_id transport parameter in IETF QUIC.
- quiche::QuicheOptional<QuicConnectionId> original_connection_id_to_send_;
- quiche::QuicheOptional<QuicConnectionId> received_original_connection_id_;
+ // The value of the Destination Connection ID field from the first
+ // 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_;
+
+ // 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_;
+
+ // 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_;
// 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 4aa10ef40b0..050a091a8d2 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
@@ -180,12 +180,8 @@ TEST_P(QuicConfigTest, ProcessClientHello) {
2 * kInitialStreamFlowControlWindowForTest);
EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
2 * kInitialSessionFlowControlWindowForTest);
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
- } else {
- EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
- }
+ EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+ EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
// IETF QUIC stream limits should not be received in QUIC crypto messages.
EXPECT_FALSE(
@@ -238,12 +234,8 @@ TEST_P(QuicConfigTest, ProcessServerHello) {
EXPECT_FALSE(config_.HasReceivedIPv6AlternateServerAddress());
EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
EXPECT_EQ(kTestResetToken, config_.ReceivedStatelessResetToken());
- if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
- EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
- EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
- } else {
- EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
- }
+ EXPECT_TRUE(config_.HasReceivedMaxAckDelayMs());
+ EXPECT_EQ(kTestMaxAckDelayMs, config_.ReceivedMaxAckDelayMs());
// IETF QUIC stream limits should not be received in QUIC crypto messages.
EXPECT_FALSE(
@@ -442,7 +434,7 @@ TEST_P(QuicConfigTest, IncomingLargeIdleTimeoutTransportParameter) {
// Since the received value is above ours, we should then use ours.
config_.SetIdleNetworkTimeout(quic::QuicTime::Delta::FromSeconds(60));
TransportParameters params;
- params.idle_timeout_milliseconds.set_value(120000);
+ params.max_idle_timeout_ms.set_value(120000);
std::string error_details = "foobar";
EXPECT_THAT(config_.ProcessTransportParameters(
@@ -468,6 +460,10 @@ TEST_P(QuicConfigTest, FillTransportParams) {
config_.SetMaxDatagramFrameSizeToSend(kMaxDatagramFrameSizeForTest);
config_.SetActiveConnectionIdLimitToSend(kFakeActiveConnectionIdLimit);
+ config_.SetOriginalConnectionIdToSend(TestConnectionId(0x1111));
+ config_.SetInitialSourceConnectionIdToSend(TestConnectionId(0x2222));
+ config_.SetRetrySourceConnectionIdToSend(TestConnectionId(0x3333));
+
TransportParameters params;
config_.FillTransportParameters(&params);
@@ -479,13 +475,23 @@ TEST_P(QuicConfigTest, FillTransportParams) {
params.initial_max_stream_data_uni.value());
EXPECT_EQ(static_cast<uint64_t>(kMaximumIdleTimeoutSecs * 1000),
- params.idle_timeout_milliseconds.value());
+ params.max_idle_timeout_ms.value());
- EXPECT_EQ(kMaxPacketSizeForTest, params.max_packet_size.value());
+ EXPECT_EQ(kMaxPacketSizeForTest, params.max_udp_payload_size.value());
EXPECT_EQ(kMaxDatagramFrameSizeForTest,
params.max_datagram_frame_size.value());
EXPECT_EQ(kFakeActiveConnectionIdLimit,
params.active_connection_id_limit.value());
+
+ ASSERT_TRUE(params.original_destination_connection_id.has_value());
+ EXPECT_EQ(TestConnectionId(0x1111),
+ params.original_destination_connection_id.value());
+ ASSERT_TRUE(params.initial_source_connection_id.has_value());
+ EXPECT_EQ(TestConnectionId(0x2222),
+ params.initial_source_connection_id.value());
+ ASSERT_TRUE(params.retry_source_connection_id.has_value());
+ EXPECT_EQ(TestConnectionId(0x3333),
+ params.retry_source_connection_id.value());
}
TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
@@ -493,7 +499,6 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
// TransportParameters are only used for QUIC+TLS.
return;
}
- SetQuicReloadableFlag(quic_negotiate_ack_delay_time, true);
TransportParameters params;
params.initial_max_stream_data_bidi_local.set_value(
@@ -502,13 +507,16 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
3 * kMinimumFlowControlSendWindow);
params.initial_max_stream_data_uni.set_value(4 *
kMinimumFlowControlSendWindow);
- params.max_packet_size.set_value(kMaxPacketSizeForTest);
+ params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
params.max_datagram_frame_size.set_value(kMaxDatagramFrameSizeForTest);
params.initial_max_streams_bidi.set_value(kDefaultMaxStreamsPerConnection);
params.stateless_reset_token = CreateFakeStatelessResetToken();
params.max_ack_delay.set_value(kFakeMaxAckDelay);
params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
params.active_connection_id_limit.set_value(kFakeActiveConnectionIdLimit);
+ params.original_destination_connection_id = TestConnectionId(0x1111);
+ params.initial_source_connection_id = TestConnectionId(0x2222);
+ params.retry_source_connection_id = TestConnectionId(0x3333);
std::string error_details;
EXPECT_THAT(config_.ProcessTransportParameters(
@@ -544,11 +552,15 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
config_.ReceivedMaxBidirectionalStreams());
EXPECT_FALSE(config_.DisableConnectionMigration());
+ EXPECT_FALSE(config_.PeerSupportsHandshakeDone());
// The following config shouldn't be processed because of resumption.
EXPECT_FALSE(config_.HasReceivedStatelessResetToken());
EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs());
EXPECT_FALSE(config_.HasReceivedAckDelayExponent());
+ EXPECT_FALSE(config_.HasReceivedOriginalConnectionId());
+ EXPECT_FALSE(config_.HasReceivedInitialSourceConnectionId());
+ EXPECT_FALSE(config_.HasReceivedRetrySourceConnectionId());
// Let the config process another slightly tweaked transport paramters.
// Note that the values for flow control and stream limit cannot be smaller
@@ -559,11 +571,12 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
4 * kMinimumFlowControlSendWindow);
params.initial_max_stream_data_uni.set_value(5 *
kMinimumFlowControlSendWindow);
- params.max_packet_size.set_value(2 * kMaxPacketSizeForTest);
+ params.max_udp_payload_size.set_value(2 * kMaxPacketSizeForTest);
params.max_datagram_frame_size.set_value(2 * kMaxDatagramFrameSizeForTest);
params.initial_max_streams_bidi.set_value(2 *
kDefaultMaxStreamsPerConnection);
- params.disable_migration = true;
+ params.disable_active_migration = true;
+ params.support_handshake_done = true;
EXPECT_THAT(config_.ProcessTransportParameters(
params, SERVER, /* is_resumption = */ false, &error_details),
@@ -598,6 +611,7 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
config_.ReceivedMaxBidirectionalStreams());
EXPECT_TRUE(config_.DisableConnectionMigration());
+ EXPECT_TRUE(config_.PeerSupportsHandshakeDone());
ASSERT_TRUE(config_.HasReceivedStatelessResetToken());
ASSERT_TRUE(config_.HasReceivedMaxAckDelayMs());
@@ -609,6 +623,15 @@ TEST_P(QuicConfigTest, ProcessTransportParametersServer) {
ASSERT_TRUE(config_.HasReceivedActiveConnectionIdLimit());
EXPECT_EQ(config_.ReceivedActiveConnectionIdLimit(),
kFakeActiveConnectionIdLimit);
+
+ ASSERT_TRUE(config_.HasReceivedOriginalConnectionId());
+ EXPECT_EQ(config_.ReceivedOriginalConnectionId(), TestConnectionId(0x1111));
+ ASSERT_TRUE(config_.HasReceivedInitialSourceConnectionId());
+ EXPECT_EQ(config_.ReceivedInitialSourceConnectionId(),
+ TestConnectionId(0x2222));
+ ASSERT_TRUE(config_.HasReceivedRetrySourceConnectionId());
+ EXPECT_EQ(config_.ReceivedRetrySourceConnectionId(),
+ TestConnectionId(0x3333));
}
TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
@@ -617,7 +640,7 @@ TEST_P(QuicConfigTest, DisableMigrationTransportParameter) {
return;
}
TransportParameters params;
- params.disable_migration = true;
+ params.disable_active_migration = true;
std::string error_details;
EXPECT_THAT(config_.ProcessTransportParameters(
params, SERVER, /* is_resumption = */ false, &error_details),
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 4f089a44fe9..4a21277e942 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
@@ -25,6 +25,7 @@
#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_legacy_version_encapsulator.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"
@@ -33,6 +34,7 @@
#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_hostname_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/quic/platform/api/quic_string_utils.h"
@@ -107,20 +109,6 @@ class SendAlarmDelegate : public QuicAlarm::Delegate {
QuicConnection* connection_;
};
-class PathDegradingAlarmDelegate : public QuicAlarm::Delegate {
- public:
- explicit PathDegradingAlarmDelegate(QuicConnection* connection)
- : connection_(connection) {}
- PathDegradingAlarmDelegate(const PathDegradingAlarmDelegate&) = delete;
- PathDegradingAlarmDelegate& operator=(const PathDegradingAlarmDelegate&) =
- delete;
-
- void OnAlarm() override { connection_->OnPathDegradingTimeout(); }
-
- private:
- QuicConnection* connection_;
-};
-
class TimeoutAlarmDelegate : public QuicAlarm::Delegate {
public:
explicit TimeoutAlarmDelegate(QuicConnection* connection)
@@ -260,7 +248,7 @@ QuicConnection::QuicConnection(
send_version_negotiation_packet_with_prefixed_lengths_(false),
idle_timeout_connection_close_behavior_(
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
- close_connection_after_five_rtos_(false),
+ num_rtos_for_blackhole_detection_(0),
uber_received_packet_manager_(&stats_),
stop_waiting_count_(0),
pending_retransmission_alarm_(false),
@@ -327,7 +315,6 @@ QuicConnection::QuicConnection(
supports_release_time_(false),
release_time_into_future_(QuicTime::Delta::Zero()),
drop_incoming_retry_packets_(false),
- max_consecutive_ptos_(0),
bytes_received_before_address_validation_(0),
bytes_sent_before_address_validation_(0),
address_validated_(false),
@@ -335,7 +322,8 @@ QuicConnection::QuicConnection(
idle_network_detector_(this,
clock_->ApproximateNow(),
&arena_,
- alarm_factory_) {
+ alarm_factory_),
+ support_handshake_done_(version().HasHandshakeDone()) {
QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
<< server_connection_id
<< " and version: " << ParsedQuicVersionToString(version());
@@ -345,9 +333,6 @@ QuicConnection::QuicConnection(
<< "QuicConnection: attempted to use server connection ID "
<< server_connection_id << " which is invalid with version "
<< QuicVersionToString(transport_version());
- if (advance_ack_timeout_update_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_advance_ack_timeout_update);
- }
framer_.set_visitor(this);
stats_.connection_creation_time = clock_->ApproximateNow();
// TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
@@ -377,6 +362,9 @@ QuicConnection::QuicConnection(
if (perspective_ == Perspective::IS_SERVER) {
SetVersionNegotiated();
}
+ if (default_enable_5rto_blackhole_detection_) {
+ num_rtos_for_blackhole_detection_ = 5;
+ }
}
void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
@@ -402,50 +390,158 @@ void QuicConnection::ClearQueuedPackets() {
buffered_packets_.clear();
}
-void QuicConnection::SetFromConfig(const QuicConfig& config) {
- if (config.negotiated()) {
- // Handshake complete, set handshake timeout to Infinite.
- SetNetworkTimeouts(QuicTime::Delta::Infinite(),
- config.IdleNetworkTimeout());
- idle_timeout_connection_close_behavior_ =
- ConnectionCloseBehavior::SILENT_CLOSE;
- if (original_connection_id_.has_value()) {
- DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
- // We received a RETRY packet, validate that the |original_connection_id|
- // from the config matches the one from the RETRY.
- if (!config.HasReceivedOriginalConnectionId() ||
- config.ReceivedOriginalConnectionId() !=
- original_connection_id_.value()) {
+bool QuicConnection::ValidateConfigConnectionIdsOld(const QuicConfig& config) {
+ // This function validates connection IDs as defined in IETF draft-27 and
+ // earlier.
+ DCHECK(config.negotiated());
+ DCHECK(!version().AuthenticatesHandshakeConnectionIds());
+ if (original_destination_connection_id_.has_value() &&
+ retry_source_connection_id_.has_value()) {
+ DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+ // We received a RETRY packet, validate that the original destination
+ // connection ID from the config matches the one from the RETRY.
+ if (!config.HasReceivedOriginalConnectionId() ||
+ config.ReceivedOriginalConnectionId() !=
+ original_destination_connection_id_.value()) {
+ std::string received_value;
+ if (config.HasReceivedOriginalConnectionId()) {
+ received_value = config.ReceivedOriginalConnectionId().ToString();
+ } else {
+ received_value = "none";
+ }
+ std::string error_details = quiche::QuicheStrCat(
+ "Bad original_connection_id: expected ",
+ original_destination_connection_id_.value().ToString(), ", received ",
+ received_value, ", RETRY used ", server_connection_id_.ToString());
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+ } else {
+ // We did not receive a RETRY packet, make sure we did not receive the
+ // original_destination_connection_id transport parameter.
+ if (config.HasReceivedOriginalConnectionId()) {
+ std::string error_details = quiche::QuicheStrCat(
+ "Bad original_connection_id: did not receive RETRY but received ",
+ config.ReceivedOriginalConnectionId().ToString());
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QuicConnection::ValidateConfigConnectionIds(const QuicConfig& config) {
+ DCHECK(config.negotiated());
+ if (!version().UsesTls()) {
+ // QUIC+TLS is required to transmit connection ID transport parameters.
+ return true;
+ }
+ if (!version().AuthenticatesHandshakeConnectionIds()) {
+ return ValidateConfigConnectionIdsOld(config);
+ }
+ // This function validates connection IDs as defined in IETF draft-28 and
+ // later.
+
+ // Validate initial_source_connection_id.
+ QuicConnectionId expected_initial_source_connection_id;
+ if (perspective_ == Perspective::IS_CLIENT) {
+ expected_initial_source_connection_id = server_connection_id_;
+ } else {
+ expected_initial_source_connection_id = client_connection_id_;
+ }
+ if (!config.HasReceivedInitialSourceConnectionId() ||
+ config.ReceivedInitialSourceConnectionId() !=
+ expected_initial_source_connection_id) {
+ std::string received_value;
+ if (config.HasReceivedInitialSourceConnectionId()) {
+ received_value = config.ReceivedInitialSourceConnectionId().ToString();
+ } else {
+ received_value = "none";
+ }
+ std::string error_details =
+ quiche::QuicheStrCat("Bad initial_source_connection_id: expected ",
+ expected_initial_source_connection_id.ToString(),
+ ", received ", received_value);
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+ if (perspective_ == Perspective::IS_CLIENT) {
+ // Validate original_destination_connection_id.
+ if (!config.HasReceivedOriginalConnectionId() ||
+ config.ReceivedOriginalConnectionId() !=
+ GetOriginalDestinationConnectionId()) {
+ std::string received_value;
+ if (config.HasReceivedOriginalConnectionId()) {
+ received_value = config.ReceivedOriginalConnectionId().ToString();
+ } else {
+ received_value = "none";
+ }
+ std::string error_details = quiche::QuicheStrCat(
+ "Bad original_destination_connection_id: expected ",
+ GetOriginalDestinationConnectionId().ToString(), ", received ",
+ received_value);
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+ // Validate retry_source_connection_id.
+ if (retry_source_connection_id_.has_value()) {
+ // We received a RETRY packet, validate that the retry source
+ // connection ID from the config matches the one from the RETRY.
+ if (!config.HasReceivedRetrySourceConnectionId() ||
+ config.ReceivedRetrySourceConnectionId() !=
+ retry_source_connection_id_.value()) {
std::string received_value;
- if (config.HasReceivedOriginalConnectionId()) {
- received_value = config.ReceivedOriginalConnectionId().ToString();
+ if (config.HasReceivedRetrySourceConnectionId()) {
+ received_value = config.ReceivedRetrySourceConnectionId().ToString();
} else {
received_value = "none";
}
- std::string error_details = quiche::QuicheStrCat(
- "Bad original_connection_id: expected ",
- original_connection_id_.value().ToString(), ", received ",
- received_value, ", RETRY used ", server_connection_id_.ToString());
+ std::string error_details =
+ quiche::QuicheStrCat("Bad retry_source_connection_id: expected ",
+ retry_source_connection_id_.value().ToString(),
+ ", received ", received_value);
CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
+ return false;
}
} else {
// We did not receive a RETRY packet, make sure we did not receive the
- // original_connection_id transport parameter.
- if (config.HasReceivedOriginalConnectionId()) {
+ // retry_source_connection_id transport parameter.
+ if (config.HasReceivedRetrySourceConnectionId()) {
std::string error_details = quiche::QuicheStrCat(
- "Bad original_connection_id: did not receive RETRY but received ",
- config.ReceivedOriginalConnectionId().ToString());
+ "Bad retry_source_connection_id: did not receive RETRY but "
+ "received ",
+ config.ReceivedRetrySourceConnectionId().ToString());
CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, error_details,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
+ return false;
}
}
+ }
+ return true;
+}
+
+void QuicConnection::SetFromConfig(const QuicConfig& config) {
+ if (config.negotiated()) {
+ // Handshake complete, set handshake timeout to Infinite.
+ SetNetworkTimeouts(QuicTime::Delta::Infinite(),
+ config.IdleNetworkTimeout());
+ idle_timeout_connection_close_behavior_ =
+ ConnectionCloseBehavior::SILENT_CLOSE;
+ if (!ValidateConfigConnectionIds(config)) {
+ return;
+ }
} else {
SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
config.max_idle_time_before_crypto_handshake());
}
+ if (config.HandshakeDoneSupported()) {
+ support_handshake_done_ = true;
+ }
sent_packet_manager_.SetFromConfig(config);
if (config.HasReceivedBytesForConnectionId() &&
@@ -461,24 +557,41 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.HasClientRequestedIndependentOption(kMTUL, perspective_)) {
SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
}
+ if (default_enable_5rto_blackhole_detection_) {
+ if (config.HasClientRequestedIndependentOption(kCBHD, perspective_)) {
+ QUIC_CODE_COUNT(quic_client_only_blackhole_detection);
+ blackhole_detection_disabled_ = true;
+ }
+ if (config.HasClientSentConnectionOption(k2RTO, perspective_)) {
+ QUIC_CODE_COUNT(quic_2rto_blackhole_detection);
+ num_rtos_for_blackhole_detection_ = 2;
+ }
+ if (config.HasClientSentConnectionOption(k3RTO, perspective_)) {
+ QUIC_CODE_COUNT(quic_3rto_blackhole_detection);
+ num_rtos_for_blackhole_detection_ = 3;
+ }
+ if (config.HasClientSentConnectionOption(k4RTO, perspective_)) {
+ QUIC_CODE_COUNT(quic_4rto_blackhole_detection);
+ num_rtos_for_blackhole_detection_ = 4;
+ }
+ if (config.HasClientSentConnectionOption(k6RTO, perspective_)) {
+ QUIC_CODE_COUNT(quic_6rto_blackhole_detection);
+ num_rtos_for_blackhole_detection_ = 6;
+ }
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnSetFromConfig(config);
}
uber_received_packet_manager_.SetFromConfig(config, perspective_);
if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
- close_connection_after_five_rtos_ = true;
+ num_rtos_for_blackhole_detection_ = 5;
}
if (sent_packet_manager_.pto_enabled()) {
- if (config.HasClientSentConnectionOption(k6PTO, perspective_)) {
- max_consecutive_ptos_ = 5;
- QUIC_CODE_COUNT(quic_close_connection_6pto);
- }
- if (config.HasClientSentConnectionOption(k7PTO, perspective_)) {
- max_consecutive_ptos_ = 6;
- }
- if (config.HasClientSentConnectionOption(k8PTO, perspective_)) {
- max_consecutive_ptos_ = 7;
+ if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
+ config.HasClientSentConnectionOption(k7PTO, perspective_) ||
+ config.HasClientSentConnectionOption(k8PTO, perspective_)) {
+ num_rtos_for_blackhole_detection_ = 5;
}
}
if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
@@ -502,8 +615,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
}
if (config.HasReceivedMaxPacketSize()) {
peer_max_packet_size_ = config.ReceivedMaxPacketSize();
- packet_creator_.SetMaxPacketLength(
- GetLimitedMaxPacketSize(packet_creator_.max_packet_length()));
+ MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
}
if (config.HasReceivedMaxDatagramFrameSize()) {
packet_creator_.SetMaxDatagramFrameSize(
@@ -519,6 +631,29 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
}
}
+void QuicConnection::EnableLegacyVersionEncapsulation(
+ const std::string& server_name) {
+ if (perspective_ != Perspective::IS_CLIENT) {
+ QUIC_BUG << "Cannot enable Legacy Version Encapsulation on the server";
+ return;
+ }
+ if (legacy_version_encapsulation_enabled_) {
+ QUIC_BUG << "Do not call EnableLegacyVersionEncapsulation twice";
+ return;
+ }
+ if (!QuicHostnameUtils::IsValidSNI(server_name)) {
+ // Legacy Version Encapsulation is only used when SNI is transmitted.
+ QUIC_DLOG(INFO)
+ << "Refusing to use Legacy Version Encapsulation with invalid SNI \""
+ << server_name << "\"";
+ return;
+ }
+ QUIC_DLOG(INFO) << "Enabling Legacy Version Encapsulation with SNI \""
+ << server_name << "\"";
+ legacy_version_encapsulation_enabled_ = true;
+ legacy_version_encapsulation_sni_ = server_name;
+}
+
void QuicConnection::ApplyConnectionOptions(
const QuicTagVector& connection_options) {
sent_packet_manager_.ApplyConnectionOptions(connection_options);
@@ -605,6 +740,7 @@ void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
// here. (Check for a bug regression.)
DCHECK_EQ(server_connection_id_, packet.connection_id);
DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+ DCHECK(!VersionHasIetfInvariantHeader(transport_version()));
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPublicResetPacket(packet);
}
@@ -718,8 +854,12 @@ void QuicConnection::OnRetryPacket(
<< server_connection_id_ << " with " << new_connection_id
<< ", received token "
<< quiche::QuicheTextUtils::HexEncode(retry_token);
- DCHECK(!original_connection_id_.has_value());
- original_connection_id_ = server_connection_id_;
+ if (!original_destination_connection_id_.has_value()) {
+ original_destination_connection_id_ = server_connection_id_;
+ }
+ DCHECK(!retry_source_connection_id_.has_value())
+ << retry_source_connection_id_.value();
+ retry_source_connection_id_ = new_connection_id;
server_connection_id_ = new_connection_id;
packet_creator_.SetServerConnectionId(server_connection_id_);
packet_creator_.SetRetryToken(retry_token);
@@ -738,11 +878,27 @@ bool QuicConnection::HasIncomingConnectionId(QuicConnectionId connection_id) {
return false;
}
-void QuicConnection::AddIncomingConnectionId(QuicConnectionId connection_id) {
- if (HasIncomingConnectionId(connection_id)) {
- return;
+void QuicConnection::SetOriginalDestinationConnectionId(
+ const QuicConnectionId& original_destination_connection_id) {
+ QUIC_DLOG(INFO) << "Setting original_destination_connection_id to "
+ << original_destination_connection_id
+ << " on connection with server_connection_id "
+ << server_connection_id_;
+ DCHECK_NE(original_destination_connection_id, server_connection_id_);
+ if (!HasIncomingConnectionId(original_destination_connection_id)) {
+ incoming_connection_ids_.push_back(original_destination_connection_id);
+ }
+ InstallInitialCrypters(original_destination_connection_id);
+ DCHECK(!original_destination_connection_id_.has_value())
+ << original_destination_connection_id_.value();
+ original_destination_connection_id_ = original_destination_connection_id;
+}
+
+QuicConnectionId QuicConnection::GetOriginalDestinationConnectionId() {
+ if (original_destination_connection_id_.has_value()) {
+ return original_destination_connection_id_.value();
}
- incoming_connection_ids_.push_back(connection_id);
+ return server_connection_id_;
}
bool QuicConnection::OnUnauthenticatedPublicHeader(
@@ -841,6 +997,35 @@ void QuicConnection::OnSuccessfulVersionNegotiation() {
}
}
+void QuicConnection::OnSuccessfulMigrationAfterProbing() {
+ DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+ if (IsPathDegrading()) {
+ // If path was previously degrading, and migration is successful after
+ // probing, restart the path degrading and blackhole detection.
+ OnForwardProgressMade();
+ }
+ // TODO(b/159074035): notify SentPacketManger with RTT sample from probing and
+ // reset cwnd if this is a successful network migration.
+}
+
+void QuicConnection::OnTransportParametersSent(
+ const TransportParameters& transport_parameters) const {
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnTransportParametersSent(transport_parameters);
+ }
+}
+
+void QuicConnection::OnTransportParametersReceived(
+ const TransportParameters& transport_parameters) const {
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnTransportParametersReceived(transport_parameters);
+ }
+}
+
+bool QuicConnection::HasPendingAcks() const {
+ return ack_alarm_->IsSet();
+}
+
void QuicConnection::OnDecryptedPacket(EncryptionLevel level) {
last_decrypted_packet_level_ = level;
last_packet_decrypted_ = true;
@@ -849,13 +1034,10 @@ void QuicConnection::OnDecryptedPacket(EncryptionLevel level) {
// Address is validated by successfully processing a HANDSHAKE packet.
address_validated_ = true;
}
- if (extend_idle_time_on_decryptable_packets_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_extend_idle_time_on_decryptable_packets);
- if (use_idle_network_detector_) {
- idle_network_detector_.OnPacketReceived(time_of_last_received_packet_);
- } else {
- time_of_last_decryptable_packet_ = time_of_last_received_packet_;
- }
+ if (use_idle_network_detector_) {
+ idle_network_detector_.OnPacketReceived(time_of_last_received_packet_);
+ } else {
+ time_of_last_decryptable_packet_ = time_of_last_received_packet_;
}
visitor_->OnPacketDecrypted(level);
@@ -923,6 +1105,9 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
--stats_.packets_dropped;
QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
last_header_ = header;
+ if (!stats_.first_decrypted_packet.IsInitialized()) {
+ stats_.first_decrypted_packet = last_header_.packet_number;
+ }
// Record packet receipt to populate ack info before processing stream
// frames, since the processing may result in sending a bundled ack.
@@ -962,14 +1147,9 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return false;
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnStreamFrame(frame);
stats_.stream_bytes_received += frame.data_length;
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
consecutive_retransmittable_on_wire_ping_count_ = 0;
return connected_;
}
@@ -984,13 +1164,8 @@ bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnCryptoFrame(frame);
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnCryptoFrame(frame);
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
@@ -1032,11 +1207,6 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return false;
}
-
- if (!GetLargestAckedPacket().IsInitialized() ||
- largest_acked > GetLargestAckedPacket()) {
- visitor_->OnForwardProgressConfirmed();
- }
processing_ack_frame_ = true;
sent_packet_manager_.OnAckFrameStart(largest_acked, ack_delay_time,
GetTimeOfLastReceivedPacket());
@@ -1177,11 +1347,7 @@ bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPingFrame(frame);
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- } else {
- should_last_packet_instigate_acks_ = true;
- }
+ MaybeUpdateAckTimeout();
return true;
}
@@ -1223,13 +1389,8 @@ bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
<< "RST_STREAM_FRAME received for stream: " << frame.stream_id
<< " with error: "
<< QuicRstStreamErrorCodeToString(frame.error_code);
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnRstStream(frame);
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
@@ -1260,11 +1421,7 @@ bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
// response.
received_path_challenge_payloads_.push_back(frame.data_buffer);
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- } else {
- should_last_packet_instigate_acks_ = true;
- }
+ MaybeUpdateAckTimeout();
return true;
}
@@ -1272,11 +1429,7 @@ bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPathResponseFrame(frame);
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- } else {
- should_last_packet_instigate_acks_ = true;
- }
+ MaybeUpdateAckTimeout();
if (!transmitted_connectivity_probe_payload_ ||
*transmitted_connectivity_probe_payload_ != frame.data_buffer) {
// Is not for the probe we sent, ignore it.
@@ -1363,13 +1516,8 @@ bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
<< frame.last_good_stream_id
<< " and error: " << QuicErrorCodeToString(frame.error_code)
<< " and reason: " << frame.reason_phrase;
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnGoAway(frame);
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
@@ -1384,13 +1532,8 @@ bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
debug_visitor_->OnWindowUpdateFrame(frame, GetTimeOfLastReceivedPacket());
}
QUIC_DVLOG(1) << ENDPOINT << "WINDOW_UPDATE_FRAME received " << frame;
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnWindowUpdateFrame(frame);
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
@@ -1427,19 +1570,20 @@ bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnMessageFrame(frame);
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnMessageReceived(
quiche::QuicheStringPiece(frame.data, frame.message_length));
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
- DCHECK(connected_ && VersionHasIetfQuicFrames(transport_version()));
+ DCHECK(connected_);
+ if (!support_handshake_done_) {
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
+ "Handshake done frame is unsupported",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
if (perspective_ == Perspective::IS_SERVER) {
CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
@@ -1455,16 +1599,17 @@ bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnHandshakeDoneFrame(frame);
}
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnHandshakeDoneReceived();
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
+bool QuicConnection::OnAckFrequencyFrame(
+ const QuicAckFrequencyFrame& /*frame*/) {
+ // TODO(b/148614353): implement this fully.
+ QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
+ return false;
+}
bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
DCHECK(connected_);
@@ -1477,14 +1622,9 @@ bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
}
QUIC_DLOG(INFO) << ENDPOINT
<< "BLOCKED_FRAME received for stream: " << frame.stream_id;
- if (advance_ack_timeout_update_) {
- MaybeUpdateAckTimeout();
- }
+ MaybeUpdateAckTimeout();
visitor_->OnBlockedFrame(frame);
stats_.blocked_frames_received++;
- if (!advance_ack_timeout_update_) {
- should_last_packet_instigate_acks_ = true;
- }
return connected_;
}
@@ -1556,7 +1696,7 @@ void QuicConnection::OnPacketComplete() {
// For IETF QUIC, it is guaranteed that TLS will give connection the
// corresponding write key before read key. In other words, connection should
// never process a packet while an ACK for it cannot be encrypted.
- if (!advance_ack_timeout_update_ || !should_last_packet_instigate_acks_) {
+ if (!should_last_packet_instigate_acks_) {
uber_received_packet_manager_.MaybeUpdateAckTimeout(
should_last_packet_instigate_acks_, last_decrypted_packet_level_,
last_header_.packet_number, GetTimeOfLastReceivedPacket(),
@@ -1576,6 +1716,14 @@ void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
const QuicIetfStatelessResetPacket& /*packet*/) {
// TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
// debug_visitor_.
+ DCHECK(VersionHasIetfInvariantHeader(transport_version()));
+ DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+ if (!visitor_->ValidateStatelessReset(last_packet_destination_address_,
+ last_packet_source_address_)) {
+ // This packet is received on a probing path. Do not close connection.
+ return;
+ }
+
const std::string error_details = "Received stateless reset.";
QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
@@ -1693,6 +1841,29 @@ void QuicConnection::SendVersionNegotiationPacket(bool ietf_quic,
pending_version_negotiation_packet_ = false;
}
+void QuicConnection::MaybeActivateLegacyVersionEncapsulation() {
+ if (!legacy_version_encapsulation_enabled_) {
+ return;
+ }
+ DCHECK(!legacy_version_encapsulation_in_progress_);
+ QUIC_BUG_IF(!packet_creator_.CanSetMaxPacketLength())
+ << "Cannot activate Legacy Version Encapsulation mid-packet";
+ QUIC_BUG_IF(coalesced_packet_.length() != 0u)
+ << "Cannot activate Legacy Version Encapsulation mid-coalesced-packet";
+ legacy_version_encapsulation_in_progress_ = true;
+ MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+void QuicConnection::MaybeDisactivateLegacyVersionEncapsulation() {
+ if (!legacy_version_encapsulation_in_progress_) {
+ return;
+ }
+ // Flush any remaining packet before disactivating encapsulation.
+ packet_creator_.FlushCurrentPacket();
+ DCHECK(legacy_version_encapsulation_enabled_);
+ legacy_version_encapsulation_in_progress_ = false;
+ MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+}
+
size_t QuicConnection::SendCryptoData(EncryptionLevel level,
size_t write_length,
QuicStreamOffset offset) {
@@ -1700,11 +1871,21 @@ size_t QuicConnection::SendCryptoData(EncryptionLevel level,
QUIC_BUG << "Attempt to send empty crypto frame";
return 0;
}
- if (!ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
+ if (!GetQuicReloadableFlag(quic_fix_checking_should_generate_packet) &&
+ !ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
return 0;
}
- ScopedPacketFlusher flusher(this);
- return packet_creator_.ConsumeCryptoData(level, write_length, offset);
+ if (level == ENCRYPTION_INITIAL) {
+ MaybeActivateLegacyVersionEncapsulation();
+ }
+ size_t consumed_length;
+ {
+ ScopedPacketFlusher flusher(this);
+ consumed_length =
+ packet_creator_.ConsumeCryptoData(level, write_length, offset);
+ } // Added scope ensures packets are flushed before continuing.
+ MaybeDisactivateLegacyVersionEncapsulation();
+ return consumed_length;
}
QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
@@ -1716,13 +1897,24 @@ QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
return QuicConsumedData(0, false);
}
- // Opportunistically bundle an ack with every outgoing packet.
- // Particularly, we want to bundle with handshake packets since we don't know
- // which decrypter will be used on an ack packet following a handshake
- // packet (a handshake packet from client to server could result in a REJ or a
- // SHLO from the server, leading to two different decrypters at the server.)
- ScopedPacketFlusher flusher(this);
- return packet_creator_.ConsumeData(id, write_length, offset, state);
+ if (packet_creator_.encryption_level() == ENCRYPTION_INITIAL &&
+ QuicUtils::IsCryptoStreamId(transport_version(), id)) {
+ MaybeActivateLegacyVersionEncapsulation();
+ }
+ QuicConsumedData consumed_data(0, false);
+ {
+ // Opportunistically bundle an ack with every outgoing packet.
+ // Particularly, we want to bundle with handshake packets since we don't
+ // know which decrypter will be used on an ack packet following a handshake
+ // packet (a handshake packet from client to server could result in a REJ or
+ // a SHLO from the server, leading to two different decrypters at the
+ // server.)
+ ScopedPacketFlusher flusher(this);
+ consumed_data =
+ packet_creator_.ConsumeData(id, write_length, offset, state);
+ } // Added scope ensures packets are flushed before continuing.
+ MaybeDisactivateLegacyVersionEncapsulation();
+ return consumed_data;
}
bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
@@ -1734,8 +1926,7 @@ bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
// anti-amplification limit is used, client needs to send something to avoid
// handshake deadlock.
QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
- << " at encryption level: "
- << EncryptionLevelToString(encryption_level_);
+ << " at encryption level: " << encryption_level_;
return false;
}
ScopedPacketFlusher flusher(this);
@@ -1795,10 +1986,6 @@ const QuicConnectionStats& QuicConnection::GetStats() {
return stats_;
}
-void QuicConnection::ResetHasNonAppLimitedSampleAfterHandshakeCompletion() {
- stats_.has_non_app_limited_sample = false;
-}
-
void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
QueueCoalescedPacket(packet);
}
@@ -1809,39 +1996,85 @@ void QuicConnection::OnUndecryptablePacket(const QuicEncryptedPacket& packet,
QUIC_DVLOG(1) << ENDPOINT << "Received undecryptable packet of length "
<< packet.length() << " with"
<< (has_decryption_key ? "" : "out") << " key at level "
- << EncryptionLevelToString(decryption_level)
+ << decryption_level
<< " while connection is at encryption level "
- << EncryptionLevelToString(encryption_level_);
+ << encryption_level_;
DCHECK(EncryptionLevelIsValid(decryption_level));
if (encryption_level_ != ENCRYPTION_FORWARD_SECURE) {
++stats_.undecryptable_packets_received_before_handshake_complete;
}
- bool should_enqueue = true;
+ const bool should_enqueue =
+ ShouldEnqueueUnDecryptablePacket(decryption_level, has_decryption_key);
+ if (should_enqueue) {
+ QueueUndecryptablePacket(packet, decryption_level);
+ }
+
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnUndecryptablePacket(decryption_level,
+ /*dropped=*/!should_enqueue);
+ }
+}
+
+bool QuicConnection::ShouldEnqueueUnDecryptablePacket(
+ EncryptionLevel decryption_level,
+ bool has_decryption_key) const {
if (encryption_level_ == ENCRYPTION_FORWARD_SECURE) {
// We do not expect to install any further keys.
- should_enqueue = false;
- } else if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
+ return false;
+ }
+ if (undecryptable_packets_.size() >= max_undecryptable_packets_) {
// We do not queue more than max_undecryptable_packets_ packets.
- should_enqueue = false;
- } else if (has_decryption_key) {
+ return false;
+ }
+ if (has_decryption_key) {
// We already have the key for this decryption level, therefore no
// future keys will allow it be decrypted.
- should_enqueue = false;
- } else if (version().KnowsWhichDecrypterToUse() &&
- decryption_level <= encryption_level_) {
+ return false;
+ }
+ if (version().KnowsWhichDecrypterToUse() &&
+ decryption_level <= encryption_level_) {
// On versions that know which decrypter to use, we install keys in order
// so we will not get newer keys for lower encryption levels.
- should_enqueue = false;
+ return false;
}
+ return true;
+}
- if (should_enqueue) {
- QueueUndecryptablePacket(packet, decryption_level);
+std::string QuicConnection::UndecryptablePacketsInfo() const {
+ std::string info = quiche::QuicheStrCat(
+ "num_undecryptable_packets: ", undecryptable_packets_.size(), " {");
+ for (const auto& packet : undecryptable_packets_) {
+ info = quiche::QuicheStrCat(
+ info, "[", EncryptionLevelToString(packet.encryption_level), ", ",
+ packet.packet->length(), ", ", packet.processed, "]");
+ }
+ info = quiche::QuicheStrCat(info, "}");
+ return info;
+}
+
+void QuicConnection::MaybeUpdatePacketCreatorMaxPacketLengthAndPadding() {
+ QuicByteCount max_packet_length = GetLimitedMaxPacketSize(long_term_mtu_);
+ if (legacy_version_encapsulation_in_progress_) {
+ DCHECK(legacy_version_encapsulation_enabled_);
+ const QuicByteCount minimum_overhead =
+ QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+ legacy_version_encapsulation_sni_);
+ if (max_packet_length < minimum_overhead) {
+ QUIC_BUG << "Cannot apply Legacy Version Encapsulation overhead because "
+ << "max_packet_length " << max_packet_length
+ << " < minimum_overhead " << minimum_overhead;
+ legacy_version_encapsulation_in_progress_ = false;
+ legacy_version_encapsulation_enabled_ = false;
+ MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+ return;
+ }
+ max_packet_length -= minimum_overhead;
}
-
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnUndecryptablePacket(decryption_level,
- /*dropped=*/!should_enqueue);
+ packet_creator_.SetMaxPacketLength(max_packet_length);
+ if (legacy_version_encapsulation_enabled_) {
+ packet_creator_.set_disable_padding_override(
+ legacy_version_encapsulation_in_progress_);
}
}
@@ -1899,14 +2132,9 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
<< " too far from current time:"
<< clock_->ApproximateNow().ToDebuggingValue();
}
- if (!extend_idle_time_on_decryptable_packets_ && use_idle_network_detector_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_idle_network_detector, 1, 6);
- idle_network_detector_.OnPacketReceived(packet.receipt_time());
- } else {
- time_of_last_received_packet_ = packet.receipt_time();
- }
+ time_of_last_received_packet_ = packet.receipt_time();
QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
- << GetTimeOfLastReceivedPacket().ToDebuggingValue();
+ << packet.receipt_time().ToDebuggingValue();
ScopedPacketFlusher flusher(this);
if (!framer_.ProcessPacket(packet)) {
@@ -2040,6 +2268,9 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
<< server_connection_id_ << " with "
<< header.source_connection_id;
+ if (!original_destination_connection_id_.has_value()) {
+ original_destination_connection_id_ = server_connection_id_;
+ }
server_connection_id_ = header.source_connection_id;
packet_creator_.SetServerConnectionId(server_connection_id_);
}
@@ -2122,12 +2353,7 @@ void QuicConnection::WriteQueuedPackets() {
// TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
mtu_discoverer_.Disable();
mtu_discovery_alarm_->Cancel();
- if (GetQuicReloadableFlag(
- quic_ignore_msg_too_big_from_buffered_packets)) {
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_ignore_msg_too_big_from_buffered_packets);
- buffered_packets_.pop_front();
- }
+ buffered_packets_.pop_front();
continue;
}
if (IsWriteError(result.status)) {
@@ -2156,17 +2382,26 @@ void QuicConnection::SendProbingRetransmissions() {
}
}
-void QuicConnection::RetransmitUnackedPackets(
- TransmissionType retransmission_type) {
- sent_packet_manager_.RetransmitUnackedPackets(retransmission_type);
+void QuicConnection::RetransmitZeroRttPackets() {
+ sent_packet_manager_.RetransmitZeroRttPackets();
- WriteIfNotBlocked();
+ if (!GetQuicReloadableFlag(
+ quic_do_not_retransmit_immediately_on_zero_rtt_reject)) {
+ WriteIfNotBlocked();
+ }
}
void QuicConnection::NeuterUnencryptedPackets() {
sent_packet_manager_.NeuterUnencryptedPackets();
// This may have changed the retransmission timer, so re-arm it.
SetRetransmissionAlarm();
+ if (default_enable_5rto_blackhole_detection_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+ 1, 3);
+ // Consider this as forward progress since this is called when initial key
+ // gets discarded (or previous unencrypted data is not needed anymore).
+ OnForwardProgressMade();
+ }
if (SupportsMultiplePacketNumberSpaces()) {
// Stop sending ack of initial packet number space.
uber_received_packet_manager_.ResetAckStates(ENCRYPTION_INITIAL);
@@ -2179,9 +2414,13 @@ void QuicConnection::NeuterUnencryptedPackets() {
bool QuicConnection::ShouldGeneratePacket(
HasRetransmittableData retransmittable,
IsHandshake handshake) {
+ DCHECK(handshake != IS_HANDSHAKE ||
+ QuicVersionUsesCryptoFrames(transport_version()))
+ << ENDPOINT
+ << "Handshake in STREAM frames should not check ShouldGeneratePacket";
// We should serialize handshake packets immediately to ensure that they
// end up sent at the right encryption level.
- if (handshake == IS_HANDSHAKE) {
+ if (!move_amplification_limit_ && handshake == IS_HANDSHAKE) {
if (LimitedByAmplificationFactor()) {
// Server is constrained by the amplification restriction.
QUIC_DVLOG(1) << ENDPOINT << "Constrained by amplification restriction";
@@ -2209,9 +2448,8 @@ const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
QuicFrame updated_ack_frame = GetUpdatedAckFrame();
QUIC_BUG_IF(updated_ack_frame.ack_frame->packets.Empty())
<< ENDPOINT << "Attempted to opportunistically bundle an empty "
- << EncryptionLevelToString(encryption_level_) << " ACK, "
- << (has_pending_ack ? "" : "!") << "has_pending_ack, stop_waiting_count_ "
- << stop_waiting_count_;
+ << encryption_level_ << " ACK, " << (has_pending_ack ? "" : "!")
+ << "has_pending_ack, stop_waiting_count_ " << stop_waiting_count_;
frames.push_back(updated_ack_frame);
if (!no_stop_waiting_frames_) {
@@ -2227,6 +2465,14 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
return false;
}
+ if (move_amplification_limit_ && LimitedByAmplificationFactor()) {
+ // Server is constrained by the amplification restriction.
+ QUIC_RELOADABLE_FLAG_COUNT(quic_move_amplification_limit);
+ QUIC_CODE_COUNT(quic_throttled_by_amplification_limit);
+ QUIC_DVLOG(1) << ENDPOINT << "Constrained by amplification restriction";
+ return false;
+ }
+
if (sent_packet_manager_.pending_timer_transmission_count() > 0) {
// Force sending the retransmissions for HANDSHAKE, TLP, RTO, PROBING cases.
return true;
@@ -2305,7 +2551,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
// Termination packets are encrypted and saved, so don't exit early.
const bool is_termination_packet = IsTerminationPacket(*packet);
QuicPacketNumber packet_number = packet->packet_number;
- const QuicPacketLength encrypted_length = packet->encrypted_length;
+ QuicPacketLength encrypted_length = packet->encrypted_length;
// Termination packets are eventually owned by TimeWaitListManager.
// Others are deleted at the end of this call.
if (is_termination_packet) {
@@ -2320,18 +2566,21 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
}
DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
- if (!is_mtu_discovery) {
- DCHECK_LE(encrypted_length, packet_creator_.max_packet_length());
- }
+ DCHECK(is_mtu_discovery ||
+ encrypted_length <= packet_creator_.max_packet_length())
+ << " encrypted_length=" << encrypted_length
+ << " > packet_creator max_packet_length="
+ << packet_creator_.max_packet_length();
QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
<< (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
? "data bearing "
: " ack only ")
- << ", encryption level: "
- << EncryptionLevelToString(packet->encryption_level)
+ << ", encryption level: " << packet->encryption_level
<< ", encrypted length:" << encrypted_length
- << ", fate: " << SerializedPacketFateToString(fate);
- QUIC_DVLOG(2) << ENDPOINT << "packet(" << packet_number << "): " << std::endl
+ << ", fate: " << fate;
+ QUIC_DVLOG(2) << ENDPOINT << packet->encryption_level << " packet number "
+ << packet_number << " of length " << encrypted_length << ": "
+ << std::endl
<< quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece(
packet->encrypted_buffer, encrypted_length));
@@ -2377,6 +2626,14 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
buffered_packets_.emplace_back(*packet, self_address(), peer_address());
break;
case SEND_TO_WRITER:
+ // At this point, packet->release_encrypted_buffer is either nullptr,
+ // meaning |packet->encrypted_buffer| is a stack buffer, or not-nullptr,
+ /// meaning it's a writer-allocated buffer. Note that connectivity probing
+ // packets do not use this function, so setting release_encrypted_buffer
+ // to nullptr will not cause probing packets to be leaked.
+ //
+ // writer_->WritePacket transfers buffer ownership back to the writer.
+ packet->release_encrypted_buffer = nullptr;
result = writer_->WritePacket(packet->encrypted_buffer, encrypted_length,
self_address().host(), peer_address(),
per_packet_options_);
@@ -2396,6 +2653,48 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
// write error has been handled.
QUIC_BUG_IF(!version().CanSendCoalescedPackets());
return false;
+ case LEGACY_VERSION_ENCAPSULATE: {
+ DCHECK(!is_mtu_discovery);
+ DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
+ DCHECK_EQ(packet->encryption_level, ENCRYPTION_INITIAL);
+ DCHECK(legacy_version_encapsulation_enabled_);
+ DCHECK(legacy_version_encapsulation_in_progress_);
+ QuicPacketLength encapsulated_length =
+ QuicLegacyVersionEncapsulator::Encapsulate(
+ legacy_version_encapsulation_sni_,
+ quiche::QuicheStringPiece(packet->encrypted_buffer,
+ packet->encrypted_length),
+ server_connection_id_, framer_.creation_time(),
+ GetLimitedMaxPacketSize(long_term_mtu_),
+ const_cast<char*>(packet->encrypted_buffer));
+ if (encapsulated_length != 0) {
+ stats_.sent_legacy_version_encapsulated_packets++;
+ packet->encrypted_length = encapsulated_length;
+ encrypted_length = encapsulated_length;
+ QUIC_DVLOG(2)
+ << ENDPOINT
+ << "Successfully performed Legacy Version Encapsulation on "
+ << packet->encryption_level << " packet number " << packet_number
+ << " of length " << encrypted_length << ": " << std::endl
+ << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece(
+ packet->encrypted_buffer, encrypted_length));
+ } else {
+ QUIC_BUG << ENDPOINT
+ << "Failed to perform Legacy Version Encapsulation on "
+ << packet->encryption_level << " packet number "
+ << packet_number << " of length " << encrypted_length;
+ }
+ if (!buffered_packets_.empty() || HandleWriteBlocked()) {
+ // Buffer the packet.
+ buffered_packets_.emplace_back(*packet, self_address(), peer_address());
+ } else { // Send the packet to the writer.
+ // writer_->WritePacket transfers buffer ownership back to the writer.
+ packet->release_encrypted_buffer = nullptr;
+ result = writer_->WritePacket(packet->encrypted_buffer,
+ encrypted_length, self_address().host(),
+ peer_address(), per_packet_options_);
+ }
+ } break;
default:
DCHECK(false);
break;
@@ -2499,6 +2798,11 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
const bool in_flight = sent_packet_manager_.OnPacketSent(
packet, packet_send_time, packet->transmission_type,
IsRetransmittable(*packet));
+ QUIC_BUG_IF(default_enable_5rto_blackhole_detection_ &&
+ blackhole_detector_.IsDetectionInProgress() &&
+ !sent_packet_manager_.HasInFlightPackets())
+ << ENDPOINT
+ << "Trying to start blackhole detection without no bytes in flight";
if (in_flight || !retransmission_alarm_->IsSet()) {
SetRetransmissionAlarm();
@@ -2620,11 +2924,11 @@ void QuicConnection::OnWriteError(int error_code) {
}
}
-char* QuicConnection::GetPacketBuffer() {
+QuicPacketBuffer QuicConnection::GetPacketBuffer() {
if (version().CanSendCoalescedPackets() && !IsHandshakeConfirmed()) {
// Do not use writer's packet buffer for coalesced packets which may contain
// multiple QUIC packets.
- return nullptr;
+ return {nullptr, nullptr};
}
return writer_->GetNextWriteLocation(self_address().host(), peer_address());
}
@@ -2700,6 +3004,11 @@ void QuicConnection::OnHandshakeComplete() {
sent_packet_manager_.SetHandshakeConfirmed();
// This may have changed the retransmission timer, so re-arm it.
SetRetransmissionAlarm();
+ if (default_enable_5rto_blackhole_detection_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+ 2, 3);
+ OnForwardProgressMade();
+ }
if (!SupportsMultiplePacketNumberSpaces()) {
// The client should immediately ack the SHLO to confirm the handshake is
// complete with the server.
@@ -2753,11 +3062,6 @@ void QuicConnection::SendAck() {
visitor_->OnAckNeedsRetransmittableFrame();
}
-void QuicConnection::OnPathDegradingTimeout() {
- is_path_degrading_ = true;
- visitor_->OnPathDegrading();
-}
-
void QuicConnection::OnRetransmissionTimeout() {
#ifndef NDEBUG
if (sent_packet_manager_.unacked_packets().empty()) {
@@ -2784,6 +3088,13 @@ void QuicConnection::OnRetransmissionTimeout() {
debug_visitor_->OnNPacketNumbersSkipped(num_packet_numbers_to_skip);
}
}
+ if (default_enable_5rto_blackhole_detection_ &&
+ !sent_packet_manager_.HasInFlightPackets() &&
+ blackhole_detector_.IsDetectionInProgress()) {
+ // Stop detection in quiescence.
+ DCHECK_EQ(QuicSentPacketManager::LOSS_MODE, retransmission_mode);
+ blackhole_detector_.StopDetection();
+ }
WriteIfNotBlocked();
// A write failure can result in the connection being closed, don't attempt to
@@ -2817,8 +3128,9 @@ void QuicConnection::OnRetransmissionTimeout() {
if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
sent_packet_manager_.AdjustPendingTimerTransmissions();
}
- if (retransmission_mode != QuicSentPacketManager::LOSS_MODE) {
- // When timer fires in TLP or RTO mode, ensure 1) at least one packet is
+ if (retransmission_mode != QuicSentPacketManager::LOSS_MODE &&
+ retransmission_mode != QuicSentPacketManager::HANDSHAKE_MODE) {
+ // When timer fires in TLP/RTO/PTO mode, ensure 1) at least one packet is
// created, or there is data to send and available credit (such that
// packets will be sent eventually).
QUIC_BUG_IF(packet_creator_.packet_number() ==
@@ -2859,8 +3171,7 @@ void QuicConnection::SetDiversificationNonce(
void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
- << EncryptionLevelToString(encryption_level_) << " to "
- << EncryptionLevelToString(level);
+ << encryption_level_ << " to " << level;
if (level != encryption_level_ && packet_creator_.HasPendingFrames()) {
// Flush all queued frames when encryption level changes.
ScopedPacketFlusher flusher(this);
@@ -2936,27 +3247,79 @@ void QuicConnection::MaybeProcessUndecryptablePackets() {
return;
}
- while (connected_ && !undecryptable_packets_.empty()) {
- // Making sure there is no pending frames when processing next undecrypted
- // packet because the queued ack frame may change.
- packet_creator_.FlushCurrentPacket();
- if (!connected_) {
- return;
+ if (GetQuicReloadableFlag(quic_fix_undecryptable_packets)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_undecryptable_packets);
+ auto iter = undecryptable_packets_.begin();
+ while (connected_ && iter != undecryptable_packets_.end()) {
+ // Making sure there is no pending frames when processing next undecrypted
+ // packet because the queued ack frame may change.
+ packet_creator_.FlushCurrentPacket();
+ if (!connected_) {
+ return;
+ }
+ UndecryptablePacket* undecryptable_packet = &*iter;
+ ++iter;
+ if (undecryptable_packet->processed) {
+ continue;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
+ undecryptable_packet->encryption_level);
+ }
+ if (framer_.ProcessPacket(*undecryptable_packet->packet)) {
+ QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
+ undecryptable_packet->processed = true;
+ ++stats_.packets_processed;
+ continue;
+ }
+ const bool has_decryption_key =
+ version().KnowsWhichDecrypterToUse() &&
+ framer_.HasDecrypterOfEncryptionLevel(
+ undecryptable_packet->encryption_level);
+ if (framer_.error() == QUIC_DECRYPTION_FAILURE &&
+ ShouldEnqueueUnDecryptablePacket(
+ undecryptable_packet->encryption_level, has_decryption_key)) {
+ QUIC_DVLOG(1)
+ << ENDPOINT
+ << "Need to attempt to process this undecryptable packet later";
+ continue;
+ }
+ undecryptable_packet->processed = true;
}
- QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
- const auto& undecryptable_packet = undecryptable_packets_.front();
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
- undecryptable_packet.encryption_level);
+ // Remove processed packets. We cannot remove elements in the while loop
+ // above because currently QuicCircularDeque does not support removing
+ // mid elements.
+ while (!undecryptable_packets_.empty()) {
+ if (!undecryptable_packets_.front().processed) {
+ break;
+ }
+ undecryptable_packets_.pop_front();
}
- if (!framer_.ProcessPacket(*undecryptable_packet.packet) &&
- framer_.error() == QUIC_DECRYPTION_FAILURE) {
- QUIC_DVLOG(1) << ENDPOINT << "Unable to process undecryptable packet...";
- break;
+ } else {
+ while (connected_ && !undecryptable_packets_.empty()) {
+ // Making sure there is no pending frames when processing next undecrypted
+ // packet because the queued ack frame may change.
+ packet_creator_.FlushCurrentPacket();
+ if (!connected_) {
+ return;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
+ const auto& undecryptable_packet = undecryptable_packets_.front();
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnAttemptingToProcessUndecryptablePacket(
+ undecryptable_packet.encryption_level);
+ }
+ if (!framer_.ProcessPacket(*undecryptable_packet.packet) &&
+ framer_.error() == QUIC_DECRYPTION_FAILURE) {
+ QUIC_DVLOG(1) << ENDPOINT
+ << "Unable to process undecryptable packet...";
+ break;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
+ ++stats_.packets_processed;
+ undecryptable_packets_.pop_front();
}
- QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
- ++stats_.packets_processed;
- undecryptable_packets_.pop_front();
}
// Once forward secure encryption is in use, there will be no
@@ -3074,8 +3437,8 @@ void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
if (!framer_.HasEncrypterOfEncryptionLevel(level)) {
continue;
}
- QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet at level: "
- << EncryptionLevelToString(level);
+ QUIC_DLOG(INFO) << ENDPOINT
+ << "Sending connection close packet at level: " << level;
SetDefaultEncryptionLevel(level);
// Bundle an ACK of the corresponding packet number space for debugging
// purpose.
@@ -3156,7 +3519,7 @@ QuicByteCount QuicConnection::max_packet_length() const {
void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
long_term_mtu_ = length;
- packet_creator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
+ MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
}
bool QuicConnection::HasQueuedData() const {
@@ -3164,22 +3527,6 @@ bool QuicConnection::HasQueuedData() const {
packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
}
-bool QuicConnection::CanWriteStreamData() {
- // Don't write stream data if there are negotiation or queued data packets
- // to send. Otherwise, continue and bundle as many frames as possible.
- if (pending_version_negotiation_packet_ || !buffered_packets_.empty()) {
- return false;
- }
-
- IsHandshake pending_handshake =
- visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE;
- // Sending queued packets may have caused the socket to become write blocked,
- // or the congestion manager to prohibit sending. If we've sent everything
- // we had queued and we're still not blocked, let the visitor know it can
- // write more.
- return ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, pending_handshake);
-}
-
void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
QuicTime::Delta idle_timeout) {
QUIC_BUG_IF(idle_timeout > handshake_timeout)
@@ -3868,15 +4215,7 @@ void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
// have a better estimate of the current rtt than when it was set.
SetRetransmissionAlarm();
if (acked_new_packet) {
- is_path_degrading_ = false;
- if (sent_packet_manager_.HasInFlightPackets()) {
- // Restart detections if forward progress has been made.
- blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
- GetNetworkBlackholeDeadline());
- } else {
- // Stop detections in quiecense.
- blackhole_detector_.StopDetection();
- }
+ OnForwardProgressMade();
}
if (send_stop_waiting) {
@@ -3963,7 +4302,7 @@ EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
// A forward secure packet has been received.
QUIC_BUG_IF(encryption_level_ != ENCRYPTION_FORWARD_SECURE)
<< ENDPOINT << "Unexpected connection close encryption level "
- << EncryptionLevelToString(encryption_level_);
+ << encryption_level_;
return ENCRYPTION_FORWARD_SECURE;
}
if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
@@ -3979,25 +4318,68 @@ EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
return ENCRYPTION_INITIAL;
}
+void QuicConnection::MaybeBundleCryptoDataWithAckOfSpace(
+ PacketNumberSpace space) {
+ DCHECK(SupportsMultiplePacketNumberSpaces());
+ QUIC_BUG_IF(space == APPLICATION_DATA);
+ const QuicTime ack_timeout =
+ uber_received_packet_manager_.GetAckTimeout(space);
+ if (!ack_timeout.IsInitialized() ||
+ (ack_timeout > clock_->ApproximateNow() &&
+ ack_timeout > uber_received_packet_manager_.GetEarliestAckTimeout())) {
+ // No pending ACK of space.
+ return;
+ }
+ if (coalesced_packet_.length() > 0) {
+ // Do not bundle CRYPTO data if the ACK could be coalesced with other
+ // packets.
+ return;
+ }
+
+ sent_packet_manager_.RetransmitDataOfSpaceIfAny(space);
+}
+
void QuicConnection::SendAllPendingAcks() {
DCHECK(SupportsMultiplePacketNumberSpaces());
QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
ack_alarm_->Cancel();
+ QuicTime earliest_ack_timeout =
+ uber_received_packet_manager_.GetEarliestAckTimeout();
+ QUIC_BUG_IF(!earliest_ack_timeout.IsInitialized());
+ if (GetQuicReloadableFlag(quic_bundle_crypto_data_with_initial_ack)) {
+ // On the server side, sends INITIAL data with INITIAL ACK. On the client
+ // side, sends HANDSHAKE data (containing client Finished) with HANDSHAKE
+ // ACK.
+ PacketNumberSpace space =
+ perspective() == Perspective::IS_SERVER ? INITIAL_DATA : HANDSHAKE_DATA;
+ MaybeBundleCryptoDataWithAckOfSpace(space);
+ earliest_ack_timeout =
+ uber_received_packet_manager_.GetEarliestAckTimeout();
+ if (!earliest_ack_timeout.IsInitialized()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_bundle_crypto_data_with_initial_ack);
+ return;
+ }
+ }
// Latches current encryption level.
const EncryptionLevel current_encryption_level = encryption_level_;
for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
static_cast<PacketNumberSpace>(i));
- if (!ack_timeout.IsInitialized() ||
- ack_timeout > clock_->ApproximateNow()) {
+ if (!ack_timeout.IsInitialized()) {
continue;
}
- if (!framer_.HasEncrypterOfEncryptionLevel(
- QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)))) {
- QUIC_BUG << ENDPOINT << "Cannot send ACKs for packet number space "
- << PacketNumberSpaceToString(static_cast<PacketNumberSpace>(i))
- << " without corresponding encrypter";
- continue;
+ if (GetQuicReloadableFlag(quic_always_send_earliest_ack)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_always_send_earliest_ack);
+ }
+ if (ack_timeout > clock_->ApproximateNow()) {
+ if (!GetQuicReloadableFlag(quic_always_send_earliest_ack)) {
+ continue;
+ }
+ if (ack_timeout > earliest_ack_timeout) {
+ // Always send the earliest ACK to make forward progress in case alarm
+ // fires early.
+ continue;
+ }
}
QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space "
<< PacketNumberSpaceToString(
@@ -4011,8 +4393,12 @@ void QuicConnection::SendAllPendingAcks() {
const bool flushed = packet_creator_.FlushAckFrame(frames);
if (!flushed) {
// Connection is write blocked.
- QUIC_BUG_IF(!writer_->IsWriteBlocked())
- << "Writer not blocked, but ACK not flushed for packet space:" << i;
+ QUIC_BUG_IF(
+ !writer_->IsWriteBlocked() &&
+ (!move_amplification_limit_ || !LimitedByAmplificationFactor()))
+ << "Writer not blocked and not throttled by amplification factor, "
+ "but ACK not flushed for packet space:"
+ << i;
break;
}
ResetAckStates();
@@ -4024,7 +4410,13 @@ void QuicConnection::SendAllPendingAcks() {
uber_received_packet_manager_.GetEarliestAckTimeout();
if (timeout.IsInitialized()) {
// If there are ACKs pending, re-arm ack alarm.
- ack_alarm_->Set(timeout);
+ if (update_ack_alarm_in_send_all_pending_acks_) {
+ QUIC_RELOADABLE_FLAG_COUNT(
+ quic_update_ack_alarm_in_send_all_pending_acks);
+ ack_alarm_->Update(timeout, kAlarmGranularity);
+ } else {
+ ack_alarm_->Set(timeout);
+ }
}
// Only try to bundle retransmittable data with ACK frame if default
// encryption level is forward secure.
@@ -4066,13 +4458,15 @@ bool QuicConnection::FlushCoalescedPacket() {
if (coalesced_packet_.length() == 0) {
return true;
}
- QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet";
+
char buffer[kMaxOutgoingPacketSize];
const size_t length = packet_creator_.SerializeCoalescedPacket(
coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
if (length == 0) {
return false;
}
+ QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet "
+ << coalesced_packet_.ToString(length);
if (!buffered_packets_.empty() || HandleWriteBlocked()) {
QUIC_DVLOG(1) << ENDPOINT
@@ -4158,6 +4552,26 @@ void QuicConnection::SetLargestReceivedPacketWithAck(
}
}
+void QuicConnection::OnForwardProgressMade() {
+ if (is_path_degrading_) {
+ visitor_->OnForwardProgressMadeAfterPathDegrading();
+ is_path_degrading_ = false;
+ }
+ if (sent_packet_manager_.HasInFlightPackets()) {
+ // Restart detections if forward progress has been made.
+ blackhole_detector_.RestartDetection(GetPathDegradingDeadline(),
+ GetNetworkBlackholeDeadline());
+ } else {
+ // Stop detections in quiecense.
+ blackhole_detector_.StopDetection();
+ }
+ QUIC_BUG_IF(default_enable_5rto_blackhole_detection_ &&
+ blackhole_detector_.IsDetectionInProgress() &&
+ !sent_packet_manager_.HasInFlightPackets())
+ << ENDPOINT
+ << "Trying to start blackhole detection without no bytes in flight";
+}
+
QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
if (SupportsMultiplePacketNumberSpaces()) {
return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
@@ -4187,21 +4601,28 @@ bool QuicConnection::EnforceAntiAmplificationLimit() const {
bool QuicConnection::LimitedByAmplificationFactor() const {
return EnforceAntiAmplificationLimit() &&
bytes_sent_before_address_validation_ >=
- GetQuicFlag(FLAGS_quic_anti_amplification_factor) *
+ anti_amplification_factor_ *
bytes_received_before_address_validation_;
}
SerializedPacketFate QuicConnection::DeterminePacketFate(
bool is_mtu_discovery) {
- if (version().CanSendCoalescedPackets() && !IsHandshakeConfirmed() &&
- !is_mtu_discovery) {
- // Before receiving ACK for any 1-RTT packets, always try to coalesce
- // packet (except MTU discovery packet).
- return COALESCE;
+ if (legacy_version_encapsulation_in_progress_) {
+ DCHECK(!is_mtu_discovery);
+ return LEGACY_VERSION_ENCAPSULATE;
}
- // Packet cannot be coalesced, flush existing coalesced packet.
- if (version().CanSendCoalescedPackets() && !FlushCoalescedPacket()) {
- return FAILED_TO_WRITE_COALESCED_PACKET;
+ if (version().CanSendCoalescedPackets()) {
+ // Disable coalescing when Legacy Version Encapsulation is in use to avoid
+ // having to reframe encapsulated packets.
+ if (!IsHandshakeConfirmed() && !is_mtu_discovery) {
+ // Before receiving ACK for any 1-RTT packets, always try to coalesce
+ // packet (except MTU discovery packet).
+ return COALESCE;
+ }
+ // Packet cannot be coalesced, flush existing coalesced packet.
+ if (!FlushCoalescedPacket()) {
+ return FAILED_TO_WRITE_COALESCED_PACKET;
+ }
}
if (!buffered_packets_.empty() || HandleWriteBlocked()) {
return BUFFER;
@@ -4269,6 +4690,11 @@ void QuicConnection::OnPathDegradingDetected() {
}
void QuicConnection::OnBlackholeDetected() {
+ QUIC_BUG_IF(default_enable_5rto_blackhole_detection_ &&
+ !sent_packet_manager_.HasInFlightPackets())
+ << ENDPOINT
+ << "Closing connection because of blackhole, but there is no bytes in "
+ "flight";
CloseConnection(QUIC_TOO_MANY_RTOS, "Network blackhole detected.",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
@@ -4278,10 +4704,14 @@ void QuicConnection::OnHandshakeTimeout() {
DCHECK(use_idle_network_detector_);
const QuicTime::Delta duration =
clock_->ApproximateNow() - stats_.connection_creation_time;
- const std::string error_details = quiche::QuicheStrCat(
+ std::string error_details = quiche::QuicheStrCat(
"Handshake timeout expired after ", duration.ToDebuggingValue(),
". Timeout:",
idle_network_detector_.handshake_timeout().ToDebuggingValue());
+ if (perspective() == Perspective::IS_CLIENT && version().UsesTls()) {
+ error_details =
+ quiche::QuicheStrCat(error_details, UndecryptablePacketsInfo());
+ }
QUIC_DVLOG(1) << ENDPOINT << error_details;
CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
@@ -4311,7 +4741,6 @@ void QuicConnection::OnIdleNetworkDetected() {
}
void QuicConnection::MaybeUpdateAckTimeout() {
- DCHECK(advance_ack_timeout_update_);
if (should_last_packet_instigate_acks_) {
return;
}
@@ -4345,20 +4774,27 @@ QuicTime QuicConnection::GetNetworkBlackholeDeadline() const {
if (!ShouldDetectBlackhole()) {
return QuicTime::Zero();
}
+ DCHECK_LT(0u, num_rtos_for_blackhole_detection_);
return clock_->ApproximateNow() +
- sent_packet_manager_.GetNetworkBlackholeDelay();
+ sent_packet_manager_.GetNetworkBlackholeDelay(
+ num_rtos_for_blackhole_detection_);
}
bool QuicConnection::ShouldDetectBlackhole() const {
- if (!connected_) {
+ if (!connected_ || blackhole_detection_disabled_) {
return false;
}
// No blackhole detection before handshake completes.
+ if (default_enable_5rto_blackhole_detection_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_enable_5rto_blackhole_detection2,
+ 3, 3);
+ return IsHandshakeComplete();
+ }
+
if (!GetHandshakeTimeout().IsInfinite()) {
return false;
}
- return close_connection_after_five_rtos_ ||
- (sent_packet_manager_.pto_enabled() && max_consecutive_ptos_ > 0);
+ return num_rtos_for_blackhole_detection_ > 0;
}
QuicTime::Delta QuicConnection::GetHandshakeTimeout() const {
@@ -4372,12 +4808,9 @@ QuicTime QuicConnection::GetTimeOfLastReceivedPacket() const {
if (use_idle_network_detector_) {
return idle_network_detector_.time_of_last_received_packet();
}
- if (extend_idle_time_on_decryptable_packets_) {
- DCHECK(time_of_last_decryptable_packet_ == time_of_last_received_packet_ ||
- !last_packet_decrypted_);
- return time_of_last_decryptable_packet_;
- }
- return time_of_last_received_packet_;
+ DCHECK(time_of_last_decryptable_packet_ == time_of_last_received_packet_ ||
+ !last_packet_decrypted_);
+ return time_of_last_decryptable_packet_;
}
#undef ENDPOINT // undef for jumbo builds
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 6586fb2870a..c0f722dd0c8 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
@@ -26,6 +26,7 @@
#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_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"
@@ -130,6 +131,12 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// bandwidth. Returns true if data was sent, false otherwise.
virtual bool SendProbingData() = 0;
+ // Called when stateless reset packet is received. Returns true if the
+ // connection needs to be closed.
+ virtual bool ValidateStatelessReset(
+ const quic::QuicSocketAddress& self_address,
+ const quic::QuicSocketAddress& peer_address) = 0;
+
// Called when the connection experiences a change in congestion window.
virtual void OnCongestionWindowChange(QuicTime now) = 0;
@@ -139,6 +146,9 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// Called when the peer seems unreachable over the current path.
virtual void OnPathDegrading() = 0;
+ // Called when forward progress made after path degrading.
+ virtual void OnForwardProgressMadeAfterPathDegrading() = 0;
+
// Called when the connection sends ack after
// max_consecutive_num_packets_with_no_retransmittable_frames_ consecutive not
// retransmittable packets sent. To instigate an ack from peer, a
@@ -155,9 +165,6 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// or yielded to other connections.
virtual bool WillingAndAbleToWrite() const = 0;
- // Called to ask if any handshake messages are pending in this visitor.
- virtual bool HasPendingHandshake() const = 0;
-
// Called to ask if the connection should be kept alive and prevented
// from timing out, for example if there are outstanding application
// transactions expecting a response.
@@ -170,10 +177,6 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// Called to get current handshake state.
virtual HandshakeState GetHandshakeState() const = 0;
- // Called when an ACK is received with a larger |largest_acked| than
- // previously observed.
- virtual void OnForwardProgressConfirmed() = 0;
-
// Called when a STOP_SENDING frame has been received.
virtual void OnStopSendingFrame(const QuicStopSendingFrame& frame) = 0;
@@ -341,6 +344,14 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
// Called when |count| packet numbers have been skipped.
virtual void OnNPacketNumbersSkipped(QuicPacketCount /*count*/) {}
+
+ // Called for QUIC+TLS versions when we send transport parameters.
+ virtual void OnTransportParametersSent(
+ const TransportParameters& /*transport_parameters*/) {}
+
+ // Called for QUIC+TLS versions when we receive transport parameters.
+ virtual void OnTransportParametersReceived(
+ const TransportParameters& /*transport_parameters*/) {}
};
class QUIC_EXPORT_PRIVATE QuicConnectionHelperInterface {
@@ -458,11 +469,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Returns statistics tracked for this connection.
const QuicConnectionStats& GetStats();
- // Mark stats_.has_non_app_limited_sample as false.
- // TODO(b/151166631) Remove this once the proper fix in b/151166631 is rolled
- // out.
- void ResetHasNonAppLimitedSampleAfterHandshakeCompletion();
-
// Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from
// the peer.
// In a client, the packet may be "stray" and have a different connection ID
@@ -578,6 +584,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
bool OnMessageFrame(const QuicMessageFrame& frame) override;
bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
void OnPacketComplete() override;
bool IsValidStatelessResetToken(QuicUint128 token) const override;
void OnAuthenticatedIetfStatelessResetPacket(
@@ -587,7 +594,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
IsHandshake handshake) override;
const QuicFrames MaybeBundleAckOpportunistically() override;
- char* GetPacketBuffer() override;
+ QuicPacketBuffer GetPacketBuffer() override;
void OnSerializedPacket(SerializedPacket packet) override;
void OnUnrecoverableError(QuicErrorCode error,
const std::string& error_details) override;
@@ -669,14 +676,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection
return server_supported_versions_;
}
- // Testing only.
+ bool HasQueuedPackets() const { return !buffered_packets_.empty(); }
+ // Testing only. TODO(ianswett): Use a peer instead.
size_t NumQueuedPackets() const { return buffered_packets_.size(); }
- // Returns true if the underlying UDP socket is writable, there is
- // no queued data and the connection is not congestion-control
- // blocked.
- bool CanWriteStreamData();
-
// Returns true if the connection has queued packets or frames.
bool HasQueuedData() const;
@@ -695,19 +698,13 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Sets up a packet with an QuicAckFrame and sends it out.
void SendAck();
- // Called when the path degrading alarm fires.
- void OnPathDegradingTimeout();
-
// Called when an RTO fires. Resets the retransmission alarm if there are
// remaining unacked packets.
void OnRetransmissionTimeout();
- // Retransmits all unacked packets with retransmittable frames if
- // |retransmission_type| is ALL_UNACKED_PACKETS, otherwise retransmits only
- // initially encrypted packets. Used when the negotiated protocol version is
- // different from what was initially assumed and when the initial encryption
- // changes.
- void RetransmitUnackedPackets(TransmissionType retransmission_type);
+ // Retransmits all sent 0-RTT encrypted packets. Called when new 0-RTT or
+ // 1-RTT key is available.
+ void RetransmitZeroRttPackets();
// Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
// connection becomes forward secure and hasn't received acks for all packets.
@@ -942,9 +939,13 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Returns the largest received packet number sent by peer.
QuicPacketNumber GetLargestReceivedPacket() const;
- // Adds the connection ID to a set of connection IDs that are accepted as
- // destination on incoming packets.
- void AddIncomingConnectionId(QuicConnectionId connection_id);
+ // Sets the original destination connection ID on the connection.
+ // This is called by QuicDispatcher when it has replaced the connection ID.
+ void SetOriginalDestinationConnectionId(
+ const QuicConnectionId& original_destination_connection_id);
+
+ // Returns the original destination connection ID used for this connection.
+ QuicConnectionId GetOriginalDestinationConnectionId();
// Called when ACK alarm goes off. Sends ACKs of those packet number spaces
// which have expired ACK timeout. Only used when this connection supports
@@ -965,6 +966,30 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Called when version is considered negotiated.
void OnSuccessfulVersionNegotiation();
+ // Called when self migration succeeds after probing.
+ void OnSuccessfulMigrationAfterProbing();
+
+ // Called for QUIC+TLS versions when we send transport parameters.
+ void OnTransportParametersSent(
+ const TransportParameters& transport_parameters) const;
+
+ // Called for QUIC+TLS versions when we receive transport parameters.
+ void OnTransportParametersReceived(
+ const TransportParameters& transport_parameters) const;
+
+ // Returns true if ack_alarm_ is set.
+ bool HasPendingAcks() const;
+
+ size_t anti_amplification_factor() const {
+ return anti_amplification_factor_;
+ }
+
+ void OnUserAgentIdKnown() { sent_packet_manager_.OnUserAgentIdKnown(); }
+
+ // Enables Legacy Version Encapsulation using |server_name| as SNI.
+ // Can only be set if this is a client connection.
+ void EnableLegacyVersionEncapsulation(const std::string& server_name);
+
protected:
// Calls cancel() on all the alarms owned by this connection.
void CancelAllAlarms();
@@ -1075,12 +1100,16 @@ class QUIC_EXPORT_PRIVATE QuicConnection
struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
UndecryptablePacket(const QuicEncryptedPacket& packet,
EncryptionLevel encryption_level)
- : packet(packet.Clone()), encryption_level(encryption_level) {}
+ : packet(packet.Clone()),
+ encryption_level(encryption_level),
+ processed(false) {}
std::unique_ptr<QuicEncryptedPacket> packet;
- // Currently, |encryption_level| is only used for logging and does not
- // affect processing of the packet.
EncryptionLevel encryption_level;
+ // This gets set to true if 1) connection sucessfully processed the packet
+ // or 2) connection failed to process the packet and will not try to process
+ // it later.
+ bool processed;
};
// Notifies the visitor of the close and marks the connection as disconnected.
@@ -1237,6 +1266,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// received packet number which contains an ACK frame.
void SetLargestReceivedPacketWithAck(QuicPacketNumber new_value);
+ // Called when new packets have been acknowledged or old keys have been
+ // discarded.
+ void OnForwardProgressMade();
+
// Returns largest received packet number which contains an ACK frame.
QuicPacketNumber GetLargestReceivedPacketWithAck() const;
@@ -1285,6 +1318,30 @@ class QUIC_EXPORT_PRIVATE QuicConnection
QuicTime::Delta GetHandshakeTimeout() const;
QuicTime GetTimeOfLastReceivedPacket() const;
+ // Validate connection IDs used during the handshake. Closes the connection
+ // on validation failure.
+ bool ValidateConfigConnectionIds(const QuicConfig& config);
+ bool ValidateConfigConnectionIdsOld(const QuicConfig& config);
+
+ // Called when ACK alarm goes off. Try to bundle crypto data with the ACK of
+ // |space|.
+ void MaybeBundleCryptoDataWithAckOfSpace(PacketNumberSpace space);
+
+ // Returns true if an undecryptable packet of |decryption_level| should be
+ // buffered (such that connection can try to decrypt it later).
+ bool ShouldEnqueueUnDecryptablePacket(EncryptionLevel decryption_level,
+ bool has_decryption_key) const;
+
+ // Returns string which contains undecryptable packets information.
+ std::string UndecryptablePacketsInfo() const;
+
+ // Sets the max packet length on the packet creator if needed.
+ void MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
+
+ // Sets internal state to enable or disable Legacy Version Encapsulation.
+ void MaybeActivateLegacyVersionEncapsulation();
+ void MaybeDisactivateLegacyVersionEncapsulation();
+
QuicFramer framer_;
// Contents received in the current packet, especially used to identify
@@ -1394,9 +1451,8 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// a connection close packet is sent, but not after.
ConnectionCloseBehavior idle_timeout_connection_close_behavior_;
- // When true, close the QUIC connection after 5 RTOs. Due to the min rto of
- // 200ms, this is over 5 seconds.
- bool close_connection_after_five_rtos_;
+ // When > 0, close the QUIC connection after this number of RTOs.
+ size_t num_rtos_for_blackhole_detection_;
UberReceivedPacketManager uber_received_packet_manager_;
@@ -1601,18 +1657,19 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// vector to improve performance since it is expected to be very small.
std::vector<QuicConnectionId> incoming_connection_ids_;
- // When we receive a RETRY packet, we replace |server_connection_id_| with the
- // value from the RETRY packet and save off the original value of
- // |server_connection_id_| into |original_connection_id_| for validation.
- quiche::QuicheOptional<QuicConnectionId> original_connection_id_;
+ // When we receive a RETRY packet or some INITIAL packets, we replace
+ // |server_connection_id_| with the value from that packet and save off the
+ // original value of |server_connection_id_| into
+ // |original_destination_connection_id_| for validation.
+ quiche::QuicheOptional<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_;
// Indicates whether received RETRY packets should be dropped.
bool drop_incoming_retry_packets_;
- // If max_consecutive_ptos_ > 0, close connection if consecutive PTOs is
- // greater than max_consecutive_ptos.
- size_t max_consecutive_ptos_;
-
// Bytes received before address validation. Only used when
// EnforceAntiAmplificationLimit returns true.
size_t bytes_received_before_address_validation_;
@@ -1644,14 +1701,40 @@ class QUIC_EXPORT_PRIVATE QuicConnection
QuicIdleNetworkDetector idle_network_detector_;
+ bool blackhole_detection_disabled_ = false;
+
+ // True if this connection supports handshake done frame.
+ bool support_handshake_done_;
+
const bool use_idle_network_detector_ =
GetQuicReloadableFlag(quic_use_idle_network_detector);
- const bool extend_idle_time_on_decryptable_packets_ =
- GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets);
-
- const bool advance_ack_timeout_update_ =
- GetQuicReloadableFlag(quic_advance_ack_timeout_update);
+ const bool update_ack_alarm_in_send_all_pending_acks_ =
+ GetQuicReloadableFlag(quic_update_ack_alarm_in_send_all_pending_acks);
+
+ const bool move_amplification_limit_ =
+ GetQuicReloadableFlag(quic_move_amplification_limit);
+
+ // TODO(fayang): Change the default value of quic_anti_amplification_factor to
+ // 5 when deprecating quic_move_amplification_limit.
+ // TODO(b/153892665): Change the default value of
+ // quic_anti_amplification_factor back to 3 when cert compression is
+ // supported.
+ const size_t anti_amplification_factor_ =
+ move_amplification_limit_
+ ? 5
+ : GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+
+ const bool default_enable_5rto_blackhole_detection_ =
+ GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2);
+
+ // Whether the Legacy Version Encapsulation feature is enabled.
+ bool legacy_version_encapsulation_enabled_ = false;
+ // Whether we are in the middle of sending a packet using Legacy Version
+ // Encapsulation.
+ bool legacy_version_encapsulation_in_progress_ = false;
+ // SNI to send when using Legacy Version Encapsulation.
+ std::string legacy_version_encapsulation_sni_;
};
} // 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 89f7e546d88..191918c9887 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
@@ -53,6 +53,8 @@ std::ostream& operator<<(std::ostream& os, const QuicConnectionStats& s) {
os << " num_coalesced_packets_processed: "
<< s.num_coalesced_packets_processed;
os << " num_ack_aggregation_epochs: " << s.num_ack_aggregation_epochs;
+ os << " sent_legacy_version_encapsulated_packets: "
+ << s.sent_legacy_version_encapsulated_packets;
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 3b0c85d2228..3579be0f6f4 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
@@ -47,9 +47,21 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
QuicPacketCount packets_lost = 0;
QuicPacketCount packet_spuriously_detected_lost = 0;
- // The sum of the detection time of all lost packets. The detection time of a
- // lost packet is defined as: T(detection) - T(send).
- QuicTime::Delta total_loss_detection_time = QuicTime::Delta::Zero();
+ // The sum of loss detection response times of all lost packets, in number of
+ // round trips.
+ // Given a packet detected as lost:
+ // T(S) T(1Rtt) T(D)
+ // |_________________________________|_______|
+ // Where
+ // T(S) is the time when the packet is sent.
+ // T(1Rtt) is one rtt after T(S), using the rtt at the time of detection.
+ // T(D) is the time of detection, i.e. when the packet is declared as lost.
+ // The loss detection response time is defined as
+ // (T(D) - T(S)) / (T(1Rtt) - T(S))
+ //
+ // The average loss detection response time is this number divided by
+ // |packets_lost|. Smaller result means detection is faster.
+ float total_loss_detection_response_time = 0.0;
// Number of times this connection went through the slow start phase.
uint32_t slowstart_count = 0;
@@ -90,6 +102,7 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
int64_t min_rtt_us = 0; // Minimum RTT in microseconds.
int64_t srtt_us = 0; // Smoothed RTT in microseconds.
+ int64_t cwnd_bootstrapping_rtt_us = 0; // RTT used in cwnd_bootstrapping.
QuicByteCount max_packet_size = 0;
QuicByteCount max_received_packet_size = 0;
QuicBandwidth estimated_bandwidth = QuicBandwidth::Zero();
@@ -104,6 +117,9 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
// Maximum sequence reordering observed from acked packets.
QuicPacketCount sent_packets_max_sequence_reordering = 0;
+ // Number of times that a packet is not detected as lost per reordering_shift,
+ // but would have been if the reordering_shift increases by one.
+ QuicPacketCount sent_packets_num_borderline_time_reorderings = 0;
// The following stats are used only in TcpCubicSender.
// The number of loss events from TCP's perspective. Each loss event includes
@@ -136,6 +152,16 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionStats {
// Whether there is any non app-limited bandwidth sample.
bool has_non_app_limited_sample = false;
+
+ // Packet number of first decrypted packet.
+ QuicPacketNumber first_decrypted_packet;
+
+ // Max consecutive retransmission timeout before making forward progress.
+ size_t max_consecutive_rto_with_forward_progress = 0;
+
+ // Number of sent packets that were encapsulated using Legacy Version
+ // Encapsulation.
+ QuicPacketCount sent_legacy_version_encapsulated_packets = 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 24f233ef233..7fc45caefb3 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
@@ -18,6 +18,7 @@
#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_connection_id.h"
+#include "net/third_party/quiche/src/quic/core/quic_constants.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"
@@ -28,6 +29,7 @@
#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_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_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"
@@ -48,7 +50,6 @@ using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::DoAll;
-using testing::Exactly;
using testing::Ge;
using testing::IgnoreResult;
using testing::InSequence;
@@ -336,6 +337,11 @@ class TestAlarmFactory : public QuicAlarmFactory {
};
class TestPacketWriter : public QuicPacketWriter {
+ struct PacketBuffer {
+ QUIC_CACHELINE_ALIGNED char buffer[1500];
+ bool in_use = false;
+ };
+
public:
TestPacketWriter(ParsedQuicVersion version, MockClock* clock)
: version_(version),
@@ -344,16 +350,40 @@ class TestPacketWriter : public QuicPacketWriter {
QuicFramerPeer::SetLastSerializedServerConnectionId(framer_.framer(),
TestConnectionId());
framer_.framer()->SetInitialObfuscators(TestConnectionId());
+
+ for (int i = 0; i < 128; ++i) {
+ PacketBuffer* p = new PacketBuffer();
+ packet_buffer_pool_.push_back(p);
+ packet_buffer_pool_index_[p->buffer] = p;
+ packet_buffer_free_list_.push_back(p);
+ }
}
TestPacketWriter(const TestPacketWriter&) = delete;
TestPacketWriter& operator=(const TestPacketWriter&) = delete;
+ ~TestPacketWriter() override {
+ EXPECT_EQ(packet_buffer_pool_.size(), packet_buffer_free_list_.size())
+ << packet_buffer_pool_.size() - packet_buffer_free_list_.size()
+ << " out of " << packet_buffer_pool_.size()
+ << " packet buffers have been leaked.";
+ for (auto p : packet_buffer_pool_) {
+ delete p;
+ }
+ }
+
// QuicPacketWriter interface
WriteResult WritePacket(const char* buffer,
size_t buf_len,
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/,
PerPacketOptions* /*options*/) override {
+ // If the buffer is allocated from the pool, return it back to the pool.
+ // Note the buffer content doesn't change.
+ if (packet_buffer_pool_index_.find(const_cast<char*>(buffer)) !=
+ packet_buffer_pool_index_.end()) {
+ FreePacketBuffer(buffer);
+ }
+
QuicEncryptedPacket packet(buffer, buf_len);
++packets_write_attempts_;
@@ -440,10 +470,15 @@ class TestPacketWriter : public QuicPacketWriter {
bool IsBatchMode() const override { return is_batch_mode_; }
- char* GetNextWriteLocation(
+ QuicPacketBuffer GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) override {
- return nullptr;
+ if (GetQuicReloadableFlag(quic_avoid_leak_writer_buffer)) {
+ return {AllocPacketBuffer(),
+ [this](const char* p) { FreePacketBuffer(p); }};
+ }
+ // Do not use writer buffer for serializing packets.
+ return {nullptr, nullptr};
}
WriteResult Flush() override {
@@ -591,6 +626,23 @@ class TestPacketWriter : public QuicPacketWriter {
SimpleQuicFramer* framer() { return &framer_; }
private:
+ char* AllocPacketBuffer() {
+ PacketBuffer* p = packet_buffer_free_list_.front();
+ EXPECT_FALSE(p->in_use);
+ p->in_use = true;
+ packet_buffer_free_list_.pop_front();
+ return p->buffer;
+ }
+
+ void FreePacketBuffer(const char* buffer) {
+ auto iter = packet_buffer_pool_index_.find(const_cast<char*>(buffer));
+ ASSERT_TRUE(iter != packet_buffer_pool_index_.end());
+ PacketBuffer* p = iter->second;
+ ASSERT_TRUE(p->in_use);
+ p->in_use = false;
+ packet_buffer_free_list_.push_back(p);
+ }
+
ParsedQuicVersion version_;
SimpleQuicFramer framer_;
size_t last_packet_size_ = 0;
@@ -619,6 +671,12 @@ class TestPacketWriter : public QuicPacketWriter {
QuicTime::Delta write_pause_time_delta_ = QuicTime::Delta::Zero();
QuicByteCount max_packet_size_ = kMaxOutgoingPacketSize;
bool supports_release_time_ = false;
+ // Used to verify writer-allocated packet buffers are properly released.
+ std::vector<PacketBuffer*> packet_buffer_pool_;
+ // Buffer address => Address of the owning PacketBuffer.
+ QuicHashMap<char*, PacketBuffer*> packet_buffer_pool_index_;
+ // Indices in packet_buffer_pool_ that are not allocated.
+ std::list<PacketBuffer*> packet_buffer_free_list_;
};
class TestConnection : public QuicConnection {
@@ -739,7 +797,7 @@ class TestConnection : public QuicConnection {
// Ensures the connection can write stream data before writing.
QuicConsumedData EnsureWritableAndSendStreamData5() {
- EXPECT_TRUE(CanWriteStreamData());
+ EXPECT_TRUE(CanWrite(HAS_RETRANSMITTABLE_DATA));
return SendStreamData5();
}
@@ -1091,14 +1149,12 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
- EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber());
EXPECT_CALL(visitor_, OnCanWrite())
.WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
.WillRepeatedly(Return(false));
EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(AnyNumber());
- EXPECT_CALL(visitor_, OnForwardProgressConfirmed()).Times(AnyNumber());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged())
.Times(testing::AtMost(1));
@@ -1317,9 +1373,8 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
level);
}
- size_t ProcessCryptoPacketAtLevel(uint64_t number,
- EncryptionLevel /*level*/) {
- QuicPacketHeader header = ConstructPacketHeader(number, ENCRYPTION_INITIAL);
+ size_t ProcessCryptoPacketAtLevel(uint64_t number, EncryptionLevel level) {
+ QuicPacketHeader header = ConstructPacketHeader(number, level);
QuicFrames frames;
if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
frames.push_back(QuicFrame(&crypto_frame_));
@@ -1329,10 +1384,10 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
std::unique_ptr<QuicPacket> packet = ConstructPacket(header, frames);
char buffer[kMaxOutgoingPacketSize];
- peer_creator_.set_encryption_level(ENCRYPTION_INITIAL);
- size_t encrypted_length = peer_framer_.EncryptPayload(
- ENCRYPTION_INITIAL, QuicPacketNumber(number), *packet, buffer,
- kMaxOutgoingPacketSize);
+ peer_creator_.set_encryption_level(level);
+ size_t encrypted_length =
+ peer_framer_.EncryptPayload(level, QuicPacketNumber(number), *packet,
+ buffer, kMaxOutgoingPacketSize);
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
@@ -1694,6 +1749,9 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
void MtuDiscoveryTestInit() {
set_perspective(Perspective::IS_SERVER);
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ if (version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(&connection_);
+ }
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
// QuicFramer::GetMaxPlaintextSize uses the smallest max plaintext size
@@ -1712,9 +1770,21 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
EXPECT_TRUE(connection_.connected());
}
+ void PathProbeTestInit(Perspective perspective) {
+ set_perspective(perspective);
+ EXPECT_EQ(connection_.perspective(), perspective);
+ if (perspective == Perspective::IS_SERVER) {
+ QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ }
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ peer_creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+ }
+
void TestClientRetryHandling(bool invalid_retry_tag,
- bool missing_id_in_config,
- bool wrong_id_in_config);
+ bool missing_original_id_in_config,
+ bool wrong_original_id_in_config,
+ bool missing_retry_id_in_config,
+ bool wrong_retry_id_in_config);
QuicConnectionId connection_id_;
QuicFramer framer_;
@@ -1941,6 +2011,9 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
set_perspective(Perspective::IS_SERVER);
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+ if (version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(&connection_);
+ }
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2022,9 +2095,7 @@ TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
}
TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_SERVER);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2068,9 +2139,6 @@ TEST_P(QuicConnectionTest, ReceivePathProbeWithNoAddressChangeAtServer) {
// Regression test for b/150161358.
TEST_P(QuicConnectionTest, BufferedMtuPacketTooBig) {
- if (!GetQuicReloadableFlag(quic_ignore_msg_too_big_from_buffered_packets)) {
- return;
- }
EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
writer_->SetWriteBlocked();
@@ -2138,9 +2206,7 @@ TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
// in IETF version: receive a packet contains PATH CHALLENGE with peer address
// change.
TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_SERVER);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2278,9 +2344,7 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingWithPortChangeAtServer) {
}
TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_SERVER);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2336,9 +2400,7 @@ TEST_P(QuicConnectionTest, ReceiveReorderedPathProbingAtServer) {
}
TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_SERVER);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2393,8 +2455,7 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
TEST_P(QuicConnectionTest, ReceivePaddedPingAtClient) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- set_perspective(Perspective::IS_CLIENT);
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_CLIENT);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -2442,8 +2503,7 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingResponseAtClient) {
return;
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- set_perspective(Perspective::IS_CLIENT);
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_CLIENT);
// Clear direct_peer_address.
QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
@@ -3129,9 +3189,12 @@ TEST_P(QuicConnectionTest, BasicSending) {
if (connection_.SupportsMultiplePacketNumberSpaces()) {
return;
}
+ const QuicConnectionStats& stats = connection_.GetStats();
+ EXPECT_FALSE(stats.first_decrypted_packet.IsInitialized());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacket(1);
+ EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
QuicPacketNumber last_packet;
SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); // Packet 1
@@ -3215,6 +3278,7 @@ TEST_P(QuicConnectionTest, BasicSending) {
} else {
EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
}
+ EXPECT_EQ(QuicPacketNumber(1), stats.first_decrypted_packet);
}
// QuicConnection should record the packet sent-time prior to sending the
@@ -3480,8 +3544,7 @@ TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
// Processs a PING frame.
ProcessFramePacket(QuicFrame(QuicPingFrame()));
// Ensure that this has caused the ACK alarm to be set.
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
// Send data and ensure the ack is bundled.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(8);
@@ -3506,7 +3569,7 @@ TEST_P(QuicConnectionTest, LargeSendWithPendingAck) {
writer_->stream_frames()[0]->stream_id);
EXPECT_TRUE(writer_->stream_frames()[0]->fin);
// Ensure the ack alarm was cancelled when the ack was sent.
- EXPECT_FALSE(ack_alarm->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, OnCanWrite) {
@@ -4241,6 +4304,12 @@ TEST_P(QuicConnectionTest, TailLossProbeDelayForNonStreamDataInTLPR) {
options.push_back(kTLPR);
config.SetConnectionOptionsToSend(options);
QuicConfigPeer::SetNegotiated(&config, true);
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_.connection_id());
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_.connection_id());
+ }
connection_.SetFromConfig(config);
connection_.SetMaxTailLossProbes(1);
@@ -4414,47 +4483,6 @@ TEST_P(QuicConnectionTest, RtoWithNoDataToRetransmit) {
}
}
-TEST_P(QuicConnectionTest, RetransmitWithSameEncryptionLevel) {
- use_tagging_decrypter();
-
- // A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
- // the end of the packet. We can test this to check which encrypter was used.
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- QuicByteCount packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&packet_size));
- connection_.SendCryptoDataWithString("foo", 0);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
-
- connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
- EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-
- {
- InSequence s;
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, QuicPacketNumber(3), _, _));
- EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, QuicPacketNumber(4), _, _));
- }
-
- // Manually mark both packets for retransmission.
- connection_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
- if (!connection_.version().CanSendCoalescedPackets()) {
- // Packet should have been sent with ENCRYPTION_INITIAL.
- // If connection can send coalesced packet, both retransmissions will be
- // coalesced in the same UDP datagram.
- EXPECT_EQ(0x01010101u, writer_->final_bytes_of_previous_packet());
- }
-
- // Packet should have been sent with ENCRYPTION_ZERO_RTT.
- EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
-}
-
TEST_P(QuicConnectionTest, SendHandshakeMessages) {
use_tagging_decrypter();
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
@@ -4514,6 +4542,8 @@ TEST_P(QuicConnectionTest,
}
TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
+ SetQuicReloadableFlag(quic_do_not_retransmit_immediately_on_zero_rtt_reject,
+ true);
use_tagging_decrypter();
connection_.SetEncrypter(ENCRYPTION_INITIAL,
std::make_unique<TaggingEncrypter>(0x01));
@@ -4526,9 +4556,9 @@ TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-
- connection_.RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION);
+ EXPECT_FALSE(notifier_.HasLostStreamData());
+ connection_.RetransmitZeroRttPackets();
+ EXPECT_TRUE(notifier_.HasLostStreamData());
}
TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
@@ -4739,7 +4769,7 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -4794,7 +4824,7 @@ TEST_P(QuicConnectionTest, IdleTimeoutAfterFirstSentPacket) {
EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -4838,7 +4868,7 @@ TEST_P(QuicConnectionTest, IdleTimeoutAfterSendTwoPackets) {
EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -4885,7 +4915,7 @@ TEST_P(QuicConnectionTest, HandshakeTimeout) {
EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -5764,6 +5794,12 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
config.ProcessPeerHello(msg, CLIENT, &error_details);
EXPECT_THAT(error, IsQuicNoError());
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_.connection_id());
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_.connection_id());
+ }
connection_.SetFromConfig(config);
const QuicTime::Delta default_idle_timeout =
@@ -5910,6 +5946,12 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
config.ProcessPeerHello(msg, CLIENT, &error_details);
EXPECT_THAT(error, IsQuicNoError());
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_.connection_id());
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_.connection_id());
+ }
connection_.SetFromConfig(config);
const QuicTime::Delta default_idle_timeout =
@@ -6074,6 +6116,16 @@ TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
connection_options.push_back(k5RTO);
config.SetConnectionOptionsToSend(connection_options);
QuicConfigPeer::SetNegotiated(&config, true);
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ }
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_.connection_id());
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_.connection_id());
+ }
connection_.SetFromConfig(config);
// Send stream data.
@@ -6212,7 +6264,7 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPacketsWithTruncation) {
TEST_P(QuicConnectionTest, SendDelayedAck) {
QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6227,7 +6279,7 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Simulate delayed ack alarm firing.
clock_.AdvanceTime(DefaultDelayedAckTime());
@@ -6242,7 +6294,7 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
@@ -6251,7 +6303,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
// The beginning of the connection counts as quiescence.
QuicTime ack_time = clock_.ApproximateNow() + kAlarmGranularity;
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6266,7 +6318,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Simulate delayed ack alarm firing.
clock_.AdvanceTime(DefaultDelayedAckTime());
@@ -6281,7 +6333,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Process another packet immedately after sending the ack and expect the
// ack alarm to be set delayed ack time in the future.
@@ -6290,7 +6342,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Simulate delayed ack alarm firing.
clock_.AdvanceTime(DefaultDelayedAckTime());
@@ -6305,7 +6357,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Wait 1 second and ensure the ack alarm is set to 1ms in the future.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -6314,7 +6366,7 @@ TEST_P(QuicConnectionTest, SendDelayedAfterQuiescence) {
ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
}
@@ -6331,7 +6383,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6346,7 +6398,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6354,12 +6406,12 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6374,7 +6426,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
@@ -6391,7 +6443,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
QuicTime ack_time =
clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6406,7 +6458,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Simulate delayed ack alarm firing.
clock_.AdvanceTime(DefaultDelayedAckTime());
@@ -6421,7 +6473,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Process another packet immedately after sending the ack and expect the
// ack alarm to be set delayed ack time in the future.
@@ -6430,7 +6482,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Simulate delayed ack alarm firing.
clock_.AdvanceTime(DefaultDelayedAckTime());
@@ -6445,7 +6497,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Wait 1 second and enesure the ack alarm is set to 1ms in the future.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -6454,7 +6506,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Process enough packets to get into ack decimation behavior.
@@ -6467,7 +6519,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(4 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6475,12 +6527,12 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6495,7 +6547,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Wait 1 second and enesure the ack alarm is set to 1ms in the future.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -6505,7 +6557,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckAckDecimationAfterQuiescence) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
}
@@ -6529,7 +6581,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6544,7 +6596,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6552,19 +6604,19 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// 18 packets will not cause an ack to be sent. 19 will because when
// stop waiting frames are in use, we ack every 20 packets no matter what.
for (int i = 0; i < 18; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
}
// The delayed ack timer should still be set to the expected deadline.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
}
@@ -6582,7 +6634,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6597,7 +6649,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6605,12 +6657,12 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6625,7 +6677,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
@@ -6641,7 +6693,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6656,7 +6708,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Receive one packet out of order and then the rest in order.
// The loop leaves a one packet gap between acks sent to simulate some loss.
@@ -6666,13 +6718,13 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9 + (j * 11),
!kHasStopWaiting, ENCRYPTION_ZERO_RTT);
ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
writer_->Reset();
for (int i = 0; i < 9; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
// The ACK shouldn't be sent until the 10th packet is processed.
EXPECT_TRUE(writer_->ack_frames().empty());
@@ -6689,7 +6741,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
}
@@ -6706,7 +6758,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6721,7 +6773,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6729,7 +6781,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Process packet 10 first and ensure the alarm is one eighth min_rtt.
@@ -6737,12 +6789,12 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 19, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 8; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6756,11 +6808,11 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The next packet received in order will cause an immediate ack,
// because it fills a hole.
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 10, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6773,7 +6825,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
@@ -6790,7 +6842,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6805,7 +6857,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6813,7 +6865,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Process packet 10 first and ensure the alarm is one eighth min_rtt.
@@ -6821,12 +6873,12 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 8; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6841,7 +6893,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest,
@@ -6859,7 +6911,7 @@ TEST_P(QuicConnectionTest,
QuicTime ack_time = clock_.ApproximateNow() +
QuicTime::Delta::FromMilliseconds(kMinRttMs / 8);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
const uint8_t tag = 0x07;
SetDecrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<StrictTaggingDecrypter>(tag));
@@ -6874,7 +6926,7 @@ TEST_P(QuicConnectionTest,
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The same as ProcessPacket(1) except that ENCRYPTION_ZERO_RTT is used
// instead of ENCRYPTION_INITIAL.
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
@@ -6882,7 +6934,7 @@ TEST_P(QuicConnectionTest,
ENCRYPTION_ZERO_RTT);
// Check if delayed ack timer is running for the expected interval.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Process packet 10 first and ensure the alarm is one eighth min_rtt.
@@ -6890,12 +6942,12 @@ TEST_P(QuicConnectionTest,
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 19, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// The 10th received packet causes an ack to be sent.
for (int i = 0; i < 8; ++i) {
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6909,11 +6961,11 @@ TEST_P(QuicConnectionTest,
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// The next packet received in order will cause an immediate ack,
// because it fills a hole.
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacketAtLevel(kFirstDecimatedPacket + 10, !kHasStopWaiting,
ENCRYPTION_ZERO_RTT);
@@ -6926,27 +6978,27 @@ TEST_P(QuicConnectionTest,
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessPacket(1);
// Check that ack is sent and that delayed ack alarm is set.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Completing the handshake as the server does nothing.
QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_SERVER);
connection_.OnHandshakeComplete();
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
// Complete the handshake as the client decreases the delayed ack time to 0ms.
QuicConnectionPeer::SetPerspective(&connection_, Perspective::IS_CLIENT);
connection_.OnHandshakeComplete();
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
if (connection_.SupportsMultiplePacketNumberSpaces()) {
EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
connection_.GetAckAlarm()->deadline());
@@ -6969,7 +7021,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
@@ -7001,7 +7053,7 @@ TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
ProcessPacket(6);
padding_frame_count = writer_->padding_frames().size();
EXPECT_EQ(padding_frame_count, writer_->frame_count());
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
@@ -7025,7 +7077,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
@@ -7045,7 +7097,7 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
EXPECT_EQ(4u, writer_->frame_count());
EXPECT_FALSE(writer_->stop_waiting_frames().empty());
}
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
@@ -7053,17 +7105,29 @@ TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
ProcessPacket(1);
BlockOnNextWrite();
writer_->set_is_write_blocked_data_buffered(true);
+ if (GetQuicReloadableFlag(quic_move_amplification_limit) &&
+ QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+ }
connection_.SendCryptoDataWithString("foo", 0);
EXPECT_TRUE(writer_->IsWriteBlocked());
EXPECT_FALSE(connection_.HasQueuedData());
connection_.SendCryptoDataWithString("bar", 3);
EXPECT_TRUE(writer_->IsWriteBlocked());
- EXPECT_TRUE(connection_.HasQueuedData());
+ if (GetQuicReloadableFlag(quic_move_amplification_limit) &&
+ QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ // CRYPTO frames are not flushed when writer is blocked.
+ EXPECT_FALSE(connection_.HasQueuedData());
+ } else {
+ EXPECT_TRUE(connection_.HasQueuedData());
+ }
}
TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
EXPECT_CALL(visitor_, OnCanWrite())
.WillOnce(IgnoreResult(InvokeWithoutArgs(
&connection_, &TestConnection::SendCryptoStreamData)));
@@ -7092,12 +7156,12 @@ TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
EXPECT_EQ(1u, writer_->padding_frames().size());
ASSERT_FALSE(writer_->ack_frames().empty());
EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Process two packets from the crypto stream, which is frame1_'s default,
// simulating a 2 packet reject.
@@ -7136,7 +7200,7 @@ TEST_P(QuicConnectionTest, BundleAckForSecondCHLOTwoPacketReject) {
EXPECT_EQ(1u, writer_->padding_frames().size());
ASSERT_FALSE(writer_->ack_frames().empty());
EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
@@ -7171,7 +7235,7 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
// Check that no packet is sent and the ack alarm isn't set.
EXPECT_EQ(0u, writer_->frame_count());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
writer_->Reset();
// Send the same ack, but send both data and an ack together.
@@ -7199,7 +7263,7 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
LargestAcked(writer_->ack_frames().front()));
}
EXPECT_EQ(1u, writer_->stream_frames().size());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, NoAckSentForClose) {
@@ -7221,7 +7285,7 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) {
connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
ConnectionCloseBehavior::SILENT_CLOSE);
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.CanWriteStreamData());
+ EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
std::unique_ptr<QuicPacket> packet =
ConstructDataPacket(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
@@ -7245,7 +7309,7 @@ TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
ConnectionCloseBehavior::SILENT_CLOSE);
EXPECT_FALSE(connection_.connected());
- EXPECT_FALSE(connection_.CanWriteStreamData());
+ EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
.Times(0);
@@ -7260,7 +7324,7 @@ TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
}
TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_CLIENT);
TestPacketWriter probing_writer(version(), &clock_);
// Block next write so that sending connectivity probe will encounter a
// blocked write when send a connectivity probe to the peer.
@@ -7276,8 +7340,7 @@ TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
}
TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ PathProbeTestInit(Perspective::IS_SERVER);
// Block next write so that sending connectivity probe will encounter a
// blocked write when send a connectivity probe to the peer.
@@ -7293,7 +7356,7 @@ TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
}
TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
- EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ PathProbeTestInit(Perspective::IS_CLIENT);
TestPacketWriter probing_writer(version(), &clock_);
probing_writer.SetShouldWriteFail();
@@ -7308,8 +7371,7 @@ TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
}
TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
- set_perspective(Perspective::IS_SERVER);
- QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ PathProbeTestInit(Perspective::IS_SERVER);
writer_->SetShouldWriteFail();
// Connection should not be closed if a connectivity probe is failed to be
@@ -7356,6 +7418,7 @@ TEST_P(QuicConnectionTest, IetfStatelessReset) {
kTestStatelessResetToken));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*packet, QuicTime::Zero()));
+ EXPECT_CALL(visitor_, ValidateStatelessReset(_, _)).WillOnce(Return(true));
EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_PEER))
.WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
@@ -7629,6 +7692,7 @@ TEST_P(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
}
TEST_P(QuicConnectionTest, OnPacketSentDebugVisitor) {
+ PathProbeTestInit(Perspective::IS_CLIENT);
MockQuicConnectionDebugVisitor debug_visitor;
connection_.set_debug_visitor(&debug_visitor);
@@ -7681,8 +7745,7 @@ TEST_P(QuicConnectionTest, WindowUpdateInstigateAcks) {
ProcessFramePacket(QuicFrame(window_update));
// Ensure that this has caused the ACK alarm to be set.
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
@@ -7695,8 +7758,7 @@ TEST_P(QuicConnectionTest, BlockedFrameInstigateAcks) {
ProcessFramePacket(QuicFrame(blocked));
// Ensure that this has caused the ACK alarm to be set.
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, ReevaluateTimeUntilSendOnAck) {
@@ -7838,32 +7900,8 @@ TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
connection_.GetRetransmissionAlarm()->Fire();
}
-TEST_P(QuicConnectionTest, PathDegradingAlarmForCryptoPacket) {
- EXPECT_TRUE(connection_.connected());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendCryptoStreamData();
-
- EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- EXPECT_FALSE(connection_.IsPathDegrading());
- QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
- ->GetPathDegradingDelay();
- EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
- clock_.ApproximateNow());
-
- // Fire the path degrading alarm, path degrading signal should be sent to
- // the visitor.
- EXPECT_CALL(visitor_, OnPathDegrading());
- clock_.AdvanceTime(delay);
- connection_.PathDegradingTimeout();
- EXPECT_TRUE(connection_.IsPathDegrading());
- EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
-}
-
// Includes regression test for b/69979024.
-TEST_P(QuicConnectionTest, PathDegradingAlarmForNonCryptoPackets) {
+TEST_P(QuicConnectionTest, PathDegradingDetectionForNonCryptoPackets) {
EXPECT_TRUE(connection_.connected());
EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
EXPECT_FALSE(connection_.IsPathDegrading());
@@ -7874,21 +7912,21 @@ TEST_P(QuicConnectionTest, PathDegradingAlarmForNonCryptoPackets) {
for (int i = 0; i < 2; ++i) {
// Send a packet. Now there's a retransmittable packet on the wire, so the
- // path degrading alarm should be set.
+ // path degrading detection should be set.
connection_.SendStreamDataWithString(
GetNthClientInitiatedStreamId(1, connection_.transport_version()), data,
offset, NO_FIN);
offset += data_size;
EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
+ // Check the deadline of the path degrading detection.
QuicTime::Delta delay =
QuicConnectionPeer::GetSentPacketManager(&connection_)
->GetPathDegradingDelay();
EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
clock_.ApproximateNow());
- // Send a second packet. The path degrading alarm's deadline should remain
- // the same.
+ // Send a second packet. The path degrading detection's deadline should
+ // remain the same.
// Regression test for b/69979024.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
QuicTime prev_deadline =
@@ -7902,7 +7940,7 @@ TEST_P(QuicConnectionTest, PathDegradingAlarmForNonCryptoPackets) {
connection_.GetBlackholeDetectorAlarm()->deadline());
// Now receive an ACK of the first packet. This should advance the path
- // degrading alarm's deadline since forward progress has been made.
+ // degrading detection's deadline since forward progress has been made.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
if (i == 0) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -7912,7 +7950,7 @@ TEST_P(QuicConnectionTest, PathDegradingAlarmForNonCryptoPackets) {
{{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
ProcessAckPacket(&frame);
EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
+ // Check the deadline of the path degrading detection.
delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
->GetPathDegradingDelay();
EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
@@ -7921,7 +7959,7 @@ TEST_P(QuicConnectionTest, PathDegradingAlarmForNonCryptoPackets) {
if (i == 0) {
// Now receive an ACK of the second packet. Since there are no more
// retransmittable packets on the wire, this should cancel the path
- // degrading alarm.
+ // degrading detection.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
@@ -8010,7 +8048,7 @@ TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPingAlarm) {
// This test verifies that the connection marks path as degrading and does not
// spin timer to detect path degrading when a new packet is sent on the
// degraded path.
-TEST_P(QuicConnectionTest, NoPathDegradingAlarmIfPathIsDegrading) {
+TEST_P(QuicConnectionTest, NoPathDegradingDetectionIfPathIsDegrading) {
EXPECT_TRUE(connection_.connected());
EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
EXPECT_FALSE(connection_.IsPathDegrading());
@@ -8024,13 +8062,13 @@ TEST_P(QuicConnectionTest, NoPathDegradingAlarmIfPathIsDegrading) {
connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
offset += data_size;
EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
- // Check the deadline of the path degrading alarm.
+ // Check the deadline of the path degrading detection.
QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
->GetPathDegradingDelay();
EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
clock_.ApproximateNow());
- // Send a second packet. The path degrading alarm's deadline should remain
+ // Send a second packet. The path degrading detection's deadline should remain
// the same.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
QuicTime prev_deadline = connection_.GetBlackholeDetectorAlarm()->deadline();
@@ -8040,7 +8078,7 @@ TEST_P(QuicConnectionTest, NoPathDegradingAlarmIfPathIsDegrading) {
EXPECT_EQ(prev_deadline, connection_.GetBlackholeDetectorAlarm()->deadline());
// Now receive an ACK of the first packet. This should advance the path
- // degrading alarm's deadline since forward progress has been made.
+ // degrading detection's deadline since forward progress has been made.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -8054,8 +8092,8 @@ TEST_P(QuicConnectionTest, NoPathDegradingAlarmIfPathIsDegrading) {
EXPECT_EQ(delay, connection_.GetBlackholeDetectorAlarm()->deadline() -
clock_.ApproximateNow());
- // Advance time to the path degrading alarm's deadline and simulate
- // firing the path degrading alarm. This path will be considered as
+ // Advance time to the path degrading detection's deadline and simulate
+ // firing the path degrading detection. This path will be considered as
// degrading.
clock_.AdvanceTime(delay);
EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
@@ -8065,7 +8103,7 @@ TEST_P(QuicConnectionTest, NoPathDegradingAlarmIfPathIsDegrading) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
- // Send a third packet. The path degrading alarm is no longer set but path
+ // Send a third packet. The path degrading detection is no longer set but path
// should still be marked as degrading.
connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
offset += data_size;
@@ -8141,6 +8179,7 @@ TEST_P(QuicConnectionTest, UnmarkPathDegradingOnForwardProgress) {
// degrading. And will set a timer to detect new path degrading.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
ProcessAckPacket(&frame);
EXPECT_FALSE(connection_.IsPathDegrading());
@@ -8382,8 +8421,7 @@ TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Send an ack by simulating delayed ack alarm firing.
ProcessPacket(1);
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
connection_.GetAckAlarm()->Fire();
// Simulate data packet causes write error.
EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
@@ -8973,45 +9011,6 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
}
-TEST_P(QuicConnectionTest, OnForwardProgressConfirmed) {
- EXPECT_CALL(visitor_, OnForwardProgressConfirmed()).Times(Exactly(0));
- EXPECT_TRUE(connection_.connected());
-
- const char data[] = "data";
- size_t data_size = strlen(data);
- QuicStreamOffset offset = 0;
-
- // Send two packets.
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
- connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
- offset += data_size;
-
- // Ack packet 1. This increases the largest_acked to 1, so
- // OnForwardProgressConfirmed() should be called
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
-
- // Ack packet 1 again. largest_acked remains at 1, so
- // OnForwardProgressConfirmed() should not be called.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
- ProcessAckPacket(&frame);
-
- // Ack packet 2. This increases the largest_acked to 2, so
- // OnForwardProgressConfirmed() should be called.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
- frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
- ProcessAckPacket(&frame);
-}
-
TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
const QuicUint128 kTestToken = 1010101;
const QuicUint128 kWrongTestToken = 1010100;
@@ -9231,6 +9230,102 @@ TEST_P(QuicConnectionTest, PathChallengeResponse) {
sizeof(challenge_data)));
}
+TEST_P(QuicConnectionTest,
+ RestartPathDegradingDetectionAfterMigrationWithProbe) {
+ // TODO(b/150095484): add test coverage for IETF to verify that client takes
+ // PATH RESPONSE with peer address change as correct validation on the new
+ // path.
+ if (GetParam().version.HasIetfQuicFrames()) {
+ return;
+ }
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ PathProbeTestInit(Perspective::IS_CLIENT);
+
+ // Clear direct_peer_address and effective_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+ .WillRepeatedly(Return(true));
+ EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+ EXPECT_FALSE(connection_.IsPathDegrading());
+ EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ } else {
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ }
+ ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
+ kPeerAddress);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+ // Send data and verify the path degrading detection is set.
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+
+ // Verify the path degrading detection is in progress.
+ EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+ EXPECT_FALSE(connection_.IsPathDegrading());
+ QuicTime ddl = connection_.GetBlackholeDetectorAlarm()->deadline();
+
+ // Simulate the firing of path degrading.
+ clock_.AdvanceTime(ddl - clock_.ApproximateNow());
+ EXPECT_CALL(visitor_, OnPathDegrading()).Times(1);
+ connection_.PathDegradingTimeout();
+ EXPECT_TRUE(connection_.IsPathDegrading());
+ EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+ // Simulate path degrading handling by sending a probe on an alternet path.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ TestPacketWriter probing_writer(version(), &clock_);
+ connection_.SendConnectivityProbingPacket(&probing_writer,
+ connection_.peer_address());
+ // Verify that path degrading detection is not reset.
+ EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
+
+ // Simulate successful path degrading handling by receiving probe response.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
+
+ if (!GetParam().version.HasIetfQuicFrames()) {
+ EXPECT_CALL(visitor_,
+ OnPacketReceived(_, _, /*is_connectivity_probe=*/true))
+ .Times(1);
+ } else {
+ EXPECT_CALL(visitor_, OnPacketReceived(_, _, _)).Times(0);
+ }
+ const QuicSocketAddress kNewSelfAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+
+ std::unique_ptr<SerializedPacket> probing_packet = ConstructProbingPacket();
+ std::unique_ptr<QuicReceivedPacket> received(ConstructReceivedPacket(
+ QuicEncryptedPacket(probing_packet->encrypted_buffer,
+ probing_packet->encrypted_length),
+ clock_.Now()));
+ uint64_t num_probing_received =
+ connection_.GetStats().num_connectivity_probing_received;
+ ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+
+ EXPECT_EQ(num_probing_received + 1,
+ connection_.GetStats().num_connectivity_probing_received);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ EXPECT_TRUE(connection_.IsPathDegrading());
+
+ // Verify new path degrading detection is activated.
+ EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
+ connection_.OnSuccessfulMigrationAfterProbing();
+ EXPECT_FALSE(connection_.IsPathDegrading());
+ EXPECT_TRUE(connection_.PathDegradingDetectionInProgress());
+}
+
// Regression test for b/110259444
TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -9238,9 +9333,8 @@ TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
writer_->SetWriteBlocked();
ProcessPacket(1);
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
// Verify ack alarm is set.
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
// Fire the ack alarm, verify no packet is sent because the writer is blocked.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
connection_.GetAckAlarm()->Fire();
@@ -9249,7 +9343,7 @@ TEST_P(QuicConnectionTest, DoNotScheduleSpuriousAckAlarm) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
ProcessPacket(2);
// Verify ack alarm is not set.
- EXPECT_FALSE(ack_alarm->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, DisablePacingOffloadConnectionOptions) {
@@ -9428,7 +9522,7 @@ TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
use_tagging_decrypter();
// Receives packet 1000 in initial data.
ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<TaggingEncrypter>(0x02));
SetDecrypter(ENCRYPTION_ZERO_RTT,
@@ -9437,13 +9531,13 @@ TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
std::make_unique<TaggingEncrypter>(0x02));
// Receives packet 1000 in application data.
ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
connection_.SendApplicationDataAtLevel(ENCRYPTION_ZERO_RTT, 5, "data", 0,
NO_FIN);
// Verify application data ACK gets bundled with outgoing data.
EXPECT_EQ(2u, writer_->frame_count());
// Make sure ACK alarm is still set because initial data is not ACKed.
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
// Receive packet 1001 in application data.
ProcessDataPacketAtLevel(1001, false, ENCRYPTION_ZERO_RTT);
clock_.AdvanceTime(DefaultRetransmissionTime());
@@ -9452,10 +9546,10 @@ TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
std::make_unique<TaggingEncrypter>(0x02));
connection_.GetAckAlarm()->Fire();
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
// Receives more packets in application data.
ProcessDataPacketAtLevel(1002, false, ENCRYPTION_ZERO_RTT);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
std::make_unique<TaggingEncrypter>(0x02));
@@ -9464,7 +9558,7 @@ TEST_P(QuicConnectionTest, MultiplePacketNumberSpacesBasicReceiving) {
// Verify zero rtt and forward secure packets get acked in the same packet.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
ProcessDataPacket(1003);
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
@@ -9479,7 +9573,7 @@ TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
use_tagging_decrypter();
// Receives packet 1000 in initial data.
ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
std::make_unique<TaggingEncrypter>(0x02));
SetDecrypter(ENCRYPTION_ZERO_RTT,
@@ -9488,7 +9582,7 @@ TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
std::make_unique<TaggingEncrypter>(0x02));
// Receives packet 1000 in application data.
ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
- EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
writer_->SetWriteBlocked();
EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AnyNumber());
@@ -9500,13 +9594,13 @@ TEST_P(QuicConnectionTest, CancelAckAlarmOnWriteBlocked) {
std::make_unique<TaggingEncrypter>(0x02));
connection_.GetAckAlarm()->Fire();
// Verify ACK alarm is not set.
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
writer_->SetWritable();
// Verify 2 ACKs are sent when connection gets unblocked.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
connection_.OnCanWrite();
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
// Make sure a packet received with the right client connection ID is processed.
@@ -9618,12 +9712,11 @@ TEST_P(QuicConnectionTest, CheckConnectedBeforeFlush) {
}
ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
kPeerAddress);
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_TRUE(connection_.HasPendingAcks());
ProcessFramePacketWithAddresses(QuicFrame(connection_close_frame.release()),
kSelfAddress, kPeerAddress);
// Verify ack alarm is not set.
- EXPECT_FALSE(ack_alarm->IsSet());
+ EXPECT_FALSE(connection_.HasPendingAcks());
}
// Verify that a packet containing three coalesced packets is parsed correctly.
@@ -9861,8 +9954,18 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
connection_options.push_back(k6PTO);
config.SetConnectionOptionsToSend(connection_options);
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);
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ }
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
// Send stream data.
@@ -9902,8 +10005,18 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
connection_options.push_back(k7PTO);
config.SetConnectionOptionsToSend(connection_options);
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);
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ }
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
// Send stream data.
@@ -9941,9 +10054,19 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter8ClientPTOs) {
connection_options.push_back(k2PTO);
connection_options.push_back(k8PTO);
QuicConfigPeer::SetNegotiated(&config, true);
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_.connection_id());
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_.connection_id());
+ }
config.SetConnectionOptionsToSend(connection_options);
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
connection_.SetFromConfig(config);
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ }
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
// Send stream data.
@@ -10009,7 +10132,7 @@ TEST_P(QuicConnectionTest, DeprecateHandshakeMode) {
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);
+ EXPECT_EQ(1u, connection_.GetStats().crypto_retransmit_count);
EXPECT_EQ(1u, writer_->ping_frames().size());
}
@@ -10023,13 +10146,17 @@ TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
// Verify no data can be sent at the beginning because bytes received is 0.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
connection_.SendCryptoDataWithString("foo", 0);
+ if (GetQuicReloadableFlag(quic_move_amplification_limit)) {
+ EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+ EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+ }
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
// Receives packet 1.
ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
const size_t anti_amplification_factor =
- GetQuicFlag(FLAGS_quic_anti_amplification_factor);
+ connection_.anti_amplification_factor();
// Verify now packets can be sent.
for (size_t i = 0; i < anti_amplification_factor; ++i) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
@@ -10064,6 +10191,48 @@ TEST_P(QuicConnectionTest, AntiAmplificationLimit) {
}
}
+TEST_P(QuicConnectionTest, AckPendingWithAmplificationLimited) {
+ if (!connection_.version().SupportsAntiAmplificationLimit() ||
+ !GetQuicReloadableFlag(quic_move_amplification_limit)) {
+ return;
+ }
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+ set_perspective(Perspective::IS_SERVER);
+ use_tagging_decrypter();
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ // Receives packet 1.
+ ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ // Send response in different encryption level and cause amplification factor
+ // throttled.
+ size_t i = 0;
+ while (connection_.CanWrite(HAS_RETRANSMITTABLE_DATA)) {
+ connection_.SendCryptoDataWithString(std::string(1024, 'a'), i * 1024,
+ ENCRYPTION_HANDSHAKE);
+ ++i;
+ }
+ // Verify ACK is still pending.
+ EXPECT_TRUE(connection_.HasPendingAcks());
+
+ // Fire ACK alarm and verify ACK cannot be sent due to amplification factor.
+ clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+ connection_.GetAckAlarm()->Fire();
+ // Verify ACK alarm is cancelled.
+ EXPECT_FALSE(connection_.HasPendingAcks());
+
+ // Receives packet 2 and verify ACK gets flushed.
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+ EXPECT_FALSE(writer_->ack_frames().empty());
+}
+
TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
if (!VersionHasIetfQuicFrames(version().transport_version)) {
// Test relevent only for IETF QUIC.
@@ -10202,6 +10371,49 @@ TEST_P(QuicConnectionTest, SendCoalescedPackets) {
EXPECT_NE(nullptr, writer_->coalesced_packet());
}
+TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
+ connection_.EnableLegacyVersionEncapsulation("test.example.org");
+
+ MockQuicConnectionDebugVisitor debug_visitor;
+ connection_.set_debug_visitor(&debug_visitor);
+ EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _)).Times(1);
+
+ // Our TestPacketWriter normally parses the sent packet using the version
+ // from the connection, so here we need to tell it to use the encapsulation
+ // version, and reset the initial decrypter for that version.
+ writer_->framer()->SetSupportedVersions(
+ SupportedVersions(LegacyVersionForEncapsulation()));
+ writer_->framer()->framer()->SetInitialObfuscators(
+ connection_.connection_id());
+
+ {
+ QuicConnection::ScopedPacketFlusher flusher(&connection_);
+ connection_.SendCryptoDataWithString("TEST_CRYPTO_DATA", /*offset=*/0);
+ }
+
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+ // Verify that the packet is fully padded.
+ EXPECT_EQ(connection_.max_packet_length(), writer_->last_packet_size());
+
+ // Check that the connection stats show Legacy Version Encapsulation was used.
+ EXPECT_GT(connection_.GetStats().sent_legacy_version_encapsulated_packets,
+ 0u);
+
+ // Verify that the sent packet was in fact encapsulated, and check header.
+ const QuicPacketHeader& encapsulated_header = writer_->last_packet_header();
+ EXPECT_TRUE(encapsulated_header.version_flag);
+ EXPECT_EQ(encapsulated_header.version, LegacyVersionForEncapsulation());
+ EXPECT_EQ(encapsulated_header.destination_connection_id,
+ connection_.connection_id());
+
+ // Encapsulated packet should contain a stream frame for the crypto stream,
+ // optionally padding, and nothing else.
+ EXPECT_EQ(0u, writer_->crypto_frames().size());
+ EXPECT_EQ(1u, writer_->stream_frames().size());
+ EXPECT_EQ(writer_->frame_count(), writer_->framer()->padding_frames().size() +
+ writer_->stream_frames().size());
+}
+
TEST_P(QuicConnectionTest, ClientReceivedHandshakeDone) {
if (!connection_.version().HasHandshakeDone()) {
return;
@@ -10299,14 +10511,20 @@ TEST_P(QuicConnectionTest, MultiplePacketNumberSpacePto) {
EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
}
-void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
- bool missing_id_in_config,
- bool wrong_id_in_config) {
+void QuicConnectionTest::TestClientRetryHandling(
+ bool invalid_retry_tag,
+ bool missing_original_id_in_config,
+ bool wrong_original_id_in_config,
+ bool missing_retry_id_in_config,
+ bool wrong_retry_id_in_config) {
if (invalid_retry_tag) {
- ASSERT_FALSE(missing_id_in_config);
- ASSERT_FALSE(wrong_id_in_config);
+ ASSERT_FALSE(missing_original_id_in_config);
+ ASSERT_FALSE(wrong_original_id_in_config);
+ ASSERT_FALSE(missing_retry_id_in_config);
+ ASSERT_FALSE(wrong_retry_id_in_config);
} else {
- ASSERT_FALSE(missing_id_in_config && wrong_id_in_config);
+ ASSERT_FALSE(missing_original_id_in_config && wrong_original_id_in_config);
+ ASSERT_FALSE(missing_retry_id_in_config && wrong_retry_id_in_config);
}
if (!version().HasRetryIntegrityTag()) {
return;
@@ -10321,15 +10539,20 @@ void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
0xff, 0xff, 0x00, 0x00, 0x1b, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xa5, 0x23, 0xcb, 0x5b,
0xa5, 0x24, 0x69, 0x5f, 0x65, 0x69, 0xf2, 0x93, 0xa1, 0x35, 0x9d, 0x8e};
+ char retry_packet29[] = {
+ 0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+ 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
+ 0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
char* retry_packet;
size_t retry_packet_length;
- if (version() ==
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27)) {
+ if (version() == ParsedQuicVersion::Draft29()) {
+ retry_packet = retry_packet29;
+ retry_packet_length = QUICHE_ARRAYSIZE(retry_packet29);
+ } else if (version() == ParsedQuicVersion::Draft27()) {
retry_packet = retry_packet27;
retry_packet_length = QUICHE_ARRAYSIZE(retry_packet27);
- } else if (version() ==
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25)) {
+ } else if (version() == ParsedQuicVersion::Draft25()) {
retry_packet = retry_packet25;
retry_packet_length = QUICHE_ARRAYSIZE(retry_packet25);
} else {
@@ -10360,11 +10583,17 @@ void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
}
QuicConnectionId config_original_connection_id = original_connection_id;
- if (wrong_id_in_config) {
+ if (wrong_original_id_in_config) {
// Flip the first bit of the connection ID.
ASSERT_FALSE(config_original_connection_id.IsEmpty());
config_original_connection_id.mutable_data()[0] ^= 0x80;
}
+ QuicConnectionId config_retry_source_connection_id = new_connection_id;
+ if (wrong_retry_id_in_config) {
+ // Flip the first bit of the connection ID.
+ ASSERT_FALSE(config_retry_source_connection_id.IsEmpty());
+ config_retry_source_connection_id.mutable_data()[0] ^= 0x80;
+ }
// Make sure the connection uses the connection ID from the test vectors,
QuicConnectionPeer::SetServerConnectionId(&connection_,
@@ -10397,11 +10626,21 @@ void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
// Test validating the original_connection_id from the config.
QuicConfig received_config;
QuicConfigPeer::SetNegotiated(&received_config, true);
- if (!missing_id_in_config) {
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &received_config, connection_.connection_id());
+ if (!missing_retry_id_in_config) {
+ QuicConfigPeer::SetReceivedRetrySourceConnectionId(
+ &received_config, config_retry_source_connection_id);
+ }
+ }
+ if (!missing_original_id_in_config) {
QuicConfigPeer::SetReceivedOriginalConnectionId(
&received_config, config_original_connection_id);
}
- if (missing_id_in_config || wrong_id_in_config) {
+
+ if (missing_original_id_in_config || wrong_original_id_in_config ||
+ missing_retry_id_in_config || wrong_retry_id_in_config) {
EXPECT_CALL(visitor_,
OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
.Times(1);
@@ -10412,8 +10651,9 @@ void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
}
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
connection_.SetFromConfig(received_config);
- if (missing_id_in_config || wrong_id_in_config) {
- EXPECT_FALSE(connection_.connected());
+ if (missing_original_id_in_config || wrong_original_id_in_config ||
+ missing_retry_id_in_config || wrong_retry_id_in_config) {
+ ASSERT_FALSE(connection_.connected());
TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
} else {
EXPECT_TRUE(connection_.connected());
@@ -10422,31 +10662,74 @@ void QuicConnectionTest::TestClientRetryHandling(bool invalid_retry_tag,
TEST_P(QuicConnectionTest, ClientParsesRetry) {
TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_id_in_config=*/false,
- /*wrong_id_in_config=*/false);
+ /*missing_original_id_in_config=*/false,
+ /*wrong_original_id_in_config=*/false,
+ /*missing_retry_id_in_config=*/false,
+ /*wrong_retry_id_in_config=*/false);
}
-TEST_P(QuicConnectionTest, ClientParsesInvalidRetry) {
+TEST_P(QuicConnectionTest, ClientParsesRetryInvalidTag) {
TestClientRetryHandling(/*invalid_retry_tag=*/true,
- /*missing_id_in_config=*/false,
- /*wrong_id_in_config=*/false);
+ /*missing_original_id_in_config=*/false,
+ /*wrong_original_id_in_config=*/false,
+ /*missing_retry_id_in_config=*/false,
+ /*wrong_retry_id_in_config=*/false);
}
-TEST_P(QuicConnectionTest, ClientParsesRetryMissingId) {
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingOriginalId) {
TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_id_in_config=*/true,
- /*wrong_id_in_config=*/false);
+ /*missing_original_id_in_config=*/true,
+ /*wrong_original_id_in_config=*/false,
+ /*missing_retry_id_in_config=*/false,
+ /*wrong_retry_id_in_config=*/false);
}
-TEST_P(QuicConnectionTest, ClientParsesRetryWrongId) {
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongOriginalId) {
TestClientRetryHandling(/*invalid_retry_tag=*/false,
- /*missing_id_in_config=*/false,
- /*wrong_id_in_config=*/true);
+ /*missing_original_id_in_config=*/false,
+ /*wrong_original_id_in_config=*/true,
+ /*missing_retry_id_in_config=*/false,
+ /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryMissingRetryId) {
+ if (!connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ // Versions that do not authenticate connection IDs never send the
+ // retry_source_connection_id transport parameter.
+ return;
+ }
+ TestClientRetryHandling(/*invalid_retry_tag=*/false,
+ /*missing_original_id_in_config=*/false,
+ /*wrong_original_id_in_config=*/false,
+ /*missing_retry_id_in_config=*/true,
+ /*wrong_retry_id_in_config=*/false);
+}
+
+TEST_P(QuicConnectionTest, ClientParsesRetryWrongRetryId) {
+ if (!connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ // Versions that do not authenticate connection IDs never send the
+ // retry_source_connection_id transport parameter.
+ return;
+ }
+ TestClientRetryHandling(/*invalid_retry_tag=*/false,
+ /*missing_original_id_in_config=*/false,
+ /*wrong_original_id_in_config=*/false,
+ /*missing_retry_id_in_config=*/false,
+ /*wrong_retry_id_in_config=*/true);
}
TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
- // Make sure that receiving the original_connection_id transport parameter
- // fails the handshake when no RETRY packet was received before it.
+ if (!connection_.version().UsesTls()) {
+ // QUIC+TLS is required to transmit connection ID transport parameters.
+ return;
+ }
+ if (connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ // Versions that authenticate connection IDs always send the
+ // original_destination_connection_id transport parameter.
+ return;
+ }
+ // Make sure that receiving the original_destination_connection_id transport
+ // parameter fails the handshake when no RETRY packet was received before it.
QuicConfig received_config;
QuicConfigPeer::SetNegotiated(&received_config, true);
QuicConfigPeer::SetReceivedOriginalConnectionId(&received_config,
@@ -10459,6 +10742,26 @@ TEST_P(QuicConnectionTest, ClientReceivesOriginalConnectionIdWithoutRetry) {
TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
}
+TEST_P(QuicConnectionTest, ClientReceivesRetrySourceConnectionIdWithoutRetry) {
+ if (!connection_.version().AuthenticatesHandshakeConnectionIds()) {
+ // Versions that do not authenticate connection IDs never send the
+ // retry_source_connection_id transport parameter.
+ return;
+ }
+ // Make sure that receiving the retry_source_connection_id transport parameter
+ // fails the handshake when no RETRY packet was received before it.
+ QuicConfig received_config;
+ QuicConfigPeer::SetNegotiated(&received_config, true);
+ QuicConfigPeer::SetReceivedRetrySourceConnectionId(&received_config,
+ TestConnectionId(0x12345));
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+ .Times(1);
+ connection_.SetFromConfig(received_config);
+ EXPECT_FALSE(connection_.connected());
+ TestConnectionCloseQuicErrorCode(IETF_QUIC_PROTOCOL_VIOLATION);
+}
+
// Regression test for http://crbug/1047977
TEST_P(QuicConnectionTest, MaxStreamsFrameCausesConnectionClose) {
if (!VersionHasIetfQuicFrames(connection_.transport_version())) {
@@ -10640,28 +10943,14 @@ TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) {
peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
std::make_unique<TaggingEncrypter>(tag));
ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
- if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) {
- // Verify deadline does not get extended.
- EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
- }
- if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
- } else {
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0);
- }
+ // Verify deadline does not get extended.
+ EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline());
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1);
QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow();
clock_.AdvanceTime(delay);
- if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) {
- connection_.GetTimeoutAlarm()->Fire();
- }
- if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) {
- // Verify connection gets closed.
- EXPECT_FALSE(connection_.connected());
- } else {
- // Verify the timeout alarm deadline is updated.
- EXPECT_TRUE(connection_.connected());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- }
+ connection_.GetTimeoutAlarm()->Fire();
+ // Verify connection gets closed.
+ EXPECT_FALSE(connection_.connected());
}
TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
@@ -10673,15 +10962,440 @@ TEST_P(QuicConnectionTest, BundleAckWithImmediateResponse) {
}));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
ProcessDataPacket(1);
- QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
- if (GetQuicReloadableFlag(quic_advance_ack_timeout_update)) {
- // Verify ACK is bundled with WINDOW_UPDATE.
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(ack_alarm->IsSet());
+ // Verify ACK is bundled with WINDOW_UPDATE.
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(connection_.HasPendingAcks());
+}
+
+TEST_P(QuicConnectionTest, AckAlarmFiresEarly) {
+ if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+ return;
+ }
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ }
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ use_tagging_decrypter();
+ // Receives packet 1000 in initial data.
+ ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+
+ peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+ std::make_unique<TaggingEncrypter>(0x02));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ std::make_unique<StrictTaggingDecrypter>(0x02));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x02));
+ // Receives packet 1000 in application data.
+ ProcessDataPacketAtLevel(1000, false, ENCRYPTION_ZERO_RTT);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ // Verify ACK deadline does not change.
+ EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+ connection_.GetAckAlarm()->deadline());
+
+ // Ack alarm fires early.
+ if (GetQuicReloadableFlag(quic_always_send_earliest_ack)) {
+ // Verify the earliest ACK is flushed.
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
} else {
- // ACK is pending.
- EXPECT_TRUE(writer_->ack_frames().empty());
- EXPECT_TRUE(ack_alarm->IsSet());
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+ }
+ connection_.GetAckAlarm()->Fire();
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ if (GetQuicReloadableFlag(quic_always_send_earliest_ack)) {
+ EXPECT_EQ(clock_.ApproximateNow() + DefaultDelayedAckTime(),
+ connection_.GetAckAlarm()->deadline());
+ } else {
+ // No forward progress has been made.
+ EXPECT_EQ(clock_.ApproximateNow() + kAlarmGranularity,
+ connection_.GetAckAlarm()->deadline());
+ }
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionClient) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kCBHD);
+ config.SetConnectionOptionsToSend(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole detection is in progress.
+ EXPECT_TRUE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, ClientOnlyBlackholeDetectionServer) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ set_perspective(Perspective::IS_SERVER);
+ QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ if (version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(&connection_);
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kCBHD);
+ config.SetInitialReceivedConnectionOptions(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole detection is disabled.
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, 2RtoBlackholeDetection) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(k2RTO);
+ config.SetConnectionOptionsToSend(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole delay is expected.
+ EXPECT_EQ(clock_.Now() +
+ connection_.sent_packet_manager().GetNetworkBlackholeDelay(2),
+ QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 3RtoBlackholeDetection) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(k3RTO);
+ config.SetConnectionOptionsToSend(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole delay is expected.
+ EXPECT_EQ(clock_.Now() +
+ connection_.sent_packet_manager().GetNetworkBlackholeDelay(3),
+ QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 4RtoBlackholeDetection) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(k4RTO);
+ config.SetConnectionOptionsToSend(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole delay is expected.
+ EXPECT_EQ(clock_.Now() +
+ connection_.sent_packet_manager().GetNetworkBlackholeDelay(4),
+ QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+TEST_P(QuicConnectionTest, 6RtoBlackholeDetection) {
+ if (!GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ return;
+ }
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(k6RTO);
+ config.SetConnectionOptionsToSend(connection_options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ connection_.SetFromConfig(config);
+ const size_t kMinRttMs = 40;
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ EXPECT_FALSE(connection_.GetBlackholeDetectorAlarm()->IsSet());
+ // Send stream data.
+ SendStreamDataToPeer(
+ GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
+ 0, FIN, nullptr);
+ // Verify blackhole delay is expected.
+ EXPECT_EQ(clock_.Now() +
+ connection_.sent_packet_manager().GetNetworkBlackholeDelay(6),
+ QuicConnectionPeer::GetBlackholeDetectionDeadline(&connection_));
+}
+
+// Regresstion test for b/158491591.
+TEST_P(QuicConnectionTest, MadeForwardProgressOnDiscardingKeys) {
+ if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+ return;
+ }
+ use_tagging_decrypter();
+ // Send handshake packet.
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(k5RTO);
+ config.SetConnectionOptionsToSend(connection_options);
+ QuicConfigPeer::SetNegotiated(&config, true);
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
+ }
+ 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_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+ EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+ // Discard handshake keys.
+ connection_.OnHandshakeComplete();
+ if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
+ // Verify blackhole detection stops.
+ EXPECT_FALSE(connection_.BlackholeDetectionInProgress());
+ } else {
+ // Problematic: although there is nothing in flight, blackhole detection is
+ // still in progress.
+ EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
+ }
+}
+
+TEST_P(QuicConnectionTest, ProcessUndecryptablePacketsBasedOnEncryptionLevel) {
+ if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+ return;
+ }
+ // SetFromConfig is always called after construction from InitializeSession.
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(AnyNumber());
+ QuicConfig config;
+ connection_.SetFromConfig(config);
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ connection_.RemoveDecrypter(ENCRYPTION_FORWARD_SECURE);
+ use_tagging_decrypter();
+
+ peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x01));
+ peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<TaggingEncrypter>(0x02));
+
+ for (uint64_t i = 1; i <= 3; ++i) {
+ ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+ }
+ ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE);
+ for (uint64_t j = 5; j <= 7; ++j) {
+ ProcessDataPacketAtLevel(j, !kHasStopWaiting, ENCRYPTION_HANDSHAKE);
+ }
+ EXPECT_EQ(7u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+ EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+ SetDecrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<StrictTaggingDecrypter>(0x01));
+ EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x01));
+ if (GetQuicReloadableFlag(quic_fix_undecryptable_packets)) {
+ // Verify all ENCRYPTION_HANDSHAKE packets get processed.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(6);
+ } else {
+ // Verify packets before 4 get processed.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(3);
+ }
+ connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+ EXPECT_EQ(4u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+
+ SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<StrictTaggingDecrypter>(0x02));
+ EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ if (GetQuicReloadableFlag(quic_fix_undecryptable_packets)) {
+ // Verify the 1-RTT packet gets processed.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ } else {
+ // Verify all packets get processed.
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(4);
+ }
+ connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
+ EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
+}
+
+TEST_P(QuicConnectionTest, ServerBundlesInitialDataWithInitialAck) {
+ if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+ return;
+ }
+ set_perspective(Perspective::IS_SERVER);
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ }
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ use_tagging_decrypter();
+ // Receives packet 1000 in initial data.
+ ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_INITIAL);
+ QuicTime expected_pto_time =
+ connection_.sent_packet_manager().GetRetransmissionTime();
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+ connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+ // Verify PTO time does not change.
+ EXPECT_EQ(expected_pto_time,
+ connection_.sent_packet_manager().GetRetransmissionTime());
+
+ // Receives packet 1001 in initial data.
+ ProcessCryptoPacketAtLevel(1001, ENCRYPTION_INITIAL);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ // Receives packet 1002 in initial data.
+ ProcessCryptoPacketAtLevel(1002, ENCRYPTION_INITIAL);
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ if (GetQuicReloadableFlag(quic_bundle_crypto_data_with_initial_ack)) {
+ // Verify CRYPTO frame is bundled with INITIAL ACK.
+ EXPECT_FALSE(writer_->crypto_frames().empty());
+ // Verify PTO time changes.
+ EXPECT_NE(expected_pto_time,
+ connection_.sent_packet_manager().GetRetransmissionTime());
+ } else {
+ EXPECT_TRUE(writer_->crypto_frames().empty());
+ // Verify PTO time does not change.
+ EXPECT_EQ(expected_pto_time,
+ connection_.sent_packet_manager().GetRetransmissionTime());
+ }
+}
+
+TEST_P(QuicConnectionTest, ClientBundlesHandshakeDataWithHandshakeAck) {
+ if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+ return;
+ }
+ EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+ }
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ use_tagging_decrypter();
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ SetDecrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<StrictTaggingDecrypter>(0x02));
+ peer_framer_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ // Receives packet 1000 in handshake data.
+ ProcessCryptoPacketAtLevel(1000, ENCRYPTION_HANDSHAKE);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(2);
+ connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
+
+ // Receives packet 1001 in handshake data.
+ ProcessCryptoPacketAtLevel(1001, ENCRYPTION_HANDSHAKE);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ // Receives packet 1002 in handshake data.
+ ProcessCryptoPacketAtLevel(1002, ENCRYPTION_HANDSHAKE);
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ if (GetQuicReloadableFlag(quic_bundle_crypto_data_with_initial_ack)) {
+ // Verify CRYPTO frame is bundled with HANDSHAKE ACK.
+ EXPECT_FALSE(writer_->crypto_frames().empty());
+ } else {
+ EXPECT_TRUE(writer_->crypto_frames().empty());
+ }
+}
+
+// Regresstion test for b/156232673.
+TEST_P(QuicConnectionTest, CoalescePacketOfLowerEncryptionLevel) {
+ if (!connection_.version().CanSendCoalescedPackets()) {
+ return;
+ }
+ if (GetQuicReloadableFlag(quic_fix_min_crypto_frame_size)) {
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+ } else {
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(0);
+ }
+ {
+ QuicConnection::ScopedPacketFlusher flusher(&connection_);
+ use_tagging_decrypter();
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ SendStreamDataToPeer(2, std::string(1286, 'a'), 0, NO_FIN, nullptr);
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ // Try to coalesce a HANDSHAKE packet after 1-RTT packet.
+ if (GetQuicReloadableFlag(quic_fix_min_crypto_frame_size)) {
+ // Verify soft max packet length gets resumed and handshake packet gets
+ // successfully sent.
+ connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE);
+ } else {
+ // Problematic: creator thinks there is space to consume 1-byte, however,
+ // extra paddings make the serialization fail because of
+ // MinPlaintextPacketSize.
+ EXPECT_CALL(visitor_,
+ OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
+ EXPECT_QUIC_BUG(
+ connection_.SendCryptoDataWithString("a", 0, ENCRYPTION_HANDSHAKE),
+ "AppendPaddingFrame of 3 failed");
+ }
}
}
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 e93fd071c07..a769da9cd60 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
@@ -171,6 +171,12 @@ size_t QuicCryptoClientHandshaker::BufferSizeLimitForLevel(
return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
}
+void QuicCryptoClientHandshaker::OnConnectionClosed(
+ QuicErrorCode /*error*/,
+ ConnectionCloseSource /*source*/) {
+ next_state_ = STATE_CONNECTION_CLOSED;
+}
+
void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
const CryptoHandshakeMessage& server_config_update) {
DCHECK(server_config_update.tag() == kSCUP);
@@ -236,6 +242,9 @@ void QuicCryptoClientHandshaker::DoHandshakeLoop(
break;
case STATE_NONE:
QUIC_NOTREACHED();
+ return;
+ case STATE_CONNECTION_CLOSED:
+ rv = QUIC_FAILURE;
return; // We are done.
}
} while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
@@ -281,7 +290,9 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
// inchoate or subsequent hello.
session()->config()->ToHandshakeMessage(&out, session()->transport_version());
- if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
+ if (!cached->IsComplete(session()->connection()->clock()->WallNow()) ||
+ session()->config()->HasClientRequestedIndependentOption(
+ kQNZR, session()->perspective())) {
crypto_config_->FillInchoateClientHello(
server_id_, session()->supported_versions().front(), cached,
session()->connection()->random_generator(),
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 5ba93f24848..90f011dd053 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
@@ -53,9 +53,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
void OnOneRttPacketAcknowledged() override {}
void OnHandshakePacketSent() override {}
void OnConnectionClosed(QuicErrorCode /*error*/,
- ConnectionCloseSource /*source*/) override {}
+ ConnectionCloseSource /*source*/) override;
void OnHandshakeDoneReceived() override;
- void OnApplicationState(
+ void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> /*application_state*/) override {
QUICHE_NOTREACHED();
}
@@ -103,6 +103,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
STATE_RECV_SHLO,
STATE_INITIALIZE_SCUP,
STATE_NONE,
+ STATE_CONNECTION_CLOSED,
};
// Handles new server config and optional source-address token provided by the
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 36dc4cdb4c3..62a261d1fc1 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
@@ -126,9 +126,10 @@ void QuicCryptoClientStream::OnHandshakeDoneReceived() {
handshaker_->OnHandshakeDoneReceived();
}
-void QuicCryptoClientStream::OnApplicationState(
+void QuicCryptoClientStream::SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) {
- handshaker_->OnApplicationState(std::move(application_state));
+ handshaker_->SetServerApplicationStateForResumption(
+ std::move(application_state));
}
} // namespace quic
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 23f83c7e390..be99fb2b949 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
@@ -63,9 +63,6 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
// client. Does not count update messages that were received prior
// to handshake confirmation.
virtual int num_scup_messages_received() const = 0;
-
- virtual void OnApplicationState(
- std::unique_ptr<ApplicationState> application_state) = 0;
};
class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
@@ -167,7 +164,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
virtual void OnHandshakeDoneReceived() = 0;
// Called when application state is received.
- virtual void OnApplicationState(
+ virtual void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) = 0;
};
@@ -223,10 +220,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
ConnectionCloseSource source) override;
void OnHandshakeDoneReceived() override;
HandshakeState GetHandshakeState() const override;
- size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
-
- void OnApplicationState(
+ void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) override;
+ size_t BufferSizeLimitForLevel(EncryptionLevel level) const 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 6542382d670..7f6d7770eb6 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
@@ -162,6 +162,25 @@ TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
}
+TEST_F(QuicCryptoClientStreamTest, ClientTurnedOffZeroRtt) {
+ // Seed the config with a cached server config.
+ CompleteCryptoHandshake();
+
+ // Recreate connection with the new config.
+ CreateConnection();
+
+ // Set connection option.
+ QuicTagVector options;
+ options.push_back(kQNZR);
+ 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());
+}
+
TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
// Test that if the client's clock is skewed with respect to the server,
// the handshake succeeds. In the past, the client would get the server
@@ -299,7 +318,6 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
// Recreate connection with the new config and verify a 0-RTT attempt.
CreateConnection();
- EXPECT_CALL(*connection_, OnCanWrite());
EXPECT_CALL(*session_, OnProofValid(testing::_));
EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
.Times(testing::AnyNumber());
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 66f82298476..6c840671daf 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
@@ -8,6 +8,7 @@
#include <string>
#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"
@@ -298,6 +299,11 @@ bool QuicCryptoServerStream::IsZeroRtt() const {
num_handshake_messages_with_server_nonces_ == 0;
}
+bool QuicCryptoServerStream::IsResumption() const {
+ // QUIC Crypto doesn't have a non-0-RTT resumption mode.
+ return IsZeroRtt();
+}
+
int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
return num_server_config_update_messages_sent_;
}
@@ -307,7 +313,7 @@ QuicCryptoServerStream::PreviousCachedNetworkParams() const {
return previous_cached_network_params_.get();
}
-bool QuicCryptoServerStream::ZeroRttAttempted() const {
+bool QuicCryptoServerStream::ResumptionAttempted() const {
return zero_rtt_attempted_;
}
@@ -370,6 +376,12 @@ HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
}
+void QuicCryptoServerStream::SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*state*/) {
+ // QUIC Crypto doesn't need to remember any application state as part of doing
+ // 0-RTT resumption, so this function is a no-op.
+}
+
size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
EncryptionLevel level) const {
return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
@@ -389,6 +401,17 @@ void QuicCryptoServerStream::ProcessClientHello(
nullptr);
return;
}
+
+ if (GetQuicReloadableFlag(quic_save_user_agent_in_quic_session)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_save_user_agent_in_quic_session, 1, 3);
+ quiche::QuicheStringPiece user_agent_id;
+ message.GetStringPiece(quic::kUAID, &user_agent_id);
+ if (!session()->user_agent_id().has_value()) {
+ std::string uaid = user_agent_id.empty() ? "" : user_agent_id.data();
+ session()->SetUserAgentId(std::move(uaid));
+ }
+ }
+
if (!result->info.server_nonce.empty()) {
++num_handshake_messages_with_server_nonces_;
}
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 52d4874994d..9ed7764a078 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
@@ -35,9 +35,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) override;
bool IsZeroRtt() const override;
+ bool IsResumption() const override;
+ bool ResumptionAttempted() const override;
int NumServerConfigUpdateMessagesSent() const override;
const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
- bool ZeroRttAttempted() const override;
void SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) override;
void OnPacketDecrypted(EncryptionLevel level) override;
@@ -55,6 +56,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
const override;
CryptoMessageParser* crypto_message_parser() override;
HandshakeState GetHandshakeState() const override;
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> state) override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
// From QuicCryptoHandshaker
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h
index cdf12a3143d..540b7a42174 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h
@@ -62,8 +62,17 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
virtual void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) = 0;
+ // Returns true if the connection was a successful 0-RTT resumption.
virtual bool IsZeroRtt() const = 0;
- virtual bool ZeroRttAttempted() const = 0;
+
+ // Returns true if the connection was the result of a resumption handshake,
+ // whether 0-RTT or not.
+ virtual bool IsResumption() const = 0;
+
+ // Returns true if the client attempted a resumption handshake, whether or not
+ // the resumption actually occurred.
+ virtual bool ResumptionAttempted() const = 0;
+
virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
const = 0;
virtual void SetPreviousCachedNetworkParams(
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 debfc3b0f52..9ff7dc05d47 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
@@ -226,7 +226,7 @@ TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
// Do a first handshake in order to prime the client config with the server's
// information.
AdvanceHandshakeWithFakeClient();
- EXPECT_FALSE(server_stream()->ZeroRttAttempted());
+ EXPECT_FALSE(server_stream()->ResumptionAttempted());
// Now do another handshake, hopefully in 0-RTT.
QUIC_LOG(INFO) << "Resetting for 0-RTT handshake attempt";
@@ -247,7 +247,7 @@ TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
client_connection_, client_stream(), server_connection_, server_stream());
EXPECT_EQ(1, client_stream()->num_sent_client_hellos());
- EXPECT_TRUE(server_stream()->ZeroRttAttempted());
+ EXPECT_TRUE(server_stream()->ResumptionAttempted());
}
TEST_F(QuicCryptoServerStreamTest, FailByPolicy) {
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 20704fb627a..59a012224e8 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
@@ -268,6 +268,12 @@ void QuicCryptoStream::WritePendingCryptoRetransmission() {
level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
if (bytes_consumed < pending.length) {
+ if (GetQuicReloadableFlag(
+ quic_fix_write_pending_crypto_retransmission)) {
+ QUIC_RELOADABLE_FLAG_COUNT(
+ quic_fix_write_pending_crypto_retransmission);
+ return;
+ }
break;
}
}
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 49d37042390..54d1b2525c2 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
@@ -100,6 +100,21 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
// Returns current handshake state.
virtual HandshakeState GetHandshakeState() const = 0;
+ // Called to provide the server-side application state that must be checked
+ // when performing a 0-RTT TLS resumption.
+ //
+ // On a client, this may be called at any time; 0-RTT tickets will not be
+ // cached until this function is called. When a 0-RTT resumption is attempted,
+ // QuicSession::SetApplicationState will be called with the state provided by
+ // a call to this function on a previous connection.
+ //
+ // On a server, this function must be called before commencing the handshake,
+ // otherwise 0-RTT tickets will not be issued. On subsequent connections,
+ // 0-RTT will be rejected if the data passed into this function does not match
+ // the data passed in on the connection where the 0-RTT ticket was issued.
+ virtual void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> state) = 0;
+
// Returns the maximum number of bytes that can be buffered at a particular
// encryption level |level|.
virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
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 5f414e6a98a..f763d2d4782 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
@@ -61,6 +61,8 @@ class MockQuicCryptoStream : public QuicCryptoStream,
void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
private:
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
@@ -419,7 +421,7 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
.WillOnce(InvokeWithoutArgs([this]() {
return session_.ConsumeData(
QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
- 1350, NO_FIN, HANDSHAKE_RETRANSMISSION, QuicheNullOpt);
+ 1350, NO_FIN, HANDSHAKE_RETRANSMISSION, QUICHE_NULLOPT);
}));
EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc
index 42220050885..b34bed49fcf 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.cc
@@ -54,10 +54,10 @@ bool QuicDefaultPacketWriter::IsBatchMode() const {
return false;
}
-char* QuicDefaultPacketWriter::GetNextWriteLocation(
+QuicPacketBuffer QuicDefaultPacketWriter::GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) {
- return nullptr;
+ return {nullptr, nullptr};
}
WriteResult QuicDefaultPacketWriter::Flush() {
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h
index 36d4d8aa267..5388cae2314 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_default_packet_writer.h
@@ -35,8 +35,9 @@ class QUIC_EXPORT_PRIVATE QuicDefaultPacketWriter : public QuicPacketWriter {
const QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
- char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
+ QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) override;
WriteResult Flush() override;
void set_fd(int fd) { fd_ = fd; }
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 c0d39700f41..afdec636120 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
@@ -68,9 +68,9 @@ class PacketCollector : public QuicPacketCreator::DelegateInterface,
serialized_packet.encrypted_length, true));
}
- char* GetPacketBuffer() override {
+ QuicPacketBuffer GetPacketBuffer() override {
// Let QuicPacketCreator to serialize packets on stack buffer.
- return nullptr;
+ return {nullptr, nullptr};
}
void OnUnrecoverableError(QuicErrorCode /*error*/,
@@ -181,21 +181,113 @@ class StatelessConnectionTerminator {
// Class which extracts the ALPN from a QUIC_CRYPTO CHLO packet.
class ChloAlpnExtractor : public ChloExtractor::Delegate {
public:
- void OnChlo(QuicTransportVersion /*version*/,
+ void OnChlo(QuicTransportVersion version,
QuicConnectionId /*server_connection_id*/,
const CryptoHandshakeMessage& chlo) override {
quiche::QuicheStringPiece alpn_value;
if (chlo.GetStringPiece(kALPN, &alpn_value)) {
alpn_ = std::string(alpn_value);
}
+ if (GetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_dispatcher_legacy_version_encapsulation,
+ 1, 3);
+ if (version == LegacyVersionForEncapsulation().transport_version) {
+ quiche::QuicheStringPiece qlve_value;
+ if (chlo.GetStringPiece(kQLVE, &qlve_value)) {
+ legacy_version_encapsulation_inner_packet_ = std::string(qlve_value);
+ }
+ }
+ }
}
std::string&& ConsumeAlpn() { return std::move(alpn_); }
+ std::string&& ConsumeLegacyVersionEncapsulationInnerPacket() {
+ DCHECK(GetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation));
+ return std::move(legacy_version_encapsulation_inner_packet_);
+ }
+
private:
std::string alpn_;
+ std::string legacy_version_encapsulation_inner_packet_;
};
+bool MaybeHandleLegacyVersionEncapsulation(
+ QuicDispatcher* dispatcher,
+ ChloAlpnExtractor* alpn_extractor,
+ const ReceivedPacketInfo& packet_info) {
+ DCHECK(GetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation));
+ std::string legacy_version_encapsulation_inner_packet =
+ alpn_extractor->ConsumeLegacyVersionEncapsulationInnerPacket();
+ if (legacy_version_encapsulation_inner_packet.empty()) {
+ // This CHLO did not contain the Legacy Version Encapsulation tag.
+ return false;
+ }
+ PacketHeaderFormat format;
+ QuicLongHeaderType long_packet_type;
+ bool version_present;
+ bool has_length_prefix;
+ QuicVersionLabel version_label;
+ ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+ QuicConnectionId destination_connection_id, source_connection_id;
+ bool retry_token_present;
+ quiche::QuicheStringPiece retry_token;
+ std::string detailed_error;
+ const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+ QuicEncryptedPacket(legacy_version_encapsulation_inner_packet.data(),
+ legacy_version_encapsulation_inner_packet.length()),
+ 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);
+ if (error != QUIC_NO_ERROR) {
+ QUIC_DLOG(ERROR)
+ << "Failed to parse Legacy Version Encapsulation inner packet:"
+ << detailed_error;
+ return false;
+ }
+ if (destination_connection_id != packet_info.destination_connection_id) {
+ // We enforce that the inner and outer connection IDs match to make sure
+ // this never impacts routing of packets.
+ QUIC_DLOG(ERROR) << "Ignoring Legacy Version Encapsulation packet "
+ "with mismatched connection ID "
+ << destination_connection_id << " vs "
+ << packet_info.destination_connection_id;
+ return false;
+ }
+ if (legacy_version_encapsulation_inner_packet.length() >=
+ packet_info.packet.length()) {
+ QUIC_BUG << "Inner packet cannot be larger than outer "
+ << legacy_version_encapsulation_inner_packet.length() << " vs "
+ << packet_info.packet.length();
+ return false;
+ }
+
+ QUIC_DVLOG(1) << "Extracted a Legacy Version Encapsulation "
+ << legacy_version_encapsulation_inner_packet.length()
+ << " byte packet of version " << parsed_version;
+
+ // Append zeroes to the end of the packet. This will ensure that
+ // we use the right number of bytes for calculating anti-amplification
+ // limits. Note that this only works for long headers of versions that carry
+ // long header lengths, since they'll ignore any trailing zeroes. We still
+ // do this for all packets to ensure version negotiation works.
+ legacy_version_encapsulation_inner_packet.append(
+ packet_info.packet.length() -
+ legacy_version_encapsulation_inner_packet.length(),
+ 0x00);
+
+ // Process the inner packet as if it had been received by itself.
+ QuicReceivedPacket received_encapsulated_packet(
+ legacy_version_encapsulation_inner_packet.data(),
+ legacy_version_encapsulation_inner_packet.length(),
+ packet_info.packet.receipt_time());
+ dispatcher->ProcessPacket(packet_info.self_address, packet_info.peer_address,
+ received_encapsulated_packet);
+ QUIC_CODE_COUNT(quic_legacy_version_encapsulation_decapsulated);
+ return true;
+}
+
} // namespace
QuicDispatcher::QuicDispatcher(
@@ -307,30 +399,54 @@ void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
}
QuicConnectionId QuicDispatcher::MaybeReplaceServerConnectionId(
- QuicConnectionId server_connection_id,
- ParsedQuicVersion version) const {
- if (server_connection_id.length() == expected_server_connection_id_length_) {
+ const QuicConnectionId& server_connection_id,
+ const ParsedQuicVersion& version) const {
+ const uint8_t server_connection_id_length = server_connection_id.length();
+ if (server_connection_id_length == expected_server_connection_id_length_) {
return server_connection_id;
}
DCHECK(version.AllowsVariableLengthConnectionIds());
-
- QuicConnectionId new_connection_id =
- GenerateNewServerConnectionId(version, server_connection_id);
+ QuicConnectionId new_connection_id;
+ if (server_connection_id_length < expected_server_connection_id_length_) {
+ new_connection_id = ReplaceShortServerConnectionId(
+ version, server_connection_id, expected_server_connection_id_length_);
+ // Verify that ReplaceShortServerConnectionId is deterministic.
+ DCHECK_EQ(new_connection_id, ReplaceShortServerConnectionId(
+ version, server_connection_id,
+ expected_server_connection_id_length_));
+ } else {
+ new_connection_id = ReplaceLongServerConnectionId(
+ version, server_connection_id, expected_server_connection_id_length_);
+ // Verify that ReplaceLongServerConnectionId is deterministic.
+ DCHECK_EQ(new_connection_id, ReplaceLongServerConnectionId(
+ version, server_connection_id,
+ expected_server_connection_id_length_));
+ }
DCHECK_EQ(expected_server_connection_id_length_, new_connection_id.length());
- // Verify that GenerateNewServerConnectionId is deterministic.
- DCHECK_EQ(new_connection_id,
- GenerateNewServerConnectionId(version, server_connection_id));
-
QUIC_DLOG(INFO) << "Replacing incoming connection ID " << server_connection_id
<< " with " << new_connection_id;
return new_connection_id;
}
-QuicConnectionId QuicDispatcher::GenerateNewServerConnectionId(
- ParsedQuicVersion /*version*/,
- QuicConnectionId connection_id) const {
- return QuicUtils::CreateReplacementConnectionId(connection_id);
+QuicConnectionId QuicDispatcher::ReplaceShortServerConnectionId(
+ const ParsedQuicVersion& /*version*/,
+ const QuicConnectionId& server_connection_id,
+ uint8_t expected_server_connection_id_length) const {
+ DCHECK_LT(server_connection_id.length(),
+ expected_server_connection_id_length);
+ return QuicUtils::CreateReplacementConnectionId(
+ server_connection_id, expected_server_connection_id_length);
+}
+
+QuicConnectionId QuicDispatcher::ReplaceLongServerConnectionId(
+ const ParsedQuicVersion& /*version*/,
+ const QuicConnectionId& server_connection_id,
+ uint8_t expected_server_connection_id_length) const {
+ DCHECK_GT(server_connection_id.length(),
+ expected_server_connection_id_length);
+ return QuicUtils::CreateReplacementConnectionId(
+ server_connection_id, expected_server_connection_id_length);
}
bool QuicDispatcher::MaybeDispatchPacket(
@@ -367,6 +483,26 @@ bool QuicDispatcher::MaybeDispatchPacket(
auto it = session_map_.find(server_connection_id);
if (it != session_map_.end()) {
DCHECK(!buffered_packets_.HasBufferedPackets(server_connection_id));
+ if (GetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_dispatcher_legacy_version_encapsulation,
+ 2, 3);
+ if (packet_info.version_flag &&
+ packet_info.version != it->second->version() &&
+ packet_info.version == LegacyVersionForEncapsulation()) {
+ // This packet is using the Legacy Version Encapsulation version but the
+ // corresponding session isn't, attempt extraction of inner packet.
+ ChloAlpnExtractor alpn_extractor;
+ if (ChloExtractor::Extract(packet_info.packet, packet_info.version,
+ config_->create_session_tag_indicators(),
+ &alpn_extractor,
+ server_connection_id.length())) {
+ if (MaybeHandleLegacyVersionEncapsulation(this, &alpn_extractor,
+ packet_info)) {
+ return true;
+ }
+ }
+ }
+ }
it->second->ProcessUdpPacket(packet_info.self_address,
packet_info.peer_address, packet_info.packet);
return true;
@@ -521,6 +657,29 @@ void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) {
BufferEarlyPacket(*packet_info);
break;
}
+ if (GetQuicReloadableFlag(quic_dont_pad_chlo)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_dont_pad_chlo, 2, 2);
+ // We only apply this check for versions that do not use the IETF
+ // invariant header because those versions are already checked in
+ // QuicDispatcher::MaybeDispatchPacket.
+ if (packet_info->version_flag &&
+ !packet_info->version.HasIetfInvariantHeader() &&
+ crypto_config()->validate_chlo_size() &&
+ packet_info->packet.length() < kMinClientInitialPacketLength) {
+ QUIC_DVLOG(1) << "Dropping CHLO packet which is too short, length: "
+ << packet_info->packet.length();
+ QUIC_CODE_COUNT(quic_drop_small_chlo_packets);
+ break;
+ }
+ }
+ if (GetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation)) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_dispatcher_legacy_version_encapsulation, 3, 3);
+ if (MaybeHandleLegacyVersionEncapsulation(this, &alpn_extractor,
+ *packet_info)) {
+ break;
+ }
+ }
ProcessChlo({alpn_extractor.ConsumeAlpn()}, packet_info);
} break;
case kFateTimeWait:
@@ -568,36 +727,6 @@ std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) {
QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
const ReceivedPacketInfo& packet_info) {
if (!packet_info.version_flag) {
- // The Android network conformance test contains a UDP test that sends a
- // 12-byte packet with the following format:
- // - 0x0c (public flags: 8-byte connection ID, 1-byte packet number)
- // - randomized 8-byte connection ID
- // - 0x01 (1-byte packet number)
- // - 0x00 (private flags)
- // - 0x07 (PING frame).
- // That packet is invalid and we would normally drop it but in order to
- // unblock this conformance testing we have the following workaround that
- // will be removed once the fixed test is deployed.
- // TODO(b/139691956) Remove this workaround once fixed test is deployed.
- if (!GetQuicReloadableFlag(
- quic_remove_android_conformance_test_workaround) &&
- packet_info.packet.length() == 12 &&
- packet_info.packet.data()[0] == 0x0c &&
- packet_info.packet.data()[9] == 0x01 &&
- packet_info.packet.data()[10] == 0x00 &&
- packet_info.packet.data()[11] == 0x07) {
- QUIC_DLOG(INFO) << "Received Android UDP network conformance test "
- "packet with connection ID "
- << packet_info.destination_connection_id;
- // Respond with a public reset that the test will know how to parse
- // then return kFateDrop to stop processing of this packet.
- time_wait_list_manager()->SendPublicReset(
- packet_info.self_address, packet_info.peer_address,
- packet_info.destination_connection_id,
- /*ietf_quic=*/false, GetPerPacketContext());
- return kFateDrop;
- }
-
QUIC_DLOG(INFO)
<< "Packet without version arrived for unknown connection ID "
<< packet_info.destination_connection_id;
@@ -884,8 +1013,8 @@ void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
CreateQuicSession(server_connection_id, packets.front().peer_address,
alpn, packet_list.version);
if (original_connection_id != server_connection_id) {
- session->connection()->AddIncomingConnectionId(original_connection_id);
- session->connection()->InstallInitialCrypters(original_connection_id);
+ session->connection()->SetOriginalDestinationConnectionId(
+ original_connection_id);
}
QUIC_DLOG(INFO) << "Created new session for " << server_connection_id;
@@ -976,10 +1105,16 @@ void QuicDispatcher::ProcessChlo(const std::vector<std::string>& alpns,
std::unique_ptr<QuicSession> session =
CreateQuicSession(packet_info->destination_connection_id,
packet_info->peer_address, alpn, packet_info->version);
- DCHECK(session);
+ if (QUIC_PREDICT_FALSE(session == nullptr)) {
+ QUIC_BUG << "CreateQuicSession returned nullptr for "
+ << packet_info->destination_connection_id << " from "
+ << packet_info->peer_address << " ALPN \"" << alpn << "\" version "
+ << packet_info->version;
+ return;
+ }
if (original_connection_id != packet_info->destination_connection_id) {
- session->connection()->AddIncomingConnectionId(original_connection_id);
- session->connection()->InstallInitialCrypters(original_connection_id);
+ session->connection()->SetOriginalDestinationConnectionId(
+ original_connection_id);
}
QUIC_DLOG(INFO) << "Created new session for "
<< packet_info->destination_connection_id;
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 73ab3ec4fd0..f0c35eae152 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
@@ -103,30 +103,17 @@ class QUIC_NO_EXPORT QuicDispatcher
void OnConnectionAddedToTimeWaitList(
QuicConnectionId server_connection_id) override;
- using SessionMap = QuicUnorderedMap<QuicConnectionId,
- std::unique_ptr<QuicSession>,
- QuicConnectionIdHash>;
+ using SessionMap = QuicHashMap<QuicConnectionId,
+ std::unique_ptr<QuicSession>,
+ QuicConnectionIdHash>;
const SessionMap& session_map() const { return session_map_; }
// Deletes all sessions on the closed session list and clears the list.
virtual void DeleteSessions();
- using ConnectionIdMap = QuicUnorderedMap<QuicConnectionId,
- QuicConnectionId,
- QuicConnectionIdHash>;
-
- // The largest packet number we expect to receive with a connection
- // ID for a connection that is not established yet. The current design will
- // send a handshake and then up to 50 or so data packets, and then it may
- // resend the handshake packet up to 10 times. (Retransmitted packets are
- // sent with unique packet numbers.)
- static const uint64_t kMaxReasonableInitialPacketNumber = 100;
- static_assert(kMaxReasonableInitialPacketNumber >=
- kInitialCongestionWindow + 10,
- "kMaxReasonableInitialPacketNumber is unreasonably small "
- "relative to kInitialCongestionWindow.");
-
+ using ConnectionIdMap =
+ QuicHashMap<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
// QuicBufferedPacketStore::VisitorInterface implementation.
void OnExpiredPackets(QuicConnectionId server_connection_id,
@@ -162,11 +149,29 @@ class QUIC_NO_EXPORT QuicDispatcher
virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
// Generate a connection ID with a length that is expected by the dispatcher.
+ // Called only when |server_connection_id| is shorter than
+ // |expected_connection_id_length|.
// Note that this MUST produce a deterministic result (calling this method
// with two connection IDs that are equal must produce the same result).
- virtual QuicConnectionId GenerateNewServerConnectionId(
- ParsedQuicVersion version,
- QuicConnectionId connection_id) const;
+ // Note that this is not used in general operation because our default
+ // |expected_server_connection_id_length| is 8, and the IETF specification
+ // requires clients to use an initial length of at least 8. However, we
+ // allow disabling that requirement via
+ // |allow_short_initial_server_connection_ids_|.
+ virtual QuicConnectionId ReplaceShortServerConnectionId(
+ const ParsedQuicVersion& version,
+ const QuicConnectionId& server_connection_id,
+ uint8_t expected_server_connection_id_length) const;
+
+ // Generate a connection ID with a length that is expected by the dispatcher.
+ // Called only when |server_connection_id| is longer than
+ // |expected_connection_id_length|.
+ // Note that this MUST produce a deterministic result (calling this method
+ // with two connection IDs that are equal must produce the same result).
+ virtual QuicConnectionId ReplaceLongServerConnectionId(
+ const ParsedQuicVersion& version,
+ const QuicConnectionId& server_connection_id,
+ uint8_t expected_server_connection_id_length) const;
// Values to be returned by ValidityChecks() to indicate what should be done
// with a packet. Fates with greater values are considered to be higher
@@ -308,11 +313,12 @@ class QUIC_NO_EXPORT QuicDispatcher
std::string SelectAlpn(const std::vector<std::string>& alpns);
// If the connection ID length is different from what the dispatcher expects,
- // replace the connection ID with a random one of the right length,
- // and save it to make sure the mapping is persistent.
+ // replace the connection ID with one of the right length.
+ // Note that this MUST produce a deterministic result (calling this method
+ // with two connection IDs that are equal must produce the same result).
QuicConnectionId MaybeReplaceServerConnectionId(
- QuicConnectionId server_connection_id,
- ParsedQuicVersion version) const;
+ const QuicConnectionId& server_connection_id,
+ const ParsedQuicVersion& version) const;
private:
friend class test::QuicDispatcherPeer;
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 814462e9d01..ef4190d470a 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
@@ -580,6 +580,73 @@ TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
TestTlsMultiPacketClientHello(/*add_reordering=*/true);
}
+TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
+ if (!version_.HasLongHeaderLengths()) {
+ // Decapsulating Legacy Version Encapsulation packets from these versions
+ // is not currently supported in QuicDispatcher.
+ return;
+ }
+ SetQuicReloadableFlag(quic_dont_pad_chlo, true);
+ SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
+ QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+ QuicConnectionId server_connection_id = TestConnectionId();
+ QuicConfig client_config = DefaultQuicConfig();
+ client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
+ std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
+ GetFirstFlightOfPackets(version_, client_config, server_connection_id);
+ ASSERT_EQ(packets.size(), 1u);
+
+ // Validate that Legacy Version Encapsulation is actually being used by
+ // checking the version of the packet before processing it.
+ PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+ QuicLongHeaderType long_packet_type;
+ bool version_present;
+ bool has_length_prefix;
+ QuicVersionLabel version_label;
+ ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+ QuicConnectionId destination_connection_id, source_connection_id;
+ bool retry_token_present;
+ quiche::QuicheStringPiece retry_token;
+ std::string detailed_error;
+ const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+ QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
+ 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);
+ ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+ EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+ EXPECT_TRUE(version_present);
+ EXPECT_FALSE(has_length_prefix);
+ EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+ EXPECT_EQ(destination_connection_id, server_connection_id);
+ EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+ EXPECT_FALSE(retry_token_present);
+ EXPECT_TRUE(detailed_error.empty());
+
+ // Processing the packet should create a new session.
+ EXPECT_CALL(*dispatcher_,
+ CreateQuicSession(server_connection_id, client_address,
+ Eq(ExpectedAlpn()), _))
+ .WillOnce(Return(ByMove(CreateSession(
+ dispatcher_.get(), config_, server_connection_id, client_address,
+ &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .Times(2);
+
+ ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
+ server_connection_id);
+ EXPECT_EQ(dispatcher_->session_map().size(), 1u);
+
+ // Processing the same packet a second time should also be routed by the
+ // dispatcher to the right connection (we expect ProcessUdpPacket to be
+ // called twice, see the EXPECT_CALL above).
+ ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
+ server_connection_id);
+}
+
TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
@@ -1010,57 +1077,20 @@ TEST_P(QuicDispatcherTestAllVersions,
ProcessFirstFlight(client_address, EmptyQuicConnectionId());
}
-TEST_P(QuicDispatcherTestAllVersions, OKSeqNoPacketProcessed) {
- if (version_.UsesTls()) {
- // QUIC+TLS allows clients to start with any packet number.
- return;
- }
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId connection_id = TestConnectionId(1);
-
- EXPECT_CALL(*dispatcher_,
- CreateQuicSession(TestConnectionId(1), client_address,
- Eq(ExpectedAlpn()), _))
- .WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, TestConnectionId(1), client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
- ValidatePacket(TestConnectionId(1), packet);
- })));
-
- // A packet whose packet number is the largest that is allowed to start a
- // connection.
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(connection_id)));
- ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
- QuicDispatcher::kMaxReasonableInitialPacketNumber);
-}
-
TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
for (ParsedQuicVersion version : CurrentSupportedVersions()) {
VerifyVersionSupported(version);
+ QuicDisableVersion(version);
+ VerifyVersionNotSupported(version);
+ QuicEnableVersion(version);
+ VerifyVersionSupported(version);
}
-
- // Turn off version Q050.
- SetQuicReloadableFlag(quic_disable_version_q050, true);
- VerifyVersionNotSupported(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
-
- // Turn on version Q050.
- SetQuicReloadableFlag(quic_disable_version_q050, false);
- VerifyVersionSupported(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
}
TEST_P(QuicDispatcherTestOneVersion,
RejectDeprecatedVersionsWithVersionNegotiation) {
- static_assert(quic::SupportedVersions().size() == 8u,
+ static_assert(quic::SupportedVersions().size() == 9u,
"Please add deprecated versions to this test");
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
CreateTimeWaitListManager();
@@ -1275,55 +1305,6 @@ TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
}
-TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
- if (GetQuicReloadableFlag(quic_remove_android_conformance_test_workaround)) {
- // TODO(b/139691956) Remove this test once the flag is deprecated.
- return;
- }
- SavingWriter* saving_writer = new SavingWriter();
- // dispatcher_ takes ownership of saving_writer.
- QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
-
- QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
- saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
- &mock_alarm_factory_);
- // dispatcher_ takes ownership of time_wait_list_manager.
- QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
- time_wait_list_manager);
- // clang-format off
- static const unsigned char packet[] = {
- // Android UDP network conformance test packet as it was before this change:
- // https://android-review.googlesource.com/c/platform/cts/+/1104285
- 0x0c, // public flags: 8-byte connection ID, 1-byte packet number
- 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
- 0x01, // 1-byte packet number
- 0x00, // private flags
- 0x07, // PING frame
- };
- // 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);
-
- QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
- ASSERT_EQ(1u, saving_writer->packets()->size());
-
- // The Android UDP network conformance test directly checks that bytes 1-9
- // of the response match the connection ID that was sent.
- static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
- 0x75, 0x76, 0x77, 0x78};
- ASSERT_GE((*(saving_writer->packets()))[0]->length(),
- 1u + sizeof(connection_id_bytes));
- quiche::test::CompareCharArraysWithHexError(
- "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
- sizeof(connection_id_bytes), connection_id_bytes,
- sizeof(connection_id_bytes));
-}
-
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.
@@ -1373,8 +1354,12 @@ TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
}
TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
- if (!version_.HasIetfInvariantHeader()) {
- // We only drop small packets when using IETF_QUIC_LONG_HEADER_PACKET.
+ if (!version_.HasIetfInvariantHeader() &&
+ !GetQuicReloadableFlag(quic_dont_pad_chlo)) {
+ // When quic_dont_pad_chlo is false, we only drop small packets when using
+ // IETF_QUIC_LONG_HEADER_PACKET. When quic_dont_pad_chlo is true, we drop
+ // small packets for all versions.
+ // TODO(dschinazi) remove this early return when we deprecate the flag.
return;
}
CreateTimeWaitListManager();
@@ -2340,7 +2325,8 @@ TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
// Regression test for b/117874922.
TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
// Ensure the preferred version is not supported by the server.
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
+ QuicDisableVersion(AllSupportedVersions().front());
+
uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
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 6afccfece10..1c0984aae17 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
@@ -203,6 +203,8 @@ const char* QuicErrorCodeToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER);
RETURN_STRING_LITERAL(QUIC_HTTP_INVALID_MAX_PUSH_ID);
RETURN_STRING_LITERAL(QUIC_HTTP_STREAM_LIMIT_TOO_LOW);
+ RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH);
+ RETURN_STRING_LITERAL(QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH);
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);
@@ -221,6 +223,9 @@ const char* QuicErrorCodeToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_HPACK_TRUNCATED_BLOCK);
RETURN_STRING_LITERAL(QUIC_HPACK_FRAGMENT_TOO_LONG);
RETURN_STRING_LITERAL(QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT);
+ RETURN_STRING_LITERAL(QUIC_ZERO_RTT_UNRETRANSMITTABLE);
+ RETURN_STRING_LITERAL(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED);
+ RETURN_STRING_LITERAL(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
@@ -567,6 +572,10 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
case QUIC_HTTP_STREAM_LIMIT_TOO_LOW:
return {false, static_cast<uint64_t>(
QuicHttp3ErrorCode::GENERAL_PROTOCOL_ERROR)};
+ case QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH:
+ return {false, static_cast<uint64_t>(QuicHttp3ErrorCode::SETTINGS_ERROR)};
+ case QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH:
+ return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
case QUIC_HPACK_INDEX_VARINT_ERROR:
return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR:
@@ -599,6 +608,12 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(
return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+ case QUIC_ZERO_RTT_UNRETRANSMITTABLE:
+ return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+ case QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED:
+ return {true, static_cast<uint64_t>(INTERNAL_ERROR)};
+ case QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED:
+ return {true, static_cast<uint64_t>(PROTOCOL_VIOLATION)};
case QUIC_LAST_ERROR:
return {false, static_cast<uint64_t>(QUIC_LAST_ERROR)};
}
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h b/chromium/net/third_party/quiche/src/quic/core/quic_error_codes.h
index f057fea1028..4c13f2c8382 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
@@ -431,6 +431,12 @@ enum QuicErrorCode {
QUIC_HTTP_INVALID_MAX_PUSH_ID = 159,
// Received unidirectional stream limit is lower than required by HTTP/3.
QUIC_HTTP_STREAM_LIMIT_TOO_LOW = 160,
+ // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+ // is accepted. Server violated the HTTP/3 spec.
+ QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH = 164,
+ // Received mismatched SETTINGS frame from HTTP/3 connection where early data
+ // is rejected. Our implementation currently doesn't support it.
+ QUIC_HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH = 165,
// HPACK header block decoding errors.
// Index varint beyond implementation limit.
@@ -466,8 +472,20 @@ enum QuicErrorCode {
// Total compressed HPACK data size exceeds limit.
QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT = 150,
+ // Stream/flow control limit from 1-RTT handshake is too low to retransmit
+ // 0-RTT data. This is our implentation error. We could in theory keep the
+ // connection alive but chose not to for simplicity.
+ QUIC_ZERO_RTT_UNRETRANSMITTABLE = 161,
+ // Stream/flow control limit from 0-RTT rejection reduces cached limit.
+ // This is our implentation error. We could in theory keep the connection
+ // alive but chose not to for simplicity.
+ QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED = 162,
+ // Stream/flow control limit from 0-RTT resumption reduces cached limit.
+ // This is the peer violating QUIC spec.
+ QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED = 163,
+
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 161,
+ QUIC_LAST_ERROR = 166,
};
// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h
index 29c3c02d1a3..daad3d9d560 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_flow_controller.h
@@ -91,6 +91,8 @@ class QUIC_EXPORT_PRIVATE QuicFlowController
QuicByteCount bytes_consumed() const { return bytes_consumed_; }
+ QuicByteCount bytes_sent() const { return bytes_sent_; }
+
QuicStreamOffset send_window_offset() const { return send_window_offset_; }
QuicStreamOffset highest_received_byte_offset() const {
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 b05b4576d8e..139896560d6 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
@@ -6,6 +6,7 @@
#include <cstddef>
#include <cstdint>
+#include <limits>
#include <memory>
#include <string>
#include <utility>
@@ -20,6 +21,7 @@
#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"
+#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_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_data_reader.h"
@@ -28,6 +30,7 @@
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
#include "net/third_party/quiche/src/quic/core/quic_stream_frame_data_producer.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/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
@@ -622,6 +625,17 @@ size_t QuicFramer::GetStopSendingFrameSize(const QuicStopSendingFrame& frame) {
}
// static
+size_t QuicFramer::GetAckFrequencyFrameSize(
+ const QuicAckFrequencyFrame& frame) {
+ return QuicDataWriter::GetVarInt62Len(IETF_ACK_FREQUENCY) +
+ QuicDataWriter::GetVarInt62Len(frame.sequence_number) +
+ QuicDataWriter::GetVarInt62Len(frame.packet_tolerance) +
+ QuicDataWriter::GetVarInt62Len(frame.max_ack_delay.ToMicroseconds()) +
+ // One byte for encoding boolean
+ 1;
+}
+
+// static
size_t QuicFramer::GetPathChallengeFrameSize(
const QuicPathChallengeFrame& frame) {
return kQuicFrameTypeSize + sizeof(frame.data_buffer);
@@ -675,7 +689,8 @@ size_t QuicFramer::GetRetransmittableControlFrameSize(
case HANDSHAKE_DONE_FRAME:
// HANDSHAKE_DONE has no payload.
return kQuicFrameTypeSize;
-
+ case ACK_FREQUENCY_FRAME:
+ return GetAckFrequencyFrameSize(*frame.ack_frequency_frame);
case STREAM_FRAME:
case ACK_FRAME:
case STOP_WAITING_FRAME:
@@ -1013,6 +1028,9 @@ size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
return 0;
}
break;
+ case HANDSHAKE_DONE_FRAME:
+ // HANDSHAKE_DONE has no payload.
+ break;
default:
RaiseError(QUIC_INVALID_FRAME_DATA);
QUIC_BUG << "QUIC_INVALID_FRAME_DATA";
@@ -1034,8 +1052,8 @@ size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
for (const QuicFrame& frame : frames) {
// Determine if we should write stream frame length in header.
const bool last_frame_in_packet = i == frames.size() - 1;
- if (!AppendIetfTypeByte(frame, last_frame_in_packet, writer)) {
- QUIC_BUG << "AppendIetfTypeByte failed: " << detailed_error();
+ if (!AppendIetfFrameType(frame, last_frame_in_packet, writer)) {
+ QUIC_BUG << "AppendIetfFrameType failed: " << detailed_error();
return 0;
}
@@ -1182,6 +1200,12 @@ size_t QuicFramer::AppendIetfFrames(const QuicFrames& frames,
case HANDSHAKE_DONE_FRAME:
// HANDSHAKE_DONE has no payload.
break;
+ case ACK_FREQUENCY_FRAME:
+ if (!AppendAckFrequencyFrame(*frame.ack_frequency_frame, writer)) {
+ QUIC_BUG << "AppendAckFrequencyFrame failed: " << detailed_error();
+ return 0;
+ }
+ break;
default:
set_detailed_error("Tried to append unknown frame type.");
RaiseError(QUIC_INVALID_FRAME_DATA);
@@ -2004,6 +2028,10 @@ bool QuicFramer::HasEncrypterOfEncryptionLevel(EncryptionLevel level) const {
return encrypter_[level] != nullptr;
}
+bool QuicFramer::HasDecrypterOfEncryptionLevel(EncryptionLevel level) const {
+ return decrypter_[level] != nullptr;
+}
+
bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
QuicDataWriter* writer,
size_t* length_field_offset) {
@@ -2986,6 +3014,19 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
}
break;
}
+ case HANDSHAKE_DONE_FRAME: {
+ // HANDSHAKE_DONE has no payload.
+ QuicHandshakeDoneFrame handshake_done_frame;
+ QUIC_DVLOG(2) << ENDPOINT << "Processing handshake done frame "
+ << handshake_done_frame;
+ if (!visitor_->OnHandshakeDoneFrame(handshake_done_frame)) {
+ QUIC_DVLOG(1) << ENDPOINT
+ << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
+ }
+ break;
+ }
default:
set_detailed_error("Illegal frame type.");
@@ -3329,7 +3370,20 @@ bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
<< handshake_done_frame;
break;
}
-
+ case IETF_ACK_FREQUENCY: {
+ QuicAckFrequencyFrame frame;
+ if (!ProcessAckFrequencyFrame(reader, &frame)) {
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
+ }
+ QUIC_DVLOG(2) << ENDPOINT << "Processing IETF ack frequency frame "
+ << frame;
+ if (!visitor_->OnAckFrequencyFrame(frame)) {
+ QUIC_DVLOG(1) << "Visitor asked to stop further processing.";
+ // Returning true since there was no parsing error.
+ return true;
+ }
+ break;
+ }
default:
set_detailed_error("Illegal frame type.");
QUIC_DLOG(WARNING)
@@ -3509,6 +3563,47 @@ bool QuicFramer::ProcessCryptoFrame(QuicDataReader* reader,
return true;
}
+bool QuicFramer::ProcessAckFrequencyFrame(QuicDataReader* reader,
+ QuicAckFrequencyFrame* frame) {
+ if (!reader->ReadVarInt62(&frame->sequence_number)) {
+ set_detailed_error("Unable to read sequence number.");
+ return false;
+ }
+
+ if (!reader->ReadVarInt62(&frame->packet_tolerance)) {
+ set_detailed_error("Unable to read packet tolerance.");
+ return false;
+ }
+ if (frame->packet_tolerance == 0) {
+ set_detailed_error("Invalid packet tolerance.");
+ return false;
+ }
+ uint64_t max_ack_delay_us;
+ if (!reader->ReadVarInt62(&max_ack_delay_us)) {
+ set_detailed_error("Unable to read max_ack_delay_us.");
+ return false;
+ }
+ constexpr uint64_t kMaxAckDelayUsBound = 1u << 24;
+ if (max_ack_delay_us > kMaxAckDelayUsBound) {
+ set_detailed_error("Invalid max_ack_delay_us.");
+ return false;
+ }
+ frame->max_ack_delay = QuicTime::Delta::FromMicroseconds(max_ack_delay_us);
+
+ uint8_t ignore_order;
+ if (!reader->ReadUInt8(&ignore_order)) {
+ set_detailed_error("Unable to read ignore_order.");
+ return false;
+ }
+ if (ignore_order > 1) {
+ set_detailed_error("Invalid ignore_order.");
+ return false;
+ }
+ frame->ignore_order = ignore_order;
+
+ return true;
+}
+
bool QuicFramer::ProcessAckFrame(QuicDataReader* reader, uint8_t frame_type) {
const bool has_ack_blocks =
ExtractBit(frame_type, kQuicHasMultipleAckBlocksOffset);
@@ -4097,8 +4192,7 @@ void QuicFramer::SetDecrypter(EncryptionLevel level,
DCHECK_GE(level, decrypter_level_);
DCHECK(!version_.KnowsWhichDecrypterToUse());
QUIC_DVLOG(1) << ENDPOINT << "Setting decrypter from level "
- << EncryptionLevelToString(decrypter_level_) << " to "
- << EncryptionLevelToString(level);
+ << decrypter_level_ << " to " << level;
decrypter_[decrypter_level_] = nullptr;
decrypter_[level] = std::move(decrypter);
decrypter_level_ = level;
@@ -4111,8 +4205,7 @@ void QuicFramer::SetAlternativeDecrypter(
DCHECK_NE(level, decrypter_level_);
DCHECK(!version_.KnowsWhichDecrypterToUse());
QUIC_DVLOG(1) << ENDPOINT << "Setting alternative decrypter from level "
- << EncryptionLevelToString(alternative_decrypter_level_)
- << " to " << EncryptionLevelToString(level);
+ << alternative_decrypter_level_ << " to " << level;
if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
decrypter_[alternative_decrypter_level_] = nullptr;
}
@@ -4124,15 +4217,13 @@ void QuicFramer::SetAlternativeDecrypter(
void QuicFramer::InstallDecrypter(EncryptionLevel level,
std::unique_ptr<QuicDecrypter> decrypter) {
DCHECK(version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Installing decrypter at level " << level;
decrypter_[level] = std::move(decrypter);
}
void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
DCHECK(version_.KnowsWhichDecrypterToUse());
- QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Removing decrypter at level " << level;
decrypter_[level] = nullptr;
}
@@ -4156,14 +4247,12 @@ void QuicFramer::SetEncrypter(EncryptionLevel level,
std::unique_ptr<QuicEncrypter> encrypter) {
DCHECK_GE(level, 0);
DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
- QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Setting encrypter at level " << level;
encrypter_[level] = std::move(encrypter);
}
void QuicFramer::RemoveEncrypter(EncryptionLevel level) {
- QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Removing encrypter of " << level;
encrypter_[level] = nullptr;
}
@@ -4185,7 +4274,7 @@ size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
if (encrypter_[level] == nullptr) {
QUIC_BUG << ENDPOINT
<< "Attempted to encrypt in place without encrypter at level "
- << EncryptionLevelToString(level);
+ << level;
RaiseError(QUIC_ENCRYPTION_FAILURE);
return 0;
}
@@ -4248,7 +4337,7 @@ bool QuicFramer::ApplyHeaderProtection(EncryptionLevel level,
QUIC_BUG
<< ENDPOINT
<< "Attempted to apply header protection without encrypter at level "
- << EncryptionLevelToString(level) << " using " << version_;
+ << level << " using " << version_;
return false;
}
@@ -4318,7 +4407,7 @@ bool QuicFramer::RemoveHeaderProtection(QuicDataReader* reader,
QUIC_DVLOG(1)
<< ENDPOINT
<< "No decrypter available for removing header protection at level "
- << EncryptionLevelToString(expected_decryption_level);
+ << expected_decryption_level;
return false;
}
@@ -4439,7 +4528,7 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level,
DCHECK(packet_number.IsInitialized());
if (encrypter_[level] == nullptr) {
QUIC_BUG << ENDPOINT << "Attempted to encrypt without encrypter at level "
- << EncryptionLevelToString(level);
+ << level;
RaiseError(QUIC_ENCRYPTION_FAILURE);
return 0;
}
@@ -4449,6 +4538,14 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level,
// Copy in the header, because the encrypter only populates the encrypted
// plaintext content.
const size_t ad_len = associated_data.length();
+ if (packet.length() < ad_len) {
+ QUIC_BUG << ENDPOINT
+ << "packet is shorter than associated data length. version:"
+ << version() << ", packet length:" << packet.length()
+ << ", associated data length:" << ad_len;
+ RaiseError(QUIC_ENCRYPTION_FAILURE);
+ return 0;
+ }
memmove(buffer, associated_data.data(), ad_len);
// Encrypt the plaintext into the buffer.
size_t output_length = 0;
@@ -4474,7 +4571,7 @@ size_t QuicFramer::GetCiphertextSize(EncryptionLevel level,
if (encrypter_[level] == nullptr) {
QUIC_BUG << ENDPOINT
<< "Attempted to get ciphertext size without encrypter at level "
- << EncryptionLevelToString(level) << " using " << version_;
+ << level << " using " << version_;
return plaintext_size;
}
return encrypter_[level]->GetCiphertextSize(plaintext_size);
@@ -4729,7 +4826,7 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
bool last_frame_in_packet,
QuicDataWriter* writer) {
if (VersionHasIetfQuicFrames(version_.transport_version)) {
- return AppendIetfTypeByte(frame, last_frame_in_packet, writer);
+ return AppendIetfFrameType(frame, last_frame_in_packet, writer);
}
uint8_t type_byte = 0;
switch (frame.type) {
@@ -4785,9 +4882,9 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
return writer->WriteUInt8(type_byte);
}
-bool QuicFramer::AppendIetfTypeByte(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer) {
+bool QuicFramer::AppendIetfFrameType(const QuicFrame& frame,
+ bool last_frame_in_packet,
+ QuicDataWriter* writer) {
uint8_t type_byte = 0;
switch (frame.type) {
case PADDING_FRAME:
@@ -4805,7 +4902,9 @@ bool QuicFramer::AppendIetfTypeByte(const QuicFrame& frame,
type_byte = IETF_CONNECTION_CLOSE;
break;
default:
- set_detailed_error("Invalid QuicConnectionCloseFrame type.");
+ set_detailed_error(quiche::QuicheStrCat(
+ "Invalid QuicConnectionCloseFrame type: ",
+ static_cast<int>(frame.connection_close_frame->close_type)));
return RaiseError(QUIC_INTERNAL_ERROR);
}
break;
@@ -4890,12 +4989,15 @@ bool QuicFramer::AppendIetfTypeByte(const QuicFrame& frame,
case HANDSHAKE_DONE_FRAME:
type_byte = IETF_HANDSHAKE_DONE;
break;
+ case ACK_FREQUENCY_FRAME:
+ type_byte = IETF_ACK_FREQUENCY;
+ break;
default:
QUIC_BUG << "Attempt to generate a frame type for an unsupported value: "
<< frame.type;
return false;
}
- return writer->WriteUInt8(type_byte);
+ return writer->WriteVarInt62(type_byte);
}
// static
@@ -5107,6 +5209,29 @@ bool QuicFramer::AppendCryptoFrame(const QuicCryptoFrame& frame,
return true;
}
+bool QuicFramer::AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteVarInt62(frame.sequence_number)) {
+ set_detailed_error("Writing sequence number failed.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.packet_tolerance)) {
+ set_detailed_error("Writing packet tolerance failed.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(
+ static_cast<uint64_t>(frame.max_ack_delay.ToMicroseconds()))) {
+ set_detailed_error("Writing max_ack_delay_us failed.");
+ return false;
+ }
+ if (!writer->WriteUInt8(static_cast<uint8_t>(frame.ignore_order))) {
+ set_detailed_error("Writing ignore_order failed.");
+ return false;
+ }
+
+ return true;
+}
+
void QuicFramer::set_version(const ParsedQuicVersion version) {
DCHECK(IsSupportedVersion(version)) << ParsedQuicVersionToString(version);
version_ = version;
@@ -5365,7 +5490,7 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
QuicDataWriter::GetVarInt62Len(frame.ecn_ce_count));
}
- if (!writer->WriteUInt8(type)) {
+ if (!writer->WriteVarInt62(type)) {
set_detailed_error("No room for frame-type");
return false;
}
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 8ace715d285..8e63fc25722 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
@@ -218,6 +218,9 @@ class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
// Called when a handshake done frame has been parsed.
virtual bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) = 0;
+ // Called when an AckFrequencyFrame has been parsed.
+ virtual bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) = 0;
+
// Called when a packet has been completely processed.
virtual void OnPacketComplete() = 0;
@@ -321,6 +324,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// Size in bytes of all reset stream frame fields.
static size_t GetRstStreamFrameSize(QuicTransportVersion version,
const QuicRstStreamFrame& frame);
+ // Size in bytes of all ack frenquency frame fields.
+ static size_t GetAckFrequencyFrameSize(const QuicAckFrequencyFrame& frame);
// Size in bytes of all connection close frame fields, including the error
// details.
static size_t GetConnectionCloseFrameSize(
@@ -481,14 +486,16 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool AppendTypeByte(const QuicFrame& frame,
bool last_frame_in_packet,
QuicDataWriter* writer);
- bool AppendIetfTypeByte(const QuicFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
+ bool AppendIetfFrameType(const QuicFrame& frame,
+ bool last_frame_in_packet,
+ QuicDataWriter* writer);
size_t AppendIetfFrames(const QuicFrames& frames, QuicDataWriter* writer);
bool AppendStreamFrame(const QuicStreamFrame& frame,
bool last_frame_in_packet,
QuicDataWriter* writer);
bool AppendCryptoFrame(const QuicCryptoFrame& frame, QuicDataWriter* writer);
+ bool AppendAckFrequencyFrame(const QuicAckFrequencyFrame& frame,
+ QuicDataWriter* writer);
// SetDecrypter sets the primary decrypter, replacing any that already exists.
// If an alternative decrypter is in place then the function DCHECKs. This is
@@ -571,6 +578,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// Returns true if encrypter of |level| is available.
bool HasEncrypterOfEncryptionLevel(EncryptionLevel level) const;
+ // Returns true if decrypter of |level| is available.
+ bool HasDecrypterOfEncryptionLevel(EncryptionLevel level) const;
void set_validate_flags(bool value) { validate_flags_ = value; }
@@ -915,7 +924,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool ProcessCryptoFrame(QuicDataReader* reader,
EncryptionLevel encryption_level,
QuicCryptoFrame* frame);
-
+ bool ProcessAckFrequencyFrame(QuicDataReader* reader,
+ QuicAckFrequencyFrame* frame);
// IETF frame appending methods. All methods append the type byte as well.
bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
bool last_frame_in_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 fb9c2eb87bc..5a5a8fa1a8a 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
@@ -406,6 +406,15 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
return true;
}
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+ ++frame_count_;
+ ack_frequency_frames_.emplace_back(
+ std::make_unique<QuicAckFrequencyFrame>(frame));
+ DCHECK(VersionHasIetfQuicFrames(transport_version_));
+ EXPECT_EQ(IETF_ACK_FREQUENCY, framer_->current_received_frame_type());
+ return true;
+ }
+
void OnPacketComplete() override { ++complete_packets_; }
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
@@ -574,6 +583,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
std::vector<std::unique_ptr<QuicPingFrame>> ping_frames_;
std::vector<std::unique_ptr<QuicMessageFrame>> message_frames_;
std::vector<std::unique_ptr<QuicHandshakeDoneFrame>> handshake_done_frames_;
+ std::vector<std::unique_ptr<QuicAckFrequencyFrame>> ack_frequency_frames_;
std::vector<std::unique_ptr<QuicEncryptedPacket>> coalesced_packets_;
std::vector<std::unique_ptr<QuicEncryptedPacket>> undecryptable_packets_;
std::vector<EncryptionLevel> undecryptable_decryption_levels_;
@@ -5159,6 +5169,52 @@ TEST_P(QuicFramerTest, HandshakeDoneFrame) {
EXPECT_EQ(1u, visitor_.handshake_done_frames_.size());
}
+TEST_P(QuicFramerTest, ParseAckFrequencyFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
+ // clang-format off
+ unsigned char packet[] = {
+ // type (short header, 4 byte packet number)
+ 0x43,
+ // connection_id
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
+
+ // ack frequency frame type (which needs two bytes as it is > 0x3F)
+ 0x40, 0xAF,
+ // sequence_number
+ 0x11,
+ // packet_tolerance
+ 0x02,
+ // max_ack_delay_us = 2'5000 us
+ 0x80, 0x00, 0x61, 0xA8,
+ // ignore_order
+ 0x01
+ };
+ // clang-format on
+
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+
+ QuicEncryptedPacket encrypted(AsChars(packet), QUICHE_ARRAYSIZE(packet),
+ false);
+ EXPECT_TRUE(framer_.ProcessPacket(encrypted));
+
+ EXPECT_THAT(framer_.error(), IsQuicNoError());
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_TRUE(CheckDecryption(
+ encrypted, !kIncludeVersion, !kIncludeDiversificationNonce,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_0BYTE_CONNECTION_ID));
+
+ ASSERT_EQ(1u, visitor_.ack_frequency_frames_.size());
+ const auto& frame = visitor_.ack_frequency_frames_.front();
+ EXPECT_EQ(17u, frame->sequence_number);
+ EXPECT_EQ(2u, frame->packet_tolerance);
+ EXPECT_EQ(2'5000u, frame->max_ack_delay.ToMicroseconds());
+ EXPECT_EQ(true, frame->ignore_order);
+}
+
TEST_P(QuicFramerTest, MessageFrame) {
if (!VersionSupportsMessageFrames(framer_.transport_version())) {
return;
@@ -8607,6 +8663,53 @@ TEST_P(QuicFramerTest, BuildHandshakeDonePacket) {
QUICHE_ARRAYSIZE(packet));
}
+TEST_P(QuicFramerTest, BuildAckFrequencyPacket) {
+ QuicPacketHeader header;
+ header.destination_connection_id = FramerTestConnectionId();
+ header.reset_flag = false;
+ header.version_flag = false;
+ header.packet_number = kPacketNumber;
+
+ QuicAckFrequencyFrame ack_frequency_frame;
+ ack_frequency_frame.sequence_number = 3;
+ ack_frequency_frame.packet_tolerance = 5;
+ ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMicroseconds(0x3fff);
+ ack_frequency_frame.ignore_order = false;
+ QuicFrames frames = {QuicFrame(&ack_frequency_frame)};
+
+ // clang-format off
+ unsigned char packet[] = {
+ // type (short header, 4 byte packet number)
+ 0x43,
+ // connection_id
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
+
+ // frame type (Ack Frequency frame)
+ 0x40, 0xaf,
+ // sequence number
+ 0x03,
+ // packet tolerance
+ 0x05,
+ // max_ack_delay_us
+ 0x7f, 0xff,
+ // ignore_oder
+ 0x00
+ };
+ // clang-format on
+ if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
+ return;
+ }
+
+ std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
+ ASSERT_TRUE(data != nullptr);
+
+ quiche::test::CompareCharArraysWithHexError(
+ "constructed packet", data->data(), data->length(), AsChars(packet),
+ QUICHE_ARRAYSIZE(packet));
+}
+
TEST_P(QuicFramerTest, BuildMessagePacket) {
if (!VersionSupportsMessageFrames(framer_.transport_version())) {
return;
@@ -9013,6 +9116,24 @@ TEST_P(QuicFramerTest, EncryptPacket) {
EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
}
+// Regression test for b/158014497.
+TEST_P(QuicFramerTest, EncryptEmptyPacket) {
+ auto packet = std::make_unique<QuicPacket>(
+ new char[100], 0, true, PACKET_8BYTE_CONNECTION_ID,
+ PACKET_0BYTE_CONNECTION_ID,
+ /*includes_version=*/true,
+ /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
+ VARIABLE_LENGTH_INTEGER_LENGTH_0,
+ /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+ char buffer[kMaxOutgoingPacketSize];
+ size_t encrypted_length = 1;
+ EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
+ ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
+ kMaxOutgoingPacketSize),
+ "packet is shorter than associated data length");
+ EXPECT_EQ(0u, encrypted_length);
+}
+
TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
QuicPacketNumber packet_number = kPacketNumber;
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
new file mode 100644
index 00000000000..816b8c79c50
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.cc
@@ -0,0 +1,145 @@
+// 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_legacy_version_encapsulator.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_utils.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"
+
+namespace quic {
+
+QuicLegacyVersionEncapsulator::QuicLegacyVersionEncapsulator(
+ QuicPacketBuffer packet_buffer)
+ : packet_buffer_(packet_buffer) {}
+
+QuicLegacyVersionEncapsulator::~QuicLegacyVersionEncapsulator() {}
+
+// static
+QuicByteCount QuicLegacyVersionEncapsulator::GetMinimumOverhead(
+ quiche::QuicheStringPiece sni) {
+ // The number 52 is the sum of:
+ // - Flags (1 byte)
+ // - Server Connection ID (8 bytes)
+ // - Version (4 bytes)
+ // - Packet Number (1 byte)
+ // - Message Authentication Hash (12 bytes)
+ // - Frame Type (1 byte)
+ // - Stream ID (1 byte)
+ // - ClientHello tag (4 bytes)
+ // - ClientHello num tags (2 bytes)
+ // - Padding (2 bytes)
+ // - SNI tag (4 bytes)
+ // - SNI end offset (4 bytes)
+ // - QLVE tag (4 bytes)
+ // - QLVE end offset (4 bytes)
+ return 52 + sni.length();
+}
+
+QuicPacketBuffer QuicLegacyVersionEncapsulator::GetPacketBuffer() {
+ return packet_buffer_;
+}
+
+void QuicLegacyVersionEncapsulator::OnSerializedPacket(
+ SerializedPacket serialized_packet) {
+ if (encrypted_length_ != 0) {
+ unrecoverable_failure_encountered_ = true;
+ QUIC_BUG << "OnSerializedPacket called twice";
+ return;
+ }
+ if (serialized_packet.encrypted_length == 0) {
+ unrecoverable_failure_encountered_ = true;
+ QUIC_BUG << "OnSerializedPacket called with empty packet";
+ return;
+ }
+ encrypted_length_ = serialized_packet.encrypted_length;
+}
+
+void QuicLegacyVersionEncapsulator::OnUnrecoverableError(
+ QuicErrorCode error,
+ const std::string& error_details) {
+ unrecoverable_failure_encountered_ = true;
+ QUIC_BUG << "QuicLegacyVersionEncapsulator received error " << error << ": "
+ << error_details;
+}
+
+bool QuicLegacyVersionEncapsulator::ShouldGeneratePacket(
+ HasRetransmittableData /*retransmittable*/,
+ IsHandshake /*handshake*/) {
+ return true;
+}
+
+const QuicFrames
+QuicLegacyVersionEncapsulator::MaybeBundleAckOpportunistically() {
+ // We do not want to ever include any ACKs here, return an empty array.
+ return QuicFrames();
+}
+
+// static
+QuicPacketLength QuicLegacyVersionEncapsulator::Encapsulate(
+ quiche::QuicheStringPiece sni,
+ quiche::QuicheStringPiece inner_packet,
+ const QuicConnectionId& server_connection_id,
+ QuicTime creation_time,
+ QuicByteCount outer_max_packet_length,
+ char* out) {
+ if (outer_max_packet_length > kMaxOutgoingPacketSize) {
+ outer_max_packet_length = kMaxOutgoingPacketSize;
+ }
+ CryptoHandshakeMessage outer_chlo;
+ outer_chlo.set_tag(kCHLO);
+ outer_chlo.SetStringPiece(kSNI, sni);
+ outer_chlo.SetStringPiece(kQLVE, inner_packet);
+ const QuicData& serialized_outer_chlo = outer_chlo.GetSerialized();
+ DCHECK(!LegacyVersionForEncapsulation().UsesCryptoFrames());
+ DCHECK(LegacyVersionForEncapsulation().UsesQuicCrypto());
+ QuicStreamFrame outer_stream_frame(
+ QuicUtils::GetCryptoStreamId(
+ LegacyVersionForEncapsulation().transport_version),
+ /*fin=*/false,
+ /*offset=*/0, serialized_outer_chlo.AsStringPiece());
+ QuicFramer outer_framer(
+ ParsedQuicVersionVector{LegacyVersionForEncapsulation()}, creation_time,
+ Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
+ outer_framer.SetInitialObfuscators(server_connection_id);
+ char outer_encrypted_packet[kMaxOutgoingPacketSize];
+ QuicPacketBuffer outer_packet_buffer(outer_encrypted_packet, nullptr);
+ QuicLegacyVersionEncapsulator creator_delegate(outer_packet_buffer);
+ QuicPacketCreator outer_creator(server_connection_id, &outer_framer,
+ &creator_delegate);
+ outer_creator.SetMaxPacketLength(outer_max_packet_length);
+ outer_creator.set_encryption_level(ENCRYPTION_INITIAL);
+ outer_creator.SetTransmissionType(NOT_RETRANSMISSION);
+ if (!outer_creator.AddPaddedSavedFrame(QuicFrame(outer_stream_frame),
+ NOT_RETRANSMISSION)) {
+ QUIC_BUG << "Failed to add Legacy Version Encapsulation stream frame "
+ "(max packet length is "
+ << outer_creator.max_packet_length() << ") " << outer_stream_frame;
+ return 0;
+ }
+ outer_creator.FlushCurrentPacket();
+ const QuicPacketLength encrypted_length = creator_delegate.encrypted_length_;
+ if (creator_delegate.unrecoverable_failure_encountered_ ||
+ encrypted_length == 0) {
+ QUIC_BUG << "Failed to perform Legacy Version Encapsulation of "
+ << inner_packet.length() << " bytes";
+ return 0;
+ }
+ if (encrypted_length > kMaxOutgoingPacketSize) {
+ QUIC_BUG << "Legacy Version Encapsulation outer creator generated a "
+ "packet with unexpected length "
+ << encrypted_length;
+ return 0;
+ }
+
+ QUIC_DLOG(INFO) << "Successfully performed Legacy Version Encapsulation from "
+ << inner_packet.length() << " bytes to " << encrypted_length;
+
+ // Replace our current packet with the encapsulated one.
+ memcpy(out, outer_encrypted_packet, encrypted_length);
+ return encrypted_length;
+}
+
+} // namespace quic
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
new file mode 100644
index 00000000000..3d9c1564506
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator.h
@@ -0,0 +1,71 @@
+// 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_LEGACY_VERSION_ENCAPSULATOR_H_
+#define QUICHE_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_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 {
+
+// QuicLegacyVersionEncapsulator is responsible for encapsulation of packets
+// using Legacy Version Encapsulation.
+
+class QUIC_EXPORT_PRIVATE QuicLegacyVersionEncapsulator
+ : public QuicPacketCreator::DelegateInterface {
+ public:
+ // Encapsulates |inner_packet| into a new encapsulated packet that uses a
+ // CHLO of version LegacyVersionForEncapsulation() with server name |sni|
+ // exposed and using |server_connection_id|. The packet will be padded up to
+ // |outer_max_packet_length| bytes if necessary. On failure, returns 0. On
+ // success, returns the length of the outer encapsulated packet, and copies
+ // 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,
+ const QuicConnectionId& server_connection_id,
+ QuicTime creation_time,
+ QuicByteCount outer_max_packet_length,
+ char* out);
+
+ // 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);
+
+ // Overrides for QuicPacketCreator::DelegateInterface.
+ QuicPacketBuffer GetPacketBuffer() override;
+ void OnSerializedPacket(SerializedPacket serialized_packet) override;
+ void OnUnrecoverableError(QuicErrorCode error,
+ const std::string& error_details) override;
+ bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+ IsHandshake handshake) override;
+ const QuicFrames MaybeBundleAckOpportunistically() override;
+
+ ~QuicLegacyVersionEncapsulator() override;
+
+ private:
+ explicit QuicLegacyVersionEncapsulator(QuicPacketBuffer packet_buffer);
+
+ // Disallow copy, move and assignment.
+ QuicLegacyVersionEncapsulator(const QuicLegacyVersionEncapsulator&) = delete;
+ QuicLegacyVersionEncapsulator(QuicLegacyVersionEncapsulator&&) = delete;
+ QuicLegacyVersionEncapsulator& operator=(
+ const QuicLegacyVersionEncapsulator&) = delete;
+ QuicLegacyVersionEncapsulator& operator=(QuicLegacyVersionEncapsulator&&) =
+ delete;
+
+ QuicPacketBuffer packet_buffer_;
+ QuicPacketLength encrypted_length_ = 0;
+ bool unrecoverable_failure_encountered_ = false;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_QUIC_LEGACY_VERSION_ENCAPSULATOR_H_
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
new file mode 100644
index 00000000000..a71b2f44eb5
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_legacy_version_encapsulator_test.cc
@@ -0,0 +1,109 @@
+// 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_legacy_version_encapsulator.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 {
+namespace test {
+namespace {
+
+class QuicLegacyVersionEncapsulatorTest
+ : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+ QuicLegacyVersionEncapsulatorTest()
+ : version_(GetParam()),
+ sni_("test.example.org"),
+ server_connection_id_(TestConnectionId()),
+ outer_max_packet_length_(kMaxOutgoingPacketSize),
+ encapsulated_length_(0) {}
+
+ void Encapsulate(const std::string& inner_packet) {
+ encapsulated_length_ = QuicLegacyVersionEncapsulator::Encapsulate(
+ sni_, inner_packet, server_connection_id_, QuicTime::Zero(),
+ outer_max_packet_length_, outer_buffer_);
+ }
+
+ void CheckEncapsulation() {
+ ASSERT_NE(encapsulated_length_, 0u);
+ ASSERT_EQ(encapsulated_length_, outer_max_packet_length_);
+ // Verify that the encapsulated packet parses as encapsulated.
+ PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
+ QuicLongHeaderType long_packet_type;
+ bool version_present;
+ bool has_length_prefix;
+ QuicVersionLabel version_label;
+ ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
+ QuicConnectionId destination_connection_id, source_connection_id;
+ bool retry_token_present;
+ quiche::QuicheStringPiece retry_token;
+ std::string detailed_error;
+ const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
+ QuicEncryptedPacket(outer_buffer_, encapsulated_length_),
+ 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);
+ ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
+ EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
+ EXPECT_TRUE(version_present);
+ EXPECT_FALSE(has_length_prefix);
+ EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
+ EXPECT_EQ(destination_connection_id, server_connection_id_);
+ EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
+ EXPECT_FALSE(retry_token_present);
+ EXPECT_TRUE(detailed_error.empty());
+ }
+
+ QuicByteCount Overhead() {
+ return QuicLegacyVersionEncapsulator::GetMinimumOverhead(sni_);
+ }
+
+ ParsedQuicVersion version_;
+ std::string sni_;
+ QuicConnectionId server_connection_id_;
+ QuicByteCount outer_max_packet_length_;
+ char outer_buffer_[kMaxOutgoingPacketSize];
+ QuicPacketLength encapsulated_length_;
+};
+
+INSTANTIATE_TEST_SUITE_P(QuicLegacyVersionEncapsulatorTests,
+ QuicLegacyVersionEncapsulatorTest,
+ ::testing::ValuesIn(AllSupportedVersions()),
+ ::testing::PrintToStringParamName());
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, Simple) {
+ Encapsulate("TEST_INNER_PACKET");
+ CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, TooBig) {
+ std::string inner_packet(kMaxOutgoingPacketSize, '?');
+ EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+ ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, BarelyFits) {
+ QuicByteCount inner_size = kMaxOutgoingPacketSize - Overhead();
+ std::string inner_packet(inner_size, '?');
+ Encapsulate(inner_packet);
+ CheckEncapsulation();
+}
+
+TEST_P(QuicLegacyVersionEncapsulatorTest, DoesNotQuiteFit) {
+ QuicByteCount inner_size = 1 + kMaxOutgoingPacketSize - Overhead();
+ std::string inner_packet(inner_size, '?');
+ EXPECT_QUIC_BUG(Encapsulate(inner_packet), "Legacy Version Encapsulation");
+ ASSERT_EQ(encapsulated_length_, 0u);
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc
new file mode 100644
index 00000000000..6dd74c3b19c
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.cc
@@ -0,0 +1,314 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
+
+#include <linux/net_tstamp.h>
+#include <netinet/in.h>
+#include <cstdint>
+
+#include "net/third_party/quiche/src/quic/core/quic_syscall_wrapper.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/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+QuicMsgHdr::QuicMsgHdr(const char* buffer,
+ size_t buf_len,
+ const QuicSocketAddress& peer_address,
+ char* cbuf,
+ size_t cbuf_size)
+ : iov_{const_cast<char*>(buffer), buf_len},
+ cbuf_(cbuf),
+ cbuf_size_(cbuf_size),
+ cmsg_(nullptr) {
+ // Only support unconnected sockets.
+ DCHECK(peer_address.IsInitialized());
+
+ raw_peer_address_ = peer_address.generic_address();
+ hdr_.msg_name = &raw_peer_address_;
+ hdr_.msg_namelen = raw_peer_address_.ss_family == AF_INET
+ ? sizeof(sockaddr_in)
+ : sizeof(sockaddr_in6);
+
+ hdr_.msg_iov = &iov_;
+ hdr_.msg_iovlen = 1;
+ hdr_.msg_flags = 0;
+
+ hdr_.msg_control = nullptr;
+ hdr_.msg_controllen = 0;
+}
+
+void QuicMsgHdr::SetIpInNextCmsg(const QuicIpAddress& self_address) {
+ if (!self_address.IsInitialized()) {
+ return;
+ }
+
+ if (self_address.IsIPv4()) {
+ QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+ self_address, GetNextCmsgData<in_pktinfo>(IPPROTO_IP, IP_PKTINFO));
+ } else {
+ QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+ self_address, GetNextCmsgData<in6_pktinfo>(IPPROTO_IPV6, IPV6_PKTINFO));
+ }
+}
+
+void* QuicMsgHdr::GetNextCmsgDataInternal(int cmsg_level,
+ int cmsg_type,
+ size_t data_size) {
+ // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+ // return nullptr.
+ hdr_.msg_controllen += CMSG_SPACE(data_size);
+ DCHECK_LE(hdr_.msg_controllen, cbuf_size_);
+
+ if (cmsg_ == nullptr) {
+ DCHECK_EQ(nullptr, hdr_.msg_control);
+ memset(cbuf_, 0, cbuf_size_);
+ hdr_.msg_control = cbuf_;
+ cmsg_ = CMSG_FIRSTHDR(&hdr_);
+ } else {
+ DCHECK_NE(nullptr, hdr_.msg_control);
+ cmsg_ = CMSG_NXTHDR(&hdr_, cmsg_);
+ }
+
+ DCHECK_NE(nullptr, cmsg_) << "Insufficient control buffer space";
+
+ cmsg_->cmsg_len = CMSG_LEN(data_size);
+ cmsg_->cmsg_level = cmsg_level;
+ cmsg_->cmsg_type = cmsg_type;
+
+ return CMSG_DATA(cmsg_);
+}
+
+void QuicMMsgHdr::InitOneHeader(int i, const BufferedWrite& buffered_write) {
+ mmsghdr* mhdr = GetMMsgHdr(i);
+ msghdr* hdr = &mhdr->msg_hdr;
+ iovec* iov = GetIov(i);
+
+ iov->iov_base = const_cast<char*>(buffered_write.buffer);
+ iov->iov_len = buffered_write.buf_len;
+ hdr->msg_iov = iov;
+ hdr->msg_iovlen = 1;
+ hdr->msg_control = nullptr;
+ hdr->msg_controllen = 0;
+
+ // Only support unconnected sockets.
+ DCHECK(buffered_write.peer_address.IsInitialized());
+
+ sockaddr_storage* peer_address_storage = GetPeerAddressStorage(i);
+ *peer_address_storage = buffered_write.peer_address.generic_address();
+ hdr->msg_name = peer_address_storage;
+ hdr->msg_namelen = peer_address_storage->ss_family == AF_INET
+ ? sizeof(sockaddr_in)
+ : sizeof(sockaddr_in6);
+}
+
+void QuicMMsgHdr::SetIpInNextCmsg(int i, const QuicIpAddress& self_address) {
+ if (!self_address.IsInitialized()) {
+ return;
+ }
+
+ if (self_address.IsIPv4()) {
+ QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+ self_address, GetNextCmsgData<in_pktinfo>(i, IPPROTO_IP, IP_PKTINFO));
+ } else {
+ QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+ self_address,
+ GetNextCmsgData<in6_pktinfo>(i, IPPROTO_IPV6, IPV6_PKTINFO));
+ }
+}
+
+void* QuicMMsgHdr::GetNextCmsgDataInternal(int i,
+ int cmsg_level,
+ int cmsg_type,
+ size_t data_size) {
+ mmsghdr* mhdr = GetMMsgHdr(i);
+ msghdr* hdr = &mhdr->msg_hdr;
+ cmsghdr*& cmsg = *GetCmsgHdr(i);
+
+ // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
+ // return nullptr.
+ hdr->msg_controllen += CMSG_SPACE(data_size);
+ DCHECK_LE(hdr->msg_controllen, cbuf_size_);
+
+ if (cmsg == nullptr) {
+ DCHECK_EQ(nullptr, hdr->msg_control);
+ hdr->msg_control = GetCbuf(i);
+ cmsg = CMSG_FIRSTHDR(hdr);
+ } else {
+ DCHECK_NE(nullptr, hdr->msg_control);
+ cmsg = CMSG_NXTHDR(hdr, cmsg);
+ }
+
+ DCHECK_NE(nullptr, cmsg) << "Insufficient control buffer space";
+
+ cmsg->cmsg_len = CMSG_LEN(data_size);
+ cmsg->cmsg_level = cmsg_level;
+ cmsg->cmsg_type = cmsg_type;
+
+ return CMSG_DATA(cmsg);
+}
+
+int QuicMMsgHdr::num_bytes_sent(int num_packets_sent) {
+ DCHECK_LE(0, num_packets_sent);
+ DCHECK_LE(num_packets_sent, num_msgs_);
+
+ int bytes_sent = 0;
+ iovec* iov = GetIov(0);
+ for (int i = 0; i < num_packets_sent; ++i) {
+ bytes_sent += iov[i].iov_len;
+ }
+ return bytes_sent;
+}
+
+// static
+int QuicLinuxSocketUtils::GetUDPSegmentSize(int fd) {
+ int optval;
+ socklen_t optlen = sizeof(optval);
+ int rc = getsockopt(fd, SOL_UDP, UDP_SEGMENT, &optval, &optlen);
+ if (rc < 0) {
+ QUIC_LOG_EVERY_N_SEC(INFO, 10)
+ << "getsockopt(UDP_SEGMENT) failed: " << strerror(errno);
+ return -1;
+ }
+ QUIC_LOG_EVERY_N_SEC(INFO, 10)
+ << "getsockopt(UDP_SEGMENT) returned segment size: " << optval;
+ return optval;
+}
+
+// static
+bool QuicLinuxSocketUtils::EnableReleaseTime(int fd, clockid_t clockid) {
+ // TODO(wub): Change to sock_txtime once it is available in linux/net_tstamp.h
+ struct LinuxSockTxTime {
+ clockid_t clockid; /* reference clockid */
+ uint32_t flags; /* flags defined by enum txtime_flags */
+ };
+
+ LinuxSockTxTime so_txtime_val{clockid, 0};
+
+ if (setsockopt(fd, SOL_SOCKET, SO_TXTIME, &so_txtime_val,
+ sizeof(so_txtime_val)) != 0) {
+ QUIC_LOG_EVERY_N_SEC(INFO, 10)
+ << "setsockopt(SOL_SOCKET,SO_TXTIME) failed: " << strerror(errno);
+ return false;
+ }
+
+ return true;
+}
+
+// static
+bool QuicLinuxSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) {
+ if (hdr->msg_controllen > 0) {
+ struct cmsghdr* cmsg;
+ for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr;
+ cmsg = CMSG_NXTHDR(hdr, cmsg)) {
+ if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
+ (cmsg->cmsg_level == IPPROTO_IPV6 &&
+ cmsg->cmsg_type == IPV6_HOPLIMIT)) {
+ *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// static
+void QuicLinuxSocketUtils::SetIpInfoInCmsgData(
+ const QuicIpAddress& self_address,
+ void* cmsg_data) {
+ DCHECK(self_address.IsInitialized());
+ const std::string& address_str = self_address.ToPackedString();
+ if (self_address.IsIPv4()) {
+ in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
+ pktinfo->ipi_ifindex = 0;
+ memcpy(&pktinfo->ipi_spec_dst, address_str.c_str(), address_str.length());
+ } else if (self_address.IsIPv6()) {
+ in6_pktinfo* pktinfo = static_cast<in6_pktinfo*>(cmsg_data);
+ memcpy(&pktinfo->ipi6_addr, address_str.c_str(), address_str.length());
+ } else {
+ QUIC_BUG << "Unrecognized IPAddress";
+ }
+}
+
+// static
+size_t QuicLinuxSocketUtils::SetIpInfoInCmsg(const QuicIpAddress& self_address,
+ cmsghdr* cmsg) {
+ std::string address_string;
+ if (self_address.IsIPv4()) {
+ cmsg->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
+ cmsg->cmsg_level = IPPROTO_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+ memset(pktinfo, 0, sizeof(in_pktinfo));
+ pktinfo->ipi_ifindex = 0;
+ address_string = self_address.ToPackedString();
+ memcpy(&pktinfo->ipi_spec_dst, address_string.c_str(),
+ address_string.length());
+ return sizeof(in_pktinfo);
+ } else if (self_address.IsIPv6()) {
+ cmsg->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
+ cmsg->cmsg_level = IPPROTO_IPV6;
+ cmsg->cmsg_type = IPV6_PKTINFO;
+ in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+ memset(pktinfo, 0, sizeof(in6_pktinfo));
+ address_string = self_address.ToPackedString();
+ memcpy(&pktinfo->ipi6_addr, address_string.c_str(),
+ address_string.length());
+ return sizeof(in6_pktinfo);
+ } else {
+ QUIC_BUG << "Unrecognized IPAddress";
+ return 0;
+ }
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WritePacket(int fd, const QuicMsgHdr& hdr) {
+ int rc;
+ do {
+ rc = GetGlobalSyscallWrapper()->Sendmsg(fd, hdr.hdr(), 0);
+ } while (rc < 0 && errno == EINTR);
+ if (rc >= 0) {
+ return WriteResult(WRITE_STATUS_OK, rc);
+ }
+ return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+ ? WRITE_STATUS_BLOCKED
+ : WRITE_STATUS_ERROR,
+ errno);
+}
+
+// static
+WriteResult QuicLinuxSocketUtils::WriteMultiplePackets(int fd,
+ QuicMMsgHdr* mhdr,
+ int* num_packets_sent) {
+ *num_packets_sent = 0;
+
+ if (mhdr->num_msgs() <= 0) {
+ return WriteResult(WRITE_STATUS_ERROR, EINVAL);
+ }
+
+ int rc;
+ do {
+ rc = GetGlobalSyscallWrapper()->Sendmmsg(fd, mhdr->mhdr(), mhdr->num_msgs(),
+ 0);
+ } while (rc < 0 && errno == EINTR);
+
+ if (rc > 0) {
+ *num_packets_sent = rc;
+
+ return WriteResult(WRITE_STATUS_OK, mhdr->num_bytes_sent(rc));
+ } else if (rc == 0) {
+ QUIC_BUG << "sendmmsg returned 0, returning WRITE_STATUS_ERROR. errno: "
+ << errno;
+ errno = EIO;
+ }
+
+ return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK)
+ ? WRITE_STATUS_BLOCKED
+ : WRITE_STATUS_ERROR,
+ errno);
+}
+
+} // namespace quic
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
new file mode 100644
index 00000000000..40916579fad
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h
@@ -0,0 +1,298 @@
+// 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_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <deque>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#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_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/quic/platform/api/quic_socket_address.h"
+
+#ifndef SOL_UDP
+#define SOL_UDP 17
+#endif
+
+#ifndef UDP_SEGMENT
+#define UDP_SEGMENT 103
+#endif
+
+#ifndef UDP_MAX_SEGMENTS
+#define UDP_MAX_SEGMENTS (1 << 6UL)
+#endif
+
+#ifndef SO_TXTIME
+#define SO_TXTIME 61
+#endif
+
+namespace quic {
+
+const int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
+const int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
+// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
+const int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
+ ? kCmsgSpaceForIpv6
+ : kCmsgSpaceForIpv4;
+
+const int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));
+
+const int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));
+
+const int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));
+
+// QuicMsgHdr is used to build msghdr objects that can be used send packets via
+// ::sendmsg.
+//
+// Example:
+// // cbuf holds control messages(cmsgs). The size is determined from what
+// // cmsgs will be set for this msghdr.
+// char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
+// QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
+//
+// // Set IP in cmsgs.
+// hdr.SetIpInNextCmsg(self_addr);
+//
+// // Set GSO size in cmsgs.
+// *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
+//
+// QuicLinuxSocketUtils::WritePacket(fd, hdr);
+class QUIC_EXPORT_PRIVATE QuicMsgHdr {
+ public:
+ QuicMsgHdr(const char* buffer,
+ size_t buf_len,
+ const QuicSocketAddress& peer_address,
+ char* cbuf,
+ size_t cbuf_size);
+
+ // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
+ void SetIpInNextCmsg(const QuicIpAddress& self_address);
+
+ template <typename DataType>
+ DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
+ return reinterpret_cast<DataType*>(
+ GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
+ }
+
+ const msghdr* hdr() const { return &hdr_; }
+
+ protected:
+ void* GetNextCmsgDataInternal(int cmsg_level,
+ int cmsg_type,
+ size_t data_size);
+
+ msghdr hdr_;
+ iovec iov_;
+ sockaddr_storage raw_peer_address_;
+ char* cbuf_;
+ const size_t cbuf_size_;
+ // The last cmsg populated so far. nullptr means nothing has been populated.
+ cmsghdr* cmsg_;
+};
+
+// BufferedWrite holds all information needed to send a packet.
+struct QUIC_EXPORT_PRIVATE BufferedWrite {
+ BufferedWrite(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address)
+ : BufferedWrite(buffer,
+ buf_len,
+ self_address,
+ peer_address,
+ std::unique_ptr<PerPacketOptions>(),
+ /*release_time=*/0) {}
+
+ BufferedWrite(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ std::unique_ptr<PerPacketOptions> options,
+ uint64_t release_time)
+ : buffer(buffer),
+ buf_len(buf_len),
+ self_address(self_address),
+ peer_address(peer_address),
+ options(std::move(options)),
+ release_time(release_time) {}
+
+ const char* buffer; // Not owned.
+ size_t buf_len;
+ QuicIpAddress self_address;
+ QuicSocketAddress peer_address;
+ std::unique_ptr<PerPacketOptions> options;
+
+ // The release time according to the owning packet writer's clock, which is
+ // often not a QuicClock. Calculated from packet writer's Now() and the
+ // release time delay in |options|.
+ // 0 means it can be sent at the same time as the previous packet in a batch,
+ // or can be sent Now() if this is the first packet of a batch.
+ uint64_t release_time;
+};
+
+// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
+// multiple packets at once via ::sendmmsg.
+//
+// Example:
+// QuicCircularDeque<BufferedWrite> buffered_writes;
+// ... (Populate buffered_writes) ...
+//
+// QuicMMsgHdr mhdr(
+// buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
+// [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+// mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+// });
+//
+// int num_packets_sent;
+// 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;
+ template <typename IteratorT>
+ QuicMMsgHdr(const IteratorT& first,
+ const IteratorT& last,
+ size_t cbuf_size,
+ ControlBufferInitializer cbuf_initializer)
+ : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
+ static_assert(
+ std::is_same<typename std::iterator_traits<IteratorT>::value_type,
+ BufferedWrite>::value,
+ "Must iterate over a collection of BufferedWrite.");
+
+ DCHECK_LE(0, num_msgs_);
+ if (num_msgs_ == 0) {
+ return;
+ }
+
+ storage_.reset(new char[StorageSize()]);
+ memset(&storage_[0], 0, StorageSize());
+
+ int i = -1;
+ for (auto it = first; it != last; ++it) {
+ ++i;
+
+ InitOneHeader(i, *it);
+ if (cbuf_initializer) {
+ cbuf_initializer(this, i, *it);
+ }
+ }
+ }
+
+ void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);
+
+ template <typename DataType>
+ DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
+ return reinterpret_cast<DataType*>(
+ GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
+ }
+
+ mmsghdr* mhdr() { return GetMMsgHdr(0); }
+
+ int num_msgs() const { return num_msgs_; }
+
+ // Get the total number of bytes in the first |num_packets_sent| packets.
+ int num_bytes_sent(int num_packets_sent);
+
+ protected:
+ void InitOneHeader(int i, const BufferedWrite& buffered_write);
+
+ void* GetNextCmsgDataInternal(int i,
+ int cmsg_level,
+ int cmsg_type,
+ size_t data_size);
+
+ size_t StorageSize() const {
+ return num_msgs_ *
+ (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
+ sizeof(cmsghdr*) + cbuf_size_);
+ }
+
+ mmsghdr* GetMMsgHdr(int i) {
+ auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
+ return &first[i];
+ }
+
+ iovec* GetIov(int i) {
+ auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
+ return &first[i];
+ }
+
+ sockaddr_storage* GetPeerAddressStorage(int i) {
+ auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
+ return &first[i];
+ }
+
+ cmsghdr** GetCmsgHdr(int i) {
+ auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
+ return &first[i];
+ }
+
+ char* GetCbuf(int i) {
+ auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
+ return &first[i * cbuf_size_];
+ }
+
+ const int num_msgs_;
+ // Size of cmsg buffer for each message.
+ const size_t cbuf_size_;
+ // storage_ holds the memory of
+ // |num_msgs_| mmsghdr
+ // |num_msgs_| iovec
+ // |num_msgs_| sockaddr_storage, for peer addresses
+ // |num_msgs_| cmsghdr*
+ // |num_msgs_| cbuf, each of size cbuf_size
+ std::unique_ptr<char[]> storage_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicLinuxSocketUtils {
+ public:
+ // Return the UDP segment size of |fd|, 0 means segment size has not been set
+ // on this socket. If GSO is not supported, return -1.
+ static int GetUDPSegmentSize(int fd);
+
+ // Enable release time on |fd|.
+ static bool EnableReleaseTime(int fd, clockid_t clockid);
+
+ // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
+ // value and return true. Otherwise it will return false.
+ static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);
+
+ // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
+ // containing cmsghdr.
+ static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
+ void* cmsg_data);
+
+ // A helper for WritePacket which fills in the cmsg with the supplied self
+ // address.
+ // Returns the length of the packet info structure used.
+ static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
+ cmsghdr* cmsg);
+
+ // Writes the packet in |hdr| to the socket, using ::sendmsg.
+ static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);
+
+ // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
+ static WriteResult WriteMultiplePackets(int fd,
+ QuicMMsgHdr* mhdr,
+ int* num_packets_sent);
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_LINUX_SOCKET_UTILS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc
new file mode 100644
index 00000000000..32ad12f1473
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_linux_socket_utils_test.cc
@@ -0,0 +1,329 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <cstddef>
+#include <sstream>
+#include <vector>
+
+#include <string>
+
+#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicLinuxSocketUtilsTest : public QuicTest {
+ protected:
+ WriteResult TestWriteMultiplePackets(
+ int fd,
+ const QuicCircularDeque<BufferedWrite>::const_iterator& first,
+ const QuicCircularDeque<BufferedWrite>::const_iterator& last,
+ int* num_packets_sent) {
+ QuicMMsgHdr mhdr(
+ first, last, kCmsgSpaceForIp,
+ [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+ mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+ });
+
+ WriteResult res =
+ QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
+ return res;
+ }
+
+ MockQuicSyscallWrapper mock_syscalls_;
+ ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
+};
+
+void CheckIpAndTtlInCbuf(msghdr* hdr,
+ const void* cbuf,
+ const QuicIpAddress& self_addr,
+ int ttl) {
+ const bool is_ipv4 = self_addr.IsIPv4();
+ const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+ EXPECT_EQ(cbuf, hdr->msg_control);
+ EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+ cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+ EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+ : CMSG_LEN(sizeof(in6_pktinfo)));
+ EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+ EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+ const std::string& self_addr_str = self_addr.ToPackedString();
+ if (is_ipv4) {
+ in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+ EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+ self_addr_str.length()));
+ } else {
+ in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+ EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+ self_addr_str.length()));
+ }
+
+ cmsg = CMSG_NXTHDR(hdr, cmsg);
+ EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
+ EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+ EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
+ EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+
+ EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+void CheckMsghdrWithoutCbuf(const msghdr* hdr,
+ const void* buffer,
+ size_t buf_len,
+ const QuicSocketAddress& peer_addr) {
+ EXPECT_EQ(
+ peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
+ hdr->msg_namelen);
+ sockaddr_storage peer_generic_addr = peer_addr.generic_address();
+ EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
+ EXPECT_EQ(1u, hdr->msg_iovlen);
+ EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
+ EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
+ EXPECT_EQ(0, hdr->msg_flags);
+ EXPECT_EQ(nullptr, hdr->msg_control);
+ EXPECT_EQ(0u, hdr->msg_controllen);
+}
+
+void CheckIpAndGsoSizeInCbuf(msghdr* hdr,
+ const void* cbuf,
+ const QuicIpAddress& self_addr,
+ uint16_t gso_size) {
+ const bool is_ipv4 = self_addr.IsIPv4();
+ const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+
+ EXPECT_EQ(cbuf, hdr->msg_control);
+ EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);
+
+ cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
+ EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
+ : CMSG_LEN(sizeof(in6_pktinfo)));
+ EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
+ EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
+
+ const std::string& self_addr_str = self_addr.ToPackedString();
+ if (is_ipv4) {
+ in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
+ EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
+ self_addr_str.length()));
+ } else {
+ in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
+ EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
+ self_addr_str.length()));
+ }
+
+ cmsg = CMSG_NXTHDR(hdr, cmsg);
+ EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
+ EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
+ EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
+ EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));
+
+ EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
+ QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
+ char packet_buf[1024];
+
+ QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
+ CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
+ peer_addr);
+
+ for (bool is_ipv4 : {true, false}) {
+ QuicIpAddress self_addr =
+ is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
+ char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
+ QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
+ sizeof(cbuf));
+ msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());
+
+ EXPECT_EQ(nullptr, hdr->msg_control);
+ EXPECT_EQ(0u, hdr->msg_controllen);
+
+ quic_hdr.SetIpInNextCmsg(self_addr);
+ EXPECT_EQ(cbuf, hdr->msg_control);
+ const size_t ip_cmsg_space =
+ is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
+ EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);
+
+ if (is_ipv4) {
+ *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
+ } else {
+ *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
+ }
+
+ CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
+ }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
+ QuicCircularDeque<BufferedWrite> buffered_writes;
+ char packet_buf1[1024];
+ char packet_buf2[512];
+ buffered_writes.emplace_back(
+ packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
+ QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
+ buffered_writes.emplace_back(
+ packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
+ QuicSocketAddress(QuicIpAddress::Loopback6(), 6));
+
+ QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
+ buffered_writes.end(), 0, nullptr);
+ for (size_t i = 0; i < buffered_writes.size(); ++i) {
+ const BufferedWrite& bw = buffered_writes[i];
+ CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
+ bw.buf_len, bw.peer_address);
+ }
+
+ QuicMMsgHdr quic_mhdr_with_cbuf(
+ buffered_writes.begin(), buffered_writes.end(),
+ kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
+ [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
+ mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
+ *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
+ });
+ for (size_t i = 0; i < buffered_writes.size(); ++i) {
+ const BufferedWrite& bw = buffered_writes[i];
+ msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
+ CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
+ }
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
+ int num_packets_sent;
+ QuicCircularDeque<BufferedWrite> buffered_writes;
+
+ EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);
+
+ EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
+ TestWriteMultiplePackets(1, buffered_writes.begin(),
+ buffered_writes.end(), &num_packets_sent));
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
+ int num_packets_sent;
+ QuicCircularDeque<BufferedWrite> buffered_writes;
+ buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+ QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+ EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+ .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+ unsigned int /*vlen*/, int /*flags*/) {
+ errno = EWOULDBLOCK;
+ return -1;
+ }));
+
+ EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
+ TestWriteMultiplePackets(1, buffered_writes.begin(),
+ buffered_writes.end(), &num_packets_sent));
+ EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
+ int num_packets_sent;
+ QuicCircularDeque<BufferedWrite> buffered_writes;
+ buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
+ QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+ EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+ .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
+ unsigned int /*vlen*/, int /*flags*/) {
+ errno = EPERM;
+ return -1;
+ }));
+
+ EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
+ TestWriteMultiplePackets(1, buffered_writes.begin(),
+ buffered_writes.end(), &num_packets_sent));
+ EXPECT_EQ(0, num_packets_sent);
+}
+
+TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
+ int num_packets_sent;
+ QuicCircularDeque<BufferedWrite> buffered_writes;
+ const int kNumBufferedWrites = 10;
+ static_assert(kNumBufferedWrites < 256, "Must be less than 256");
+ std::vector<std::string> buffer_holder;
+ for (int i = 0; i < kNumBufferedWrites; ++i) {
+ size_t buf_len = (i + 1) * 2;
+ std::ostringstream buffer_ostream;
+ while (buffer_ostream.str().length() < buf_len) {
+ buffer_ostream << i;
+ }
+ buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');
+
+ buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
+ QuicIpAddress(),
+ QuicSocketAddress(QuicIpAddress::Any4(), 0));
+
+ // Leave the first self_address uninitialized.
+ if (i != 0) {
+ ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
+ }
+
+ std::ostringstream peer_ip_ostream;
+ QuicIpAddress peer_ip_address;
+ peer_ip_ostream << "127.0.1." << i + 1;
+ ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
+ buffered_writes.back().peer_address =
+ QuicSocketAddress(peer_ip_address, i + 1);
+ }
+
+ InSequence s;
+
+ for (int expected_num_packets_sent : {1, 2, 3, 10}) {
+ SCOPED_TRACE(testing::Message()
+ << "expected_num_packets_sent=" << expected_num_packets_sent);
+ EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
+ .WillOnce(Invoke(
+ [&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen, int /*flags*/) {
+ EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent),
+ vlen);
+ for (unsigned int i = 0; i < vlen; ++i) {
+ const BufferedWrite& buffered_write = buffered_writes[i];
+ const msghdr& hdr = msgvec[i].msg_hdr;
+ EXPECT_EQ(1u, hdr.msg_iovlen);
+ EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
+ EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
+ sockaddr_storage expected_peer_address =
+ buffered_write.peer_address.generic_address();
+ EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
+ sizeof(sockaddr_storage)));
+ EXPECT_EQ(buffered_write.self_address.IsInitialized(),
+ hdr.msg_control != nullptr);
+ }
+ return expected_num_packets_sent;
+ }))
+ .RetiresOnSaturation();
+
+ int expected_bytes_written = 0;
+ for (auto it = buffered_writes.cbegin();
+ it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
+ expected_bytes_written += it->buf_len;
+ }
+
+ EXPECT_EQ(
+ WriteResult(WRITE_STATUS_OK, expected_bytes_written),
+ TestWriteMultiplePackets(1, buffered_writes.cbegin(),
+ buffered_writes.cend(), &num_packets_sent));
+ EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
+ }
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
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 0ae78d22fa6..c1f8982f705 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
@@ -47,10 +47,10 @@ QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
case ENCRYPTION_FORWARD_SECURE:
QUIC_BUG
<< "Try to derive long header type for packet with encryption level: "
- << EncryptionLevelToString(level);
+ << level;
return INVALID_PACKET_TYPE;
default:
- QUIC_BUG << EncryptionLevelToString(level);
+ QUIC_BUG << level;
return INVALID_PACKET_TYPE;
}
}
@@ -165,6 +165,8 @@ void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
if (length == max_packet_length_) {
return;
}
+ QUIC_DVLOG(1) << "Updating packet creator max packet length from "
+ << max_packet_length_ << " to " << length;
max_packet_length_ = length;
max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
@@ -198,6 +200,8 @@ void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
}
if (framer_->GetMaxPlaintextSize(length) <
PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
+ // Please note: this would not guarantee to fit next packet if the size of
+ // packet header increases (e.g., encryption level changes).
QUIC_DLOG(INFO) << length << " is too small to fit packet header";
return;
}
@@ -281,6 +285,10 @@ bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
bool needs_full_padding,
TransmissionType transmission_type,
QuicFrame* frame) {
+ QUIC_DVLOG(2) << "ConsumeCryptoDataToFillCurrentPacket " << level
+ << " write_length " << write_length << " offset " << offset
+ << (needs_full_padding ? " needs_full_padding" : "") << " "
+ << transmission_type;
if (!CreateCryptoFrame(level, write_length, offset, frame)) {
return false;
}
@@ -423,8 +431,17 @@ bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
QuicFrame* frame) {
size_t min_frame_size =
QuicFramer::GetMinCryptoFrameSize(write_length, offset);
- if (BytesFree() <= min_frame_size &&
- (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
+ size_t min_plaintext_bytes = min_frame_size;
+ if (fix_min_crypto_frame_size_ && queued_frames_.empty()) {
+ // TODO(fayang): to make this more general, we need to move the checking
+ // when trying to add a frame when GetSerializedFrameLength. Remove soft
+ // limit if current packet needs extra padding and the space is too small.
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_min_crypto_frame_size);
+ min_plaintext_bytes =
+ std::max(min_frame_size, MinPlaintextPacketSize(framer_->version()));
+ }
+ if (BytesFree() <= min_plaintext_bytes &&
+ (!RemoveSoftMaxPacketLength() || BytesFree() <= min_plaintext_bytes)) {
return false;
}
size_t max_write_length = BytesFree() - min_frame_size;
@@ -439,12 +456,23 @@ void QuicPacketCreator::FlushCurrentPacket() {
}
QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
- char* serialized_packet_buffer = delegate_->GetPacketBuffer();
- if (serialized_packet_buffer == nullptr) {
- serialized_packet_buffer = stack_buffer;
+ QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
+
+ if (!avoid_leak_writer_buffer_ && external_buffer.release_buffer != nullptr) {
+ // This is not a flag count because it is incremented when flag is false.
+ QUIC_CODE_COUNT(quic_avoid_leak_writer_buffer_flag_false_noop_1);
+
+ // Setting it to nullptr to keep the behavior unchanged when flag is false.
+ external_buffer.release_buffer = nullptr;
+ }
+
+ if (external_buffer.buffer == nullptr) {
+ external_buffer.buffer = stack_buffer;
+ external_buffer.release_buffer = nullptr;
}
- SerializePacket(serialized_packet_buffer, kMaxOutgoingPacketSize);
+ DCHECK_EQ(nullptr, packet_.encrypted_buffer);
+ SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize);
OnSerializedPacket();
}
@@ -471,6 +499,12 @@ void QuicPacketCreator::ClearPacket() {
packet_.transmission_type = NOT_RETRANSMISSION;
packet_.encrypted_buffer = nullptr;
packet_.encrypted_length = 0;
+ if (avoid_leak_writer_buffer_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_avoid_leak_writer_buffer, 2, 3);
+ QUIC_BUG_IF(packet_.release_encrypted_buffer != nullptr)
+ << "packet_.release_encrypted_buffer should be empty";
+ packet_.release_encrypted_buffer = nullptr;
+ }
DCHECK(packet_.retransmittable_frames.empty());
DCHECK(packet_.nonretransmittable_frames.empty());
packet_.largest_acked.Clear();
@@ -514,7 +548,7 @@ size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
return 0;
}
}
- SerializePacket(buffer, buffer_len);
+ SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len);
const size_t encrypted_length = packet_.encrypted_length;
// Clear frames in packet_. No need to DeleteFrames since frames are owned by
// initial_packet.
@@ -533,16 +567,29 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame(
TransmissionType transmission_type,
size_t* num_bytes_consumed) {
DCHECK(queued_frames_.empty());
+ DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
// Write out the packet header
QuicPacketHeader header;
FillPacketHeader(&header);
QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
- char* encrypted_buffer = delegate_->GetPacketBuffer();
- if (encrypted_buffer == nullptr) {
- encrypted_buffer = stack_buffer;
+ QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
+
+ if (!avoid_leak_writer_buffer_ && packet_buffer.release_buffer != nullptr) {
+ // This is not a flag count because it is incremented when flag is false.
+ QUIC_CODE_COUNT(quic_avoid_leak_writer_buffer_flag_false_noop_2);
+
+ // Setting it to nullptr to keep the behavior unchanged when flag is false.
+ packet_buffer.release_buffer = nullptr;
}
+ if (packet_buffer.buffer == nullptr) {
+ packet_buffer.buffer = stack_buffer;
+ packet_buffer.release_buffer = nullptr;
+ }
+
+ char* encrypted_buffer = packet_buffer.buffer;
+
QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
size_t length_field_offset = 0;
if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
@@ -609,6 +656,9 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame(
packet_.transmission_type = transmission_type;
+ DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
+ packet_.encryption_level == ENCRYPTION_ZERO_RTT)
+ << packet_.encryption_level;
size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header),
@@ -623,6 +673,14 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame(
packet_size_ = 0;
packet_.encrypted_buffer = encrypted_buffer;
packet_.encrypted_length = encrypted_length;
+ if (avoid_leak_writer_buffer_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_avoid_leak_writer_buffer, 3, 3);
+ packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
+ } else {
+ // If flag --quic_avoid_leak_writer_buffer is false, the release function
+ // should be empty.
+ DCHECK(packet_buffer.release_buffer == nullptr);
+ }
packet_.retransmittable_frames.push_back(QuicFrame(frame));
OnSerializedPacket();
}
@@ -674,6 +732,9 @@ size_t QuicPacketCreator::BytesFree() {
}
size_t QuicPacketCreator::PacketSize() {
+ if (update_packet_size_) {
+ return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
+ }
if (!queued_frames_.empty()) {
return packet_size_;
}
@@ -691,7 +752,7 @@ bool QuicPacketCreator::AddPaddedSavedFrame(
return false;
}
-void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
+void QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
size_t encrypted_buffer_len) {
DCHECK_LT(0u, encrypted_buffer_len);
QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
@@ -704,14 +765,13 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
<< QuicFramesToString(queued_frames_) << " at encryption_level "
- << EncryptionLevelToString(packet_.encryption_level);
+ << packet_.encryption_level;
if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
QUIC_BUG << ENDPOINT << "Attempting to serialize " << header
<< QuicFramesToString(queued_frames_)
- << " at missing encryption_level "
- << EncryptionLevelToString(packet_.encryption_level) << " using "
- << framer_->version();
+ << " at missing encryption_level " << packet_.encryption_level
+ << " using " << framer_->version();
return;
}
@@ -719,10 +779,18 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
// Use the packet_size_ instead of the buffer size to ensure smaller
// packet sizes are properly used.
size_t length =
- framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer,
+ framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer.buffer,
packet_size_, packet_.encryption_level);
if (length == 0) {
- QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
+ QUIC_BUG << "Failed to serialize " << QuicFramesToString(queued_frames_)
+ << " at encryption_level: " << packet_.encryption_level
+ << ", needs_full_padding_: " << needs_full_padding_
+ << ", packet_.num_padding_bytes: " << packet_.num_padding_bytes
+ << ", pending_padding_bytes_: " << pending_padding_bytes_
+ << ", latched_hard_max_packet_length_: "
+ << latched_hard_max_packet_length_
+ << ", max_packet_length_: " << max_packet_length_
+ << ", header: " << header;
return;
}
@@ -741,7 +809,7 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
const size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header), length,
- encrypted_buffer_len, encrypted_buffer);
+ encrypted_buffer_len, encrypted_buffer.buffer);
if (encrypted_length == 0) {
QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
return;
@@ -749,8 +817,17 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
packet_size_ = 0;
queued_frames_.clear();
- packet_.encrypted_buffer = encrypted_buffer;
+ packet_.encrypted_buffer = encrypted_buffer.buffer;
packet_.encrypted_length = encrypted_length;
+ if (avoid_leak_writer_buffer_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_avoid_leak_writer_buffer, 1, 3);
+ packet_.release_encrypted_buffer =
+ std::move(encrypted_buffer).release_buffer;
+ } else {
+ // If flag --quic_avoid_leak_writer_buffer is false, the release function
+ // should be empty.
+ DCHECK(encrypted_buffer.release_buffer == nullptr);
+ }
}
std::unique_ptr<QuicEncryptedPacket>
@@ -785,6 +862,7 @@ QuicPacketCreator::SerializeConnectivityProbingPacket() {
header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
DCHECK(length);
+ DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
const size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header), length,
@@ -824,6 +902,7 @@ QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
packet_.encryption_level);
DCHECK(length);
+ DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
const size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header), length,
@@ -865,6 +944,7 @@ QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
payloads, is_padded, packet_.encryption_level);
DCHECK(length);
+ DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
const size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header), length,
@@ -1180,9 +1260,9 @@ QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
latched_hard_max_packet_length_ == 0;
- while (!run_fast_path && delegate_->ShouldGeneratePacket(
- HAS_RETRANSMITTABLE_DATA,
- has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
+ while (!run_fast_path &&
+ (has_handshake || delegate_->ShouldGeneratePacket(
+ HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
QuicFrame frame;
bool needs_full_padding =
has_handshake && fully_pad_crypto_handshake_packets_;
@@ -1268,6 +1348,8 @@ QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
size_t write_length,
QuicStreamOffset offset) {
+ QUIC_DVLOG(2) << "ConsumeCryptoData " << level << " write_length "
+ << write_length << " offset " << offset;
QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
"generator tries to write crypto data.";
MaybeBundleAckOpportunistically();
@@ -1282,7 +1364,13 @@ size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
size_t total_bytes_consumed = 0;
- while (total_bytes_consumed < write_length) {
+ while (total_bytes_consumed < write_length &&
+ (!GetQuicReloadableFlag(quic_fix_checking_should_generate_packet) ||
+ delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
+ IS_HANDSHAKE))) {
+ if (GetQuicReloadableFlag(quic_fix_checking_should_generate_packet)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_checking_should_generate_packet);
+ }
QuicFrame frame;
if (!ConsumeCryptoDataToFillCurrentPacket(
level, write_length - total_bytes_consumed,
@@ -1484,7 +1572,7 @@ void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
TransmissionType transmission_type) {
QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
- << TransmissionTypeToString(transmission_type) << ": " << frame;
+ << transmission_type << ": " << frame;
if (frame.type == STREAM_FRAME &&
!QuicUtils::IsCryptoStreamId(framer_->transport_version(),
frame.stream_frame.stream_id) &&
@@ -1518,10 +1606,15 @@ bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
/* last_frame_in_packet= */ true, GetPacketNumberLength());
}
if (frame_len == 0) {
- // Current open packet is full.
+ QUIC_DVLOG(1) << "Flushing because current open packet is full when adding "
+ << frame;
FlushCurrentPacket();
return false;
}
+ if (update_packet_size_ && queued_frames_.empty()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_update_packet_size);
+ packet_size_ = PacketHeaderSize();
+ }
DCHECK_LT(0u, packet_size_);
packet_size_ += ExpansionOnNewFrame() + frame_len;
@@ -1641,6 +1734,10 @@ void QuicPacketCreator::MaybeAddPadding() {
}
}
+ if (disable_padding_override_) {
+ needs_full_padding_ = false;
+ }
+
// Header protection requires a minimum plaintext packet size.
size_t extra_padding_bytes = 0;
if (framer_->version().HasHeaderProtection()) {
@@ -1675,8 +1772,7 @@ void QuicPacketCreator::MaybeAddPadding() {
bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
packet_.transmission_type);
QUIC_BUG_IF(!success) << "Failed to add padding_bytes: " << padding_bytes
- << " transmission_type: "
- << TransmissionTypeToString(packet_.transmission_type);
+ << " transmission_type: " << packet_.transmission_type;
}
bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
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 7695587f9f5..76d65574e51 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
@@ -41,9 +41,9 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
public:
virtual ~DelegateInterface() {}
// Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
- // packet. If return nullptr, QuicPacketCreator will serialize on a stack
- // buffer.
- virtual char* GetPacketBuffer() = 0;
+ // packet. If the return value's buffer is nullptr, QuicPacketCreator will
+ // serialize on a stack buffer.
+ virtual QuicPacketBuffer GetPacketBuffer() = 0;
// Called when a packet is serialized. Delegate take the ownership of
// |serialized_packet|.
virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
@@ -142,12 +142,14 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Returns true if current open packet can accommodate more stream frames of
// stream |id| at |offset| and data length |data_size|, false otherwise.
+ // TODO(fayang): mark this const when deprecating quic_update_packet_size.
bool HasRoomForStreamFrame(QuicStreamId id,
QuicStreamOffset offset,
size_t data_size);
// Returns true if current open packet can accommodate a message frame of
// |length|.
+ // TODO(fayang): mark this const when deprecating quic_update_packet_size.
bool HasRoomForMessageFrame(QuicByteCount length);
// Serializes all added frames into a single packet and invokes the delegate_
@@ -179,6 +181,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// frames in the packet. Since stream frames are slightly smaller when they
// are the last frame in a packet, this method will return a different
// value than max_packet_size - PacketSize(), in this case.
+ // TODO(fayang): mark this const when deprecating quic_update_packet_size.
size_t BytesFree();
// Returns the number of bytes that the packet will expand by if a new frame
@@ -191,6 +194,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// if serialized with the current frames. Adding a frame to the packet
// may change the serialized length of existing frames, as per the comment
// in BytesFree.
+ // TODO(fayang): mark this const when deprecating quic_update_packet_size.
size_t PacketSize();
// Tries to add |frame| to the packet creator's list of frames to be
@@ -255,6 +259,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
void set_encryption_level(EncryptionLevel level) {
packet_.encryption_level = level;
}
+ EncryptionLevel encryption_level() { return packet_.encryption_level; }
// packet number of the last created packet, or 0 if no packets have been
// created.
@@ -429,6 +434,10 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
char* buffer,
size_t buffer_len);
+ void set_disable_padding_override(bool should_disable_padding) {
+ disable_padding_override_ = should_disable_padding;
+ }
+
private:
friend class test::QuicPacketCreatorPeer;
@@ -459,7 +468,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// retransmitted to packet_.retransmittable_frames. All frames must fit into
// a single packet.
// Fails if |encrypted_buffer_len| isn't long enough for the encrypted packet.
- void SerializePacket(char* encrypted_buffer, size_t encrypted_buffer_len);
+ void SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
+ size_t encrypted_buffer_len);
// Called after a new SerialiedPacket is created to call the delegate's
// OnSerializedPacket and reset state.
@@ -551,7 +561,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Frames to be added to the next SerializedPacket
QuicFrames queued_frames_;
- // packet_size should never be read directly, use PacketSize() instead.
+ // Serialization size of header + frames. If there is no queued frames,
+ // packet_size_ is 0.
// TODO(ianswett): Move packet_size_ into SerializedPacket once
// QuicEncryptedPacket has been flattened into SerializedPacket.
size_t packet_size_;
@@ -597,6 +608,17 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
// negotiates this during the handshake.
QuicByteCount max_datagram_frame_size_;
+
+ const bool avoid_leak_writer_buffer_ =
+ GetQuicReloadableFlag(quic_avoid_leak_writer_buffer);
+
+ const bool fix_min_crypto_frame_size_ =
+ GetQuicReloadableFlag(quic_fix_min_crypto_frame_size);
+
+ // When true, this will override the padding generation code to disable it.
+ bool disable_padding_override_ = false;
+
+ bool update_packet_size_ = GetQuicReloadableFlag(quic_update_packet_size);
};
} // 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 d1beea7c01d..394b82ec364 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
@@ -162,7 +162,8 @@ class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
connection_id_.length()),
data_("foo"),
creator_(connection_id_, &client_framer_, &delegate_, &producer_) {
- EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr));
+ EXPECT_CALL(delegate_, GetPacketBuffer())
+ .WillRepeatedly(Return(QuicPacketBuffer()));
creator_.SetEncrypter(ENCRYPTION_INITIAL, std::make_unique<NullEncrypter>(
Perspective::IS_CLIENT));
creator_.SetEncrypter(ENCRYPTION_HANDSHAKE, std::make_unique<NullEncrypter>(
@@ -930,40 +931,36 @@ TEST_P(QuicPacketCreatorTest, BuildPathResponsePacket3ResponsesPadded) {
}
TEST_P(QuicPacketCreatorTest, SerializeConnectivityProbingPacket) {
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
-
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- std::unique_ptr<SerializedPacket> encrypted;
+ std::unique_ptr<SerializedPacket> encrypted;
+ if (VersionHasIetfQuicFrames(creator_.transport_version())) {
+ QuicPathFrameBuffer payload = {
+ {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
+ encrypted =
+ creator_.SerializePathChallengeConnectivityProbingPacket(&payload);
+ } else {
+ encrypted = creator_.SerializeConnectivityProbingPacket();
+ }
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
if (VersionHasIetfQuicFrames(creator_.transport_version())) {
- QuicPathFrameBuffer payload = {
- {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
- encrypted =
- creator_.SerializePathChallengeConnectivityProbingPacket(&payload);
+ EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
} else {
- encrypted = creator_.SerializeConnectivityProbingPacket();
- }
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- if (VersionHasIetfQuicFrames(creator_.transport_version())) {
- EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- } else {
- EXPECT_CALL(framer_visitor_, OnPingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- }
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
+ EXPECT_CALL(framer_visitor_, OnPingFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
}
- // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
@@ -973,28 +970,24 @@ TEST_P(QuicPacketCreatorTest, SerializePathChallengeProbePacket) {
QuicPathFrameBuffer payload = {
{0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
-
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathChallengeConnectivityProbingPacket(&payload));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathChallengeConnectivityProbingPacket(&payload));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathChallengeFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ // QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
@@ -1004,30 +997,26 @@ TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket1PayloadPadded) {
QuicPathFrameBuffer payload0 = {
{0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest,
@@ -1038,29 +1027,25 @@ TEST_P(QuicPacketCreatorTest,
QuicPathFrameBuffer payload0 = {
{0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- false));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
@@ -1072,31 +1057,27 @@ TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket2PayloadsPadded) {
QuicPathFrameBuffer payload1 = {
{0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
+ payloads.push_back(payload1);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest,
@@ -1109,30 +1090,26 @@ TEST_P(QuicPacketCreatorTest,
QuicPathFrameBuffer payload1 = {
{0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
+ payloads.push_back(payload1);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- false));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(2);
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
@@ -1146,32 +1123,28 @@ TEST_P(QuicPacketCreatorTest, SerializePathResponseProbePacket3PayloadsPadded) {
QuicPathFrameBuffer payload2 = {
{0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
+ payloads.push_back(payload1);
+ payloads.push_back(payload2);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- true));
- {
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
- EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
- }
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, true));
+ {
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+ EXPECT_CALL(framer_visitor_, OnPaddingFrame(_));
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
}
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest,
@@ -1186,30 +1159,26 @@ TEST_P(QuicPacketCreatorTest,
QuicPathFrameBuffer payload2 = {
{0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xee, 0xde, 0xad}};
- for (int i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
- EncryptionLevel level = static_cast<EncryptionLevel>(i);
- creator_.set_encryption_level(level);
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- QuicCircularDeque<QuicPathFrameBuffer> payloads;
- payloads.push_back(payload0);
- payloads.push_back(payload1);
- payloads.push_back(payload2);
+ QuicCircularDeque<QuicPathFrameBuffer> payloads;
+ payloads.push_back(payload0);
+ payloads.push_back(payload1);
+ payloads.push_back(payload2);
- std::unique_ptr<SerializedPacket> encrypted(
- creator_.SerializePathResponseConnectivityProbingPacket(payloads,
- false));
- InSequence s;
- EXPECT_CALL(framer_visitor_, OnPacket());
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
- EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
- EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
- EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
- EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
- EXPECT_CALL(framer_visitor_, OnPacketComplete());
+ std::unique_ptr<SerializedPacket> encrypted(
+ creator_.SerializePathResponseConnectivityProbingPacket(payloads, false));
+ InSequence s;
+ EXPECT_CALL(framer_visitor_, OnPacket());
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedPublicHeader(_));
+ EXPECT_CALL(framer_visitor_, OnUnauthenticatedHeader(_));
+ EXPECT_CALL(framer_visitor_, OnDecryptedPacket(_));
+ EXPECT_CALL(framer_visitor_, OnPacketHeader(_));
+ EXPECT_CALL(framer_visitor_, OnPathResponseFrame(_)).Times(3);
+ EXPECT_CALL(framer_visitor_, OnPacketComplete());
- server_framer_.ProcessPacket(QuicEncryptedPacket(
- encrypted->encrypted_buffer, encrypted->encrypted_length));
- }
+ server_framer_.ProcessPacket(QuicEncryptedPacket(
+ encrypted->encrypted_buffer, encrypted->encrypted_length));
}
TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
@@ -1499,6 +1468,7 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
}
TEST_P(QuicPacketCreatorTest, SerializeAndSendStreamFrame) {
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
if (!GetParam().version_serialization) {
creator_.StopSendingVersion();
}
@@ -1534,6 +1504,7 @@ TEST_P(QuicPacketCreatorTest, SerializeStreamFrameWithPadding) {
// Regression test to check that CreateAndSerializeStreamFrame uses a
// correctly formatted stream frame header when appending padding.
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
if (!GetParam().version_serialization) {
creator_.StopSendingVersion();
}
@@ -1725,9 +1696,10 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataAndRandomPadding) {
TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
- char external_buffer[kMaxOutgoingPacketSize];
- char* expected_buffer = external_buffer;
- EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(expected_buffer));
+ char* buffer = new char[kMaxOutgoingPacketSize];
+ QuicPacketBuffer external_buffer = {buffer,
+ [](const char* p) { delete[] p; }};
+ EXPECT_CALL(delegate_, GetPacketBuffer()).WillOnce(Return(external_buffer));
QuicFrame frame;
MakeIOVector("test", &iov_);
@@ -1738,10 +1710,13 @@ TEST_P(QuicPacketCreatorTest, FlushWithExternalBuffer) {
/*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
EXPECT_CALL(delegate_, OnSerializedPacket(_))
- .WillOnce(Invoke([expected_buffer](SerializedPacket serialized_packet) {
- EXPECT_EQ(expected_buffer, serialized_packet.encrypted_buffer);
+ .WillOnce(Invoke([&external_buffer](SerializedPacket serialized_packet) {
+ EXPECT_EQ(external_buffer.buffer, serialized_packet.encrypted_buffer);
}));
creator_.FlushCurrentPacket();
+ if (!GetQuicReloadableFlag(quic_avoid_leak_writer_buffer)) {
+ delete[] buffer;
+ }
}
// Test for error found in
@@ -2311,7 +2286,7 @@ class MockDelegate : public QuicPacketCreator::DelegateInterface {
MaybeBundleAckOpportunistically,
(),
(override));
- MOCK_METHOD(char*, GetPacketBuffer, (), (override));
+ MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
MOCK_METHOD(void,
OnUnrecoverableError,
@@ -2466,7 +2441,8 @@ class QuicPacketCreatorMultiplePacketsTest : public QuicTest {
&delegate_,
&producer_),
ack_frame_(InitAckFrame(1)) {
- EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr));
+ EXPECT_CALL(delegate_, GetPacketBuffer())
+ .WillRepeatedly(Return(QuicPacketBuffer()));
creator_.SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
@@ -2679,6 +2655,37 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeCryptoData) {
CheckPacketContains(contents, 0);
}
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+ ConsumeCryptoDataCheckShouldGeneratePacket) {
+ delegate_.SetCanNotWrite();
+
+ if (GetQuicReloadableFlag(quic_fix_checking_should_generate_packet)) {
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
+ } else {
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(
+ Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+ }
+ std::string data = "crypto data";
+ size_t consumed_bytes =
+ creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
+ creator_.Flush();
+ if (GetQuicReloadableFlag(quic_fix_checking_should_generate_packet)) {
+ EXPECT_EQ(0u, consumed_bytes);
+ } else {
+ EXPECT_EQ(data.length(), consumed_bytes);
+ }
+ EXPECT_FALSE(creator_.HasPendingFrames());
+ EXPECT_FALSE(creator_.HasPendingRetransmittableFrames());
+ if (GetQuicReloadableFlag(quic_fix_checking_should_generate_packet)) {
+ return;
+ }
+ PacketContents contents;
+ contents.num_crypto_frames = 1;
+ contents.num_padding_frames = 1;
+ CheckPacketContains(contents, 0);
+}
+
TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) {
delegate_.SetCanNotWrite();
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h
index ab29e15aa88..6efdb6005d8 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer.h
@@ -125,17 +125,22 @@ class QUIC_EXPORT_PRIVATE QuicPacketWriter {
// True=Batch mode. False=PassThrough mode.
virtual bool IsBatchMode() const = 0;
- // PassThrough mode: Return nullptr.
+ // PassThrough mode: Return {nullptr, nullptr}
//
// Batch mode:
- // Return the starting address for the next packet's data. A minimum of
+ // Return the QuicPacketBuffer for the next packet. A minimum of
// kMaxOutgoingPacketSize is guaranteed to be available from the returned
- // address. If the internal buffer does not have enough space, nullptr is
- // returned. All arguments should be identical to the follow-up call to
- // |WritePacket|, they are here to allow advanced packet memory management in
- // packet writers, e.g. one packet buffer pool per |peer_address|.
- virtual char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) = 0;
+ // address. If the internal buffer does not have enough space,
+ // {nullptr, nullptr} is returned. All arguments should be identical to the
+ // follow-up call to |WritePacket|, they are here to allow advanced packet
+ // memory management in packet writers, e.g. one packet buffer pool per
+ // |peer_address|.
+ //
+ // If QuicPacketBuffer.release_buffer is !nullptr, it should be called iff
+ // the caller does not call WritePacket for the returned buffer.
+ virtual QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) = 0;
// PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
//
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc
index f1f25d871bf..d2b54d1b175 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.cc
@@ -45,7 +45,7 @@ bool QuicPacketWriterWrapper::IsBatchMode() const {
return writer_->IsBatchMode();
}
-char* QuicPacketWriterWrapper::GetNextWriteLocation(
+QuicPacketBuffer QuicPacketWriterWrapper::GetNextWriteLocation(
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address) {
return writer_->GetNextWriteLocation(self_address, peer_address);
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h
index 0b331aec6f8..afd360580b4 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h
@@ -35,8 +35,9 @@ class QUIC_NO_EXPORT QuicPacketWriterWrapper : public QuicPacketWriter {
const QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
- char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
+ QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) override;
WriteResult Flush() override;
// Takes ownership of |writer|.
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 04522e8538b..3e37a200c21 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
@@ -379,6 +379,8 @@ struct QUIC_EXPORT_PRIVATE SerializedPacket {
SerializedPacket(SerializedPacket&& other);
~SerializedPacket();
+ // TODO(wub): replace |encrypted_buffer|+|release_encrypted_buffer| by a
+ // QuicOwnedPacketBuffer.
// Not owned if |release_encrypted_buffer| is nullptr. Otherwise it is
// released by |release_encrypted_buffer| on destruction.
const char* encrypted_buffer;
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 92401b0db72..43730135c14 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
@@ -32,9 +32,6 @@ static const size_t kMaxRetransmissionsOnTimeout = 2;
// The path degrading delay is the sum of this number of consecutive RTO delays.
const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
-// The blachkhole delay is the sum of this number of consecutive RTO delays.
-const size_t kNumRetransmissionDelaysForBlackholeDelay = 5;
-
// Ensure the handshake timer isnt't faster than 10ms.
// This limits the tenth retransmitted packet to 10s after the initial CHLO.
static const int64_t kMinHandshakeTimeoutMs = 10;
@@ -110,7 +107,8 @@ QuicSentPacketManager::QuicSentPacketManager(
one_rtt_packet_acked_(false),
one_rtt_packet_sent_(false),
first_pto_srtt_multiplier_(0),
- use_standard_deviation_for_pto_(false) {
+ use_standard_deviation_for_pto_(false),
+ pto_multiplier_without_rtt_samples_(3) {
SetSendAlgorithm(congestion_control_type);
if (pto_enabled_) {
QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 1, 2);
@@ -200,6 +198,9 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
} else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
first_pto_srtt_multiplier_ = 1.5;
}
+ if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
+ pto_multiplier_without_rtt_samples_ = 1.5;
+ }
if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
use_standard_deviation_for_pto_ = true;
rtt_stats_.EnableStandardDeviationCalculation();
@@ -403,6 +404,17 @@ void QuicSentPacketManager::PostProcessNewlyAckedPackets(
}
}
}
+ // Records the max consecutive RTO or PTO before forward progress has been
+ // made.
+ if (consecutive_rto_count_ >
+ stats_->max_consecutive_rto_with_forward_progress) {
+ stats_->max_consecutive_rto_with_forward_progress =
+ consecutive_rto_count_;
+ } else if (consecutive_pto_count_ >
+ stats_->max_consecutive_rto_with_forward_progress) {
+ stats_->max_consecutive_rto_with_forward_progress =
+ consecutive_pto_count_;
+ }
// Reset all retransmit counters any time a new packet is acked.
consecutive_rto_count_ = 0;
consecutive_tlp_count_ = 0;
@@ -442,40 +454,27 @@ void QuicSentPacketManager::MaybeInvokeCongestionEvent(
}
}
-void QuicSentPacketManager::RetransmitUnackedPackets(
- TransmissionType retransmission_type) {
- DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
- retransmission_type == ALL_INITIAL_RETRANSMISSION);
+void QuicSentPacketManager::RetransmitZeroRttPackets() {
QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
for (QuicUnackedPacketMap::iterator it = unacked_packets_.begin();
it != unacked_packets_.end(); ++it, ++packet_number) {
- if ((retransmission_type == ALL_UNACKED_RETRANSMISSION ||
- it->encryption_level == ENCRYPTION_ZERO_RTT)) {
+ 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, retransmission_type);
+ MarkForRetransmission(packet_number, ALL_ZERO_RTT_RETRANSMISSION);
}
}
}
- if (retransmission_type == ALL_UNACKED_RETRANSMISSION &&
- unacked_packets_.bytes_in_flight() > 0) {
- QUIC_BUG << "RetransmitUnackedPackets should remove all packets from flight"
- << ", bytes_in_flight:" << unacked_packets_.bytes_in_flight();
- }
}
void QuicSentPacketManager::NeuterUnencryptedPackets() {
for (QuicPacketNumber packet_number :
unacked_packets_.NeuterUnencryptedPackets()) {
- if (avoid_overestimate_bandwidth_with_aggregation_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_avoid_overestimate_bandwidth_with_aggregation, 1, 4);
- send_algorithm_->OnPacketNeutered(packet_number);
- }
+ send_algorithm_->OnPacketNeutered(packet_number);
}
if (handshake_mode_disabled_) {
consecutive_pto_count_ = 0;
@@ -486,11 +485,7 @@ void QuicSentPacketManager::NeuterUnencryptedPackets() {
void QuicSentPacketManager::NeuterHandshakePackets() {
for (QuicPacketNumber packet_number :
unacked_packets_.NeuterHandshakePackets()) {
- if (avoid_overestimate_bandwidth_with_aggregation_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_avoid_overestimate_bandwidth_with_aggregation, 2, 4);
- send_algorithm_->OnPacketNeutered(packet_number);
- }
+ send_algorithm_->OnPacketNeutered(packet_number);
}
if (handshake_mode_disabled_) {
consecutive_pto_count_ = 0;
@@ -573,7 +568,7 @@ void QuicSentPacketManager::MarkForRetransmission(
QUIC_BUG_IF(transmission_type != LOSS_RETRANSMISSION &&
transmission_type != RTO_RETRANSMISSION &&
!unacked_packets_.HasRetransmittableFrames(*transmission_info))
- << "transmission_type: " << TransmissionTypeToString(transmission_type);
+ << "transmission_type: " << transmission_type;
// Handshake packets should never be sent as probing retransmissions.
DCHECK(!transmission_info->has_crypto_handshake ||
transmission_type != PROBING_RETRANSMISSION);
@@ -646,8 +641,7 @@ void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
// Record as a spurious retransmission if this packet is a
// retransmission and no new data gets acked.
QUIC_DVLOG(1) << "Detect spurious retransmitted packet " << packet_number
- << " transmission type: "
- << TransmissionTypeToString(info->transmission_type);
+ << " transmission type: " << info->transmission_type;
RecordOneSpuriousRetransmission(*info);
}
}
@@ -754,6 +748,9 @@ QuicSentPacketManager::OnRetransmissionTimeout() {
case PTO_MODE:
QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
++stats_->pto_count;
+ if (handshake_mode_disabled_ && !ShouldArmPtoForApplicationData()) {
+ ++stats_->crypto_retransmit_count;
+ }
++consecutive_pto_count_;
pending_timer_transmission_count_ = max_probe_packets_per_pto_;
return PTO_MODE;
@@ -919,6 +916,26 @@ void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
}
+void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
+ PacketNumberSpace space) {
+ DCHECK(supports_multiple_packet_number_spaces());
+ if (!unacked_packets_.GetLastInFlightPacketSentTime(space).IsInitialized()) {
+ // 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);
+ MarkForRetransmission(packet_number, PTO_RETRANSMISSION);
+ return;
+ }
+ }
+}
+
QuicSentPacketManager::RetransmissionTimeoutMode
QuicSentPacketManager::GetRetransmissionMode() const {
DCHECK(unacked_packets_.HasInFlightPackets() ||
@@ -958,14 +975,16 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
detection_stats.sent_packets_max_sequence_reordering;
}
+ stats_->sent_packets_num_borderline_time_reorderings +=
+ detection_stats.sent_packets_num_borderline_time_reorderings;
+
+ stats_->total_loss_detection_response_time +=
+ detection_stats.total_loss_detection_response_time;
+
for (const LostPacket& packet : packets_lost_) {
QuicTransmissionInfo* info =
unacked_packets_.GetMutableTransmissionInfo(packet.packet_number);
++stats_->packets_lost;
- if (time > info->sent_time) {
- stats_->total_loss_detection_time =
- stats_->total_loss_detection_time + (time - info->sent_time);
- }
if (debug_delegate_ != nullptr) {
debug_delegate_->OnPacketLoss(packet.packet_number,
info->encryption_level, LOSS_RETRANSMISSION,
@@ -1041,6 +1060,16 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
// Do not set the timer if there is any credit left.
return QuicTime::Zero();
}
+ PacketNumberSpace packet_number_space;
+ if (GetQuicReloadableFlag(quic_fix_server_pto_timeout) &&
+ supports_multiple_packet_number_spaces() &&
+ unacked_packets_.perspective() == Perspective::IS_SERVER &&
+ !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
+ // Do not set the timer on the server side if the only in flight packets are
+ // half RTT data.
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_server_pto_timeout);
+ return QuicTime::Zero();
+ }
switch (GetRetransmissionMode()) {
case HANDSHAKE_MODE:
return unacked_packets_.GetLastCryptoPacketSentTime() +
@@ -1131,9 +1160,10 @@ const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
}
-const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay() const {
+const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
+ int8_t num_rtos_for_blackhole_detection) const {
return GetNConsecutiveRetransmissionTimeoutDelay(
- max_tail_loss_probes_ + kNumRetransmissionDelaysForBlackholeDelay);
+ max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
}
const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
@@ -1202,8 +1232,9 @@ const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay() const {
if (rtt_stats_.smoothed_rtt().IsZero()) {
// Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
QUIC_BUG_IF(rtt_stats_.initial_rtt().IsZero());
- return std::max(3 * rtt_stats_.initial_rtt(),
- QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
+ return std::max(
+ pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
+ QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
(1 << consecutive_pto_count_);
}
const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
@@ -1354,8 +1385,7 @@ AckResult QuicSentPacketManager::OnAckFrameEnd(
<< ", least_unacked: " << unacked_packets_.GetLeastUnacked()
<< ", packets_acked_: " << packets_acked_;
} else {
- QUIC_PEER_BUG << "Received "
- << EncryptionLevelToString(ack_decrypted_level)
+ QUIC_PEER_BUG << "Received " << ack_decrypted_level
<< " ack for unackable packet: "
<< acked_packet.packet_number << " with state: "
<< QuicUtils::SentPacketStateToString(info->state);
@@ -1368,8 +1398,7 @@ AckResult QuicSentPacketManager::OnAckFrameEnd(
}
continue;
}
- QUIC_DVLOG(1) << ENDPOINT << "Got an "
- << EncryptionLevelToString(ack_decrypted_level)
+ QUIC_DVLOG(1) << ENDPOINT << "Got an " << ack_decrypted_level
<< " ack for packet " << acked_packet.packet_number
<< " , state: "
<< QuicUtils::SentPacketStateToString(info->state);
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 371fa814537..72307b3b838 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
@@ -140,15 +140,11 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// TODO(fayang): Rename this function to OnHandshakeComplete.
void SetHandshakeConfirmed();
- // Requests retransmission of all unacked packets of |retransmission_type|.
- // The behavior of this method depends on the value of |retransmission_type|:
- // ALL_UNACKED_RETRANSMISSION - All unacked packets will be retransmitted.
- // This can happen, for example, after a version negotiation packet has been
- // received and all packets needs to be retransmitted with the new version.
- // ALL_INITIAL_RETRANSMISSION - Only initially encrypted packets will be
- // retransmitted. This can happen, for example, when a CHLO has been rejected
- // and the previously encrypted data needs to be encrypted with a new key.
- void RetransmitUnackedPackets(TransmissionType retransmission_type);
+ // Requests retransmission of all unacked 0-RTT packets.
+ // Only initially encrypted packets will be retransmitted. This can happen,
+ // for example, when a CHLO has been rejected and the previously encrypted
+ // data needs to be encrypted with a new key.
+ void RetransmitZeroRttPackets();
// Notify the sent packet manager of an external network measurement or
// prediction for either |bandwidth| or |rtt|; either can be empty.
@@ -216,7 +212,8 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
const QuicTime::Delta GetPathDegradingDelay() const;
// Returns the current delay for detecting network blackhole.
- const QuicTime::Delta GetNetworkBlackholeDelay() const;
+ const QuicTime::Delta GetNetworkBlackholeDelay(
+ int8_t num_rtos_for_blackhole_detection) const;
const RttStats* GetRttStats() const { return &rtt_stats_; }
@@ -397,6 +394,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void StartExponentialBackoffAfterNthPto(
size_t exponential_backoff_start_point);
+ // Called to retransmit in flight packet of |space| if any.
+ void RetransmitDataOfSpaceIfAny(PacketNumberSpace space);
+
bool supports_multiple_packet_number_spaces() const {
return unacked_packets_.supports_multiple_packet_number_spaces();
}
@@ -411,6 +411,8 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
+ void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
+
private:
friend class test::QuicConnectionPeer;
friend class test::QuicSentPacketManagerPeer;
@@ -657,8 +659,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// calculating PTO timeout.
bool use_standard_deviation_for_pto_;
- const bool avoid_overestimate_bandwidth_with_aggregation_ =
- GetQuicReloadableFlag(quic_avoid_overestimate_bandwidth_with_aggregation);
+ // The multiplier for caculating PTO timeout before any RTT sample is
+ // available.
+ float pto_multiplier_without_rtt_samples_;
};
} // namespace quic
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 79fc798568b..97d83f57933 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,6 +7,7 @@
#include <memory>
#include <utility>
+#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"
@@ -621,7 +622,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
// know packet 2 is a spurious until it gets acked.
EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
EXPECT_EQ(1u, stats_.packets_lost);
- EXPECT_LT(QuicTime::Delta::Zero(), stats_.total_loss_detection_time);
+ EXPECT_LT(0.0, stats_.total_loss_detection_response_time);
EXPECT_LE(1u, stats_.sent_packets_max_sequence_reordering);
}
@@ -942,6 +943,7 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
manager_.OnRetransmissionTimeout();
EXPECT_EQ(2u, stats_.tlp_count);
EXPECT_EQ(1u, stats_.rto_count);
+ EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
// There are 2 RTO retransmissions.
EXPECT_EQ(104 * kDefaultLength, manager_.GetBytesInFlight());
QuicPacketNumber largest_acked = QuicPacketNumber(103);
@@ -965,6 +967,7 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
// All packets before 103 should be lost.
// Packet 104 is still in flight.
EXPECT_EQ(1000u, manager_.GetBytesInFlight());
+ EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
}
TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
@@ -1019,54 +1022,6 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
EXPECT_FALSE(manager_.HasUnackedCryptoPackets());
}
-TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutVersionNegotiation) {
- // Send 2 crypto packets and 3 data packets.
- const size_t kNumSentCryptoPackets = 2;
- for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
- SendCryptoPacket(i);
- }
- const size_t kNumSentDataPackets = 3;
- for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
- SendDataPacket(kNumSentCryptoPackets + i);
- }
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(6); }))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(7); }));
- manager_.OnRetransmissionTimeout();
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Now act like a version negotiation packet arrived, which would cause all
- // unacked packets to be retransmitted.
- // Mark packets [1, 7] lost. And the frames in 6 and 7 are same as packets 1
- // and 2, respectively.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(7);
- manager_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
-
- // Ensure the first two pending packets are the crypto retransmits.
- RetransmitCryptoPacket(8);
- RetransmitCryptoPacket(9);
- RetransmitDataPacket(10, ALL_UNACKED_RETRANSMISSION);
- RetransmitDataPacket(11, ALL_UNACKED_RETRANSMISSION);
- RetransmitDataPacket(12, ALL_UNACKED_RETRANSMISSION);
-
- EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
- // Least unacked isn't raised until an ack is received, so ack the
- // crypto packets.
- uint64_t acked[] = {8, 9};
- ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- EXPECT_EQ(QuicPacketNumber(10u), manager_.GetLeastUnacked());
-}
-
TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
// Send 1 crypto packet.
SendCryptoPacket(1);
@@ -1119,28 +1074,6 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
}
TEST_F(QuicSentPacketManagerTest,
- CryptoHandshakeRetransmissionThenRetransmitAll) {
- // Send 1 crypto packet.
- SendCryptoPacket(1);
-
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
-
- // Retransmit the crypto packet as 2.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
- manager_.OnRetransmissionTimeout();
- // Now retransmit all the unacked packets, which occurs when there is a
- // version negotiation.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
- manager_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
- // Both packets 1 and 2 are unackable.
- EXPECT_FALSE(manager_.unacked_packets().IsUnacked(QuicPacketNumber(1)));
- EXPECT_FALSE(manager_.unacked_packets().IsUnacked(QuicPacketNumber(2)));
- EXPECT_TRUE(manager_.HasUnackedCryptoPackets());
- EXPECT_FALSE(manager_.HasInFlightPackets());
-}
-
-TEST_F(QuicSentPacketManagerTest,
CryptoHandshakeRetransmissionThenNeuterAndAck) {
// Send 1 crypto packet.
SendCryptoPacket(1);
@@ -2732,6 +2665,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
manager_.OnRetransmissionTimeout();
EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
EXPECT_EQ(1u, stats_.pto_count);
+ EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
// Verify two probe packets get sent.
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
@@ -2765,6 +2699,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
// Verify PTO is correctly re-armed based on sent time of packet 4.
EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
+ EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
}
TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
@@ -2811,7 +2746,7 @@ TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- manager_.EnableIetfPtoAndLossDetection();
+ manager_.EnableMultiplePacketNumberSpacesSupport();
// Send CHLO.
SendCryptoPacket(1);
EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
@@ -3340,6 +3275,7 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
manager_.OnRetransmissionTimeout();
EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
EXPECT_EQ(1u, stats_.pto_count);
+ EXPECT_EQ(1u, stats_.crypto_retransmit_count);
// Verify probe packet gets sent.
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
@@ -3823,11 +3759,7 @@ TEST_F(QuicSentPacketManagerTest, SetHandshakeConfirmed) {
return true;
}));
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2)))
- .Times(1);
- }
+ EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(2))).Times(1);
manager_.SetHandshakeConfirmed();
}
@@ -3841,11 +3773,8 @@ TEST_F(QuicSentPacketManagerTest, NeuterUnencryptedPackets) {
.WillOnce(Return(false))
.WillOnce(Return(true));
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- if (GetQuicReloadableFlag(
- quic_avoid_overestimate_bandwidth_with_aggregation)) {
- EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1)))
- .Times(1);
- }
+
+ EXPECT_CALL(*send_algorithm_, OnPacketNeutered(QuicPacketNumber(1))).Times(1);
manager_.NeuterUnencryptedPackets();
}
@@ -3911,7 +3840,7 @@ TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
// Regression test for b/154050235.
TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- manager_.EnableIetfPtoAndLossDetection();
+ manager_.EnableMultiplePacketNumberSpacesSupport();
RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
rtt_stats->initial_rtt());
@@ -3939,7 +3868,7 @@ TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
}
TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
- manager_.EnableIetfPtoAndLossDetection();
+ manager_.EnableMultiplePacketNumberSpacesSupport();
RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
// Assume client provided a tiny initial RTT.
rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
@@ -3998,6 +3927,199 @@ TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
manager_.MaybeSendProbePackets();
}
+// Regression test for b/156487311
+TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
+ manager_.EnableMultiplePacketNumberSpacesSupport();
+ EXPECT_CALL(*send_algorithm_, PacingRate(_))
+ .WillRepeatedly(Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+ // Send INITIAL 1.
+ SendDataPacket(1, ENCRYPTION_INITIAL);
+ const QuicTime packet1_sent_time = clock_.Now();
+ // Send HANDSHAKE 2.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+ SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+ SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+ const QuicTime packet2_sent_time = clock_.Now();
+
+ // Send half RTT 5.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+ // Received ACK for INITIAL 1.
+ ExpectAck(1);
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+ manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+ clock_.Now());
+ manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+ EXPECT_EQ(PACKETS_NEWLY_ACKED,
+ manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+ ENCRYPTION_INITIAL));
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ int pto_rttvar_multiplier =
+ GetQuicReloadableFlag(quic_default_on_pto) ? 2 : 4;
+ const QuicTime::Delta pto_delay =
+ rtt_stats->smoothed_rtt() +
+ pto_rttvar_multiplier * rtt_stats->mean_deviation() +
+ QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+ if (GetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time)) {
+ // Verify PTO is armed based on handshake data.
+ EXPECT_EQ(packet2_sent_time + pto_delay, manager_.GetRetransmissionTime());
+ } else {
+ // Problematic: PTO is still armed based on initial data.
+ EXPECT_EQ(packet1_sent_time + pto_delay, manager_.GetRetransmissionTime());
+ clock_.AdvanceTime(pto_delay);
+ manager_.OnRetransmissionTimeout();
+ // Nothing to retransmit in INITIAL space.
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
+ manager_.MaybeSendProbePackets();
+ // PING packet gets sent.
+ SendPingPacket(6, ENCRYPTION_INITIAL);
+ manager_.AdjustPendingTimerTransmissions();
+
+ // Verify PTO is armed based on packet 2.
+ EXPECT_EQ(packet2_sent_time + pto_delay * 2,
+ manager_.GetRetransmissionTime());
+ clock_.AdvanceTime(pto_delay * 2);
+ manager_.OnRetransmissionTimeout();
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(testing::AtLeast(1));
+ manager_.MaybeSendProbePackets();
+ }
+}
+
+// Regression test for b/157895910.
+TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) {
+ SetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time, true);
+ manager_.EnableMultiplePacketNumberSpacesSupport();
+ EXPECT_CALL(*send_algorithm_, PacingRate(_))
+ .WillRepeatedly(Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+ // Send INITIAL 1.
+ SendDataPacket(1, ENCRYPTION_INITIAL);
+
+ // Send HANDSHAKE packets.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+ SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+ SendDataPacket(4, ENCRYPTION_HANDSHAKE);
+
+ // Send half RTT packet.
+ SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
+
+ // Received ACK for INITIAL packet 1.
+ ExpectAck(1);
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+ manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+ clock_.Now());
+ manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+ EXPECT_EQ(PACKETS_NEWLY_ACKED,
+ manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+ ENCRYPTION_INITIAL));
+
+ // Received ACK for HANDSHAKE packets.
+ uint64_t acked[] = {2, 3, 4};
+ ExpectAcksAndLosses(true, acked, QUICHE_ARRAYSIZE(acked), nullptr, 0);
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
+ manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+ clock_.Now());
+ manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(5));
+ EXPECT_EQ(PACKETS_NEWLY_ACKED,
+ manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
+ ENCRYPTION_HANDSHAKE));
+ if (GetQuicReloadableFlag(quic_fix_server_pto_timeout)) {
+ // Verify PTO will not be armed.
+ EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+ return;
+ }
+ // PTO fires but there is nothing to send.
+ EXPECT_NE(QuicTime::Zero(), manager_.GetRetransmissionTime());
+ manager_.OnRetransmissionTimeout();
+ EXPECT_QUIC_BUG(manager_.MaybeSendProbePackets(),
+ "earlist_sent_time not initialized when trying to send PTO "
+ "retransmissions");
+}
+
+TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
+ manager_.EnableMultiplePacketNumberSpacesSupport();
+ EXPECT_CALL(*send_algorithm_, PacingRate(_))
+ .WillRepeatedly(Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
+
+ // Send packet 1.
+ SendDataPacket(1, ENCRYPTION_INITIAL);
+ QuicTime packet1_sent_time = clock_.Now();
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ // Send packets 2 and 3.
+ SendDataPacket(2, ENCRYPTION_HANDSHAKE);
+ QuicTime packet2_sent_time = clock_.Now();
+ SendDataPacket(3, ENCRYPTION_HANDSHAKE);
+ // Verify PTO is correctly set based on packet 1.
+ int pto_rttvar_multiplier =
+ GetQuicReloadableFlag(quic_default_on_pto) ? 2 : 4;
+ QuicTime::Delta expected_pto_delay =
+ srtt + pto_rttvar_multiplier * rtt_stats->mean_deviation() +
+ QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+ EXPECT_EQ(packet1_sent_time + expected_pto_delay,
+ manager_.GetRetransmissionTime());
+
+ // Assume connection is going to send INITIAL ACK.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+ .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+ RetransmitDataPacket(4, type, ENCRYPTION_INITIAL);
+ })));
+ manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+ // Verify PTO is re-armed based on packet 2.
+ EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+ manager_.GetRetransmissionTime());
+
+ // Connection is going to send another INITIAL ACK.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+ .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+ RetransmitDataPacket(5, type, ENCRYPTION_INITIAL);
+ })));
+ manager_.RetransmitDataOfSpaceIfAny(INITIAL_DATA);
+ // Verify PTO does not change.
+ EXPECT_EQ(packet2_sent_time + expected_pto_delay,
+ manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest,
+ AggressivePtoBeforeAnyRttSamplesAreAvailable) {
+ manager_.EnableMultiplePacketNumberSpacesSupport();
+ EXPECT_CALL(*send_algorithm_, PacingRate(_))
+ .WillRepeatedly(Return(QuicBandwidth::Zero()));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+
+ QuicConfig config;
+ QuicTagVector options;
+ options.push_back(kAPTO);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ manager_.SetFromConfig(config);
+
+ // Send INITIAL 1.
+ SendDataPacket(1, ENCRYPTION_INITIAL);
+ // Verify retransmission timeout is expected.
+ EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
+ manager_.GetRetransmissionTime());
+}
+
} // 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 0f00ff3843d..59e6cc8093e 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
@@ -73,12 +73,9 @@ QuicSession::QuicSession(
config_.GetMaxBidirectionalStreamsToSend(),
config_.GetMaxUnidirectionalStreamsToSend() +
num_expected_unidirectional_static_streams),
- num_dynamic_incoming_streams_(0),
- num_draining_incoming_streams_(0),
- num_draining_outgoing_streams_(0),
- num_outgoing_static_streams_(0),
- num_incoming_static_streams_(0),
- num_locally_closed_incoming_streams_highest_offset_(0),
+ num_draining_streams_(0),
+ num_outgoing_draining_streams_(0),
+ num_static_streams_(0),
flow_controller_(
this,
QuicUtils::GetInvalidStreamId(connection->transport_version()),
@@ -101,10 +98,9 @@ QuicSession::QuicSession(
use_http2_priority_write_scheduler_(false),
is_configured_(false),
enable_round_robin_scheduling_(false),
- deprecate_draining_streams_(
- GetQuicReloadableFlag(quic_deprecate_draining_streams)),
- break_close_loop_(
- GetQuicReloadableFlag(quic_break_session_stream_close_loop)) {
+ was_zero_rtt_rejected_(false),
+ fix_gquic_stream_type_(
+ GetQuicReloadableFlag(quic_fix_gquic_stream_type)) {
closed_streams_clean_up_alarm_ =
QuicWrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
new ClosedStreamsCleanUpDelegate(this)));
@@ -117,9 +113,6 @@ QuicSession::QuicSession(
config_.GetMaxUnidirectionalStreamsToSend() +
num_expected_unidirectional_static_streams);
}
- if (break_close_loop_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_break_session_stream_close_loop);
- }
}
void QuicSession::Initialize() {
@@ -127,7 +120,11 @@ void QuicSession::Initialize() {
connection_->SetSessionNotifier(this);
connection_->SetDataProducer(this);
connection_->SetFromConfig(config_);
-
+ if (GetQuicReloadableFlag(quic_support_handshake_done_in_t050) &&
+ version().UsesTls() && !version().HasHandshakeDone() &&
+ perspective_ == Perspective::IS_CLIENT) {
+ config_.SetSupportHandshakeDone();
+ }
// On the server side, version negotiation has been done by the dispatcher,
// and the server session is created with the right version.
if (perspective() == Perspective::IS_SERVER) {
@@ -144,16 +141,6 @@ void QuicSession::Initialize() {
QuicSession::~QuicSession() {
QUIC_LOG_IF(WARNING, !zombie_streams_.empty()) << "Still have zombie streams";
- QUIC_LOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() >
- stream_id_manager_.max_open_incoming_streams())
- << "Surprisingly high number of locally closed peer initiated streams"
- "still waiting for final byte offset: "
- << num_locally_closed_incoming_streams_highest_offset();
- QUIC_LOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() >
- stream_id_manager_.max_open_outgoing_streams())
- << "Surprisingly high number of locally closed self initiated streams"
- "still waiting for final byte offset: "
- << GetNumLocallyClosedOutgoingStreamsHighestOffset();
}
void QuicSession::PendingStreamOnStreamFrame(const QuicStreamFrame& frame) {
@@ -197,8 +184,8 @@ void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
if (UsesPendingStreams() &&
QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id)) ==
- READ_UNIDIRECTIONAL &&
+ IsIncomingStream(stream_id),
+ version()) == READ_UNIDIRECTIONAL &&
stream_map_.find(stream_id) == stream_map_.end()) {
PendingStreamOnStreamFrame(frame);
return;
@@ -245,8 +232,8 @@ void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
// If stream_id is READ_UNIDIRECTIONAL, close the connection.
if (QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id)) ==
- READ_UNIDIRECTIONAL) {
+ IsIncomingStream(stream_id),
+ version()) == READ_UNIDIRECTIONAL) {
QUIC_DVLOG(1) << ENDPOINT
<< "Received STOP_SENDING for a read-only stream_id: "
<< stream_id << ".";
@@ -311,7 +298,7 @@ void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
// Pending stream is currently read only. We can safely close the stream.
DCHECK_EQ(READ_UNIDIRECTIONAL,
QuicUtils::GetStreamType(pending->id(), perspective(),
- /*peer_initiated = */ true));
+ /*peer_initiated = */ true, version()));
ClosePendingStream(stream_id);
}
@@ -326,8 +313,8 @@ void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
if (VersionHasIetfQuicFrames(transport_version()) &&
QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id)) ==
- WRITE_UNIDIRECTIONAL) {
+ IsIncomingStream(stream_id),
+ version()) == WRITE_UNIDIRECTIONAL) {
connection()->CloseConnection(
QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
@@ -340,8 +327,8 @@ void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
if (UsesPendingStreams() &&
QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id)) ==
- READ_UNIDIRECTIONAL &&
+ IsIncomingStream(stream_id),
+ version()) == READ_UNIDIRECTIONAL &&
stream_map_.find(stream_id) == stream_map_.end()) {
PendingStreamOnRstStream(frame);
return;
@@ -398,10 +385,7 @@ void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
on_closed_frame_ = frame;
}
- if (GetQuicReloadableFlag(quic_notify_handshaker_on_connection_close)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_notify_handshaker_on_connection_close);
- GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
- }
+ GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
// Copy all non static streams in a new map for the ease of deleting.
QuicSmallMap<QuicStreamId, QuicStream*, 10> non_static_streams;
@@ -460,12 +444,12 @@ void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
void QuicSession::OnPathDegrading() {}
+void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
+
bool QuicSession::AllowSelfAddressChange() const {
return false;
}
-void QuicSession::OnForwardProgressConfirmed() {}
-
void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
// Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
// assume that it still exists.
@@ -483,8 +467,8 @@ void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
if (VersionHasIetfQuicFrames(transport_version()) &&
QuicUtils::GetStreamType(stream_id, perspective(),
- IsIncomingStream(stream_id)) ==
- READ_UNIDIRECTIONAL) {
+ IsIncomingStream(stream_id),
+ version()) == READ_UNIDIRECTIONAL) {
connection()->CloseConnection(
QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
"WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
@@ -619,7 +603,7 @@ void QuicSession::OnCanWrite() {
ConnectionCloseBehavior::SILENT_CLOSE);
return;
}
- if (!connection_->CanWriteStreamData()) {
+ if (!CanWriteStreamData()) {
return;
}
currently_writing_stream_id_ = write_blocked_streams_.PopFront();
@@ -663,11 +647,26 @@ bool QuicSession::WillingAndAbleToWrite() const {
HasPendingHandshake()) {
return true;
}
- return control_frame_manager_.WillingToWrite() ||
- !streams_with_pending_retransmission_.empty() ||
- write_blocked_streams_.HasWriteBlockedSpecialStream() ||
- (!flow_controller_.IsBlocked() &&
- write_blocked_streams_.HasWriteBlockedDataStreams());
+ if (control_frame_manager_.WillingToWrite() ||
+ !streams_with_pending_retransmission_.empty()) {
+ return true;
+ }
+ if (!GetQuicReloadableFlag(quic_fix_willing_and_able_to_write)) {
+ return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+ (!flow_controller_.IsBlocked() &&
+ write_blocked_streams_.HasWriteBlockedDataStreams());
+ }
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_willing_and_able_to_write);
+ if (flow_controller_.IsBlocked()) {
+ if (VersionUsesHttp3(transport_version())) {
+ return false;
+ }
+ // Crypto and headers streams are not blocked by connection level flow
+ // control.
+ return write_blocked_streams_.HasWriteBlockedSpecialStream();
+ }
+ return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
+ write_blocked_streams_.HasWriteBlockedDataStreams();
}
bool QuicSession::HasPendingHandshake() const {
@@ -681,12 +680,6 @@ bool QuicSession::HasPendingHandshake() const {
QuicUtils::GetCryptoStreamId(transport_version()));
}
-uint64_t QuicSession::GetNumOpenDynamicStreams() const {
- return stream_map_.size() - GetNumDrainingStreams() +
- locally_closed_streams_highest_offset_.size() -
- num_incoming_static_streams_ - num_outgoing_static_streams_;
-}
-
void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
const QuicReceivedPacket& packet) {
@@ -763,22 +756,11 @@ void QuicSession::SendRstStream(QuicStreamId id,
connection_->OnStreamReset(id, error);
}
-
- if (break_close_loop_) {
- return;
- }
-
- if (error != QUIC_STREAM_NO_ERROR && QuicContainsKey(zombie_streams_, id)) {
- OnStreamDoneWaitingForAcks(id);
- return;
- }
- CloseStreamInner(id, true);
}
void QuicSession::ResetStream(QuicStreamId id,
QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written) {
- DCHECK(break_close_loop_);
QuicStream* stream = GetStream(id);
if (stream != nullptr && stream->is_static()) {
connection()->CloseConnection(
@@ -800,8 +782,8 @@ void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
QuicStreamOffset bytes_written) {
DCHECK(connection()->connected());
if (!VersionHasIetfQuicFrames(transport_version()) ||
- QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id)) !=
- READ_UNIDIRECTIONAL) {
+ QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+ version()) != READ_UNIDIRECTIONAL) {
control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
}
}
@@ -810,8 +792,8 @@ void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
QuicRstStreamErrorCode error) {
DCHECK(connection()->connected());
if (VersionHasIetfQuicFrames(transport_version()) &&
- QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id)) !=
- WRITE_UNIDIRECTIONAL) {
+ QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
+ version()) != WRITE_UNIDIRECTIONAL) {
control_frame_manager_.WriteOrBufferStopSending(error, id);
}
}
@@ -854,24 +836,11 @@ void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
}
void QuicSession::CloseStream(QuicStreamId stream_id) {
- CloseStreamInner(stream_id, false);
-}
-
-void QuicSession::InsertLocallyClosedStreamsHighestOffset(
- const QuicStreamId id,
- QuicStreamOffset offset) {
- locally_closed_streams_highest_offset_[id] = offset;
- if (IsIncomingStream(id)) {
- ++num_locally_closed_incoming_streams_highest_offset_;
- }
-}
-
-void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool rst_sent) {
QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
StreamMap::iterator it = stream_map_.find(stream_id);
if (it == stream_map_.end()) {
- // When CloseStreamInner has been called recursively (via
+ // When CloseStream has been called recursively (via
// QuicStream::OnClose), the stream will already have been deleted
// from stream_map_, so return immediately.
QUIC_DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id;
@@ -887,89 +856,18 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool rst_sent) {
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return;
}
- if (break_close_loop_) {
- stream->CloseReadSide();
- stream->CloseWriteSide();
- return;
- }
- StreamType type = stream->type();
-
- // Tell the stream that a RST has been sent.
- if (rst_sent) {
- stream->set_rst_sent(true);
- }
-
- if (stream->IsWaitingForAcks()) {
- zombie_streams_[stream->id()] = std::move(it->second);
- } else {
- // Clean up the stream since it is no longer waiting for acks.
- streams_waiting_for_acks_.erase(stream->id());
- closed_streams_.push_back(std::move(it->second));
- // Do not retransmit data of a closed stream.
- streams_with_pending_retransmission_.erase(stream_id);
- if (!closed_streams_clean_up_alarm_->IsSet()) {
- closed_streams_clean_up_alarm_->Set(
- connection_->clock()->ApproximateNow());
- }
- }
-
- // If we haven't received a FIN or RST for this stream, we need to keep track
- // of the how many bytes the stream's flow controller believes it has
- // received, for accurate connection level flow control accounting.
- const bool had_fin_or_rst = stream->HasReceivedFinalOffset();
- if (!had_fin_or_rst) {
- InsertLocallyClosedStreamsHighestOffset(
- stream_id, stream->flow_controller()->highest_received_byte_offset());
- }
- bool stream_was_draining = false;
- if (deprecate_draining_streams_) {
- stream_was_draining = stream->was_draining();
- QUIC_DVLOG_IF(1, stream_was_draining)
- << ENDPOINT << "Stream " << stream_id << " was draining";
- }
- stream_map_.erase(it);
- if (IsIncomingStream(stream_id)) {
- --num_dynamic_incoming_streams_;
- }
- if (!deprecate_draining_streams_) {
- stream_was_draining =
- draining_streams_.find(stream_id) != draining_streams_.end();
- }
- if (stream_was_draining) {
- if (IsIncomingStream(stream_id)) {
- QUIC_BUG_IF(num_draining_incoming_streams_ == 0);
- --num_draining_incoming_streams_;
- } else if (deprecate_draining_streams_) {
- QUIC_BUG_IF(num_draining_outgoing_streams_ == 0);
- --num_draining_outgoing_streams_;
- }
- draining_streams_.erase(stream_id);
- } else if (VersionHasIetfQuicFrames(transport_version())) {
- // Stream was not draining, but we did have a fin or rst, so we can now
- // free the stream ID if version 99.
- if (had_fin_or_rst && connection_->connected()) {
- // Do not bother informing stream ID manager if connection is closed.
- v99_streamid_manager_.OnStreamClosed(stream_id);
- }
- } else if (stream_id_manager_.handles_accounting() && had_fin_or_rst &&
- connection_->connected()) {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
-
- stream->OnClose();
+ stream->CloseReadSide();
+ stream->CloseWriteSide();
+}
- if (!stream_was_draining && !IsIncomingStream(stream_id) && had_fin_or_rst &&
- !VersionHasIetfQuicFrames(transport_version())) {
- // Streams that first became draining already called OnCanCreate...
- // This covers the case where the stream went directly to being closed.
- OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
- }
+void QuicSession::InsertLocallyClosedStreamsHighestOffset(
+ const QuicStreamId id,
+ QuicStreamOffset offset) {
+ locally_closed_streams_highest_offset_[id] = offset;
}
void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
- DCHECK(break_close_loop_);
StreamMap::iterator it = stream_map_.find(stream_id);
if (it == stream_map_.end()) {
QUIC_DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id;
@@ -1002,48 +900,38 @@ void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
InsertLocallyClosedStreamsHighestOffset(
stream_id, stream->flow_controller()->highest_received_byte_offset());
stream_map_.erase(it);
- if (IsIncomingStream(stream_id)) {
- --num_dynamic_incoming_streams_;
- }
return;
}
- bool stream_was_draining = false;
- if (deprecate_draining_streams_) {
- stream_was_draining = stream->was_draining();
- QUIC_DVLOG_IF(1, stream_was_draining)
- << ENDPOINT << "Stream " << stream_id << " was draining";
- }
+ const bool stream_was_draining = stream->was_draining();
+ QUIC_DVLOG_IF(1, stream_was_draining)
+ << ENDPOINT << "Stream " << stream_id << " was draining";
stream_map_.erase(it);
- if (IsIncomingStream(stream_id)) {
- --num_dynamic_incoming_streams_;
- }
- if (!deprecate_draining_streams_) {
- stream_was_draining =
- draining_streams_.find(stream_id) != draining_streams_.end();
- }
if (stream_was_draining) {
- if (IsIncomingStream(stream_id)) {
- QUIC_BUG_IF(num_draining_incoming_streams_ == 0);
- --num_draining_incoming_streams_;
- } else if (deprecate_draining_streams_) {
- QUIC_BUG_IF(num_draining_outgoing_streams_ == 0);
- --num_draining_outgoing_streams_;
+ QUIC_BUG_IF(num_draining_streams_ == 0);
+ --num_draining_streams_;
+ if (!IsIncomingStream(stream_id)) {
+ QUIC_BUG_IF(num_outgoing_draining_streams_ == 0);
+ --num_outgoing_draining_streams_;
}
- draining_streams_.erase(stream_id);
// Stream Id manager has been informed with draining streams.
return;
}
- if (!connection_->connected()) {
+ if (!GetQuicReloadableFlag(quic_notify_stream_id_manager_when_disconnected) &&
+ !connection_->connected()) {
// Do not bother informing stream ID manager if connection has been
// disconnected.
return;
}
- if (stream_id_manager_.handles_accounting() &&
- !VersionHasIetfQuicFrames(transport_version())) {
+ if (!VersionHasIetfQuicFrames(transport_version())) {
stream_id_manager_.OnStreamClosed(
/*is_incoming=*/IsIncomingStream(stream_id));
}
+ if (GetQuicReloadableFlag(quic_notify_stream_id_manager_when_disconnected) &&
+ !connection_->connected()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_notify_stream_id_manager_when_disconnected);
+ return;
+ }
if (IsIncomingStream(stream_id)) {
// Stream Id manager is only interested in peer initiated stream IDs.
if (VersionHasIetfQuicFrames(transport_version())) {
@@ -1090,13 +978,11 @@ void QuicSession::OnFinalByteOffsetReceived(
flow_controller_.AddBytesConsumed(offset_diff);
locally_closed_streams_highest_offset_.erase(it);
- if (stream_id_manager_.handles_accounting() &&
- !VersionHasIetfQuicFrames(transport_version())) {
+ if (!VersionHasIetfQuicFrames(transport_version())) {
stream_id_manager_.OnStreamClosed(
/*is_incoming=*/IsIncomingStream(stream_id));
}
if (IsIncomingStream(stream_id)) {
- --num_locally_closed_incoming_streams_highest_offset_;
if (VersionHasIetfQuicFrames(transport_version())) {
v99_streamid_manager_.OnStreamClosed(stream_id);
}
@@ -1120,6 +1006,21 @@ bool QuicSession::OneRttKeysAvailable() const {
}
void QuicSession::OnConfigNegotiated() {
+ // In versions with TLS, the configs will be set twice if 0-RTT is available.
+ // In the second config setting, 1-RTT keys are guaranteed to be available.
+ if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) &&
+ version().UsesTls() && is_configured_ &&
+ connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
+ QUIC_BUG
+ << ENDPOINT
+ << "1-RTT keys missing when config is negotiated for the second time.";
+ connection_->CloseConnection(
+ QUIC_INTERNAL_ERROR,
+ "1-RTT keys missing when config is negotiated for the second time.",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
+
QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
connection_->SetFromConfig(config_);
@@ -1128,6 +1029,19 @@ void QuicSession::OnConfigNegotiated() {
if (config_.HasReceivedMaxBidirectionalStreams()) {
max_streams = config_.ReceivedMaxBidirectionalStreams();
}
+ if (was_zero_rtt_rejected_ &&
+ max_streams <
+ v99_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()),
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
QUIC_DVLOG(1) << ENDPOINT
<< "Setting Bidirectional outgoing_max_streams_ to "
<< max_streams;
@@ -1135,8 +1049,12 @@ void QuicSession::OnConfigNegotiated() {
max_streams <
v99_streamid_manager_.max_outgoing_bidirectional_streams()) {
connection_->CloseConnection(
- QUIC_MAX_STREAMS_ERROR,
+ was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+ : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
quiche::QuicheStrCat(
+ was_zero_rtt_rejected_
+ ? "Server rejected 0-RTT, aborting because "
+ : "",
"new bidirectional limit ", max_streams,
" decreases the current limit: ",
v99_streamid_manager_.max_outgoing_bidirectional_streams()),
@@ -1152,11 +1070,30 @@ void QuicSession::OnConfigNegotiated() {
if (config_.HasReceivedMaxUnidirectionalStreams()) {
max_streams = config_.ReceivedMaxUnidirectionalStreams();
}
+
+ if (was_zero_rtt_rejected_ &&
+ max_streams <
+ v99_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()),
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
+
if (max_streams <
v99_streamid_manager_.max_outgoing_unidirectional_streams()) {
connection_->CloseConnection(
- QUIC_MAX_STREAMS_ERROR,
+ was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+ : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
quiche::QuicheStrCat(
+ was_zero_rtt_rejected_
+ ? "Server rejected 0-RTT, aborting because "
+ : "",
"new unidirectional limit ", max_streams,
" decreases the current limit: ",
v99_streamid_manager_.max_outgoing_unidirectional_streams()),
@@ -1177,6 +1114,17 @@ void QuicSession::OnConfigNegotiated() {
}
QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
<< max_streams;
+ if (was_zero_rtt_rejected_ &&
+ max_streams < stream_id_manager_.num_open_outgoing_streams()) {
+ connection_->CloseConnection(
+ QUIC_INTERNAL_ERROR,
+ quiche::QuicheStrCat(
+ "Server rejected 0-RTT, aborting because new stream limit ",
+ max_streams, " is less than current open streams: ",
+ stream_id_manager_.num_open_outgoing_streams()),
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
stream_id_manager_.set_max_open_outgoing_streams(max_streams);
}
@@ -1271,11 +1219,16 @@ void QuicSession::OnConfigNegotiated() {
OnNewSessionFlowControlWindow(
config_.ReceivedInitialSessionFlowControlWindowBytes());
}
+
is_configured_ = true;
connection()->OnConfigNegotiated();
// Ask flow controllers to try again since the config could have unblocked us.
- if (connection_->version().AllowsLowFlowControlLimits()) {
+ // Or if this session is configured on TLS enabled QUIC versions,
+ // attempt to retransmit 0-RTT data if there's any.
+ if (connection_->version().AllowsLowFlowControlLimits() ||
+ (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) &&
+ version().UsesTls())) {
OnCanWrite();
}
}
@@ -1373,8 +1326,15 @@ void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
// Inform all existing outgoing unidirectional streams about the new window.
for (auto const& kv : stream_map_) {
const QuicStreamId id = kv.first;
- if (QuicUtils::IsBidirectionalStreamId(id)) {
- continue;
+ if (fix_gquic_stream_type_ && !version().HasIetfQuicFrames()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_gquic_stream_type, 1, 3);
+ if (kv.second->type() == BIDIRECTIONAL) {
+ continue;
+ }
+ } else {
+ if (QuicUtils::IsBidirectionalStreamId(id, version())) {
+ continue;
+ }
}
if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
perspective())) {
@@ -1382,6 +1342,9 @@ void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
}
QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
<< " of new stream flow control window " << new_window;
+ if (!ValidateStreamFlowControlLimit(new_window, kv.second.get())) {
+ return;
+ }
if (!kv.second->ConfigSendWindowOffset(new_window)) {
return;
}
@@ -1397,8 +1360,15 @@ void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
// Inform all existing outgoing bidirectional streams about the new window.
for (auto const& kv : stream_map_) {
const QuicStreamId id = kv.first;
- if (!QuicUtils::IsBidirectionalStreamId(id)) {
- continue;
+ if (fix_gquic_stream_type_ && !version().HasIetfQuicFrames()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_gquic_stream_type, 2, 3);
+ if (kv.second->type() != BIDIRECTIONAL) {
+ continue;
+ }
+ } else {
+ if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+ continue;
+ }
}
if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
perspective())) {
@@ -1406,6 +1376,9 @@ void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
}
QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
<< id << " of new stream flow control window " << new_window;
+ if (!ValidateStreamFlowControlLimit(new_window, kv.second.get())) {
+ return;
+ }
if (!kv.second->ConfigSendWindowOffset(new_window)) {
return;
}
@@ -1421,8 +1394,15 @@ void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
// Inform all existing incoming bidirectional streams about the new window.
for (auto const& kv : stream_map_) {
const QuicStreamId id = kv.first;
- if (!QuicUtils::IsBidirectionalStreamId(id)) {
- continue;
+ if (fix_gquic_stream_type_ && !version().HasIetfQuicFrames()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_gquic_stream_type, 3, 3);
+ if (kv.second->type() != BIDIRECTIONAL) {
+ continue;
+ }
+ } else {
+ if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
+ continue;
+ }
}
if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
perspective())) {
@@ -1430,39 +1410,92 @@ void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
}
QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
<< id << " of new stream flow control window " << new_window;
+ if (!ValidateStreamFlowControlLimit(new_window, kv.second.get())) {
+ return;
+ }
if (!kv.second->ConfigSendWindowOffset(new_window)) {
return;
}
}
}
+bool QuicSession::ValidateStreamFlowControlLimit(QuicStreamOffset new_window,
+ const QuicStream* stream) {
+ if (was_zero_rtt_rejected_ &&
+ new_window < stream->flow_controller()->bytes_sent()) {
+ QUIC_BUG_IF(perspective() == Perspective::IS_SERVER)
+ << "Server should never receive configs twice.";
+ connection_->CloseConnection(
+ QUIC_ZERO_RTT_UNRETRANSMITTABLE,
+ quiche::QuicheStrCat(
+ "Server rejected 0-RTT, aborting because new stream max data ",
+ new_window, " for stream ", stream->id(),
+ " is less than currently used: ",
+ stream->flow_controller()->bytes_sent()),
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+
+ if (version().AllowsLowFlowControlLimits() &&
+ new_window < stream->flow_controller()->send_window_offset()) {
+ QUIC_BUG_IF(perspective() == Perspective::IS_SERVER)
+ << "Server should never receive configs twice.";
+ connection_->CloseConnection(
+ was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+ : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+ quiche::QuicheStrCat(
+ was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
+ : "",
+ "new stream max data ", new_window, " decreases current limit: ",
+ stream->flow_controller()->send_window_offset()),
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ }
+ return true;
+}
+
void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
- bool close_connection = false;
- if (!connection_->version().AllowsLowFlowControlLimits()) {
- if (new_window < kMinimumFlowControlSendWindow) {
- close_connection = true;
- QUIC_LOG_FIRST_N(ERROR, 1)
- << "Peer sent us an invalid session flow control send window: "
- << new_window << ", below default: " << kMinimumFlowControlSendWindow;
- }
- } else if (perspective_ == Perspective::IS_CLIENT &&
- new_window < flow_controller_.send_window_offset()) {
- // The client receives a lower limit than remembered, violating
- // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
- QUIC_LOG_FIRST_N(ERROR, 1)
- << "Peer sent us an invalid session flow control send window: "
- << new_window
- << ", below current: " << flow_controller_.send_window_offset();
- close_connection = true;
+
+ if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
+ std::string error_details = quiche::QuicheStrCat(
+ "Server rejected 0-RTT. Aborting because the client received session "
+ "flow control send window: ",
+ new_window,
+ ", which is below currently used: ", flow_controller_.bytes_sent());
+ QUIC_LOG(ERROR) << error_details;
+ connection_->CloseConnection(
+ QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
}
- if (close_connection) {
+ if (!connection_->version().AllowsLowFlowControlLimits() &&
+ new_window < kMinimumFlowControlSendWindow) {
+ std::string error_details = quiche::QuicheStrCat(
+ "Peer sent us an invalid session flow control send window: ",
+ new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
+ QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
connection_->CloseConnection(
- QUIC_FLOW_CONTROL_INVALID_WINDOW,
- quiche::QuicheStrCat("New connection window too low: ", new_window),
+ QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return;
}
+ if (perspective_ == Perspective::IS_CLIENT &&
+ new_window < flow_controller_.send_window_offset()) {
+ // The client receives a lower limit than remembered, violating
+ // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
+ std::string error_details = quiche::QuicheStrCat(
+ was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
+ : "",
+ "new session max data ", new_window,
+ " decreases current limit: ", flow_controller_.send_window_offset());
+ QUIC_LOG(ERROR) << error_details;
+ connection_->CloseConnection(
+ was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
+ : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
+ error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
flow_controller_.UpdateSendWindowOffset(new_window);
}
@@ -1497,31 +1530,17 @@ void QuicSession::OnNewEncryptionKeyAvailable(
EncryptionLevel level,
std::unique_ptr<QuicEncrypter> encrypter) {
connection()->SetEncrypter(level, std::move(encrypter));
-
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
- (perspective() == Perspective::IS_CLIENT ||
- GetQuicReloadableFlag(quic_change_default_encryption_level))) {
- QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to "
- << EncryptionLevelToString(level);
- QUIC_RELOADABLE_FLAG_COUNT(quic_change_default_encryption_level);
- connection()->SetDefaultEncryptionLevel(level);
+ if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
return;
}
- if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
- level == ENCRYPTION_FORWARD_SECURE) {
- // Set connection's default encryption level once 1-RTT write key is
- // available.
- QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to "
- << EncryptionLevelToString(level);
- connection()->SetDefaultEncryptionLevel(level);
- }
+ QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
+ connection()->SetDefaultEncryptionLevel(level);
}
void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
DCHECK_EQ(PROTOCOL_QUIC_CRYPTO, connection_->version().handshake_protocol);
- QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
connection()->SetDefaultEncryptionLevel(level);
switch (level) {
@@ -1531,7 +1550,7 @@ void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
if (perspective() == Perspective::IS_CLIENT) {
// Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
// they can't be decrypted by the server.
- connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION);
+ connection_->RetransmitZeroRttPackets();
// Given any streams blocked by encryption a chance to write.
OnCanWrite();
}
@@ -1541,13 +1560,9 @@ void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
case ENCRYPTION_FORWARD_SECURE:
QUIC_BUG_IF(!config_.negotiated())
<< ENDPOINT << "Handshake confirmed without parameter negotiation.";
- if (!GetQuicReloadableFlag(quic_bw_sampler_app_limited_starting_value)) {
- connection_->ResetHasNonAppLimitedSampleAfterHandshakeCompletion();
- }
break;
default:
- QUIC_BUG << "Unknown encryption level: "
- << EncryptionLevelToString(level);
+ QUIC_BUG << "Unknown encryption level: " << level;
}
}
@@ -1557,15 +1572,17 @@ void QuicSession::OnOneRttKeysAvailable() {
<< ENDPOINT << "Handshake completes without cipher suite negotiation.";
QUIC_BUG_IF(!config_.negotiated())
<< ENDPOINT << "Handshake completes without parameter negotiation.";
- if (connection()->version().HasHandshakeDone() &&
+ if ((connection()->version().HasHandshakeDone() ||
+ (GetQuicReloadableFlag(quic_support_handshake_done_in_t050) &&
+ config_.PeerSupportsHandshakeDone())) &&
perspective_ == Perspective::IS_SERVER) {
+ if (!connection()->version().HasHandshakeDone()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_support_handshake_done_in_t050);
+ }
// Server sends HANDSHAKE_DONE to signal confirmation of the handshake
// to the client.
control_frame_manager_.WriteOrBufferHandshakeDone();
}
- if (!GetQuicReloadableFlag(quic_bw_sampler_app_limited_starting_value)) {
- connection_->ResetHasNonAppLimitedSampleAfterHandshakeCompletion();
- }
}
void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
@@ -1576,8 +1593,7 @@ void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
}
void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
- QUIC_DVLOG(1) << ENDPOINT << "Discard keys of "
- << EncryptionLevelToString(level);
+ QUIC_DVLOG(1) << ENDPOINT << "Discard keys of " << level;
if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
connection()->RemoveEncrypter(level);
}
@@ -1594,8 +1610,7 @@ void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
QUIC_BUG << "Tries to drop 1-RTT keys";
break;
default:
- QUIC_BUG << "Unknown encryption level: "
- << EncryptionLevelToString(level);
+ QUIC_BUG << "Unknown encryption level: " << level;
}
}
@@ -1603,6 +1618,46 @@ void QuicSession::NeuterHandshakeData() {
connection()->OnHandshakeComplete();
}
+void QuicSession::OnZeroRttRejected() {
+ was_zero_rtt_rejected_ = true;
+ connection_->RetransmitZeroRttPackets();
+ if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
+ QUIC_BUG << "1-RTT keys already available when 0-RTT is rejected.";
+ connection_->CloseConnection(
+ QUIC_INTERNAL_ERROR,
+ "1-RTT keys already available when 0-RTT is rejected.",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ }
+}
+
+bool QuicSession::FillTransportParameters(TransportParameters* params) {
+ if (version().AuthenticatesHandshakeConnectionIds()) {
+ if (perspective() == Perspective::IS_SERVER) {
+ config_.SetOriginalConnectionIdToSend(
+ connection_->GetOriginalDestinationConnectionId());
+ config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
+ } else {
+ config_.SetInitialSourceConnectionIdToSend(
+ connection_->client_connection_id());
+ }
+ }
+ return config_.FillTransportParameters(params);
+}
+
+QuicErrorCode QuicSession::ProcessTransportParameters(
+ const TransportParameters& params,
+ bool is_resumption,
+ std::string* error_details) {
+ HelloType hello_type;
+ if (perspective_ == Perspective::IS_CLIENT) {
+ hello_type = SERVER;
+ } else {
+ hello_type = CLIENT;
+ }
+ return config_.ProcessTransportParameters(params, hello_type, is_resumption,
+ error_details);
+}
+
void QuicSession::OnCryptoHandshakeMessageSent(
const CryptoHandshakeMessage& /*message*/) {}
@@ -1648,14 +1703,11 @@ void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
<< ". activating stream " << stream_id;
DCHECK(!QuicContainsKey(stream_map_, stream_id));
stream_map_[stream_id] = std::move(stream);
- if (IsIncomingStream(stream_id)) {
- is_static ? ++num_incoming_static_streams_
- : ++num_dynamic_incoming_streams_;
- } else if (is_static) {
- ++num_outgoing_static_streams_;
+ if (is_static) {
+ ++num_static_streams_;
+ return;
}
- if (stream_id_manager_.handles_accounting() && !is_static &&
- !VersionHasIetfQuicFrames(transport_version())) {
+ if (!VersionHasIetfQuicFrames(transport_version())) {
// Do not inform stream ID manager of static streams.
stream_id_manager_.ActivateStream(
/*is_incoming=*/IsIncomingStream(stream_id));
@@ -1678,8 +1730,7 @@ QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
if (!VersionHasIetfQuicFrames(transport_version())) {
- return stream_id_manager_.CanOpenNextOutgoingStream(
- GetNumOpenOutgoingStreams());
+ return stream_id_manager_.CanOpenNextOutgoingStream();
}
if (v99_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
return true;
@@ -1695,8 +1746,7 @@ bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
if (!VersionHasIetfQuicFrames(transport_version())) {
- return stream_id_manager_.CanOpenNextOutgoingStream(
- GetNumOpenOutgoingStreams());
+ return stream_id_manager_.CanOpenNextOutgoingStream();
}
if (v99_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
return true;
@@ -1745,19 +1795,11 @@ QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
return nullptr;
}
- if (!VersionHasIetfQuicFrames(transport_version())) {
- // TODO(fayang): Let LegacyQuicStreamIdManager count open streams and make
- // CanOpenIncomingStream interface consistent with that of v99.
- if (!stream_id_manager_.CanOpenIncomingStream(
- GetNumOpenIncomingStreams())) {
- // Refuse to open the stream.
- if (break_close_loop_) {
- ResetStream(stream_id, QUIC_REFUSED_STREAM, 0);
- } else {
- SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0);
- }
- return nullptr;
- }
+ if (!VersionHasIetfQuicFrames(transport_version()) &&
+ !stream_id_manager_.CanOpenIncomingStream()) {
+ // Refuse to open the stream.
+ ResetStream(stream_id, QUIC_REFUSED_STREAM, 0);
+ return nullptr;
}
return CreateIncomingStream(stream_id);
@@ -1765,48 +1807,17 @@ QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
DCHECK(QuicContainsKey(stream_map_, stream_id));
- if (deprecate_draining_streams_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_deprecate_draining_streams);
- QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
- if (VersionHasIetfQuicFrames(transport_version())) {
- v99_streamid_manager_.OnStreamClosed(stream_id);
- } else if (stream_id_manager_.handles_accounting()) {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
- if (IsIncomingStream(stream_id)) {
- ++num_draining_incoming_streams_;
- return;
- }
- ++num_draining_outgoing_streams_;
- OnCanCreateNewOutgoingStream(unidirectional);
- return;
- }
- if (!QuicContainsKey(draining_streams_, stream_id)) {
- draining_streams_.insert(stream_id);
- if (IsIncomingStream(stream_id)) {
- ++num_draining_incoming_streams_;
- }
- if (VersionHasIetfQuicFrames(transport_version())) {
- v99_streamid_manager_.OnStreamClosed(stream_id);
- } else if (stream_id_manager_.handles_accounting()) {
- stream_id_manager_.OnStreamClosed(
- /*is_incoming=*/IsIncomingStream(stream_id));
- }
+ QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
+ if (VersionHasIetfQuicFrames(transport_version())) {
+ v99_streamid_manager_.OnStreamClosed(stream_id);
+ } else {
+ stream_id_manager_.OnStreamClosed(
+ /*is_incoming=*/IsIncomingStream(stream_id));
}
+ ++num_draining_streams_;
if (!IsIncomingStream(stream_id)) {
- // Inform application that a stream is available.
- if (VersionHasIetfQuicFrames(transport_version())) {
- OnCanCreateNewOutgoingStream(
- !QuicUtils::IsBidirectionalStreamId(stream_id));
- } else {
- QuicStream* stream = GetStream(stream_id);
- if (!stream) {
- QUIC_BUG << "Stream doesn't exist when draining.";
- return;
- }
- OnCanCreateNewOutgoingStream(stream->type() != BIDIRECTIONAL);
- }
+ ++num_outgoing_draining_streams_;
+ OnCanCreateNewOutgoingStream(unidirectional);
}
}
@@ -1924,46 +1935,15 @@ bool QuicSession::IsStaticStream(QuicStreamId id) const {
return it->second->is_static();
}
-size_t QuicSession::GetNumOpenIncomingStreams() const {
- DCHECK(!VersionHasIetfQuicFrames(transport_version()));
- if (stream_id_manager_.handles_accounting()) {
- return stream_id_manager_.num_open_incoming_streams();
- }
- return num_dynamic_incoming_streams_ - num_draining_incoming_streams_ +
- num_locally_closed_incoming_streams_highest_offset_;
-}
-
-size_t QuicSession::GetNumOpenOutgoingStreams() const {
- DCHECK(!VersionHasIetfQuicFrames(transport_version()));
- if (stream_id_manager_.handles_accounting()) {
- return stream_id_manager_.num_open_outgoing_streams();
- }
- DCHECK_GE(GetNumDynamicOutgoingStreams() +
- GetNumLocallyClosedOutgoingStreamsHighestOffset(),
- GetNumDrainingOutgoingStreams());
- return GetNumDynamicOutgoingStreams() +
- GetNumLocallyClosedOutgoingStreamsHighestOffset() -
- GetNumDrainingOutgoingStreams();
-}
-
size_t QuicSession::GetNumActiveStreams() const {
- if (!VersionHasIetfQuicFrames(transport_version()) &&
- stream_id_manager_.handles_accounting()) {
+ if (!VersionHasIetfQuicFrames(transport_version())) {
// Exclude locally_closed_streams when determine whether to keep connection
// alive.
return stream_id_manager_.num_open_incoming_streams() +
stream_id_manager_.num_open_outgoing_streams() -
locally_closed_streams_highest_offset_.size();
}
- return stream_map_.size() - GetNumDrainingStreams() -
- num_incoming_static_streams_ - num_outgoing_static_streams_;
-}
-
-size_t QuicSession::GetNumDrainingStreams() const {
- if (deprecate_draining_streams_) {
- return num_draining_incoming_streams_ + num_draining_outgoing_streams_;
- }
- return draining_streams_.size();
+ return stream_map_.size() - num_draining_streams_ - num_static_streams_;
}
void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
@@ -1994,31 +1974,6 @@ void QuicSession::SendPing() {
control_frame_manager_.WritePing();
}
-size_t QuicSession::GetNumDynamicOutgoingStreams() const {
- DCHECK_GE(
- static_cast<size_t>(stream_map_.size() + pending_stream_map_.size()),
- num_dynamic_incoming_streams_ + num_outgoing_static_streams_ +
- num_incoming_static_streams_);
- return stream_map_.size() + pending_stream_map_.size() -
- num_dynamic_incoming_streams_ - num_outgoing_static_streams_ -
- num_incoming_static_streams_;
-}
-
-size_t QuicSession::GetNumDrainingOutgoingStreams() const {
- if (deprecate_draining_streams_) {
- return num_draining_outgoing_streams_;
- }
- DCHECK_GE(draining_streams_.size(), num_draining_incoming_streams_);
- return draining_streams_.size() - num_draining_incoming_streams_;
-}
-
-size_t QuicSession::GetNumLocallyClosedOutgoingStreamsHighestOffset() const {
- DCHECK_GE(locally_closed_streams_highest_offset_.size(),
- num_locally_closed_incoming_streams_highest_offset_);
- return locally_closed_streams_highest_offset_.size() -
- num_locally_closed_incoming_streams_highest_offset_;
-}
-
bool QuicSession::IsConnectionFlowControlBlocked() const {
return flow_controller_.IsBlocked();
}
@@ -2273,6 +2228,18 @@ QuicUint128 QuicSession::GetStatelessResetToken() const {
return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
}
+bool QuicSession::CanWriteStreamData() const {
+ // Don't write stream data if there are queued data packets.
+ if (connection_->HasQueuedPackets()) {
+ return false;
+ }
+ // Immediately write handshake data.
+ if (HasPendingHandshake()) {
+ return true;
+ }
+ return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
+}
+
bool QuicSession::RetransmitLostData() {
QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
// Retransmit crypto data first.
@@ -2305,7 +2272,7 @@ bool QuicSession::RetransmitLostData() {
}
}
while (!streams_with_pending_retransmission_.empty()) {
- if (!connection_->CanWriteStreamData()) {
+ if (!CanWriteStreamData()) {
break;
}
// Retransmit lost data on headers and data streams.
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 5a1ebbc602c..9233402d4ea 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
@@ -33,6 +33,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_string_piece.h"
namespace quic {
@@ -110,17 +111,21 @@ class QUIC_EXPORT_PRIVATE QuicSession
bool is_connectivity_probe) override;
void OnCanWrite() override;
bool SendProbingData() override;
+ bool ValidateStatelessReset(
+ const quic::QuicSocketAddress& /*self_address*/,
+ const quic::QuicSocketAddress& /*peer_address*/) override {
+ return true;
+ }
void OnCongestionWindowChange(QuicTime /*now*/) override {}
void OnConnectionMigration(AddressChangeType /*type*/) override {}
// Adds a connection level WINDOW_UPDATE frame.
void OnAckNeedsRetransmittableFrame() override;
void SendPing() override;
bool WillingAndAbleToWrite() const override;
- bool HasPendingHandshake() const override;
void OnPathDegrading() override;
+ void OnForwardProgressMadeAfterPathDegrading() override;
bool AllowSelfAddressChange() const override;
HandshakeState GetHandshakeState() const override;
- void OnForwardProgressConfirmed() override;
bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
@@ -255,6 +260,11 @@ class QUIC_EXPORT_PRIVATE QuicSession
void DiscardOldEncryptionKey(EncryptionLevel level) override;
void NeuterUnencryptedData() override;
void NeuterHandshakeData() override;
+ void OnZeroRttRejected() override;
+ bool FillTransportParameters(TransportParameters* params) override;
+ QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
+ bool is_resumption,
+ std::string* error_details) override;
// Implement StreamDelegateInterface.
void OnStreamError(QuicErrorCode error_code,
@@ -322,33 +332,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
// never counting unfinished streams.
size_t GetNumActiveStreams() const;
- // Returns the number of currently draining streams.
- size_t GetNumDrainingStreams() const;
-
- // Returns the number of currently open peer initiated streams, excluding
- // static streams.
- // TODO(fayang): remove this and instead use
- // LegacyStreamIdManager::num_open_incoming_streams() in tests when
- // deprecating quic_stream_id_manager_handles_accounting.
- size_t GetNumOpenIncomingStreams() const;
-
- // Returns the number of currently open self initiated streams, excluding
- // static streams.
- // TODO(fayang): remove this and instead use
- // LegacyStreamIdManager::num_open_outgoing_streams() in tests when
- // deprecating quic_stream_id_manager_handles_accounting.
- size_t GetNumOpenOutgoingStreams() const;
-
- // Returns the number of open peer initiated static streams.
- size_t num_incoming_static_streams() const {
- return num_incoming_static_streams_;
- }
-
- // Returns the number of open self initiated static streams.
- size_t num_outgoing_static_streams() const {
- return num_outgoing_static_streams_;
- }
-
// Add the stream to the session's write-blocked list because it is blocked by
// connection-level flow control but not by its own stream-level flow control.
// The stream will be given a chance to write when a connection-level
@@ -363,6 +346,10 @@ class QUIC_EXPORT_PRIVATE QuicSession
// Called when stream |id| is newly waiting for acks.
void OnStreamWaitingForAcks(QuicStreamId id);
+ // Returns true if there is pending handshake data in the crypto stream.
+ // TODO(ianswett): Make this private or remove.
+ bool HasPendingHandshake() const;
+
// Returns true if the session has data to be sent, either queued in the
// connection, or in a write-blocked stream.
bool HasDataToWrite() const;
@@ -435,12 +422,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
// Return true if given stream is peer initiated.
bool IsIncomingStream(QuicStreamId id) const;
- size_t GetNumLocallyClosedOutgoingStreamsHighestOffset() const;
-
- size_t num_locally_closed_incoming_streams_highest_offset() const {
- return num_locally_closed_incoming_streams_highest_offset_;
- }
-
// Record errors when a connection is closed at the server side, should only
// be called from server's perspective.
// Noop if |error| is QUIC_NO_ERROR.
@@ -478,27 +459,30 @@ class QUIC_EXPORT_PRIVATE QuicSession
// uses TLS handshake.
virtual void OnAlpnSelected(quiche::QuicheStringPiece alpn);
- bool deprecate_draining_streams() const {
- return deprecate_draining_streams_;
- }
-
- bool break_close_loop() const { return break_close_loop_; }
-
// Called on clients by the crypto handshaker to provide application state
// necessary for sending application data in 0-RTT. The state provided here is
// the same state that was provided to the crypto handshaker in
- // QuicCryptoClientStream::OnApplicationState on a previous connection.
- // Application protocols that require state to be carried over from the
- // previous connection to support 0-RTT data must implement this method to
- // ingest this state. For example, an HTTP/3 QuicSession would implement this
- // function to process the remembered server SETTINGS frame and apply those
- // SETTINGS to 0-RTT data. This function returns true if the application state
- // has been successfully processed, and false if there was an error processing
- // the cached state and the connection should be closed.
- virtual bool SetApplicationState(ApplicationState* /*cached_state*/) {
+ // QuicCryptoStream::SetServerApplicationStateForResumption on a previous
+ // connection. Application protocols that require state to be carried over
+ // from the previous connection to support 0-RTT data must implement this
+ // method to ingest this state. For example, an HTTP/3 QuicSession would
+ // implement this function to process the remembered server SETTINGS and apply
+ // those SETTINGS to 0-RTT data. This function returns true if the application
+ // state has been successfully processed, and false if there was an error
+ // processing the cached state and the connection should be closed.
+ virtual bool ResumeApplicationState(ApplicationState* /*cached_state*/) {
return true;
}
+ const quiche::QuicheOptional<std::string> user_agent_id() const {
+ return user_agent_id_;
+ }
+
+ void SetUserAgentId(std::string user_agent_id) {
+ user_agent_id_ = std::move(user_agent_id);
+ connection()->OnUserAgentIdKnown();
+ }
+
protected:
using StreamMap = QuicSmallMap<QuicStreamId, std::unique_ptr<QuicStream>, 10>;
@@ -541,18 +525,10 @@ class QUIC_EXPORT_PRIVATE QuicSession
bool CanOpenNextOutgoingBidirectionalStream();
bool CanOpenNextOutgoingUnidirectionalStream();
- // Returns the number of open dynamic streams.
- uint64_t GetNumOpenDynamicStreams() const;
-
// Returns the maximum bidirectional streams parameter sent with the handshake
// as a transport parameter, or in the most recent MAX_STREAMS frame.
QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const;
- // Performs the work required to close |stream_id|. If |rst_sent| then a
- // Reset Stream frame has already been sent for this stream.
- // TODO(fayang): Remove CloseStreamInner.
- virtual void CloseStreamInner(QuicStreamId stream_id, bool rst_sent);
-
// When a stream is closed locally, it may not yet know how many bytes the
// peer sent on that stream.
// When this data arrives (via stream frame w. FIN, trailing headers, or RST)
@@ -589,10 +565,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
return &write_blocked_streams_;
}
- size_t GetNumDynamicOutgoingStreams() const;
-
- size_t GetNumDrainingOutgoingStreams() const;
-
// Returns true if the stream is still active.
bool IsOpenStream(QuicStreamId id);
@@ -630,6 +602,14 @@ class QUIC_EXPORT_PRIVATE QuicSession
QuicDatagramQueue* datagram_queue() { return &datagram_queue_; }
+ size_t num_static_streams() const { return num_static_streams_; }
+
+ bool was_zero_rtt_rejected() const { return was_zero_rtt_rejected_; }
+
+ size_t num_outgoing_draining_streams() const {
+ return num_outgoing_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.
@@ -704,6 +684,9 @@ class QUIC_EXPORT_PRIVATE QuicSession
// if all lost data is retransmitted. Returns false otherwise.
bool RetransmitLostData();
+ // Returns true if stream data should be written.
+ bool CanWriteStreamData() const;
+
// Closes the pending stream |stream_id| before it has been created.
void ClosePendingStream(QuicStreamId stream_id);
@@ -720,6 +703,12 @@ class QUIC_EXPORT_PRIVATE QuicSession
QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written);
+ // Closes the connection and returns false if |new_window| is lower than
+ // |stream|'s current flow control window.
+ // Returns true otherwise.
+ bool ValidateStreamFlowControlLimit(QuicStreamOffset new_window,
+ const QuicStream* stream);
+
// Sends a STOP_SENDING frame if the stream type allows.
void MaybeSendStopSendingFrame(QuicStreamId id, QuicRstStreamErrorCode error);
@@ -756,13 +745,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
// which are waiting for the first byte of payload to arrive.
PendingStreamMap pending_stream_map_;
- // Set of stream ids that are "draining" -- a FIN has been sent and received,
- // but the stream object still exists because not all the received data has
- // been consumed.
- // TODO(fayang): Remove draining_streams_ when deprecate
- // quic_deprecate_draining_streams.
- QuicHashSet<QuicStreamId> draining_streams_;
-
// Set of stream ids that are waiting for acks excluding crypto stream id.
QuicHashSet<QuicStreamId> streams_waiting_for_acks_;
@@ -774,37 +756,16 @@ class QUIC_EXPORT_PRIVATE QuicSession
// Manages stream IDs for version99/IETF QUIC
UberQuicStreamIdManager v99_streamid_manager_;
- // A counter for peer initiated dynamic streams which are in the stream_map_.
- // TODO(fayang): Remove this when deprecating
- // quic_stream_id_manager_handles_accounting.
- size_t num_dynamic_incoming_streams_;
+ // A counter for streams which have sent and received FIN but waiting for
+ // application to consume data.
+ size_t num_draining_streams_;
- // A counter for peer initiated streams which have sent and received FIN but
+ // A counter for self initiated streams which have sent and received FIN but
// waiting for application to consume data.
- // TODO(fayang): Remove this when deprecating
- // quic_stream_id_manager_handles_accounting.
- size_t num_draining_incoming_streams_;
+ size_t num_outgoing_draining_streams_;
- // A counter for self initiated streams which have sent and received FIN but
- // waiting for application to consume data. Only used when
- // deprecate_draining_streams_ is true.
- // TODO(fayang): Remove this when deprecating
- // quic_stream_id_manager_handles_accounting.
- size_t num_draining_outgoing_streams_;
-
- // A counter for self initiated static streams which are in
- // stream_map_.
- size_t num_outgoing_static_streams_;
-
- // A counter for peer initiated static streams which are in
- // stream_map_.
- size_t num_incoming_static_streams_;
-
- // A counter for peer initiated streams which are in the
- // locally_closed_streams_highest_offset_.
- // TODO(fayang): Remove this when deprecating
- // quic_stream_id_manager_handles_accounting.
- size_t num_locally_closed_incoming_streams_highest_offset_;
+ // A counter for static streams which are in stream_map_.
+ size_t num_static_streams_;
// Received information for a connection close.
QuicConnectionCloseFrame on_closed_frame_;
@@ -842,6 +803,8 @@ 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_;
+
// If true, write_blocked_streams_ uses HTTP2 (tree-style) priority write
// scheduler.
bool use_http2_priority_write_scheduler_;
@@ -853,11 +816,11 @@ class QUIC_EXPORT_PRIVATE QuicSession
// If true, enables round robin scheduling.
bool enable_round_robin_scheduling_;
- // Latched value of quic_deprecate_draining_streams.
- const bool deprecate_draining_streams_;
+ // Whether the session has received a 0-RTT rejection (QUIC+TLS only).
+ bool was_zero_rtt_rejected_;
- // Latched value of quic_break_session_stream_close_loop.
- const bool break_close_loop_;
+ // Latched value of flag quic_fix_gquic_stream_type.
+ const bool fix_gquic_stream_type_;
};
} // 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 9d5e977d0a6..12a48300bdb 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
@@ -10,6 +10,7 @@
#include <utility>
#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"
#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
#include "net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h"
@@ -77,6 +78,17 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
kInitialStreamFlowControlWindowForTest);
session()->config()->SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
+ if (session()->version().AuthenticatesHandshakeConnectionIds()) {
+ if (session()->perspective() == Perspective::IS_CLIENT) {
+ session()->config()->SetOriginalConnectionIdToSend(
+ session()->connection()->connection_id());
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->connection_id());
+ } else {
+ session()->config()->SetInitialSourceConnectionIdToSend(
+ session()->connection()->client_connection_id());
+ }
+ }
if (session()->connection()->version().handshake_protocol ==
PROTOCOL_TLS1_3) {
TransportParameters transport_parameters;
@@ -123,6 +135,8 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
HandshakeState GetHandshakeState() const override {
return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
}
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
MOCK_METHOD(void, OnCanWrite, (), (override));
bool HasPendingCryptoRetransmission() const override { return false; }
@@ -183,6 +197,9 @@ class TestSession : public QuicSession {
this->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(connection->perspective()));
+ if (this->connection()->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(this->connection());
+ }
}
~TestSession() override { DeleteConnection(); }
@@ -216,7 +233,7 @@ class TestSession : public QuicSession {
TestStream* CreateIncomingStream(QuicStreamId id) override {
// Enforce the limit on the number of open streams.
if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
- GetNumOpenIncomingStreams() + 1 >
+ stream_id_manager().num_open_incoming_streams() + 1 >
max_open_incoming_bidirectional_streams()) {
// No need to do this test for version 99; it's done by
// QuicSession::GetOrCreateStream.
@@ -226,11 +243,10 @@ class TestSession : public QuicSession {
return nullptr;
}
- TestStream* stream =
- new TestStream(id, this,
- DetermineStreamType(
- id, connection()->transport_version(), perspective(),
- /*is_incoming=*/true, BIDIRECTIONAL));
+ TestStream* stream = new TestStream(
+ id, this,
+ DetermineStreamType(id, connection()->version(), perspective(),
+ /*is_incoming=*/true, BIDIRECTIONAL));
ActivateStream(QuicWrapUnique(stream));
++num_incoming_streams_created_;
return stream;
@@ -239,8 +255,7 @@ class TestSession : public QuicSession {
TestStream* CreateIncomingStream(PendingStream* pending) override {
QuicStreamId id = pending->id();
TestStream* stream = new TestStream(
- pending, DetermineStreamType(id, connection()->transport_version(),
- perspective(),
+ pending, DetermineStreamType(id, connection()->version(), perspective(),
/*is_incoming=*/true, BIDIRECTIONAL));
ActivateStream(QuicWrapUnique(stream));
++num_incoming_streams_created_;
@@ -309,7 +324,7 @@ 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, QuicheNullOpt);
+ WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION, QUICHE_NULLOPT);
QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
consumed.bytes_consumed);
return consumed;
@@ -326,7 +341,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,
- QuicheNullOpt);
+ QUICHE_NULLOPT);
}
bool UsesPendingStreams() const override { return uses_pending_streams_; }
@@ -421,15 +436,15 @@ class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
void CloseStream(QuicStreamId id) {
if (VersionHasIetfQuicFrames(transport_version())) {
- if (QuicUtils::GetStreamType(id, session_.perspective(),
- session_.IsIncomingStream(id)) ==
- READ_UNIDIRECTIONAL) {
+ if (QuicUtils::GetStreamType(
+ id, session_.perspective(), session_.IsIncomingStream(id),
+ connection_->version()) == READ_UNIDIRECTIONAL) {
// Verify reset is not sent for READ_UNIDIRECTIONAL streams.
EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(0);
- } else if (QuicUtils::GetStreamType(id, session_.perspective(),
- session_.IsIncomingStream(id)) ==
- WRITE_UNIDIRECTIONAL) {
+ } else if (QuicUtils::GetStreamType(
+ id, session_.perspective(), session_.IsIncomingStream(id),
+ connection_->version()) == WRITE_UNIDIRECTIONAL) {
// Verify RESET_STREAM but not STOP_SENDING is sent for write-only
// stream.
EXPECT_CALL(*connection_, SendControlFrame(_))
@@ -554,6 +569,11 @@ class QuicSessionTestServer : public QuicSessionTestBase {
kQuicDefaultConnectionIdLength) {
client_framer_.set_visitor(&framer_visitor_);
client_framer_.SetInitialObfuscators(TestConnectionId());
+ if (client_framer_.version().KnowsWhichDecrypterToUse()) {
+ client_framer_.InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<NullDecrypter>(Perspective::IS_CLIENT));
+ }
}
QuicPathFrameBuffer path_frame_buffer1_;
@@ -595,6 +615,7 @@ TEST_P(QuicSessionTestServer, OneRttKeysAvailable) {
if (connection_->version().HasHandshakeDone()) {
EXPECT_CALL(*connection_, SendControlFrame(_));
}
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
EXPECT_TRUE(session_.OneRttKeysAvailable());
}
@@ -990,6 +1011,7 @@ TEST_P(QuicSessionTestServer, Http2Priority) {
QuicTagVector copt;
copt.push_back(kH2PR);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
ASSERT_TRUE(session_.use_http2_priority_write_scheduler());
@@ -1072,6 +1094,7 @@ TEST_P(QuicSessionTestServer, RoundRobinScheduling) {
QuicTagVector copt;
copt.push_back(kRRWS);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
session_.set_writev_consumes_all_data(true);
@@ -1117,6 +1140,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
CryptoHandshakeMessage msg;
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
// Drive congestion control manually.
@@ -1428,6 +1452,7 @@ TEST_P(QuicSessionTestServer, InvalidGoAway) {
// Test that server session will send a connectivity probe in response to a
// connectivity probe on the same path.
TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbe) {
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
QuicSocketAddress old_peer_address =
QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
EXPECT_EQ(old_peer_address, session_.peer_address());
@@ -1461,6 +1486,7 @@ TEST_P(QuicSessionTestServer, ServerReplyToConnectivityProbes) {
if (!VersionHasIetfQuicFrames(transport_version())) {
return;
}
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
QuicSocketAddress old_peer_address =
QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
EXPECT_EQ(old_peer_address, session_.peer_address());
@@ -1495,6 +1521,7 @@ TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
EXPECT_CALL(*connection_, SendControlFrame(_));
}
CryptoHandshakeMessage msg;
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
@@ -1775,6 +1802,7 @@ TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
} else {
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
}
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
}
@@ -1784,6 +1812,7 @@ TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
copt.push_back(kIFW7);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
session_.flow_controller()));
@@ -2047,8 +2076,13 @@ TEST_P(QuicSessionTestClient, InvalidSessionFlowControlWindowInHandshake) {
const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
kInvalidWindow);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(connection_->version().AllowsLowFlowControlLimits()
+ ? QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED
+ : QUIC_FLOW_CONTROL_INVALID_WINDOW,
+ _, _));
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
}
@@ -2059,7 +2093,9 @@ TEST_P(QuicSessionTestClient, InvalidBidiStreamLimitInHandshake) {
}
QuicConfigPeer::SetReceivedMaxBidirectionalStreams(
session_.config(), kDefaultMaxStreamsPerConnection - 1);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAMS_ERROR, _, _));
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
}
@@ -2070,7 +2106,9 @@ TEST_P(QuicSessionTestClient, InvalidUniStreamLimitInHandshake) {
}
QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
session_.config(), kDefaultMaxStreamsPerConnection - 1);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAMS_ERROR, _, _));
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, _, _));
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
}
@@ -2088,6 +2126,8 @@ TEST_P(QuicSessionTestClient, InvalidStreamFlowControlWindowInHandshake) {
.WillOnce(
Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _));
+
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.OnConfigNegotiated();
}
@@ -2430,14 +2470,9 @@ TEST_P(QuicSessionTestServer, RetransmitLostDataCausesConnectionClose) {
session_.OnFrameLost(QuicFrame(frame));
// Retransmit stream data causes connection close. Stream has not sent fin
// yet, so an RST is sent.
- if (session_.break_close_loop()) {
- EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
- session_.CloseStream(stream->id());
- }));
- } else {
- EXPECT_CALL(*stream, OnCanWrite())
- .WillOnce(Invoke(stream, &QuicStream::OnClose));
- }
+ EXPECT_CALL(*stream, OnCanWrite()).WillOnce(Invoke([this, stream]() {
+ session_.CloseStream(stream->id());
+ }));
if (VersionHasIetfQuicFrames(transport_version())) {
// Once for the RST_STREAM, once for the STOP_SENDING
EXPECT_CALL(*connection_, SendControlFrame(_))
@@ -2466,6 +2501,7 @@ TEST_P(QuicSessionTestServer, SendMessage) {
EXPECT_CALL(*connection_, SendControlFrame(_));
}
CryptoHandshakeMessage handshake_message;
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_.GetMutableCryptoStream()->OnHandshakeMessage(handshake_message);
EXPECT_TRUE(session_.OneRttKeysAvailable());
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 40a67bba21c..6318ac1ecff 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
@@ -46,7 +46,7 @@ QuicByteCount GetInitialStreamFlowControlWindowToSend(QuicSession* session,
// Unidirectional streams (v99 only).
if (VersionHasIetfQuicFrames(version.transport_version) &&
- !QuicUtils::IsBidirectionalStreamId(stream_id)) {
+ !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
return session->config()
->GetInitialMaxStreamDataBytesUnidirectionalToSend();
}
@@ -74,7 +74,7 @@ QuicByteCount GetReceivedFlowControlWindow(QuicSession* session,
// Unidirectional streams (v99 only).
if (VersionHasIetfQuicFrames(version.transport_version) &&
- !QuicUtils::IsBidirectionalStreamId(stream_id)) {
+ !QuicUtils::IsBidirectionalStreamId(stream_id, version)) {
if (session->config()
->HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
return session->config()
@@ -359,7 +359,8 @@ QuicStream::QuicStream(QuicStreamId id,
type != CRYPTO
? QuicUtils::GetStreamType(id_,
session->perspective(),
- session->IsIncomingStream(id_))
+ session->IsIncomingStream(id_),
+ session->version())
: type),
perspective_(session->perspective()) {
if (type_ == WRITE_UNIDIRECTIONAL) {
@@ -432,15 +433,13 @@ void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
return;
}
- if (frame.fin) {
- if (!session_->deprecate_draining_streams() || !fin_received_) {
- fin_received_ = true;
- if (fin_sent_) {
- DCHECK(!was_draining_ || !session_->deprecate_draining_streams());
- session_->StreamDraining(id_,
- /*unidirectional=*/type_ != BIDIRECTIONAL);
- was_draining_ = true;
- }
+ if (frame.fin && !fin_received_) {
+ fin_received_ = true;
+ if (fin_sent_) {
+ DCHECK(!was_draining_);
+ session_->StreamDraining(id_,
+ /*unidirectional=*/type_ != BIDIRECTIONAL);
+ was_draining_ = true;
}
}
@@ -582,14 +581,12 @@ void QuicStream::Reset(QuicRstStreamErrorCode error) {
stream_error_ = error;
session()->SendRstStream(id(), error, stream_bytes_written());
rst_sent_ = true;
- if (session_->break_close_loop()) {
- if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
- session()->OnStreamDoneWaitingForAcks(id_);
- return;
- }
- CloseReadSide();
- CloseWriteSide();
+ if (read_side_closed_ && write_side_closed_ && !IsWaitingForAcks()) {
+ session()->OnStreamDoneWaitingForAcks(id_);
+ return;
}
+ CloseReadSide();
+ CloseWriteSide();
}
void QuicStream::OnUnrecoverableError(QuicErrorCode error,
@@ -781,12 +778,8 @@ void QuicStream::CloseReadSide() {
if (write_side_closed_) {
QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
- if (session_->break_close_loop()) {
- session_->OnStreamClosed(id());
- OnClose();
- } else {
- session_->CloseStream(id());
- }
+ session_->OnStreamClosed(id());
+ OnClose();
}
}
@@ -799,12 +792,8 @@ void QuicStream::CloseWriteSide() {
write_side_closed_ = true;
if (read_side_closed_) {
QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
- if (session_->break_close_loop()) {
- session_->OnStreamClosed(id());
- OnClose();
- } else {
- session_->CloseStream(id());
- }
+ session_->OnStreamClosed(id());
+ OnClose();
}
}
@@ -827,12 +816,7 @@ void QuicStream::StopReading() {
}
void QuicStream::OnClose() {
- if (session()->break_close_loop()) {
- DCHECK(read_side_closed_ && write_side_closed_);
- } else {
- CloseReadSide();
- CloseWriteSide();
- }
+ DCHECK(read_side_closed_ && write_side_closed_);
if (!fin_sent_ && !rst_sent_) {
// For flow control accounting, tell the peer how many bytes have been
@@ -946,16 +930,11 @@ bool QuicStream::ConfigSendWindowOffset(QuicStreamOffset new_offset) {
<< "ConfigSendWindowOffset called on stream without flow control";
return false;
}
- if (perspective_ == Perspective::IS_CLIENT &&
- session()->version().AllowsLowFlowControlLimits() &&
- new_offset < flow_controller_->send_window_offset()) {
- OnUnrecoverableError(
- QUIC_FLOW_CONTROL_INVALID_WINDOW,
- quiche::QuicheStrCat("New stream max data ", new_offset,
- " decreases current limit: ",
- flow_controller_->send_window_offset()));
- return false;
- }
+
+ QUIC_BUG_IF(session()->version().AllowsLowFlowControlLimits() &&
+ new_offset < flow_controller_->send_window_offset())
+ << ENDPOINT << "The new offset " << new_offset
+ << " decreases current offset " << flow_controller_->send_window_offset();
if (flow_controller_->UpdateSendWindowOffset(new_offset)) {
// Let session unblock this stream.
session_->MarkConnectionLevelWriteBlocked(id_);
@@ -1048,7 +1027,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, QuicheNullOpt);
+ can_bundle_fin ? FIN : NO_FIN, type, QUICHE_NULLOPT);
QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
<< " is forced to retransmit stream data ["
<< retransmission_offset << ", "
@@ -1070,7 +1049,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, QuicheNullOpt);
+ type, QUICHE_NULLOPT);
if (!consumed.fin_consumed) {
return false;
}
@@ -1148,7 +1127,7 @@ void QuicStream::WriteBufferedData() {
}
QuicConsumedData consumed_data =
stream_delegate_->WritevData(id(), write_length, stream_bytes_written(),
- state, NOT_RETRANSMISSION, QuicheNullOpt);
+ state, NOT_RETRANSMISSION, QUICHE_NULLOPT);
OnStreamDataConsumed(consumed_data.bytes_consumed);
@@ -1228,7 +1207,7 @@ void QuicStream::WritePendingRetransmission() {
<< " retransmits fin only frame.";
consumed =
stream_delegate_->WritevData(id_, 0, stream_bytes_written(), FIN,
- LOSS_RETRANSMISSION, QuicheNullOpt);
+ LOSS_RETRANSMISSION, QUICHE_NULLOPT);
fin_lost_ = !consumed.fin_consumed;
if (fin_lost_) {
// Connection is write blocked.
@@ -1243,7 +1222,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, QuicheNullOpt);
+ LOSS_RETRANSMISSION, QUICHE_NULLOPT);
QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
<< " tries to retransmit stream data [" << pending.offset
<< ", " << pending.offset + pending.length
@@ -1302,6 +1281,22 @@ void QuicStream::SendStopSending(uint16_t code) {
session_->SendStopSending(code, id_);
}
+QuicFlowController* QuicStream::flow_controller() {
+ if (flow_controller_.has_value()) {
+ return &flow_controller_.value();
+ }
+ QUIC_BUG << "Trying to access non-existent flow controller.";
+ return nullptr;
+}
+
+const QuicFlowController* QuicStream::flow_controller() const {
+ if (flow_controller_.has_value()) {
+ return &flow_controller_.value();
+ }
+ QUIC_BUG << "Trying to access non-existent flow controller.";
+ return nullptr;
+}
+
// static
spdy::SpdyStreamPrecedence QuicStream::CalculateDefaultPriority(
const QuicSession* session) {
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 fe9d04c021f..7a847f09ec1 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
@@ -165,14 +165,6 @@ class QUIC_EXPORT_PRIVATE QuicStream
// stream to write any pending data.
virtual void OnCanWrite();
- // Called just before the object is destroyed.
- // The object should not be accessed after OnClose is called.
- // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
- // a RST_STREAM has been sent.
- // TODO(fayang): move this to protected when deprecating
- // quic_break_session_stream_close_loop.
- virtual void OnClose();
-
// Called by the session when the endpoint receives a RST_STREAM from the
// peer.
virtual void OnStreamReset(const QuicRstStreamFrame& frame);
@@ -237,7 +229,9 @@ class QUIC_EXPORT_PRIVATE QuicStream
int num_frames_received() const;
int num_duplicate_frames_received() const;
- QuicFlowController* flow_controller() { return &*flow_controller_; }
+ QuicFlowController* flow_controller();
+
+ const QuicFlowController* flow_controller() const;
// Called when endpoint receives a frame which could increase the highest
// offset.
@@ -381,6 +375,12 @@ class QUIC_EXPORT_PRIVATE QuicStream
const QuicReferenceCountedPointer<QuicAckListenerInterface>&
/*ack_listener*/) {}
+ // Called just before the object is destroyed.
+ // The object should not be accessed after OnClose is called.
+ // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
+ // a RST_STREAM has been sent.
+ virtual void OnClose();
+
// True if buffered data in send buffer is below buffered_data_threshold_.
bool CanWriteNewData() const;
@@ -539,8 +539,7 @@ class QUIC_EXPORT_PRIVATE QuicStream
// If initialized, reset this stream at this deadline.
QuicTime deadline_;
- // True if this stream has entered draining state. Only used when
- // quic_deprecate_draining_streams is true.
+ // True if this stream has entered draining state.
bool was_draining_;
// Indicates whether this stream is bidirectional, read unidirectional or
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc
index ba31decd2b9..528d9557ec4 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager.cc
@@ -55,6 +55,14 @@ bool QuicStreamIdManager::OnStreamsBlockedFrame(
" exceeds incoming max stream ", incoming_advertised_max_streams_);
return false;
}
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_stop_sending_duplicate_max_streams);
+ DCHECK_LE(incoming_advertised_max_streams_, incoming_actual_max_streams_);
+ if (incoming_advertised_max_streams_ == incoming_actual_max_streams_) {
+ // We have told peer about current max.
+ return true;
+ }
+ }
if (frame.stream_count < incoming_actual_max_streams_) {
// Peer thinks it's blocked on a stream count that is less than our current
// max. Inform the peer of the correct stream count.
@@ -104,12 +112,17 @@ void QuicStreamIdManager::MaybeSendMaxStreamsFrame() {
}
void QuicStreamIdManager::SendMaxStreamsFrame() {
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ QUIC_BUG_IF(incoming_advertised_max_streams_ >=
+ incoming_actual_max_streams_);
+ }
incoming_advertised_max_streams_ = incoming_actual_max_streams_;
delegate_->SendMaxStreams(incoming_advertised_max_streams_, unidirectional_);
}
void QuicStreamIdManager::OnStreamClosed(QuicStreamId stream_id) {
- DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id), unidirectional_);
+ DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+ unidirectional_);
if (QuicUtils::IsOutgoingStreamId(version_, stream_id, perspective_)) {
// Nothing to do for outgoing streams.
return;
@@ -147,7 +160,8 @@ bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
const QuicStreamId stream_id,
std::string* error_details) {
// |stream_id| must be an incoming stream of the right directionality.
- DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id), unidirectional_);
+ DCHECK_NE(QuicUtils::IsBidirectionalStreamId(stream_id, version_),
+ unidirectional_);
DCHECK_NE(QuicUtils::IsServerInitiatedStreamId(version_.transport_version,
stream_id),
perspective_ == Perspective::IS_SERVER);
@@ -193,7 +207,7 @@ bool QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
}
bool QuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
- DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id), unidirectional_);
+ DCHECK_NE(QuicUtils::IsBidirectionalStreamId(id, version_), unidirectional_);
if (QuicUtils::IsOutgoingStreamId(version_, id, perspective_)) {
// Stream IDs under next_ougoing_stream_id_ are either open or previously
// open but now closed.
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc
index 2179ba2c860..689d4112d85 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_stream_id_manager_test.cc
@@ -139,13 +139,18 @@ TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
}
// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
-// the count most recently advertised in a MAX_STREAMS frame. This should cause
-// a MAX_STREAMS frame with the most recently advertised count to be sent.
+// the count most recently advertised in a MAX_STREAMS frame.
TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
QuicStreamCount stream_count =
stream_id_manager_.incoming_initial_max_open_streams();
QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
- EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()));
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ // We have notified peer about current max.
+ EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()))
+ .Times(0);
+ } else {
+ EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()));
+ }
std::string error_details;
EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
}
@@ -398,7 +403,12 @@ TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
// Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
// MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
- stream_id_manager_.SetMaxOpenIncomingStreams(123);
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ QuicStreamIdManagerPeer::set_incoming_actual_max_streams(
+ &stream_id_manager_, 123);
+ } else {
+ stream_id_manager_.SetMaxOpenIncomingStreams(123);
+ }
frame.stream_count = 0;
EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame, &error_details));
}
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 f30a3be7216..356a77d2f59 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
@@ -305,7 +305,7 @@ TEST_P(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), false,
nullptr);
@@ -324,7 +324,7 @@ TEST_P(QuicStreamTest, BlockIfFinNotConsumedWithData) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
nullptr);
@@ -372,7 +372,7 @@ TEST_P(QuicStreamTest, WriteOrBufferData) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(kData1, false, nullptr);
@@ -388,7 +388,8 @@ TEST_P(QuicStreamTest, WriteOrBufferData) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
- NO_FIN, NOT_RETRANSMISSION, QuicheNullOpt);
+ NO_FIN, NOT_RETRANSMISSION,
+ QUICHE_NULLOPT);
}));
EXPECT_CALL(*stream_, OnCanWriteNewData());
stream_->OnCanWrite();
@@ -398,7 +399,8 @@ TEST_P(QuicStreamTest, WriteOrBufferData) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
- NO_FIN, NOT_RETRANSMISSION, QuicheNullOpt);
+ NO_FIN, NOT_RETRANSMISSION,
+ QUICHE_NULLOPT);
}));
EXPECT_CALL(*stream_, OnCanWriteNewData());
stream_->OnCanWrite();
@@ -445,7 +447,7 @@ TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), false,
nullptr);
@@ -455,12 +457,8 @@ TEST_P(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
// Now close the stream, and expect that we send a RST.
EXPECT_CALL(*session_, SendRstStream(_, _, _));
- if (session_->break_close_loop()) {
- stream_->CloseReadSide();
- stream_->CloseWriteSide();
- } else {
- stream_->OnClose();
- }
+ stream_->CloseReadSide();
+ stream_->CloseWriteSide();
EXPECT_FALSE(session_->HasUnackedStreamData());
EXPECT_FALSE(fin_sent());
EXPECT_TRUE(rst_sent());
@@ -479,7 +477,7 @@ TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 1u, 0u, FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), true,
nullptr);
@@ -487,12 +485,8 @@ TEST_P(QuicStreamTest, RstNotSentIfFinSent) {
EXPECT_FALSE(rst_sent());
// Now close the stream, and expect that we do not send a RST.
- if (session_->break_close_loop()) {
- stream_->CloseReadSide();
- stream_->CloseWriteSide();
- } else {
- stream_->OnClose();
- }
+ stream_->CloseReadSide();
+ stream_->CloseWriteSide();
EXPECT_TRUE(fin_sent());
EXPECT_FALSE(rst_sent());
}
@@ -516,12 +510,8 @@ TEST_P(QuicStreamTest, OnlySendOneRst) {
// Now close the stream (any further resets being sent would break the
// expectation above).
- if (session_->break_close_loop()) {
- stream_->CloseReadSide();
- stream_->CloseWriteSide();
- } else {
- stream_->OnClose();
- }
+ stream_->CloseReadSide();
+ stream_->CloseWriteSide();
EXPECT_FALSE(fin_sent());
EXPECT_TRUE(rst_sent());
}
@@ -657,12 +647,8 @@ TEST_P(QuicStreamTest, InvalidFinalByteOffsetFromRst) {
CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
stream_->OnStreamReset(rst_frame);
EXPECT_TRUE(stream_->HasReceivedFinalOffset());
- if (session_->break_close_loop()) {
- stream_->CloseReadSide();
- stream_->CloseWriteSide();
- } else {
- stream_->OnClose();
- }
+ stream_->CloseReadSide();
+ stream_->CloseWriteSide();
}
TEST_P(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
@@ -760,13 +746,13 @@ TEST_P(QuicStreamTest, SetDrainingIncomingOutgoing) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
nullptr);
EXPECT_TRUE(stream_->write_side_closed());
- EXPECT_EQ(1u, session_->GetNumDrainingStreams());
+ EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
}
@@ -778,7 +764,7 @@ TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 2u, 0u, FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
nullptr);
@@ -794,7 +780,7 @@ TEST_P(QuicStreamTest, SetDrainingOutgoingIncoming) {
EXPECT_FALSE(QuicStreamPeer::read_side_closed(stream_));
EXPECT_FALSE(stream_->reading_stopped());
- EXPECT_EQ(1u, session_->GetNumDrainingStreams());
+ EXPECT_EQ(1u, QuicSessionPeer::GetNumDrainingStreams(session_.get()));
EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
}
@@ -1054,7 +1040,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->WriteOrBufferData(data, false, nullptr);
stream_->WriteOrBufferData(data, false, nullptr);
@@ -1067,7 +1053,7 @@ TEST_P(QuicStreamTest, WriteBufferedData) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
// Buffered data size > threshold, do not ask upper layer for more data.
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
@@ -1082,7 +1068,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, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
// Buffered data size < threshold, ask upper layer for more data.
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
@@ -1132,7 +1118,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, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
@@ -1194,7 +1180,7 @@ TEST_P(QuicStreamTest, WriteMemSlices) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
// There is no buffered data before, all data should be consumed.
QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
@@ -1217,7 +1203,7 @@ TEST_P(QuicStreamTest, WriteMemSlices) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this, data_to_write]() {
return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
stream_->OnCanWrite();
@@ -1254,7 +1240,7 @@ TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
// There is no buffered data before, all data should be consumed.
QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
@@ -1392,7 +1378,7 @@ TEST_P(QuicStreamTest, OnStreamFrameLost) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 9u, 18u, FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
stream_->OnCanWrite();
EXPECT_FALSE(stream_->HasPendingRetransmission());
@@ -1422,7 +1408,7 @@ TEST_P(QuicStreamTest, CannotBundleLostFin) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(InvokeWithoutArgs([this]() {
return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN,
- NOT_RETRANSMISSION, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(Return(QuicConsumedData(0, true)));
@@ -1511,7 +1497,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, QuicheNullOpt);
+ NOT_RETRANSMISSION, QUICHE_NULLOPT);
}));
EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true, PTO_RETRANSMISSION));
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc
new file mode 100644
index 00000000000..b2404c6ee97
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.cc
@@ -0,0 +1,49 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h"
+
+#include <atomic>
+#include <cerrno>
+
+namespace quic {
+namespace {
+std::atomic<QuicSyscallWrapper*> global_syscall_wrapper(new QuicSyscallWrapper);
+} // namespace
+
+ssize_t QuicSyscallWrapper::Sendmsg(int sockfd, const msghdr* msg, int flags) {
+ return ::sendmsg(sockfd, msg, flags);
+}
+
+int QuicSyscallWrapper::Sendmmsg(int sockfd,
+ mmsghdr* msgvec,
+ unsigned int vlen,
+ int flags) {
+#if defined(__linux__) && !defined(__ANDROID__)
+ return ::sendmmsg(sockfd, msgvec, vlen, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+QuicSyscallWrapper* GetGlobalSyscallWrapper() {
+ return global_syscall_wrapper.load();
+}
+
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper) {
+ global_syscall_wrapper.store(wrapper);
+}
+
+ScopedGlobalSyscallWrapperOverride::ScopedGlobalSyscallWrapperOverride(
+ QuicSyscallWrapper* wrapper_in_scope)
+ : original_wrapper_(GetGlobalSyscallWrapper()) {
+ SetGlobalSyscallWrapper(wrapper_in_scope);
+}
+
+ScopedGlobalSyscallWrapperOverride::~ScopedGlobalSyscallWrapperOverride() {
+ SetGlobalSyscallWrapper(original_wrapper_);
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h
new file mode 100644
index 00000000000..3a80ac6f6cf
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h
@@ -0,0 +1,49 @@
+// 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_IMPL_QUIC_SYSCALL_WRAPPER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+
+struct mmsghdr;
+namespace quic {
+
+// QuicSyscallWrapper is a pass-through proxy to the real syscalls.
+class QUIC_EXPORT_PRIVATE QuicSyscallWrapper {
+ public:
+ virtual ~QuicSyscallWrapper() = default;
+
+ virtual ssize_t Sendmsg(int sockfd, const msghdr* msg, int flags);
+
+ virtual int Sendmmsg(int sockfd,
+ mmsghdr* msgvec,
+ unsigned int vlen,
+ int flags);
+};
+
+// A global instance of QuicSyscallWrapper, used by some socket util functions.
+QuicSyscallWrapper* GetGlobalSyscallWrapper();
+
+// Change the global QuicSyscallWrapper to |wrapper|, for testing.
+void SetGlobalSyscallWrapper(QuicSyscallWrapper* wrapper);
+
+// ScopedGlobalSyscallWrapperOverride changes the global QuicSyscallWrapper
+// during its lifetime, for testing.
+class QUIC_EXPORT_PRIVATE ScopedGlobalSyscallWrapperOverride {
+ public:
+ explicit ScopedGlobalSyscallWrapperOverride(
+ QuicSyscallWrapper* wrapper_in_scope);
+ ~ScopedGlobalSyscallWrapperOverride();
+
+ private:
+ QuicSyscallWrapper* original_wrapper_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_SYSCALL_WRAPPER_H_
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 270383d27ae..d6c2f6c25de 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
@@ -74,4 +74,35 @@ bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
tag_vector.end();
}
+QuicTag ParseQuicTag(quiche::QuicheStringPiece tag_string) {
+ quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
+ std::string tag_bytes;
+ if (tag_string.length() == 8) {
+ tag_bytes = quiche::QuicheTextUtils::HexDecode(tag_string);
+ tag_string = tag_bytes;
+ }
+ QuicTag tag = 0;
+ // Iterate over every character from right to left.
+ for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
+ // The cast here is required on platforms where char is signed.
+ unsigned char token_char = static_cast<unsigned char>(*it);
+ tag <<= 8;
+ tag |= token_char;
+ }
+ return tag;
+}
+
+QuicTagVector ParseQuicTagVector(quiche::QuicheStringPiece 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) {
+ tag_vector.push_back(ParseQuicTag(tag_string));
+ }
+ }
+ return tag_vector;
+}
+
} // namespace quic
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 71fcdd597f4..7ba6cfc5f39 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
@@ -10,6 +10,7 @@
#include <vector>
#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,6 +49,17 @@ QUIC_EXPORT_PRIVATE bool FindMutualQuicTag(const QuicTagVector& our_tags,
// treat it as a number if not.
QUIC_EXPORT_PRIVATE std::string QuicTagToString(QuicTag tag);
+// Utility function that converts a string of the form "ABCD" to its
+// 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);
+
+// 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);
+
} // namespace quic
#endif // QUICHE_QUIC_CORE_QUIC_TAG_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc
index 3d58133eeb7..13c899edd41 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_tag_test.cc
@@ -33,6 +33,48 @@ TEST_F(QuicTagTest, MakeQuicTag) {
EXPECT_EQ('D', bytes[3]);
}
+TEST_F(QuicTagTest, ParseQuicTag) {
+ QuicTag tag_abcd = MakeQuicTag('A', 'B', 'C', 'D');
+ EXPECT_EQ(ParseQuicTag("ABCD"), tag_abcd);
+ EXPECT_EQ(ParseQuicTag("ABCDE"), tag_abcd);
+ QuicTag tag_efgh = MakeQuicTag('E', 'F', 'G', 'H');
+ EXPECT_EQ(ParseQuicTag("EFGH"), tag_efgh);
+ QuicTag tag_ijk = MakeQuicTag('I', 'J', 'K', 0);
+ EXPECT_EQ(ParseQuicTag("IJK"), tag_ijk);
+ QuicTag tag_l = MakeQuicTag('L', 0, 0, 0);
+ EXPECT_EQ(ParseQuicTag("L"), tag_l);
+ QuicTag tag_hex = MakeQuicTag('M', 'N', 'O', static_cast<char>(255));
+ EXPECT_EQ(ParseQuicTag("4d4e4fff"), tag_hex);
+ EXPECT_EQ(ParseQuicTag("4D4E4FFF"), tag_hex);
+ QuicTag tag_with_numbers = MakeQuicTag('P', 'Q', '1', '2');
+ EXPECT_EQ(ParseQuicTag("PQ12"), tag_with_numbers);
+ QuicTag tag_with_custom_chars = MakeQuicTag('r', '$', '_', '7');
+ EXPECT_EQ(ParseQuicTag("r$_7"), tag_with_custom_chars);
+ QuicTag tag_zero = 0;
+ EXPECT_EQ(ParseQuicTag(""), tag_zero);
+ QuicTagVector tag_vector;
+ EXPECT_EQ(ParseQuicTagVector(""), tag_vector);
+ EXPECT_EQ(ParseQuicTagVector(" "), tag_vector);
+ tag_vector.push_back(tag_abcd);
+ EXPECT_EQ(ParseQuicTagVector("ABCD"), tag_vector);
+ tag_vector.push_back(tag_efgh);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH"), tag_vector);
+ tag_vector.push_back(tag_ijk);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK"), tag_vector);
+ tag_vector.push_back(tag_l);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L"), tag_vector);
+ tag_vector.push_back(tag_hex);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff"), tag_vector);
+ tag_vector.push_back(tag_with_numbers);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12"), tag_vector);
+ tag_vector.push_back(tag_with_custom_chars);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7"),
+ tag_vector);
+ tag_vector.push_back(tag_zero);
+ EXPECT_EQ(ParseQuicTagVector("ABCD,EFGH,IJK,L,4d4e4fff,PQ12,r$_7,"),
+ tag_vector);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_time.h b/chromium/net/third_party/quiche/src/quic/core/quic_time.h
index adecbcd1514..079b59a6bdc 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_time.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_time.h
@@ -184,6 +184,14 @@ class QUIC_EXPORT_PRIVATE QuicWallTime {
QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
Subtract(QuicTime::Delta delta) const;
+ bool operator==(const QuicWallTime& other) const {
+ return microseconds_ == other.microseconds_;
+ }
+
+ QuicTime::Delta operator-(const QuicWallTime& rhs) const {
+ return QuicTime::Delta::FromMicroseconds(microseconds_ - rhs.microseconds_);
+ }
+
private:
explicit constexpr QuicWallTime(uint64_t microseconds)
: microseconds_(microseconds) {}
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 edbce0c709c..eeaf297c1ca 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
@@ -64,6 +64,7 @@ void QuicTraceVisitor::OnPacketSent(const SerializedPacket& serialized_packet,
case BLOCKED_FRAME:
case PING_FRAME:
case HANDSHAKE_DONE_FRAME:
+ case ACK_FREQUENCY_FRAME:
PopulateFrameInfo(frame, event->add_frames());
break;
@@ -218,6 +219,7 @@ void QuicTraceVisitor::PopulateFrameInfo(const QuicFrame& frame,
case MESSAGE_FRAME:
case CRYPTO_FRAME:
case NEW_TOKEN_FRAME:
+ case ACK_FREQUENCY_FRAME:
break;
case NUM_FRAME_TYPES:
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 36614cd8f0a..a52571e3905 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
@@ -173,8 +173,7 @@ std::string TransmissionTypeToString(TransmissionType transmission_type) {
switch (transmission_type) {
RETURN_STRING_LITERAL(NOT_RETRANSMISSION);
RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
- RETURN_STRING_LITERAL(ALL_UNACKED_RETRANSMISSION);
- RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
+ RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
RETURN_STRING_LITERAL(RTO_RETRANSMISSION);
RETURN_STRING_LITERAL(TLP_RETRANSMISSION);
@@ -191,6 +190,11 @@ std::string TransmissionTypeToString(TransmissionType transmission_type) {
}
}
+std::ostream& operator<<(std::ostream& os, TransmissionType transmission_type) {
+ os << TransmissionTypeToString(transmission_type);
+ return os;
+}
+
std::string PacketHeaderFormatToString(PacketHeaderFormat format) {
switch (format) {
RETURN_STRING_LITERAL(IETF_QUIC_LONG_HEADER_PACKET);
@@ -261,11 +265,17 @@ std::string SerializedPacketFateToString(SerializedPacketFate fate) {
RETURN_STRING_LITERAL(BUFFER);
RETURN_STRING_LITERAL(SEND_TO_WRITER);
RETURN_STRING_LITERAL(FAILED_TO_WRITE_COALESCED_PACKET);
+ RETURN_STRING_LITERAL(LEGACY_VERSION_ENCAPSULATE);
default:
return quiche::QuicheStrCat("Unknown(", static_cast<int>(fate), ")");
}
}
+std::ostream& operator<<(std::ostream& os, SerializedPacketFate fate) {
+ os << SerializedPacketFateToString(fate);
+ return os;
+}
+
std::string EncryptionLevelToString(EncryptionLevel level) {
switch (level) {
RETURN_STRING_LITERAL(ENCRYPTION_INITIAL);
@@ -278,6 +288,11 @@ std::string EncryptionLevelToString(EncryptionLevel level) {
}
}
+std::ostream& operator<<(std::ostream& os, EncryptionLevel level) {
+ os << EncryptionLevelToString(level);
+ return os;
+}
+
std::string QuicConnectionCloseTypeString(QuicConnectionCloseType type) {
switch (type) {
RETURN_STRING_LITERAL(GOOGLE_QUIC_CONNECTION_CLOSE);
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 f2919ef3766..0c736f93178 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
@@ -163,21 +163,24 @@ struct QUIC_EXPORT_PRIVATE WriteResult {
enum TransmissionType : int8_t {
NOT_RETRANSMISSION,
FIRST_TRANSMISSION_TYPE = NOT_RETRANSMISSION,
- HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
- // TODO(fayang): remove ALL_UNACKED_RETRANSMISSION.
- ALL_UNACKED_RETRANSMISSION, // Retransmits all unacked packets.
- ALL_INITIAL_RETRANSMISSION, // Retransmits all initially encrypted packets.
- LOSS_RETRANSMISSION, // Retransmits due to loss detection.
- RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
- TLP_RETRANSMISSION, // Tail loss probes.
- PTO_RETRANSMISSION, // Retransmission due to probe timeout.
- PROBING_RETRANSMISSION, // Retransmission in order to probe bandwidth.
+ HANDSHAKE_RETRANSMISSION, // Retransmits due to handshake timeouts.
+ ALL_ZERO_RTT_RETRANSMISSION, // Retransmits all packets encrypted with 0-RTT
+ // key.
+ LOSS_RETRANSMISSION, // Retransmits due to loss detection.
+ RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
+ TLP_RETRANSMISSION, // Tail loss probes.
+ PTO_RETRANSMISSION, // Retransmission due to probe timeout.
+ PROBING_RETRANSMISSION, // Retransmission in order to probe bandwidth.
LAST_TRANSMISSION_TYPE = PROBING_RETRANSMISSION,
};
QUIC_EXPORT_PRIVATE std::string TransmissionTypeToString(
TransmissionType transmission_type);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ TransmissionType transmission_type);
+
enum HasRetransmittableData : uint8_t {
NO_RETRANSMITTABLE_DATA,
HAS_RETRANSMITTABLE_DATA,
@@ -224,6 +227,8 @@ enum QuicFrameType : uint8_t {
STOP_WAITING_FRAME = 6,
PING_FRAME = 7,
CRYPTO_FRAME = 8,
+ // TODO(b/157935330): stop hard coding this when deprecate T050.
+ HANDSHAKE_DONE_FRAME = 9,
// STREAM and ACK frames are special frames. They are encoded differently on
// the wire and their values do not need to be stable.
@@ -245,7 +250,7 @@ enum QuicFrameType : uint8_t {
MESSAGE_FRAME,
NEW_TOKEN_FRAME,
RETIRE_CONNECTION_ID_FRAME,
- HANDSHAKE_DONE_FRAME,
+ ACK_FREQUENCY_FRAME,
NUM_FRAME_TYPES
};
@@ -305,6 +310,9 @@ enum QuicIetfFrameType : uint8_t {
IETF_EXTENSION_MESSAGE = 0x21,
IETF_EXTENSION_MESSAGE_NO_LENGTH_V99 = 0x30,
IETF_EXTENSION_MESSAGE_V99 = 0x31,
+
+ // An QUIC extension frame for sender control of acknowledgement delays
+ IETF_ACK_FREQUENCY = 0xaf
};
QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const QuicIetfFrameType& c);
@@ -440,6 +448,9 @@ inline bool EncryptionLevelIsValid(EncryptionLevel level) {
QUIC_EXPORT_PRIVATE std::string EncryptionLevelToString(EncryptionLevel level);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+ EncryptionLevel level);
+
// Enumeration of whether a server endpoint will request a client certificate,
// and whether that endpoint requires a valid client certificate to establish a
// connection.
@@ -687,11 +698,16 @@ enum SerializedPacketFate : uint8_t {
SEND_TO_WRITER, // Send packet to writer.
FAILED_TO_WRITE_COALESCED_PACKET, // Packet cannot be coalesced, error occurs
// when sending existing coalesced packet.
+ LEGACY_VERSION_ENCAPSULATE, // Perform Legacy Version Encapsulation on this
+ // packet.
};
QUIC_EXPORT_PRIVATE std::string SerializedPacketFateToString(
SerializedPacketFate fate);
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+ const SerializedPacketFate fate);
+
// There are three different forms of CONNECTION_CLOSE.
enum QuicConnectionCloseType {
GOOGLE_QUIC_CONNECTION_CLOSE = 0,
@@ -734,6 +750,45 @@ struct QUIC_NO_EXPORT NextReleaseTimeResult {
bool allow_burst;
};
+// QuicPacketBuffer bundles a buffer and a function that releases it. Note
+// it does not assume ownership of buffer, i.e. it doesn't release the buffer on
+// destruction.
+struct QUIC_NO_EXPORT QuicPacketBuffer {
+ QuicPacketBuffer() = default;
+
+ QuicPacketBuffer(char* buffer,
+ std::function<void(const char*)> release_buffer)
+ : buffer(buffer), release_buffer(std::move(release_buffer)) {}
+
+ char* buffer = nullptr;
+ std::function<void(const char*)> release_buffer;
+};
+
+// QuicOwnedPacketBuffer is a QuicPacketBuffer that assumes buffer ownership.
+struct QUIC_NO_EXPORT QuicOwnedPacketBuffer : public QuicPacketBuffer {
+ QuicOwnedPacketBuffer(const QuicOwnedPacketBuffer&) = delete;
+ QuicOwnedPacketBuffer& operator=(const QuicOwnedPacketBuffer&) = delete;
+
+ QuicOwnedPacketBuffer(char* buffer,
+ std::function<void(const char*)> release_buffer)
+ : QuicPacketBuffer(buffer, std::move(release_buffer)) {}
+
+ QuicOwnedPacketBuffer(QuicOwnedPacketBuffer&& owned_buffer)
+ : QuicPacketBuffer(std::move(owned_buffer)) {
+ // |owned_buffer| does not own a buffer any more.
+ owned_buffer.buffer = nullptr;
+ }
+
+ explicit QuicOwnedPacketBuffer(QuicPacketBuffer&& packet_buffer)
+ : QuicPacketBuffer(std::move(packet_buffer)) {}
+
+ ~QuicOwnedPacketBuffer() {
+ if (release_buffer != nullptr && buffer != nullptr) {
+ release_buffer(buffer);
+ }
+ }
+};
+
} // namespace quic
#endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h
index 04f84357dab..258de080118 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket.h
@@ -163,10 +163,14 @@ class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
public:
// Creates a non-blocking udp socket, sets the receive/send buffer and enable
// receiving of self ip addresses on read.
- // Return kQuicInvalidSocketFd if failed.
+ // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
+ // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
+ // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
+ // failed.
QuicUdpSocketFd Create(int address_family,
int receive_buffer_size,
- int send_buffer_size);
+ int send_buffer_size,
+ bool ipv6_only = false);
// Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
void Destroy(QuicUdpSocketFd fd);
@@ -238,7 +242,8 @@ class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
bool SetupSocket(QuicUdpSocketFd fd,
int address_family,
int receive_buffer_size,
- int send_buffer_size);
+ int send_buffer_size,
+ bool ipv6_only);
bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
};
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc
index b6c58cdb1d3..c5ab345f433 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_posix.cc
@@ -239,7 +239,8 @@ bool NextCmsg(msghdr* hdr,
QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
int receive_buffer_size,
- int send_buffer_size) {
+ int send_buffer_size,
+ bool ipv6_only) {
// DCHECK here so the program exits early(before reading packets) in debug
// mode. This should have been a static_assert, however it can't be done on
// ios/osx because CMSG_SPACE isn't a constant expression there.
@@ -250,7 +251,8 @@ QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
return kQuicInvalidSocketFd;
}
- if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size)) {
+ if (!SetupSocket(fd, address_family, receive_buffer_size, send_buffer_size,
+ ipv6_only)) {
Destroy(fd);
return kQuicInvalidSocketFd;
}
@@ -261,7 +263,8 @@ QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
int address_family,
int receive_buffer_size,
- int send_buffer_size) {
+ int send_buffer_size,
+ bool ipv6_only) {
// Receive buffer size.
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &receive_buffer_size,
sizeof(receive_buffer_size)) != 0) {
@@ -276,14 +279,20 @@ bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd,
return false;
}
- if (!EnableReceiveSelfIpAddressForV4(fd)) {
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to enable receiving of self v4 ip";
- return false;
+ if (!(address_family == AF_INET6 && ipv6_only)) {
+ if (!EnableReceiveSelfIpAddressForV4(fd)) {
+ QUIC_LOG_FIRST_N(ERROR, 100)
+ << "Failed to enable receiving of self v4 ip";
+ return false;
+ }
}
- if (address_family == AF_INET6 && !EnableReceiveSelfIpAddressForV6(fd)) {
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to enable receiving of self v6 ip";
- return false;
+ if (address_family == AF_INET6) {
+ if (!EnableReceiveSelfIpAddressForV6(fd)) {
+ QUIC_LOG_FIRST_N(ERROR, 100)
+ << "Failed to enable receiving of self v6 ip";
+ return false;
+ }
}
return true;
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_test.cc b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_test.cc
index e43fb10c40b..f54b0edd073 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_udp_socket_test.cc
@@ -3,6 +3,11 @@
// found in the LICENSE file.
#include "net/third_party/quiche/src/quic/core/quic_udp_socket.h"
+#include <sys/socket.h>
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -15,33 +20,49 @@ struct ReadBuffers {
char control_buffer[512];
char packet_buffer[1536];
};
+
+// Allows IPv6-specific testing.
+struct TestParameters {
+ // If true, the test will only use IPv6. If false, IPv4 will be used if
+ // possible, with IPv6 used as a fallback.
+ bool force_ipv6;
+ // The value of ipv6_only to be used in QuicUdpSocketApi::Create calls.
+ bool ipv6_only;
+};
} // namespace
-class QuicUdpSocketTest : public QuicTest {
+class QuicUdpSocketTest : public QuicTestWithParam<TestParameters> {
protected:
void SetUp() override {
- // Try creating AF_INET socket, if it fails because of unsupported address
- // family then tests are being run under IPv6-only environment, initialize
- // address family to use for running the test under as AF_INET6 otherwise
- // initialize it as AF_INET.
- address_family_ = AF_INET;
- fd_client_ =
- api_.Create(address_family_,
- /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+ const TestParameters& parameters = GetParam();
+ if (!parameters.force_ipv6) {
+ // Try creating AF_INET socket, if it fails because of unsupported address
+ // family then tests are being run under IPv6-only environment, initialize
+ // address family to use for running the test under as AF_INET6 otherwise
+ // initialize it as AF_INET.
+ address_family_ = AF_INET;
+ fd_client_ =
+ api_.Create(address_family_,
+ /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
+ /*send_buffer_size =*/kDefaultSocketReceiveBuffer,
+ /*ipv6_only =*/parameters.ipv6_only);
+ }
if (fd_client_ == kQuicInvalidSocketFd) {
+ // Either AF_INET is unsupported, or force_ipv6 is true.
address_family_ = AF_INET6;
fd_client_ =
api_.Create(address_family_,
/*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+ /*send_buffer_size =*/kDefaultSocketReceiveBuffer,
+ /*ipv6_only =*/parameters.ipv6_only);
}
ASSERT_NE(fd_client_, kQuicInvalidSocketFd);
fd_server_ =
api_.Create(address_family_,
/*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
- /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
+ /*send_buffer_size =*/kDefaultSocketReceiveBuffer,
+ /*ipv6_only =*/parameters.ipv6_only);
ASSERT_NE(fd_server_, kQuicInvalidSocketFd);
ASSERT_TRUE(
@@ -114,8 +135,8 @@ class QuicUdpSocketTest : public QuicTest {
}
QuicUdpSocketApi api_;
- QuicUdpSocketFd fd_client_;
- QuicUdpSocketFd fd_server_;
+ QuicUdpSocketFd fd_client_ = kQuicInvalidSocketFd;
+ QuicUdpSocketFd fd_server_ = kQuicInvalidSocketFd;
QuicSocketAddress server_address_;
int address_family_;
char client_packet_buffer_[kEthernetMTU] = {0};
@@ -123,7 +144,22 @@ class QuicUdpSocketTest : public QuicTest {
char server_control_buffer_[512] = {0};
};
-TEST_F(QuicUdpSocketTest, ReadPacketResultReset) {
+INSTANTIATE_TEST_SUITE_P(
+ PlatformIndependent,
+ QuicUdpSocketTest,
+ testing::Values(TestParameters{/*force_ipv6 =*/false, /*ipv6_only =*/false},
+ TestParameters{/*force_ipv6 =*/false, /*ipv6_only =*/true},
+ TestParameters{/*force_ipv6 =*/true, /*ipv6_only =*/true}));
+
+#ifndef TARGET_OS_IPHONE
+// IPv6 on iOS is known to fail without ipv6_only, so should not be tested.
+INSTANTIATE_TEST_SUITE_P(NonIos,
+ QuicUdpSocketTest,
+ testing::Values(TestParameters{/*force_ipv6 =*/true,
+ /*ipv6_only =*/false}));
+#endif
+
+TEST_P(QuicUdpSocketTest, ReadPacketResultReset) {
QuicUdpSocketApi::ReadPacketResult result;
result.packet_info.SetDroppedPackets(100);
result.packet_buffer.buffer_len = 100;
@@ -137,7 +173,7 @@ TEST_F(QuicUdpSocketTest, ReadPacketResultReset) {
EXPECT_EQ(200u, result.packet_buffer.buffer_len);
}
-TEST_F(QuicUdpSocketTest, ReadPacketOnly) {
+TEST_P(QuicUdpSocketTest, ReadPacketOnly) {
const size_t kPacketSize = 512;
memset(client_packet_buffer_, '-', kPacketSize);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, kPacketSize),
@@ -150,7 +186,7 @@ TEST_F(QuicUdpSocketTest, ReadPacketOnly) {
ASSERT_EQ(0, ComparePacketBuffers(kPacketSize));
}
-TEST_F(QuicUdpSocketTest, ReadTruncated) {
+TEST_P(QuicUdpSocketTest, ReadTruncated) {
const size_t kPacketSize = kDefaultMaxPacketSize + 1;
memset(client_packet_buffer_, '*', kPacketSize);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, kPacketSize),
@@ -161,7 +197,7 @@ TEST_F(QuicUdpSocketTest, ReadTruncated) {
ASSERT_FALSE(read_result.ok);
}
-TEST_F(QuicUdpSocketTest, ReadDroppedPackets) {
+TEST_P(QuicUdpSocketTest, ReadDroppedPackets) {
const size_t kPacketSize = kDefaultMaxPacketSize;
memset(client_packet_buffer_, '-', kPacketSize);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, kPacketSize),
@@ -193,7 +229,7 @@ TEST_F(QuicUdpSocketTest, ReadDroppedPackets) {
}
}
-TEST_F(QuicUdpSocketTest, ReadSelfIp) {
+TEST_P(QuicUdpSocketTest, ReadSelfIp) {
const QuicUdpPacketInfoBit self_ip_bit =
(address_family_ == AF_INET) ? QuicUdpPacketInfoBit::V4_SELF_IP
: QuicUdpPacketInfoBit::V6_SELF_IP;
@@ -214,7 +250,7 @@ TEST_F(QuicUdpSocketTest, ReadSelfIp) {
: read_result.packet_info.self_v6_ip());
}
-TEST_F(QuicUdpSocketTest, ReadReceiveTimestamp) {
+TEST_P(QuicUdpSocketTest, ReadReceiveTimestamp) {
const size_t kPacketSize = kDefaultMaxPacketSize;
memset(client_packet_buffer_, '-', kPacketSize);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, kPacketSize),
@@ -249,7 +285,7 @@ TEST_F(QuicUdpSocketTest, ReadReceiveTimestamp) {
QuicWallTime::FromUNIXSeconds(1577836800).IsBefore(recv_timestamp));
}
-TEST_F(QuicUdpSocketTest, Ttl) {
+TEST_P(QuicUdpSocketTest, Ttl) {
const size_t kPacketSize = 512;
memset(client_packet_buffer_, '$', kPacketSize);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, kPacketSize),
@@ -282,7 +318,7 @@ TEST_F(QuicUdpSocketTest, Ttl) {
EXPECT_EQ(13, read_result.packet_info.ttl());
}
-TEST_F(QuicUdpSocketTest, ReadMultiplePackets) {
+TEST_P(QuicUdpSocketTest, ReadMultiplePackets) {
const QuicUdpPacketInfoBit self_ip_bit =
(address_family_ == AF_INET) ? QuicUdpPacketInfoBit::V4_SELF_IP
: QuicUdpPacketInfoBit::V6_SELF_IP;
@@ -335,7 +371,7 @@ TEST_F(QuicUdpSocketTest, ReadMultiplePackets) {
}
}
-TEST_F(QuicUdpSocketTest, ReadMultiplePacketsSomeTruncated) {
+TEST_P(QuicUdpSocketTest, ReadMultiplePacketsSomeTruncated) {
const QuicUdpPacketInfoBit self_ip_bit =
(address_family_ == AF_INET) ? QuicUdpPacketInfoBit::V4_SELF_IP
: QuicUdpPacketInfoBit::V6_SELF_IP;
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 8276f1c287c..f06d0746e40 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
@@ -28,6 +28,7 @@ QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
: perspective_(perspective),
least_unacked_(FirstSendingPacketNumber()),
bytes_in_flight_(0),
+ bytes_in_flight_per_packet_number_space_{0, 0, 0},
packets_in_flight_(0),
last_inflight_packet_sent_time_(QuicTime::Zero()),
last_inflight_packets_sent_time_{{QuicTime::Zero()},
@@ -72,6 +73,7 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
const PacketNumberSpace packet_number_space =
GetPacketNumberSpace(info.encryption_level);
bytes_in_flight_ += bytes_sent;
+ bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
++packets_in_flight_;
info.in_flight = true;
largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
@@ -195,6 +197,27 @@ void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
QUIC_BUG_IF(packets_in_flight_ == 0);
bytes_in_flight_ -= info->bytes_sent;
--packets_in_flight_;
+
+ const PacketNumberSpace packet_number_space =
+ GetPacketNumberSpace(info->encryption_level);
+ if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
+ info->bytes_sent) {
+ QUIC_BUG << "bytes_in_flight: "
+ << bytes_in_flight_per_packet_number_space_[packet_number_space]
+ << " is smaller than bytes_sent: " << info->bytes_sent
+ << " for packet number space: "
+ << PacketNumberSpaceToString(packet_number_space);
+ bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
+ } else {
+ bytes_in_flight_per_packet_number_space_[packet_number_space] -=
+ info->bytes_sent;
+ }
+ if (GetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time) &&
+ bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_last_inflight_packets_sent_time);
+ last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
+ }
+
info->in_flight = false;
}
}
@@ -230,7 +253,12 @@ QuicUnackedPacketMap::NeuterUnencryptedPackets() {
}
}
if (supports_multiple_packet_number_spaces_) {
- last_inflight_packets_sent_time_[INITIAL_DATA] = QuicTime::Zero();
+ if (GetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time)) {
+ DCHECK_EQ(QuicTime::Zero(),
+ last_inflight_packets_sent_time_[INITIAL_DATA]);
+ } else {
+ last_inflight_packets_sent_time_[INITIAL_DATA] = QuicTime::Zero();
+ }
}
return neutered_packets;
}
@@ -254,7 +282,12 @@ QuicUnackedPacketMap::NeuterHandshakePackets() {
}
}
if (supports_multiple_packet_number_spaces()) {
- last_inflight_packets_sent_time_[HANDSHAKE_DATA] = QuicTime::Zero();
+ if (GetQuicReloadableFlag(quic_fix_last_inflight_packets_sent_time)) {
+ DCHECK_EQ(QuicTime::Zero(),
+ last_inflight_packets_sent_time_[HANDSHAKE_DATA]);
+ } else {
+ last_inflight_packets_sent_time_[HANDSHAKE_DATA] = QuicTime::Zero();
+ }
}
return neutered_packets;
}
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 bcf5061927a..43e900802f4 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
@@ -281,6 +281,9 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
QuicPacketNumber least_unacked_;
QuicByteCount bytes_in_flight_;
+ // Bytes in flight per packet number space.
+ QuicByteCount
+ bytes_in_flight_per_packet_number_space_[NUM_PACKET_NUMBER_SPACES];
QuicPacketCount packets_in_flight_;
// Time that the last inflight packet was sent.
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 60354f332fa..de4350390b0 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
@@ -6,6 +6,7 @@
#include <algorithm>
#include <cstdint>
+#include <cstring>
#include <string>
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
@@ -335,8 +336,7 @@ bool QuicUtils::ContainsFrameType(const QuicFrames& frames,
SentPacketState QuicUtils::RetransmissionTypeToPacketState(
TransmissionType retransmission_type) {
switch (retransmission_type) {
- case ALL_UNACKED_RETRANSMISSION:
- case ALL_INITIAL_RETRANSMISSION:
+ case ALL_ZERO_RTT_RETRANSMISSION:
return UNACKABLE;
case HANDSHAKE_RETRANSMISSION:
return HANDSHAKE_RETRANSMITTED;
@@ -351,8 +351,7 @@ SentPacketState QuicUtils::RetransmissionTypeToPacketState(
case PROBING_RETRANSMISSION:
return PROBE_RETRANSMITTED;
default:
- QUIC_BUG << TransmissionTypeToString(retransmission_type)
- << " is not a retransmission_type";
+ QUIC_BUG << retransmission_type << " is not a retransmission_type";
return UNACKABLE;
}
}
@@ -429,15 +428,21 @@ bool QuicUtils::IsOutgoingStreamId(ParsedQuicVersion version,
}
// static
-bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id) {
+bool QuicUtils::IsBidirectionalStreamId(QuicStreamId id,
+ ParsedQuicVersion version) {
+ DCHECK(!GetQuicReloadableFlag(quic_fix_gquic_stream_type) ||
+ version.HasIetfQuicFrames());
return id % 4 < 2;
}
// static
StreamType QuicUtils::GetStreamType(QuicStreamId id,
Perspective perspective,
- bool peer_initiated) {
- if (IsBidirectionalStreamId(id)) {
+ bool peer_initiated,
+ ParsedQuicVersion version) {
+ DCHECK(!GetQuicReloadableFlag(quic_fix_gquic_stream_type) ||
+ version.HasIetfQuicFrames());
+ if (IsBidirectionalStreamId(id, version)) {
return BIDIRECTIONAL;
}
@@ -491,11 +496,37 @@ QuicStreamId QuicUtils::GetFirstUnidirectionalStreamId(
// static
QuicConnectionId QuicUtils::CreateReplacementConnectionId(
- QuicConnectionId connection_id) {
- const uint64_t connection_id_hash = FNV1a_64_Hash(
+ const QuicConnectionId& connection_id) {
+ return CreateReplacementConnectionId(connection_id,
+ kQuicDefaultConnectionIdLength);
+}
+
+// static
+QuicConnectionId QuicUtils::CreateReplacementConnectionId(
+ const QuicConnectionId& connection_id,
+ uint8_t expected_connection_id_length) {
+ if (expected_connection_id_length == 0) {
+ return EmptyQuicConnectionId();
+ }
+ const uint64_t connection_id_hash64 = FNV1a_64_Hash(
+ quiche::QuicheStringPiece(connection_id.data(), connection_id.length()));
+ if (expected_connection_id_length <= sizeof(uint64_t)) {
+ return QuicConnectionId(
+ reinterpret_cast<const char*>(&connection_id_hash64),
+ expected_connection_id_length);
+ }
+ char new_connection_id_data[255] = {};
+ const QuicUint128 connection_id_hash128 = FNV1a_128_Hash(
quiche::QuicheStringPiece(connection_id.data(), connection_id.length()));
- return QuicConnectionId(reinterpret_cast<const char*>(&connection_id_hash),
- sizeof(connection_id_hash));
+ static_assert(sizeof(connection_id_hash64) + sizeof(connection_id_hash128) <=
+ sizeof(new_connection_id_data),
+ "bad size");
+ memcpy(new_connection_id_data, &connection_id_hash64,
+ sizeof(connection_id_hash64));
+ memcpy(new_connection_id_data + sizeof(connection_id_hash64),
+ &connection_id_hash128, sizeof(connection_id_hash128));
+ return QuicConnectionId(new_connection_id_data,
+ expected_connection_id_length);
}
// static
@@ -603,7 +634,7 @@ PacketNumberSpace QuicUtils::GetPacketNumberSpace(
return APPLICATION_DATA;
default:
QUIC_BUG << "Try to get packet number space of encryption level: "
- << EncryptionLevelToString(encryption_level);
+ << encryption_level;
return NUM_PACKET_NUMBER_SPACES;
}
}
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 eec9a5f25df..9e190e0b386 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
@@ -146,14 +146,16 @@ class QUIC_EXPORT_PRIVATE QuicUtils {
// Returns true if |id| is considered as bidirectional stream ID. Only used in
// v99.
- static bool IsBidirectionalStreamId(QuicStreamId id);
+ static bool IsBidirectionalStreamId(QuicStreamId id,
+ ParsedQuicVersion version);
// Returns stream type. Either |perspective| or |peer_initiated| would be
// enough together with |id|. This method enforces that the three parameters
// are consistent. Only used in v99.
static StreamType GetStreamType(QuicStreamId id,
Perspective perspective,
- bool peer_initiated);
+ bool peer_initiated,
+ ParsedQuicVersion version);
// Returns the delta between consecutive stream IDs of the same type.
static QuicStreamId StreamIdDelta(QuicTransportVersion version);
@@ -168,11 +170,19 @@ class QUIC_EXPORT_PRIVATE QuicUtils {
QuicTransportVersion version,
Perspective perspective);
- // Generates a 64bit connection ID derived from the input connection ID.
+ // 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
// connection IDs that are equal is guaranteed to produce the same result).
static QuicConnectionId CreateReplacementConnectionId(
- QuicConnectionId connection_id);
+ const QuicConnectionId& connection_id,
+ uint8_t expected_connection_id_length);
+
+ // Generates a 64bit connection ID derived from |connection_id|.
+ // This is guaranteed to be deterministic (calling this method with two
+ // connection IDs that are equal is guaranteed to produce the same result).
+ static QuicConnectionId CreateReplacementConnectionId(
+ const QuicConnectionId& connection_id);
// Generates a random 64bit connection ID.
static QuicConnectionId CreateRandomConnectionId();
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 5b2186acde4..041cd9856a1 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
@@ -125,8 +125,7 @@ TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
EXPECT_EQ(HANDSHAKE_RETRANSMITTED, state);
} else if (i == LOSS_RETRANSMISSION) {
EXPECT_EQ(LOST, state);
- } else if (i == ALL_UNACKED_RETRANSMISSION ||
- i == ALL_INITIAL_RETRANSMISSION) {
+ } else if (i == ALL_ZERO_RTT_RETRANSMISSION) {
EXPECT_EQ(UNACKABLE, state);
} else if (i == TLP_RETRANSMISSION) {
EXPECT_EQ(TLP_RETRANSMITTED, state);
@@ -180,6 +179,23 @@ TEST_F(QuicUtilsTest, ReplacementConnectionIdIsDeterministic) {
EXPECT_EQ(connection_id72a, connection_id72b);
EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a),
QuicUtils::CreateReplacementConnectionId(connection_id72b));
+ // Test variant with custom length.
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 7),
+ QuicUtils::CreateReplacementConnectionId(connection_id64b, 7));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 9),
+ QuicUtils::CreateReplacementConnectionId(connection_id64b, 9));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id64a, 16),
+ QuicUtils::CreateReplacementConnectionId(connection_id64b, 16));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 7),
+ QuicUtils::CreateReplacementConnectionId(connection_id72b, 7));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 9),
+ QuicUtils::CreateReplacementConnectionId(connection_id72b, 9));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 16),
+ QuicUtils::CreateReplacementConnectionId(connection_id72b, 16));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 32),
+ QuicUtils::CreateReplacementConnectionId(connection_id72b, 32));
+ EXPECT_EQ(QuicUtils::CreateReplacementConnectionId(connection_id72a, 255),
+ QuicUtils::CreateReplacementConnectionId(connection_id72b, 255));
}
TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
@@ -191,6 +207,22 @@ TEST_F(QuicUtilsTest, ReplacementConnectionIdLengthIsCorrect) {
QuicUtils::CreateReplacementConnectionId(connection_id);
EXPECT_EQ(kQuicDefaultConnectionIdLength,
replacement_connection_id.length());
+ // Test variant with custom length.
+ QuicConnectionId replacement_connection_id7 =
+ QuicUtils::CreateReplacementConnectionId(connection_id, 7);
+ EXPECT_EQ(7, replacement_connection_id7.length());
+ QuicConnectionId replacement_connection_id9 =
+ QuicUtils::CreateReplacementConnectionId(connection_id, 9);
+ EXPECT_EQ(9, replacement_connection_id9.length());
+ QuicConnectionId replacement_connection_id16 =
+ QuicUtils::CreateReplacementConnectionId(connection_id, 16);
+ EXPECT_EQ(16, replacement_connection_id16.length());
+ QuicConnectionId replacement_connection_id32 =
+ QuicUtils::CreateReplacementConnectionId(connection_id, 32);
+ EXPECT_EQ(32, replacement_connection_id32.length());
+ QuicConnectionId replacement_connection_id255 =
+ QuicUtils::CreateReplacementConnectionId(connection_id, 255);
+ EXPECT_EQ(255, replacement_connection_id255.length());
}
}
@@ -205,6 +237,17 @@ TEST_F(QuicUtilsTest, ReplacementConnectionIdHasEntropy) {
EXPECT_NE(connection_id_i, connection_id_j);
EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i),
QuicUtils::CreateReplacementConnectionId(connection_id_j));
+ // Test variant with custom length.
+ EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 7),
+ QuicUtils::CreateReplacementConnectionId(connection_id_j, 7));
+ EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 9),
+ QuicUtils::CreateReplacementConnectionId(connection_id_j, 9));
+ EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 16),
+ QuicUtils::CreateReplacementConnectionId(connection_id_j, 16));
+ EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 32),
+ QuicUtils::CreateReplacementConnectionId(connection_id_j, 32));
+ EXPECT_NE(QuicUtils::CreateReplacementConnectionId(connection_id_i, 255),
+ QuicUtils::CreateReplacementConnectionId(connection_id_j, 255));
}
}
}
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 0a014bebe78..90c49823d99 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
@@ -15,18 +15,20 @@ namespace quic {
QuicVersionManager::QuicVersionManager(
ParsedQuicVersionVector supported_versions)
- : enable_version_draft_27_(
- GetQuicReloadableFlag(quic_enable_version_draft_27)),
- enable_version_draft_25_(
- GetQuicReloadableFlag(quic_enable_version_draft_25_v3)),
+ : enable_version_draft_29_(
+ GetQuicReloadableFlag(quic_enable_version_draft_29)),
+ disable_version_draft_27_(
+ GetQuicReloadableFlag(quic_disable_version_draft_27)),
+ disable_version_draft_25_(
+ GetQuicReloadableFlag(quic_disable_version_draft_25)),
disable_version_q050_(GetQuicReloadableFlag(quic_disable_version_q050)),
- enable_version_t050_(GetQuicReloadableFlag(quic_enable_version_t050_v2)),
+ disable_version_t050_(GetQuicReloadableFlag(quic_disable_version_t050)),
disable_version_q049_(GetQuicReloadableFlag(quic_disable_version_q049)),
disable_version_q048_(GetQuicReloadableFlag(quic_disable_version_q048)),
disable_version_q046_(GetQuicReloadableFlag(quic_disable_version_q046)),
disable_version_q043_(GetQuicReloadableFlag(quic_disable_version_q043)),
allowed_supported_versions_(std::move(supported_versions)) {
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync");
RefilterSupportedVersions();
}
@@ -56,16 +58,18 @@ const std::vector<std::string>& QuicVersionManager::GetSupportedAlpns() {
}
void QuicVersionManager::MaybeRefilterSupportedVersions() {
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync");
- if (enable_version_draft_27_ !=
- GetQuicReloadableFlag(quic_enable_version_draft_27) ||
- enable_version_draft_25_ !=
- GetQuicReloadableFlag(quic_enable_version_draft_25_v3) ||
+ if (enable_version_draft_29_ !=
+ GetQuicReloadableFlag(quic_enable_version_draft_29) ||
+ disable_version_draft_27_ !=
+ GetQuicReloadableFlag(quic_disable_version_draft_27) ||
+ disable_version_draft_25_ !=
+ GetQuicReloadableFlag(quic_disable_version_draft_25) ||
disable_version_q050_ !=
GetQuicReloadableFlag(quic_disable_version_q050) ||
- enable_version_t050_ !=
- GetQuicReloadableFlag(quic_enable_version_t050_v2) ||
+ disable_version_t050_ !=
+ GetQuicReloadableFlag(quic_disable_version_t050) ||
disable_version_q049_ !=
GetQuicReloadableFlag(quic_disable_version_q049) ||
disable_version_q048_ !=
@@ -74,12 +78,14 @@ void QuicVersionManager::MaybeRefilterSupportedVersions() {
GetQuicReloadableFlag(quic_disable_version_q046) ||
disable_version_q043_ !=
GetQuicReloadableFlag(quic_disable_version_q043)) {
- enable_version_draft_27_ =
- GetQuicReloadableFlag(quic_enable_version_draft_27);
- enable_version_draft_25_ =
- GetQuicReloadableFlag(quic_enable_version_draft_25_v3);
+ enable_version_draft_29_ =
+ GetQuicReloadableFlag(quic_enable_version_draft_29);
+ disable_version_draft_27_ =
+ GetQuicReloadableFlag(quic_disable_version_draft_27);
+ disable_version_draft_25_ =
+ GetQuicReloadableFlag(quic_disable_version_draft_25);
disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
- enable_version_t050_ = GetQuicReloadableFlag(quic_enable_version_t050_v2);
+ disable_version_t050_ = GetQuicReloadableFlag(quic_disable_version_t050);
disable_version_q049_ = GetQuicReloadableFlag(quic_disable_version_q049);
disable_version_q048_ = GetQuicReloadableFlag(quic_disable_version_q048);
disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
index c5111edf260..e6bb8f6b6bd 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager.h
@@ -52,14 +52,16 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager {
private:
// Cached value of reloadable flags.
- // quic_enable_version_draft_27 flag
- bool enable_version_draft_27_;
- // quic_enable_version_draft_25_v3 flag
- bool enable_version_draft_25_;
+ // quic_enable_version_draft_29 flag
+ bool enable_version_draft_29_;
+ // quic_disable_version_draft_27 flag
+ bool disable_version_draft_27_;
+ // quic_disable_version_draft_25 flag
+ bool disable_version_draft_25_;
// quic_disable_version_q050 flag
bool disable_version_q050_;
- // quic_enable_version_t050_v2 flag
- bool enable_version_t050_;
+ // quic_disable_version_t050 flag
+ bool disable_version_t050_;
// quic_disable_version_q049 flag
bool disable_version_q049_;
// quic_disable_version_q048 flag
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 3a8e98ff520..4687b791fd9 100644
--- a/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/quic_version_manager_test.cc
@@ -18,11 +18,12 @@ namespace {
class QuicVersionManagerTest : public QuicTest {};
TEST_F(QuicVersionManagerTest, QuicVersionManager) {
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync");
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
- SetQuicReloadableFlag(quic_enable_version_t050_v2, false);
+ SetQuicReloadableFlag(quic_enable_version_draft_29, false);
+ SetQuicReloadableFlag(quic_disable_version_draft_27, true);
+ SetQuicReloadableFlag(quic_disable_version_draft_25, true);
+ SetQuicReloadableFlag(quic_disable_version_t050, false);
SetQuicReloadableFlag(quic_disable_version_q050, false);
SetQuicReloadableFlag(quic_disable_version_q049, false);
SetQuicReloadableFlag(quic_disable_version_q048, false);
@@ -32,6 +33,8 @@ TEST_F(QuicVersionManagerTest, QuicVersionManager) {
ParsedQuicVersionVector expected_parsed_versions;
expected_parsed_versions.push_back(
+ ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
+ expected_parsed_versions.push_back(
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
expected_parsed_versions.push_back(
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
@@ -43,59 +46,56 @@ TEST_F(QuicVersionManagerTest, QuicVersionManager) {
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43));
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions,
- manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
manager.GetSupportedVersions());
EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
manager.GetSupportedVersionsWithQuicCrypto());
- EXPECT_THAT(
- manager.GetSupportedAlpns(),
- ElementsAre("h3-Q050", "h3-Q049", "h3-Q048", "h3-Q046", "h3-Q043"));
+ EXPECT_THAT(manager.GetSupportedAlpns(),
+ ElementsAre("h3-T050", "h3-Q050", "h3-Q049", "h3-Q048", "h3-Q046",
+ "h3-Q043"));
- SetQuicReloadableFlag(quic_enable_version_draft_27, true);
- expected_parsed_versions.insert(
- expected_parsed_versions.begin(),
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
+ SetQuicReloadableFlag(quic_enable_version_draft_29, true);
+ expected_parsed_versions.insert(expected_parsed_versions.begin(),
+ ParsedQuicVersion::Draft29());
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions.size() - 1,
+ EXPECT_EQ(expected_parsed_versions.size() - 2,
manager.GetSupportedVersionsWithQuicCrypto().size());
EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
manager.GetSupportedVersions());
EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3-27", "h3-Q050", "h3-Q049", "h3-Q048", "h3-Q046",
- "h3-Q043"));
+ ElementsAre("h3-29", "h3-T050", "h3-Q050", "h3-Q049", "h3-Q048",
+ "h3-Q046", "h3-Q043"));
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
+ SetQuicReloadableFlag(quic_disable_version_draft_27, false);
expected_parsed_versions.insert(
expected_parsed_versions.begin() + 1,
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+ ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions.size() - 2,
+ EXPECT_EQ(expected_parsed_versions.size() - 3,
manager.GetSupportedVersionsWithQuicCrypto().size());
+ EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+ manager.GetSupportedVersions());
EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3-27", "h3-25", "h3-Q050", "h3-Q049", "h3-Q048",
- "h3-Q046", "h3-Q043"));
+ ElementsAre("h3-29", "h3-27", "h3-T050", "h3-Q050", "h3-Q049",
+ "h3-Q048", "h3-Q046", "h3-Q043"));
- SetQuicReloadableFlag(quic_enable_version_t050_v2, true);
+ SetQuicReloadableFlag(quic_disable_version_draft_25, false);
expected_parsed_versions.insert(
expected_parsed_versions.begin() + 2,
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
+ ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
- EXPECT_EQ(expected_parsed_versions.size() - 3,
+ EXPECT_EQ(expected_parsed_versions.size() - 4,
manager.GetSupportedVersionsWithQuicCrypto().size());
- EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
- manager.GetSupportedVersions());
EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
manager.GetSupportedVersionsWithQuicCrypto());
EXPECT_THAT(manager.GetSupportedAlpns(),
- ElementsAre("h3-27", "h3-25", "h3-T050", "h3-Q050", "h3-Q049",
- "h3-Q048", "h3-Q046", "h3-Q043"));
+ ElementsAre("h3-29", "h3-27", "h3-25", "h3-T050", "h3-Q050",
+ "h3-Q049", "h3-Q048", "h3-Q046", "h3-Q043"));
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc b/chromium/net/third_party/quiche/src/quic/core/quic_versions.cc
index bf93e8383d2..461a4882e2b 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
@@ -39,6 +39,35 @@ QuicVersionLabel CreateRandomVersionLabelForNegotiation() {
return result;
}
+void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
+ static_assert(SupportedVersions().size() == 9u,
+ "Supported versions out of sync");
+ const bool enable = should_enable;
+ const bool disable = !should_enable;
+ if (version == ParsedQuicVersion::Draft29()) {
+ SetQuicReloadableFlag(quic_enable_version_draft_29, enable);
+ } else if (version == ParsedQuicVersion::Draft27()) {
+ SetQuicReloadableFlag(quic_disable_version_draft_27, disable);
+ } else if (version == ParsedQuicVersion::Draft25()) {
+ SetQuicReloadableFlag(quic_disable_version_draft_25, disable);
+ } else if (version == ParsedQuicVersion::T050()) {
+ SetQuicReloadableFlag(quic_disable_version_t050, disable);
+ } else if (version == ParsedQuicVersion::Q050()) {
+ SetQuicReloadableFlag(quic_disable_version_q050, disable);
+ } else if (version == ParsedQuicVersion::Q049()) {
+ SetQuicReloadableFlag(quic_disable_version_q049, disable);
+ } else if (version == ParsedQuicVersion::Q048()) {
+ SetQuicReloadableFlag(quic_disable_version_q048, disable);
+ } else if (version == ParsedQuicVersion::Q046()) {
+ SetQuicReloadableFlag(quic_disable_version_q046, disable);
+ } else if (version == ParsedQuicVersion::Q043()) {
+ SetQuicReloadableFlag(quic_disable_version_q043, disable);
+ } else {
+ QUIC_BUG << "Cannot " << (should_enable ? "en" : "dis") << "able version "
+ << version;
+ }
+}
+
} // namespace
bool ParsedQuicVersion::IsKnown() const {
@@ -158,6 +187,11 @@ bool ParsedQuicVersion::HasVarIntTransportParams() const {
return transport_version >= QUIC_VERSION_IETF_DRAFT_27;
}
+bool ParsedQuicVersion::AuthenticatesHandshakeConnectionIds() const {
+ DCHECK(IsKnown());
+ return transport_version > QUIC_VERSION_IETF_DRAFT_27;
+}
+
bool ParsedQuicVersion::UsesTls() const {
DCHECK(IsKnown());
return handshake_protocol == PROTOCOL_TLS1_3;
@@ -211,7 +245,7 @@ QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
<< parsed_version.handshake_protocol;
return 0;
}
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync");
switch (parsed_version.transport_version) {
case QUIC_VERSION_43:
@@ -236,6 +270,12 @@ QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
}
QUIC_BUG << "QUIC_VERSION_IETF_DRAFT_27 requires TLS";
return 0;
+ case QUIC_VERSION_IETF_DRAFT_29:
+ if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
+ return MakeVersionLabel(0xff, 0x00, 0x00, 29);
+ }
+ QUIC_BUG << "QUIC_VERSION_IETF_DRAFT_29 requires TLS";
+ return 0;
case QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
return CreateRandomVersionLabelForNegotiation();
default:
@@ -391,15 +431,20 @@ ParsedQuicVersionVector FilterSupportedVersions(
ParsedQuicVersionVector versions) {
ParsedQuicVersionVector filtered_versions;
filtered_versions.reserve(versions.size());
- for (ParsedQuicVersion version : versions) {
- if (version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
+ for (const ParsedQuicVersion& version : versions) {
+ if (version.transport_version == QUIC_VERSION_IETF_DRAFT_29) {
+ QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
+ if (GetQuicReloadableFlag(quic_enable_version_draft_29)) {
+ filtered_versions.push_back(version);
+ }
+ } else if (version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
- if (GetQuicReloadableFlag(quic_enable_version_draft_27)) {
+ if (!GetQuicReloadableFlag(quic_disable_version_draft_27)) {
filtered_versions.push_back(version);
}
} else if (version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
- if (GetQuicReloadableFlag(quic_enable_version_draft_25_v3)) {
+ if (!GetQuicReloadableFlag(quic_disable_version_draft_25)) {
filtered_versions.push_back(version);
}
} else if (version.transport_version == QUIC_VERSION_50) {
@@ -408,7 +453,7 @@ ParsedQuicVersionVector FilterSupportedVersions(
filtered_versions.push_back(version);
}
} else {
- if (GetQuicReloadableFlag(quic_enable_version_t050_v2)) {
+ if (!GetQuicReloadableFlag(quic_disable_version_t050)) {
filtered_versions.push_back(version);
}
}
@@ -518,7 +563,7 @@ HandshakeProtocol QuicVersionLabelToHandshakeProtocol(
return #x
std::string QuicVersionToString(QuicTransportVersion transport_version) {
- static_assert(SupportedTransportVersions().size() == 7u,
+ static_assert(SupportedTransportVersions().size() == 8u,
"Supported versions out of sync");
switch (transport_version) {
RETURN_STRING_LITERAL(QUIC_VERSION_43);
@@ -528,6 +573,7 @@ std::string QuicVersionToString(QuicTransportVersion transport_version) {
RETURN_STRING_LITERAL(QUIC_VERSION_50);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_25);
RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_27);
+ RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
}
@@ -621,21 +667,25 @@ bool QuicVersionLabelUses4BitConnectionIdLength(
}
ParsedQuicVersion UnsupportedQuicVersion() {
- return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
+ return ParsedQuicVersion::Unsupported();
}
ParsedQuicVersion QuicVersionReservedForNegotiation() {
- return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
- QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+ return ParsedQuicVersion::ReservedForNegotiation();
+}
+
+ParsedQuicVersion LegacyVersionForEncapsulation() {
+ return ParsedQuicVersion::Q043();
}
std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
- if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
- return "h3-25";
- }
- if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
+ if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_29) {
+ return "h3-29";
+ } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
return "h3-27";
+ } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
+ return "h3-25";
}
}
return "h3-" + ParsedQuicVersionToString(parsed_version);
@@ -643,32 +693,21 @@ std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
void QuicVersionInitializeSupportForIetfDraft() {
// Enable necessary flags.
+ SetQuicReloadableFlag(quic_enable_tls_resumption, true);
+ SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
}
-void QuicEnableVersion(ParsedQuicVersion parsed_version) {
- static_assert(SupportedVersions().size() == 8u,
- "Supported versions out of sync");
- if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
- QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
- SetQuicReloadableFlag(quic_enable_version_draft_27, true);
- } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
- QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
- } else if (parsed_version.transport_version == QUIC_VERSION_50) {
- if (parsed_version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
- SetQuicReloadableFlag(quic_disable_version_q050, false);
- } else {
- SetQuicReloadableFlag(quic_enable_version_t050_v2, true);
- }
- } else if (parsed_version.transport_version == QUIC_VERSION_49) {
- SetQuicReloadableFlag(quic_disable_version_q049, false);
- } else if (parsed_version.transport_version == QUIC_VERSION_48) {
- SetQuicReloadableFlag(quic_disable_version_q048, false);
- } else if (parsed_version.transport_version == QUIC_VERSION_46) {
- SetQuicReloadableFlag(quic_disable_version_q046, false);
- } else if (parsed_version.transport_version == QUIC_VERSION_43) {
- SetQuicReloadableFlag(quic_disable_version_q043, false);
- }
+void QuicEnableVersion(const ParsedQuicVersion& version) {
+ SetVersionFlag(version, /*should_enable=*/true);
+}
+
+void QuicDisableVersion(const ParsedQuicVersion& version) {
+ SetVersionFlag(version, /*should_enable=*/false);
+}
+
+bool QuicVersionIsEnabled(const ParsedQuicVersion& version) {
+ ParsedQuicVersionVector current = CurrentSupportedVersions();
+ return std::find(current.begin(), current.end(), version) != current.end();
}
#undef RETURN_STRING_LITERAL // undef for jumbo builds
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 5f3a9689198..341d39896cb 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
@@ -4,13 +4,21 @@
// Definitions and utility functions related to handling of QUIC versions.
//
-// QUIC version is a four-byte tag that can be represented in memory as a
-// QuicVersionLabel type (which is an alias to uint32_t). In actuality, all
-// versions supported by this implementation have the following format:
-// [QT]0\d\d
-// e.g. Q046. Q or T distinguishes the type of handshake used (Q for QUIC
-// Crypto handshake, T for TLS-based handshake), and the two digits at the end
-// is the actual numeric value of transport version used by the code.
+// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
+// encoding is represented in memory as a QuicVersionLabel type (which is an
+// alias to uint32_t). Conceptual versions are represented in memory as
+// ParsedQuicVersion.
+//
+// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
+//
+// All GoogleQUIC versions use a wire encoding that matches the following regex
+// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
+// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
+// handshake), and the two digits at the end contain the numeric value of
+// the transport version used.
+//
+// All IETF QUIC versions use the wire encoding described in:
+// https://tools.ietf.org/html/draft-ietf-quic-transport
#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
@@ -25,11 +33,12 @@
namespace quic {
-// The available versions of QUIC. The numeric value of the enum is guaranteed
-// to match the number in the name. The versions not currently supported are
-// documented in comments.
-//
-// See go/new-quic-version for more details on how to roll out new versions.
+// The list of existing QUIC transport versions. Note that QUIC versions are
+// sent over the wire as an encoding of ParsedQuicVersion, which requires a
+// QUIC transport version and handshake protocol. For transport versions of the
+// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
+// guaranteed to match the name. Older deprecated transport versions are
+// documented in comments below.
enum QuicTransportVersion {
// Special case to indicate unknown/unsupported QUIC version.
QUIC_VERSION_UNSUPPORTED = 0,
@@ -110,6 +119,8 @@ enum QuicTransportVersion {
QUIC_VERSION_50 = 50, // Header protection and initial obfuscators.
QUIC_VERSION_IETF_DRAFT_25 = 70, // draft-ietf-quic-transport-25.
QUIC_VERSION_IETF_DRAFT_27 = 71, // draft-ietf-quic-transport-27.
+ // Number 72 used to represent draft-ietf-quic-transport-28.
+ QUIC_VERSION_IETF_DRAFT_29 = 73, // draft-ietf-quic-transport-29.
// Version 99 was a dumping ground for IETF QUIC changes which were not yet
// yet ready for production between 2018-02 and 2020-02.
@@ -123,13 +134,10 @@ enum QuicTransportVersion {
};
// This array contains QUIC transport versions which we currently support.
-// This should be ordered such that the highest supported version is the first
-// element, with subsequent elements in descending order (versions can be
-// skipped as necessary).
-//
-// See go/new-quic-version for more details on how to roll out new versions.
-constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() {
- return {QUIC_VERSION_IETF_DRAFT_27,
+// DEPRECATED. Use SupportedVersions() instead.
+constexpr std::array<QuicTransportVersion, 8> SupportedTransportVersions() {
+ return {QUIC_VERSION_IETF_DRAFT_29,
+ QUIC_VERSION_IETF_DRAFT_27,
QUIC_VERSION_IETF_DRAFT_25,
QUIC_VERSION_50,
QUIC_VERSION_49,
@@ -191,7 +199,8 @@ QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
case PROTOCOL_QUIC_CRYPTO:
return transport_version != QUIC_VERSION_UNSUPPORTED &&
transport_version != QUIC_VERSION_IETF_DRAFT_25 &&
- transport_version != QUIC_VERSION_IETF_DRAFT_27;
+ transport_version != QUIC_VERSION_IETF_DRAFT_27 &&
+ transport_version != QUIC_VERSION_IETF_DRAFT_29;
case PROTOCOL_TLS1_3:
// The TLS handshake is only deployable if CRYPTO frames are also used.
// We explicitly removed support for T048 and T049 to reduce test load.
@@ -242,6 +251,51 @@ struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
transport_version != other.transport_version;
}
+ static constexpr ParsedQuicVersion Draft29() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
+ }
+
+ static constexpr ParsedQuicVersion Draft27() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27);
+ }
+
+ static constexpr ParsedQuicVersion Draft25() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
+ }
+
+ static constexpr ParsedQuicVersion T050() {
+ return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50);
+ }
+
+ static constexpr ParsedQuicVersion Q050() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
+ }
+
+ static constexpr ParsedQuicVersion Q049() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49);
+ }
+
+ static constexpr ParsedQuicVersion Q048() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
+ }
+
+ static constexpr ParsedQuicVersion Q046() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
+ }
+
+ static constexpr ParsedQuicVersion Q043() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
+ }
+
+ static constexpr ParsedQuicVersion Unsupported() {
+ return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
+ }
+
+ static constexpr ParsedQuicVersion ReservedForNegotiation() {
+ return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
+ QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
+ }
+
// Returns whether our codebase understands this version. This should only be
// called on valid versions, see ParsedQuicVersionIsValid. Assuming the
// version is valid, IsKnown returns whether the version is not
@@ -331,6 +385,10 @@ struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
// encoding transport parameter types and lengths.
bool HasVarIntTransportParams() const;
+ // Returns true if this version uses transport parameters to authenticate all
+ // the connection IDs used during the handshake.
+ bool AuthenticatesHandshakeConnectionIds() const;
+
// Returns whether this version uses PROTOCOL_TLS1_3.
bool UsesTls() const;
@@ -342,6 +400,10 @@ QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();
+// Outer version used when encapsulating other packets using the Legacy Version
+// Encapsulation feature.
+QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();
+
QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const ParsedQuicVersion& version);
@@ -365,16 +427,13 @@ constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
}
-constexpr std::array<ParsedQuicVersion, 8> SupportedVersions() {
+constexpr std::array<ParsedQuicVersion, 9> SupportedVersions() {
return {
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27),
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25),
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
+ ParsedQuicVersion::Draft29(), ParsedQuicVersion::Draft27(),
+ ParsedQuicVersion::Draft25(), ParsedQuicVersion::T050(),
+ ParsedQuicVersion::Q050(), ParsedQuicVersion::Q049(),
+ ParsedQuicVersion::Q048(), ParsedQuicVersion::Q046(),
+ ParsedQuicVersion::Q043(),
};
}
@@ -604,8 +663,14 @@ QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
// correct flags.
QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();
-// Enables the flags required to support this version of QUIC.
-QUIC_EXPORT_PRIVATE void QuicEnableVersion(ParsedQuicVersion parsed_version);
+// Configures the flags required to enable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);
+
+// Configures the flags required to disable support for this version of QUIC.
+QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);
+
+// Returns whether support for this version of QUIC is currently enabled.
+QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);
} // namespace quic
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 3a07221ab94..c7ebb82a4ed 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
@@ -84,10 +84,8 @@ TEST_F(QuicVersionsTest, KnownAndValid) {
}
TEST_F(QuicVersionsTest, Features) {
- ParsedQuicVersion parsed_version_q043 =
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
- ParsedQuicVersion parsed_version_draft_27 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27);
+ ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
+ ParsedQuicVersion parsed_version_draft_27 = ParsedQuicVersion::Draft27();
EXPECT_TRUE(parsed_version_q043.IsKnown());
EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
@@ -208,35 +206,28 @@ TEST_F(QuicVersionsTest, QuicVersionLabelToHandshakeProtocol) {
}
TEST_F(QuicVersionsTest, ParseQuicVersionLabel) {
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
+ EXPECT_EQ(ParsedQuicVersion::Q043(),
ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
+ EXPECT_EQ(ParsedQuicVersion::Q046(),
ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48),
+ EXPECT_EQ(ParsedQuicVersion::Q048(),
ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '8')));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
+ EXPECT_EQ(ParsedQuicVersion::Q050(),
ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
+ EXPECT_EQ(ParsedQuicVersion::T050(),
ParseQuicVersionLabel(MakeVersionLabel('T', '0', '5', '0')));
}
TEST_F(QuicVersionsTest, ParseQuicVersionString) {
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
- ParseQuicVersionString("Q043"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
+ EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
+ EXPECT_EQ(ParsedQuicVersion::Q046(),
ParseQuicVersionString("QUIC_VERSION_46"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
- ParseQuicVersionString("46"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
- ParseQuicVersionString("Q046"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48),
- ParseQuicVersionString("Q048"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
- ParseQuicVersionString("Q050"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
- ParseQuicVersionString("50"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
- ParseQuicVersionString("h3-Q050"));
+ EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
+ EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
+ EXPECT_EQ(ParsedQuicVersion::Q048(), ParseQuicVersionString("Q048"));
+ EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
+ EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
+ EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
@@ -244,18 +235,14 @@ TEST_F(QuicVersionsTest, ParseQuicVersionString) {
EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
- ParseQuicVersionString("T050"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
- ParseQuicVersionString("h3-T050"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27),
- ParseQuicVersionString("ff00001b"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27),
- ParseQuicVersionString("h3-27"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25),
- ParseQuicVersionString("ff000019"));
- EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25),
- ParseQuicVersionString("h3-25"));
+ EXPECT_EQ(ParsedQuicVersion::T050(), ParseQuicVersionString("T050"));
+ EXPECT_EQ(ParsedQuicVersion::T050(), ParseQuicVersionString("h3-T050"));
+ EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
+ EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
+ EXPECT_EQ(ParsedQuicVersion::Draft27(), ParseQuicVersionString("ff00001b"));
+ EXPECT_EQ(ParsedQuicVersion::Draft27(), ParseQuicVersionString("h3-27"));
+ EXPECT_EQ(ParsedQuicVersion::Draft25(), ParseQuicVersionString("ff000019"));
+ EXPECT_EQ(ParsedQuicVersion::Draft25(), ParseQuicVersionString("h3-25"));
}
TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
@@ -266,6 +253,7 @@ TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
QUIC_VERSION_IETF_DRAFT_25);
ParsedQuicVersion version_draft_27(PROTOCOL_TLS1_3,
QUIC_VERSION_IETF_DRAFT_27);
+ ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
@@ -286,6 +274,8 @@ TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
ElementsAre(version_draft_25, version_draft_27));
EXPECT_THAT(ParseQuicVersionVectorString("h3-27,h3-25"),
ElementsAre(version_draft_27, version_draft_25));
+ EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-27"),
+ ElementsAre(version_draft_29, version_draft_27));
EXPECT_THAT(ParseQuicVersionVectorString("h3-27,50"),
ElementsAre(version_draft_27, version_q050));
@@ -332,22 +322,17 @@ TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
TEST_F(QuicVersionsTest, CreateQuicVersionLabel) {
EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '3'),
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43)));
+ CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '6'),
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46)));
+ CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '8'),
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48)));
+ CreateQuicVersionLabel(ParsedQuicVersion::Q048()));
EXPECT_EQ(MakeVersionLabel('Q', '0', '5', '0'),
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50)));
+ CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
// Test a TLS version:
EXPECT_EQ(MakeVersionLabel('T', '0', '5', '0'),
- CreateQuicVersionLabel(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50)));
+ CreateQuicVersionLabel(ParsedQuicVersion::T050()));
// Make sure the negotiation reserved version is in the IETF reserved space.
EXPECT_EQ(MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a) & 0x0f0f0f0f,
@@ -442,97 +427,29 @@ TEST_F(QuicVersionsTest, ParsedQuicVersionToString) {
}
TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
- static_assert(SupportedVersions().size() == 8u,
- "Supported versions out of sync");
- SetQuicReloadableFlag(quic_enable_version_draft_27, true);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
- SetQuicReloadableFlag(quic_enable_version_t050_v2, true);
- SetQuicReloadableFlag(quic_disable_version_q050, false);
- SetQuicReloadableFlag(quic_disable_version_q049, false);
- SetQuicReloadableFlag(quic_disable_version_q048, false);
- SetQuicReloadableFlag(quic_disable_version_q046, false);
- SetQuicReloadableFlag(quic_disable_version_q043, false);
-
- ParsedQuicVersionVector expected_parsed_versions;
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43));
-
- ASSERT_EQ(expected_parsed_versions,
- FilterSupportedVersions(AllSupportedVersions()));
- ASSERT_EQ(expected_parsed_versions, AllSupportedVersions());
-}
-
-TEST_F(QuicVersionsTest, FilterSupportedVersionsNo99) {
- static_assert(SupportedVersions().size() == 8u,
- "Supported versions out of sync");
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
- SetQuicReloadableFlag(quic_enable_version_t050_v2, true);
- SetQuicReloadableFlag(quic_disable_version_q050, false);
- SetQuicReloadableFlag(quic_disable_version_q049, false);
- SetQuicReloadableFlag(quic_disable_version_q048, false);
- SetQuicReloadableFlag(quic_disable_version_q046, false);
- SetQuicReloadableFlag(quic_disable_version_q043, false);
-
+ for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+ QuicEnableVersion(version);
+ }
ParsedQuicVersionVector expected_parsed_versions;
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43));
-
- ASSERT_EQ(expected_parsed_versions,
+ for (const ParsedQuicVersion& version : SupportedVersions()) {
+ expected_parsed_versions.push_back(version);
+ }
+ EXPECT_EQ(expected_parsed_versions,
FilterSupportedVersions(AllSupportedVersions()));
+ EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
}
-TEST_F(QuicVersionsTest, FilterSupportedVersionsNoFlags) {
- static_assert(SupportedVersions().size() == 8u,
- "Supported versions out of sync");
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
- SetQuicReloadableFlag(quic_enable_version_t050_v2, false);
- SetQuicReloadableFlag(quic_disable_version_q050, false);
- SetQuicReloadableFlag(quic_disable_version_q049, false);
- SetQuicReloadableFlag(quic_disable_version_q048, false);
- SetQuicReloadableFlag(quic_disable_version_q046, false);
- SetQuicReloadableFlag(quic_disable_version_q043, false);
-
+TEST_F(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
+ for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+ QuicEnableVersion(version);
+ }
+ QuicDisableVersion(AllSupportedVersions().front());
ParsedQuicVersionVector expected_parsed_versions;
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46));
- expected_parsed_versions.push_back(
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43));
-
- ASSERT_EQ(expected_parsed_versions,
+ for (const ParsedQuicVersion& version : SupportedVersions()) {
+ expected_parsed_versions.push_back(version);
+ }
+ expected_parsed_versions.erase(expected_parsed_versions.begin());
+ EXPECT_EQ(expected_parsed_versions,
FilterSupportedVersions(AllSupportedVersions()));
}
@@ -540,10 +457,11 @@ TEST_F(QuicVersionsTest, LookUpVersionByIndex) {
QuicTransportVersionVector all_versions = {QUIC_VERSION_43};
int version_count = all_versions.size();
for (int i = -5; i <= version_count + 1; ++i) {
+ QuicTransportVersionVector index = VersionOfIndex(all_versions, i);
if (i >= 0 && i < version_count) {
- EXPECT_EQ(all_versions[i], VersionOfIndex(all_versions, i)[0]);
+ EXPECT_EQ(all_versions[i], index[0]);
} else {
- EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, VersionOfIndex(all_versions, i)[0]);
+ EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, index[0]);
}
}
}
@@ -552,11 +470,11 @@ TEST_F(QuicVersionsTest, LookUpParsedVersionByIndex) {
ParsedQuicVersionVector all_versions = AllSupportedVersions();
int version_count = all_versions.size();
for (int i = -5; i <= version_count + 1; ++i) {
+ ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
if (i >= 0 && i < version_count) {
- EXPECT_EQ(all_versions[i], ParsedVersionOfIndex(all_versions, i)[0]);
+ EXPECT_EQ(all_versions[i], index[0]);
} else {
- EXPECT_EQ(UnsupportedQuicVersion(),
- ParsedVersionOfIndex(all_versions, i)[0]);
+ EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
}
}
}
@@ -575,7 +493,7 @@ TEST_F(QuicVersionsTest, ParsedVersionsToTransportVersions) {
// yet a typo was made in doing the #defines and it was caught
// only in some test far removed from here... Better safe than sorry.
TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
- static_assert(SupportedTransportVersions().size() == 7u,
+ static_assert(SupportedTransportVersions().size() == 8u,
"Supported versions out of sync");
EXPECT_EQ(QUIC_VERSION_43, 43);
EXPECT_EQ(QUIC_VERSION_46, 46);
@@ -584,23 +502,18 @@ TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
EXPECT_EQ(QUIC_VERSION_50, 50);
EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_25, 70);
EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_27, 71);
+ EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
}
TEST_F(QuicVersionsTest, AlpnForVersion) {
- static_assert(SupportedVersions().size() == 8u,
+ static_assert(SupportedVersions().size() == 9u,
"Supported versions out of sync");
- ParsedQuicVersion parsed_version_q048 =
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
- ParsedQuicVersion parsed_version_q049 =
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49);
- ParsedQuicVersion parsed_version_q050 =
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
- ParsedQuicVersion parsed_version_t050 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50);
- ParsedQuicVersion parsed_version_draft_25 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
- ParsedQuicVersion parsed_version_draft_27 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27);
+ ParsedQuicVersion parsed_version_q048 = ParsedQuicVersion::Q048();
+ ParsedQuicVersion parsed_version_q049 = ParsedQuicVersion::Q049();
+ ParsedQuicVersion parsed_version_q050 = ParsedQuicVersion::Q050();
+ ParsedQuicVersion parsed_version_t050 = ParsedQuicVersion::T050();
+ ParsedQuicVersion parsed_version_draft_25 = ParsedQuicVersion::Draft25();
+ ParsedQuicVersion parsed_version_draft_27 = ParsedQuicVersion::Draft27();
EXPECT_EQ("h3-Q048", AlpnForVersion(parsed_version_q048));
EXPECT_EQ("h3-Q049", AlpnForVersion(parsed_version_q049));
@@ -608,54 +521,16 @@ TEST_F(QuicVersionsTest, AlpnForVersion) {
EXPECT_EQ("h3-T050", AlpnForVersion(parsed_version_t050));
EXPECT_EQ("h3-25", AlpnForVersion(parsed_version_draft_25));
EXPECT_EQ("h3-27", AlpnForVersion(parsed_version_draft_27));
+ EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
}
-TEST_F(QuicVersionsTest, QuicEnableVersion) {
- static_assert(SupportedVersions().size() == 8u,
- "Supported versions out of sync");
- ParsedQuicVersion parsed_version_draft_27 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27);
- ParsedQuicVersion parsed_version_draft_25 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
- ParsedQuicVersion parsed_version_q050 =
- ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
- ParsedQuicVersion parsed_version_t050 =
- ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50);
-
- {
- QuicFlagSaver flag_saver;
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
- QuicEnableVersion(parsed_version_draft_27);
- EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_27));
- }
-
- {
- QuicFlagSaver flag_saver;
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
- QuicEnableVersion(parsed_version_draft_25);
- EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_25_v3));
- }
-
- {
- QuicFlagSaver flag_saver;
- SetQuicReloadableFlag(quic_disable_version_q050, true);
- QuicEnableVersion(parsed_version_q050);
- EXPECT_FALSE(GetQuicReloadableFlag(quic_disable_version_q050));
- }
-
- {
- QuicFlagSaver flag_saver;
- SetQuicReloadableFlag(quic_enable_version_t050_v2, false);
- QuicEnableVersion(parsed_version_t050);
- EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_t050_v2));
- }
-
- {
+TEST_F(QuicVersionsTest, QuicVersionEnabling) {
+ for (const ParsedQuicVersion& version : AllSupportedVersions()) {
QuicFlagSaver flag_saver;
- for (const ParsedQuicVersion& version : SupportedVersions()) {
- QuicEnableVersion(version);
- }
- ASSERT_EQ(AllSupportedVersions(), CurrentSupportedVersions());
+ QuicDisableVersion(version);
+ EXPECT_FALSE(QuicVersionIsEnabled(version));
+ QuicEnableVersion(version);
+ EXPECT_TRUE(QuicVersionIsEnabled(version));
}
}
@@ -676,7 +551,8 @@ TEST_F(QuicVersionsTest, SupportedVersionsHasCorrectList) {
SupportedTransportVersions()) {
SCOPED_TRACE(index);
if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
- EXPECT_EQ(SupportedVersions()[index],
+ ParsedQuicVersion version = SupportedVersions()[index];
+ EXPECT_EQ(version,
ParsedQuicVersion(handshake_protocol, transport_version));
index++;
}
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 1762566d70a..b50d2e236ab 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
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
#include "third_party/boringssl/src/include/openssl/ssl.h"
+#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_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
@@ -151,6 +152,9 @@ class QUIC_NO_EXPORT TlsChloExtractor
bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
return true;
}
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override {
+ return true;
+ }
void OnPacketComplete() override {}
bool IsValidStatelessResetToken(QuicUint128 /*token*/) const override {
return true;
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 ba57ad02bb9..955e58c0ee6 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
@@ -48,8 +48,9 @@ class TlsChloExtractorTest : public QuicTestWithParam<ParsedQuicVersion> {
void ValidateChloDetails() {
EXPECT_TRUE(tls_chlo_extractor_.HasParsedFullChlo());
- ASSERT_EQ(tls_chlo_extractor_.alpns().size(), 1u);
- EXPECT_EQ(tls_chlo_extractor_.alpns()[0], AlpnForVersion(version_));
+ std::vector<std::string> alpns = tls_chlo_extractor_.alpns();
+ ASSERT_EQ(alpns.size(), 1u);
+ EXPECT_EQ(alpns[0], AlpnForVersion(version_));
EXPECT_EQ(tls_chlo_extractor_.server_name(), TestHostname());
}
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 d4e8ed023b1..23a74e4fc28 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
@@ -12,6 +12,7 @@
#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/quic_session.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/quic/platform/api/quic_hostname_utils.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
@@ -67,6 +68,7 @@ TlsClientHandshaker::TlsClientHandshaker(
pre_shared_key_(crypto_config->pre_shared_key()),
crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
has_application_state_(has_application_state),
+ attempting_zero_rtt_(crypto_config->early_data_enabled_for_tls()),
tls_connection_(crypto_config->ssl_ctx(), this) {}
TlsClientHandshaker::~TlsClientHandshaker() {
@@ -114,17 +116,16 @@ bool TlsClientHandshaker::CryptoConnect() {
}
// Set a session to resume, if there is one.
+ std::unique_ptr<QuicResumptionState> cached_state;
if (session_cache_) {
- std::unique_ptr<QuicResumptionState> cached_state =
- session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl()));
- if (cached_state) {
- SSL_set_session(ssl(), cached_state->tls_session.get());
- if (GetQuicReloadableFlag(quic_enable_zero_rtt_for_tls) &&
- VersionHasIetfQuicFrames(session()->transport_version()) &&
- SSL_SESSION_early_data_capable(cached_state->tls_session.get())) {
- if (!PrepareZeroRttConfig(cached_state.get())) {
- return false;
- }
+ cached_state = session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl()));
+ }
+ if (cached_state) {
+ SSL_set_session(ssl(), cached_state->tls_session.get());
+ if (attempting_zero_rtt_ &&
+ SSL_SESSION_early_data_capable(cached_state->tls_session.get())) {
+ if (!PrepareZeroRttConfig(cached_state.get())) {
+ return false;
}
}
}
@@ -137,8 +138,8 @@ bool TlsClientHandshaker::CryptoConnect() {
bool TlsClientHandshaker::PrepareZeroRttConfig(
QuicResumptionState* cached_state) {
std::string error_details;
- if (session()->config()->ProcessTransportParameters(
- *(cached_state->transport_params), SERVER,
+ if (handshaker_delegate()->ProcessTransportParameters(
+ *(cached_state->transport_params),
/*is_resumption = */ true, &error_details) != QUIC_NO_ERROR) {
QUIC_BUG << "Unable to parse cached transport parameters.";
CloseConnection(QUIC_HANDSHAKE_FAILED,
@@ -148,7 +149,7 @@ bool TlsClientHandshaker::PrepareZeroRttConfig(
session()->OnConfigNegotiated();
if (has_application_state_) {
- if (!session()->SetApplicationState(cached_state->application_state)) {
+ if (!session()->ResumeApplicationState(cached_state->application_state)) {
QUIC_BUG << "Unable to parse cached application state.";
CloseConnection(QUIC_HANDSHAKE_FAILED,
"Client failed to parse cached application state.");
@@ -204,7 +205,7 @@ bool TlsClientHandshaker::SetTransportParameters() {
params.version =
CreateQuicVersionLabel(session()->supported_versions().front());
- if (!session()->config()->FillTransportParameters(&params)) {
+ if (!handshaker_delegate()->FillTransportParameters(&params)) {
return false;
}
if (GetQuicRestartFlag(quic_google_transport_param_send_new)) {
@@ -216,6 +217,9 @@ bool TlsClientHandshaker::SetTransportParameters() {
params.google_quic_params->SetStringPiece(kUAID, user_agent_id_);
}
+ // Notify QuicConnectionDebugVisitor.
+ session()->connection()->OnTransportParametersSent(params);
+
std::vector<uint8_t> param_bytes;
return SerializeTransportParameters(session()->connection()->version(),
params, &param_bytes) &&
@@ -244,6 +248,10 @@ bool TlsClientHandshaker::ProcessTransportParameters(
return false;
}
+ // Notify QuicConnectionDebugVisitor.
+ session()->connection()->OnTransportParametersReceived(
+ *received_transport_params_);
+
// When interoperating with non-Google implementations that do not send
// the version extension, set it to what we expect.
if (received_transport_params_->version == 0) {
@@ -264,8 +272,8 @@ bool TlsClientHandshaker::ProcessTransportParameters(
received_transport_params_->supported_versions,
session()->connection()->server_supported_versions(),
error_details) != QUIC_NO_ERROR ||
- session()->config()->ProcessTransportParameters(
- *received_transport_params_, SERVER, /* is_resumption = */ false,
+ handshaker_delegate()->ProcessTransportParameters(
+ *received_transport_params_, /* is_resumption = */ false,
error_details) != QUIC_NO_ERROR) {
DCHECK(!error_details->empty());
return false;
@@ -378,9 +386,12 @@ void TlsClientHandshaker::SetWriteSecret(
if (state_ == STATE_CONNECTION_CLOSED) {
return;
}
- if (level == ENCRYPTION_FORWARD_SECURE) {
+ if (level == ENCRYPTION_FORWARD_SECURE || level == ENCRYPTION_ZERO_RTT) {
encryption_established_ = true;
}
+ if (level == ENCRYPTION_FORWARD_SECURE) {
+ handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_ZERO_RTT);
+ }
TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
}
@@ -421,6 +432,10 @@ void TlsClientHandshaker::AdvanceHandshake() {
}
int ssl_error = SSL_get_error(ssl(), rv);
bool should_close = true;
+ if (ssl_error == SSL_ERROR_EARLY_DATA_REJECTED) {
+ HandleZeroRttReject();
+ return;
+ }
switch (state_) {
// TODO(b/153726130): handle the case where the server rejects early data.
case STATE_HANDSHAKE_RUNNING:
@@ -449,6 +464,15 @@ void TlsClientHandshaker::CloseConnection(QuicErrorCode error,
}
void TlsClientHandshaker::FinishHandshake() {
+ if (SSL_in_early_data(ssl())) {
+ // SSL_do_handshake returns after sending the ClientHello if the session is
+ // 0-RTT-capable, which means that FinishHandshake will get called twice -
+ // the first time after sending the ClientHello, and the second time after
+ // the handshake is complete. If we're in the first time FinishHandshake is
+ // called, we can't do any end-of-handshake processing, so we return early
+ // from this function.
+ return;
+ }
QUIC_LOG(INFO) << "Client: handshake finished";
state_ = STATE_HANDSHAKE_COMPLETE;
// Fill crypto_negotiated_params_:
@@ -498,6 +522,17 @@ void TlsClientHandshaker::FinishHandshake() {
handshaker_delegate()->OnOneRttKeysAvailable();
}
+void TlsClientHandshaker::HandleZeroRttReject() {
+ QUIC_LOG(INFO) << "0-RTT handshake attempted but was rejected by the server";
+ DCHECK(session_cache_);
+ // Disable encrytion to block outgoing data until 1-RTT keys are available.
+ encryption_established_ = false;
+ handshaker_delegate()->OnZeroRttRejected();
+ SSL_reset_early_data_reject(ssl());
+ session_cache_->ClearEarlyData(server_id_);
+ AdvanceHandshake();
+}
+
enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) {
if (verify_result_ != ssl_verify_retry ||
state_ == STATE_CERT_VERIFY_PENDING) {
@@ -584,7 +619,7 @@ void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
TlsHandshaker::WriteMessage(level, data);
}
-void TlsClientHandshaker::OnApplicationState(
+void TlsClientHandshaker::SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) {
DCHECK_EQ(STATE_HANDSHAKE_COMPLETE, state_);
received_application_state_ = std::move(application_state);
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 cc601219dfa..573c055c48c 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
@@ -71,7 +71,7 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
void WriteMessage(EncryptionLevel level,
quiche::QuicheStringPiece data) override;
- void OnApplicationState(
+ void SetServerApplicationStateForResumption(
std::unique_ptr<ApplicationState> application_state) override;
void AllowEmptyAlpnForTests() { allow_empty_alpn_for_tests_ = true; }
@@ -124,6 +124,7 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
bool SetTransportParameters();
bool ProcessTransportParameters(std::string* error_details);
void FinishHandshake();
+ void HandleZeroRttReject();
// Called when server completes handshake (i.e., either handshake done is
// received or 1-RTT packet gets acknowledged).
@@ -175,6 +176,7 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
bool allow_invalid_sni_for_tests_ = false;
const bool has_application_state_;
+ bool attempting_zero_rtt_;
TlsClientConnection tls_connection_;
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 68c413fbb63..47989a75f5e 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
@@ -8,13 +8,18 @@
#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"
#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_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"
#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/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_framer_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/quic/test_tools/simple_session_cache.h"
@@ -167,13 +172,13 @@ class TlsClientHandshakerTest : public QuicTestWithParam<ParsedQuicVersion> {
TlsClientHandshakerTest()
: supported_versions_({GetParam()}),
server_id_(kServerHostname, kServerPort, false),
- crypto_config_(std::make_unique<QuicCryptoClientConfig>(
- std::make_unique<TestProofVerifier>(),
- std::make_unique<test::SimpleSessionCache>())),
server_compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
SetQuicReloadableFlag(quic_enable_tls_resumption, true);
SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
+ crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+ std::make_unique<TestProofVerifier>(),
+ std::make_unique<test::SimpleSessionCache>());
server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting();
CreateConnection();
}
@@ -342,6 +347,72 @@ TEST_P(TlsClientHandshakerTest, Resumption) {
EXPECT_TRUE(stream()->IsResumption());
}
+TEST_P(TlsClientHandshakerTest, ZeroRttResumption) {
+ // Finish establishing the first connection:
+ CompleteCryptoHandshake();
+
+ EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->one_rtt_keys_available());
+ EXPECT_FALSE(stream()->IsResumption());
+
+ // Create a second connection
+ CreateConnection();
+ CompleteCryptoHandshake();
+
+ // TODO(b/152551499): Add a test that checks we have keys after calling
+ // stream()->CryptoConnect().
+ EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->one_rtt_keys_available());
+ EXPECT_TRUE(stream()->IsResumption());
+ EXPECT_TRUE(stream()->EarlyDataAccepted());
+}
+
+// TODO(b/152551499): Also test resumption getting rejected.
+TEST_P(TlsClientHandshakerTest, ZeroRttRejection) {
+ // Finish establishing the first connection:
+ CompleteCryptoHandshake();
+
+ EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->one_rtt_keys_available());
+ EXPECT_FALSE(stream()->IsResumption());
+
+ // Create a second connection, but disable 0-RTT on the server.
+ SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
+ CreateConnection();
+
+ // 4 packets will be sent in this connection: initial handshake packet, 0-RTT
+ // packet containing SETTINGS, handshake packet upon 0-RTT rejection, 0-RTT
+ // packet retransmission.
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
+ if (VersionUsesHttp3(session_->transport_version())) {
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION));
+ }
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_HANDSHAKE, NOT_RETRANSMISSION));
+ if (VersionUsesHttp3(session_->transport_version())) {
+ // TODO(b/158027651): change transmission type to
+ // ALL_ZERO_RTT_RETRANSMISSION.
+ EXPECT_CALL(*connection_,
+ OnPacketSent(ENCRYPTION_FORWARD_SECURE, LOSS_RETRANSMISSION));
+ }
+
+ CompleteCryptoHandshake();
+
+ QuicFramer* framer = QuicConnectionPeer::GetFramer(connection_);
+ EXPECT_EQ(nullptr, QuicFramerPeer::GetEncrypter(framer, ENCRYPTION_ZERO_RTT));
+
+ EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->one_rtt_keys_available());
+ EXPECT_TRUE(stream()->IsResumption());
+ EXPECT_FALSE(stream()->EarlyDataAccepted());
+}
+
TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
// Reconfigure client to sent an empty server hostname. The crypto config also
// needs to be recreated to use a FakeProofVerifier since the server's cert
@@ -423,7 +494,6 @@ TEST_P(TlsClientHandshakerTest, BadTransportParams) {
if (!connection_->version().UsesHttp3()) {
return;
}
- SetQuicReloadableFlag(quic_notify_handshaker_on_connection_close, true);
// Finish establishing the first connection:
CompleteCryptoHandshake();
@@ -438,7 +508,8 @@ TEST_P(TlsClientHandshakerTest, BadTransportParams) {
config.SetMaxBidirectionalStreamsToSend(
config.GetMaxBidirectionalStreamsToSend() - 1);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAMS_ERROR, _, _))
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED, _, _))
.WillOnce(testing::Invoke(connection_,
&MockQuicConnection::ReallyCloseConnection));
// Close connection will be called again in the handshaker, but this will be
diff --git a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker_test.cc b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker_test.cc
index 5a2bd6400aa..caf9a9c6b1b 100644
--- a/chromium/net/third_party/quiche/src/quic/core/tls_handshaker_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/tls_handshaker_test.cc
@@ -192,6 +192,8 @@ class TestQuicCryptoStream : public QuicCryptoStream {
HandshakeState GetHandshakeState() const override {
return handshaker()->GetHandshakeState();
}
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
const std::vector<std::pair<std::string, EncryptionLevel>>& pending_writes() {
return pending_writes_;
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 5bd5b3d642d..69b523723d8 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
@@ -13,7 +13,9 @@
#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.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 {
@@ -123,8 +125,15 @@ void TlsServerHandshaker::SendServerConfigUpdate(
}
bool TlsServerHandshaker::IsZeroRtt() const {
- // TODO(nharper): Support 0-RTT with TLS 1.3 in QUIC.
- return false;
+ return SSL_early_data_accepted(ssl());
+}
+
+bool TlsServerHandshaker::IsResumption() const {
+ return SSL_session_reused(ssl());
+}
+
+bool TlsServerHandshaker::ResumptionAttempted() const {
+ return ticket_received_;
}
int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
@@ -137,11 +146,6 @@ TlsServerHandshaker::PreviousCachedNetworkParams() const {
return nullptr;
}
-bool TlsServerHandshaker::ZeroRttAttempted() const {
- // TODO(nharper): Support 0-RTT with TLS 1.3 in QUIC.
- return false;
-}
-
void TlsServerHandshaker::SetPreviousCachedNetworkParams(
CachedNetworkParameters /*cached_network_params*/) {}
@@ -194,6 +198,11 @@ HandshakeState TlsServerHandshaker::GetHandshakeState() const {
return HANDSHAKE_START;
}
+void TlsServerHandshaker::SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> state) {
+ application_state_ = std::move(state);
+}
+
size_t TlsServerHandshaker::BufferSizeLimitForLevel(
EncryptionLevel level) const {
return TlsHandshaker::BufferSizeLimitForLevel(level);
@@ -201,19 +210,6 @@ size_t TlsServerHandshaker::BufferSizeLimitForLevel(
void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
-bool TlsServerHandshaker::SetReadSecret(
- EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) {
- if (level != ENCRYPTION_FORWARD_SECURE || one_rtt_keys_available_) {
- return TlsHandshaker::SetReadSecret(level, cipher, read_secret);
- }
- // Delay setting read secret for ENCRYPTION_FORWARD_SECURE until handshake
- // completes.
- app_data_read_secret_ = read_secret;
- return true;
-}
-
void TlsServerHandshaker::AdvanceHandshake() {
if (state_ == STATE_CONNECTION_CLOSED) {
QUIC_LOG(INFO) << "TlsServerHandshaker received handshake message after "
@@ -248,8 +244,8 @@ void TlsServerHandshaker::AdvanceHandshake() {
should_close = true;
}
if (should_close && state_ != STATE_CONNECTION_CLOSED) {
- QUIC_LOG(WARNING) << "SSL_do_handshake failed; SSL_get_error returns "
- << ssl_error << ", state_ = " << state_;
+ 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");
@@ -284,6 +280,9 @@ bool TlsServerHandshaker::ProcessTransportParameters(
return false;
}
+ // Notify QuicConnectionDebugVisitor.
+ session()->connection()->OnTransportParametersReceived(client_params);
+
// When interoperating with non-Google implementations that do not send
// the version extension, set it to what we expect.
if (client_params.version == 0) {
@@ -294,12 +293,26 @@ bool TlsServerHandshaker::ProcessTransportParameters(
if (CryptoUtils::ValidateClientHelloVersion(
client_params.version, session()->connection()->version(),
session()->supported_versions(), error_details) != QUIC_NO_ERROR ||
- session()->config()->ProcessTransportParameters(
- client_params, CLIENT, /* is_resumption = */ false, error_details) !=
+ handshaker_delegate()->ProcessTransportParameters(
+ client_params, /* is_resumption = */ false, error_details) !=
QUIC_NO_ERROR) {
return false;
}
ProcessAdditionalTransportParameters(client_params);
+ if (GetQuicReloadableFlag(quic_save_user_agent_in_quic_session) &&
+ !session()->user_agent_id().has_value()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_save_user_agent_in_quic_session, 2, 3);
+
+ if (client_params.user_agent_id.has_value()) {
+ session()->SetUserAgentId(client_params.user_agent_id.value());
+ } else if (client_params.google_quic_params) {
+ quiche::QuicheStringPiece user_agent_id;
+ client_params.google_quic_params->GetStringPiece(kUAID, &user_agent_id);
+ if (!user_agent_id.empty()) {
+ session()->SetUserAgentId(user_agent_id.data());
+ }
+ }
+ }
return true;
}
@@ -312,12 +325,13 @@ bool TlsServerHandshaker::SetTransportParameters() {
server_params.version =
CreateQuicVersionLabel(session()->connection()->version());
- if (!session()->config()->FillTransportParameters(&server_params)) {
+ if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
return false;
}
- // TODO(nharper): Provide an actual value for the stateless reset token.
- server_params.stateless_reset_token.resize(16);
+ // Notify QuicConnectionDebugVisitor.
+ session()->connection()->OnTransportParametersSent(server_params);
+
std::vector<uint8_t> server_params_bytes;
if (!SerializeTransportParameters(session()->connection()->version(),
server_params, &server_params_bytes) ||
@@ -325,6 +339,17 @@ bool TlsServerHandshaker::SetTransportParameters() {
server_params_bytes.size()) != 1) {
return false;
}
+ if (application_state_) {
+ std::vector<uint8_t> early_data_context;
+ if (!SerializeTransportParametersForTicket(
+ server_params, *application_state_, &early_data_context)) {
+ QUIC_BUG << "Failed to serialize Transport Parameters for ticket.";
+ return false;
+ }
+ SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
+ early_data_context.size());
+ application_state_.reset(nullptr);
+ }
return true;
}
@@ -332,8 +357,7 @@ void TlsServerHandshaker::SetWriteSecret(
EncryptionLevel level,
const SSL_CIPHER* cipher,
const std::vector<uint8_t>& write_secret) {
- if (GetQuicReloadableFlag(quic_notify_handshaker_on_connection_close) &&
- state_ == STATE_CONNECTION_CLOSED) {
+ if (state_ == STATE_CONNECTION_CLOSED) {
return;
}
if (level == ENCRYPTION_FORWARD_SECURE) {
@@ -349,6 +373,16 @@ void TlsServerHandshaker::SetWriteSecret(
}
void TlsServerHandshaker::FinishHandshake() {
+ if (SSL_in_early_data(ssl())) {
+ // If the server accepts early data, SSL_do_handshake returns success twice:
+ // once after processing the ClientHello and sending the server's first
+ // flight, and then again after the handshake is complete. This results in
+ // FinishHandshake getting called twice. On the first call to
+ // FinishHandshake, we don't have any confirmation that the client is live,
+ // so all end of handshake processing is deferred until the handshake is
+ // actually complete.
+ return;
+ }
if (!valid_alpn_received_) {
QUIC_DLOG(ERROR)
<< "Server: handshake finished without receiving a known ALPN";
@@ -363,21 +397,10 @@ void TlsServerHandshaker::FinishHandshake() {
state_ = STATE_HANDSHAKE_COMPLETE;
one_rtt_keys_available_ = true;
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
-
- if (!app_data_read_secret_.empty()) {
- if (!SetReadSecret(ENCRYPTION_FORWARD_SECURE, cipher,
- app_data_read_secret_)) {
- QUIC_BUG << "Failed to set forward secure read key.";
- CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to set app data read key");
- return;
- }
- app_data_read_secret_.clear();
- }
-
handshaker_delegate()->OnOneRttKeysAvailable();
handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
+ handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_ZERO_RTT);
}
ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
@@ -446,6 +469,7 @@ ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
DCHECK(proof_source_->GetTicketCrypter());
if (!ticket_decryption_callback_) {
+ ticket_received_ = true;
ticket_decryption_callback_ = new DecryptCallback(this);
proof_source_->GetTicketCrypter()->Decrypt(
in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
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 c62dbbbe47c..13b734e3a78 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
@@ -40,9 +40,10 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) override;
bool IsZeroRtt() const override;
+ bool IsResumption() const override;
+ bool ResumptionAttempted() const override;
int NumServerConfigUpdateMessagesSent() const override;
const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
- bool ZeroRttAttempted() const override;
void SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) override;
void OnPacketDecrypted(EncryptionLevel level) override;
@@ -60,6 +61,8 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
const override;
CryptoMessageParser* crypto_message_parser() override;
HandshakeState GetHandshakeState() const override;
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> state) override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
void SetWriteSecret(EncryptionLevel level,
const SSL_CIPHER* cipher,
@@ -81,13 +84,6 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
virtual void ProcessAdditionalTransportParameters(
const TransportParameters& /*params*/) {}
- // Override of TlsHandshaker::SetReadSecret so that setting the read secret
- // for ENCRYPTION_FORWARD_SECURE can be delayed until the handshake is
- // complete.
- bool SetReadSecret(EncryptionLevel level,
- const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) override;
-
// Called when a new message is received on the crypto stream and is available
// for the TLS stack to read.
void AdvanceHandshake() override;
@@ -181,19 +177,21 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
// |decrypted_session_ticket_| contains the decrypted session ticket after the
// callback has run but before it is passed to BoringSSL.
std::vector<uint8_t> decrypted_session_ticket_;
+ // |ticket_received_| tracks whether we received a resumption ticket from the
+ // client. It does not matter whether we were able to decrypt said ticket or
+ // if we actually resumed a session with it - the presence of this ticket
+ // indicates that the client attempted a resumption.
+ bool ticket_received_ = false;
std::string hostname_;
std::string cert_verify_sig_;
std::unique_ptr<ProofSource::Details> proof_source_details_;
+ std::unique_ptr<ApplicationState> application_state_;
+
// Pre-shared key used during the handshake.
std::string pre_shared_key_;
- // Used to hold the ENCRYPTION_FORWARD_SECURE read secret until the handshake
- // is complete. This is temporary until
- // https://bugs.chromium.org/p/boringssl/issues/detail?id=303 is resolved.
- std::vector<uint8_t> app_data_read_secret_;
-
bool encryption_established_ = false;
bool one_rtt_keys_available_ = false;
bool valid_alpn_received_ = false;
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 a71338c5f5b..70550fcb21d 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
@@ -47,9 +47,12 @@ class TlsServerHandshakerTest : public QuicTest {
TlsServerHandshakerTest()
: server_compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
- server_id_(kServerHostname, kServerPort, false),
- client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
- std::make_unique<test::SimpleSessionCache>()) {
+ server_id_(kServerHostname, kServerPort, false) {
+ SetQuicReloadableFlag(quic_enable_tls_resumption, true);
+ SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true);
+ client_crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+ crypto_test_utils::ProofVerifierForTesting(),
+ std::make_unique<test::SimpleSessionCache>());
InitializeServerConfig();
InitializeServer();
InitializeFakeClient();
@@ -65,7 +68,6 @@ class TlsServerHandshakerTest : public QuicTest {
}
void InitializeServerConfig() {
- SetQuicReloadableFlag(quic_enable_tls_resumption, true);
auto ticket_crypter = std::make_unique<TestTicketCrypter>();
ticket_crypter_ = ticket_crypter.get();
auto proof_source = std::make_unique<FakeProofSource>();
@@ -126,7 +128,7 @@ class TlsServerHandshakerTest : public QuicTest {
CreateClientSessionForTest(
server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
helpers_.back().get(), alarm_factories_.back().get(),
- &client_crypto_config_, &client_connection_, &client_session);
+ client_crypto_config_.get(), &client_connection_, &client_session);
const std::string default_alpn =
AlpnForVersion(client_connection_->version());
ON_CALL(*client_session, GetAlpnsToOffer())
@@ -212,7 +214,7 @@ class TlsServerHandshakerTest : public QuicTest {
// Client state.
PacketSavingConnection* client_connection_;
- QuicCryptoClientConfig client_crypto_config_;
+ std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
std::unique_ptr<TestQuicSpdyClientSession> client_session_;
crypto_test_utils::FakeClientOptions client_options_;
@@ -383,6 +385,8 @@ TEST_F(TlsServerHandshakerTest, Resumption) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
EXPECT_FALSE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->ResumptionAttempted());
// Now do another handshake
InitializeServer();
@@ -390,6 +394,8 @@ TEST_F(TlsServerHandshakerTest, Resumption) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
EXPECT_TRUE(client_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->ResumptionAttempted());
}
TEST_F(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
@@ -411,6 +417,8 @@ TEST_F(TlsServerHandshakerTest, ResumptionWithAsyncDecryptCallback) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
EXPECT_TRUE(client_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->ResumptionAttempted());
}
TEST_F(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
@@ -426,6 +434,8 @@ TEST_F(TlsServerHandshakerTest, ResumptionWithFailingDecryptCallback) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
EXPECT_FALSE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->ResumptionAttempted());
}
TEST_F(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
@@ -448,6 +458,8 @@ TEST_F(TlsServerHandshakerTest, ResumptionWithFailingAsyncDecryptCallback) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
EXPECT_FALSE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->ResumptionAttempted());
}
TEST_F(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
@@ -462,6 +474,53 @@ TEST_F(TlsServerHandshakerTest, HandshakeFailsWithFailingProofSource) {
EXPECT_EQ(moved_messages_counts_.second, 0u);
}
+TEST_F(TlsServerHandshakerTest, ZeroRttResumption) {
+ std::vector<uint8_t> application_state = {0, 1, 2, 3};
+
+ // Do the first handshake
+ server_stream()->SetServerApplicationStateForResumption(
+ std::make_unique<ApplicationState>(application_state));
+ InitializeFakeClient();
+ CompleteCryptoHandshake();
+ ExpectHandshakeSuccessful();
+ EXPECT_FALSE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+ // Now do another handshake
+ InitializeServer();
+ server_stream()->SetServerApplicationStateForResumption(
+ std::make_unique<ApplicationState>(application_state));
+ InitializeFakeClient();
+ CompleteCryptoHandshake();
+ ExpectHandshakeSuccessful();
+ EXPECT_TRUE(client_stream()->IsResumption());
+ EXPECT_TRUE(server_stream()->IsZeroRtt());
+}
+
+TEST_F(TlsServerHandshakerTest, ZeroRttRejectOnApplicationStateChange) {
+ std::vector<uint8_t> original_application_state = {1, 2};
+ std::vector<uint8_t> new_application_state = {3, 4};
+
+ // Do the first handshake
+ server_stream()->SetServerApplicationStateForResumption(
+ std::make_unique<ApplicationState>(original_application_state));
+ InitializeFakeClient();
+ CompleteCryptoHandshake();
+ ExpectHandshakeSuccessful();
+ EXPECT_FALSE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsZeroRtt());
+
+ // Do another handshake, but change the application state
+ InitializeServer();
+ server_stream()->SetServerApplicationStateForResumption(
+ std::make_unique<ApplicationState>(new_application_state));
+ InitializeFakeClient();
+ CompleteCryptoHandshake();
+ ExpectHandshakeSuccessful();
+ EXPECT_TRUE(client_stream()->IsResumption());
+ EXPECT_FALSE(server_stream()->IsZeroRtt());
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc
index 6951b2cea3f..2f33594e042 100644
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.cc
@@ -17,7 +17,8 @@ UberQuicStreamIdManager::UberQuicStreamIdManager(
QuicStreamCount max_open_outgoing_unidirectional_streams,
QuicStreamCount max_open_incoming_bidirectional_streams,
QuicStreamCount max_open_incoming_unidirectional_streams)
- : bidirectional_stream_id_manager_(delegate,
+ : version_(version),
+ bidirectional_stream_id_manager_(delegate,
/*unidirectional=*/false,
perspective,
version,
@@ -69,7 +70,7 @@ QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
QuicStreamId id,
std::string* error_details) {
- if (QuicUtils::IsBidirectionalStreamId(id)) {
+ if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
id, error_details);
}
@@ -78,7 +79,7 @@ bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
}
void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
- if (QuicUtils::IsBidirectionalStreamId(id)) {
+ if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
bidirectional_stream_id_manager_.OnStreamClosed(id);
return;
}
@@ -97,7 +98,7 @@ bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
}
bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
- if (QuicUtils::IsBidirectionalStreamId(id)) {
+ if (QuicUtils::IsBidirectionalStreamId(id, version_)) {
return bidirectional_stream_id_manager_.IsAvailableStream(id);
}
return unidirectional_stream_id_manager_.IsAvailableStream(id);
@@ -162,4 +163,14 @@ UberQuicStreamIdManager::advertised_max_incoming_unidirectional_streams()
return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
}
+QuicStreamCount UberQuicStreamIdManager::outgoing_bidirectional_stream_count()
+ const {
+ return bidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
+QuicStreamCount UberQuicStreamIdManager::outgoing_unidirectional_stream_count()
+ const {
+ return unidirectional_stream_id_manager_.outgoing_stream_count();
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h
index b1fc1260987..0e03b42c8d6 100644
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h
+++ b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager.h
@@ -87,10 +87,14 @@ class QUIC_EXPORT_PRIVATE UberQuicStreamIdManager {
QuicStreamCount advertised_max_incoming_bidirectional_streams() const;
QuicStreamCount advertised_max_incoming_unidirectional_streams() const;
+ QuicStreamCount outgoing_bidirectional_stream_count() const;
+ QuicStreamCount outgoing_unidirectional_stream_count() const;
+
private:
friend class test::QuicSessionPeer;
friend class test::UberQuicStreamIdManagerPeer;
+ ParsedQuicVersion version_;
// Manages stream IDs of bidirectional streams.
QuicStreamIdManager bidirectional_stream_id_manager_;
diff --git a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc
index 7cae0a6e1de..b3dfedcf71f 100644
--- a/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/uber_quic_stream_id_manager_test.cc
@@ -287,18 +287,32 @@ TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
/*unidirectional=*/false);
- EXPECT_CALL(delegate_,
- SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
- frame.unidirectional));
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ EXPECT_CALL(delegate_,
+ SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
+ frame.unidirectional))
+ .Times(0);
+ } else {
+ EXPECT_CALL(delegate_,
+ SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
+ frame.unidirectional));
+ }
EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
frame.stream_count = stream_count;
frame.unidirectional = true;
- EXPECT_CALL(delegate_,
- SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
- frame.unidirectional));
+ if (GetQuicReloadableFlag(quic_stop_sending_duplicate_max_streams)) {
+ EXPECT_CALL(delegate_,
+ SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
+ frame.unidirectional))
+ .Times(0);
+ } else {
+ EXPECT_CALL(delegate_,
+ SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
+ frame.unidirectional));
+ }
EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
}
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 7c9749aa374..1f3986284ac 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
@@ -47,10 +47,10 @@ class MasquePacketWriter : public QuicPacketWriter {
bool SupportsReleaseTime() const override { return false; }
bool IsBatchMode() const override { return false; }
- char* GetNextWriteLocation(
+ QuicPacketBuffer GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) override {
- return nullptr;
+ return {nullptr, nullptr};
}
WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
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 52ba763118f..98d8a51faa7 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
@@ -94,8 +94,7 @@ void QboneClientSession::OnProofVerifyDetailsAvailable(
const ProofVerifyDetails& verify_details) {}
bool QboneClientSession::HasActiveRequests() const {
- return (stream_map().size() - num_incoming_static_streams() -
- num_outgoing_static_streams()) > 0;
+ return (stream_map().size() - num_static_streams()) > 0;
}
} // namespace quic
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 cdb611c9209..91be62a3c6c 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
@@ -139,13 +139,6 @@ class QuicQboneDispatcher : public QuicDispatcher {
return session;
}
- QuicConnectionId GenerateNewServerConnectionId(
- ParsedQuicVersion version,
- QuicConnectionId connection_id) const override {
- char connection_id_bytes[kQuicDefaultConnectionIdLength] = {};
- return QuicConnectionId(connection_id_bytes, sizeof(connection_id_bytes));
- }
-
private:
QbonePacketWriter* writer_;
};
@@ -248,7 +241,7 @@ TEST_P(QboneClientTest, SendDataFromClient) {
crypto_test_utils::ProofVerifierForTesting());
ASSERT_TRUE(client.Initialize());
ASSERT_TRUE(client.Connect());
- ASSERT_TRUE(client.WaitForCryptoHandshakeConfirmed());
+ ASSERT_TRUE(client.WaitForOneRttKeysAvailable());
client.SendData(TestPacketIn("hello"));
client.SendData(TestPacketIn("world"));
client.WaitForWriteToFlush();
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 10edaf6650d..976847de5f1 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
@@ -131,9 +131,10 @@ class DummyPacketWriter : public QuicPacketWriter {
bool IsBatchMode() const override { return false; }
- char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override {
- return nullptr;
+ QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) override {
+ return {nullptr, nullptr};
}
WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/counting_packet_filter.h b/chromium/net/third_party/quiche/src/quic/quartc/counting_packet_filter.h
deleted file mode 100644
index 4c7c27041ba..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/counting_packet_filter.h
+++ /dev/null
@@ -1,43 +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_QUARTC_COUNTING_PACKET_FILTER_H_
-#define QUICHE_QUIC_QUARTC_COUNTING_PACKET_FILTER_H_
-
-#include <string>
-
-#include "net/third_party/quiche/src/quic/test_tools/simulator/packet_filter.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace simulator {
-
-// Simple packet filter which drops the first N packets it observes.
-class CountingPacketFilter : public simulator::PacketFilter {
- public:
- CountingPacketFilter(simulator::Simulator* simulator,
- const std::string& name,
- simulator::Endpoint* endpoint)
- : PacketFilter(simulator, name, endpoint) {}
-
- void set_packets_to_drop(int count) { packets_to_drop_ = count; }
-
- protected:
- bool FilterPacket(const simulator::Packet& /*packet*/) override {
- if (packets_to_drop_ > 0) {
- --packets_to_drop_;
- return false;
- }
- return true;
- }
-
- private:
- int packets_to_drop_ = 0;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_COUNTING_PACKET_FILTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.cc
deleted file mode 100644
index da74858d69b..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
-
-namespace quic {
-
-QuartcConnectionHelper::QuartcConnectionHelper(const QuicClock* clock,
- QuicRandom* random)
- : clock_(clock), random_(random) {}
-
-const QuicClock* QuartcConnectionHelper::GetClock() const {
- return clock_;
-}
-
-QuicRandom* QuartcConnectionHelper::GetRandomGenerator() {
- return random_;
-}
-
-QuicBufferAllocator* QuartcConnectionHelper::GetStreamSendBufferAllocator() {
- return &buffer_allocator_;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h
deleted file mode 100644
index 72cc707aced..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
-#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_clock.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
-
-namespace quic {
-
-// Simple implementation of QuicConnectionHelperInterface for Quartc.
-class QuartcConnectionHelper : public QuicConnectionHelperInterface {
- public:
- QuartcConnectionHelper(const QuicClock* clock, QuicRandom* random);
-
- // QuicConnectionHelperInterface overrides.
- const QuicClock* GetClock() const override;
- QuicRandom* GetRandomGenerator() override;
- QuicBufferAllocator* GetStreamSendBufferAllocator() override;
-
- private:
- const QuicClock* clock_;
- QuicRandom* random_;
- SimpleBufferAllocator buffer_allocator_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_CONNECTION_HELPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.cc
deleted file mode 100644
index 14645f83da0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-
-namespace quic {
-
-void DummyProofSource::GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& /*server_config*/,
- QuicTransportVersion /*transport_version*/,
- quiche::QuicheStringPiece /*chlo_hash*/,
- std::unique_ptr<Callback> callback) {
- QuicReferenceCountedPointer<ProofSource::Chain> chain =
- GetCertChain(server_address, client_address, hostname);
- QuicCryptoProof proof;
- proof.signature = "Dummy signature";
- proof.leaf_cert_scts = "Dummy timestamp";
- callback->Run(true, chain, proof, nullptr /* details */);
-}
-
-QuicReferenceCountedPointer<DummyProofSource::Chain>
-DummyProofSource::GetCertChain(const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/) {
- std::vector<std::string> certs;
- certs.push_back(kDummyCertName);
- return QuicReferenceCountedPointer<ProofSource::Chain>(
- new ProofSource::Chain(certs));
-}
-
-void DummyProofSource::ComputeTlsSignature(
- const QuicSocketAddress& /*server_address*/,
- const QuicSocketAddress& /*client_address*/,
- const std::string& /*hostname*/,
- uint16_t /*signature_algorithm*/,
- quiche::QuicheStringPiece /*in*/,
- std::unique_ptr<SignatureCallback> callback) {
- callback->Run(true, "Dummy signature", /*details=*/nullptr);
-}
-
-QuicAsyncStatus InsecureProofVerifier::VerifyProof(
- const std::string& /*hostname*/,
- const uint16_t /*port*/,
- const std::string& /*server_config*/,
- QuicTransportVersion /*transport_version*/,
- quiche::QuicheStringPiece /*chlo_hash*/,
- const std::vector<std::string>& /*certs*/,
- const std::string& /*cert_sct*/,
- const std::string& /*signature*/,
- const ProofVerifyContext* /*context*/,
- std::string* /*error_details*/,
- std::unique_ptr<ProofVerifyDetails>* /*verify_details*/,
- std::unique_ptr<ProofVerifierCallback> /*callback*/) {
- return QUIC_SUCCESS;
-}
-
-QuicAsyncStatus InsecureProofVerifier::VerifyCertChain(
- const std::string& /*hostname*/,
- const uint16_t /*port*/,
- const std::vector<std::string>& /*certs*/,
- const std::string& /*ocsp_response*/,
- const std::string& /*cert_sct*/,
- const ProofVerifyContext* /*context*/,
- std::string* /*error_details*/,
- std::unique_ptr<ProofVerifyDetails>* /*details*/,
- std::unique_ptr<ProofVerifierCallback> /*callback*/) {
- return QUIC_SUCCESS;
-}
-
-std::unique_ptr<ProofVerifyContext>
-InsecureProofVerifier::CreateDefaultContext() {
- return nullptr;
-}
-
-bool QuartcCryptoServerStreamHelper::CanAcceptClientHello(
- const CryptoHandshakeMessage& /*message*/,
- const QuicSocketAddress& /*client_address*/,
- const QuicSocketAddress& /*peer_address*/,
- const QuicSocketAddress& /*self_address*/,
- std::string* /*error_details*/) const {
- return true;
-}
-
-std::unique_ptr<QuicCryptoClientConfig> CreateCryptoClientConfig(
- quiche::QuicheStringPiece pre_shared_key) {
- auto config = std::make_unique<QuicCryptoClientConfig>(
- std::make_unique<InsecureProofVerifier>());
- config->set_pad_inchoate_hello(false);
- config->set_pad_full_hello(false);
- if (!pre_shared_key.empty()) {
- config->set_pre_shared_key(pre_shared_key);
- }
- return config;
-}
-
-CryptoServerConfig CreateCryptoServerConfig(
- QuicRandom* random,
- const QuicClock* clock,
- quiche::QuicheStringPiece pre_shared_key) {
- CryptoServerConfig crypto_server_config;
-
- // Generate a random source address token secret. For long-running servers
- // it's better to not regenerate it for each connection to enable zero-RTT
- // handshakes, but for transient clients it does not matter.
- char source_address_token_secret[kInputKeyingMaterialLength];
- random->RandBytes(source_address_token_secret, kInputKeyingMaterialLength);
- auto config = std::make_unique<QuicCryptoServerConfig>(
- std::string(source_address_token_secret, kInputKeyingMaterialLength),
- random, std::make_unique<DummyProofSource>(),
- KeyExchangeSource::Default());
-
- // We run QUIC over ICE, and ICE is verifying remote side with STUN pings.
- // We disable source address token validation in order to allow for 0-rtt
- // setup (plus source ip addresses are changing even during the connection
- // when ICE is used).
- config->set_validate_source_address_token(false);
-
- // Effectively disables the anti-amplification measures (we don't need
- // them because we use ICE, and we need to disable them because we disable
- // padding of crypto packets).
- // This multiplier must be large enough so that the crypto handshake packet
- // (approx. 300 bytes) multiplied by this multiplier is larger than a fully
- // sized packet (currently 1200 bytes).
- // 1500 is a bit extreme: if you can imagine sending a 1 byte packet, and
- // your largest MTU would be below 1500 bytes, 1500*1 >=
- // any_packet_that_you_can_imagine_sending.
- // (again, we hardcode packet size to 1200, so we are not dealing with jumbo
- // frames).
- config->set_chlo_multiplier(1500);
-
- // We are sending small client hello, we must not validate its size.
- config->set_validate_chlo_size(false);
-
- // Provide server with serialized config string to prove ownership.
- QuicCryptoServerConfig::ConfigOptions options;
- // The |message| is used to handle the return value of AddDefaultConfig
- // which is raw pointer of the CryptoHandshakeMessage.
- std::unique_ptr<CryptoHandshakeMessage> message(
- config->AddDefaultConfig(random, clock, options));
- config->set_pad_rej(false);
- config->set_pad_shlo(false);
- if (!pre_shared_key.empty()) {
- config->set_pre_shared_key(pre_shared_key);
- }
- crypto_server_config.config = std::move(config);
- const QuicData& data = message->GetSerialized();
-
- crypto_server_config.serialized_crypto_config =
- std::string(data.data(), data.length());
- return crypto_server_config;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h
deleted file mode 100644
index 806786f2f3d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_
-
-#include <string>
-
-#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
-#include "net/third_party/quiche/src/quic/core/crypto/proof_source.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/quic_crypto_server_config.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
-#include "net/third_party/quiche/src/quic/core/quic_versions.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 {
-
-// Never, ever, change this certificate name. You will break 0-rtt handshake if
-// you do.
-static constexpr char kDummyCertName[] = "Dummy cert";
-
-struct CryptoServerConfig {
- std::unique_ptr<QuicCryptoServerConfig> config;
- std::string serialized_crypto_config;
-};
-
-// Length of HKDF input keying material, equal to its number of bytes.
-// https://tools.ietf.org/html/rfc5869#section-2.2.
-// TODO(zhihuang): Verify that input keying material length is correct.
-constexpr size_t kInputKeyingMaterialLength = 32;
-
-// Used by QuicCryptoServerConfig to provide dummy proof credentials.
-// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible.
-class DummyProofSource : public ProofSource {
- public:
- DummyProofSource() {}
- ~DummyProofSource() override {}
-
- // ProofSource overrides.
- void GetProof(const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- quiche::QuicheStringPiece chlo_hash,
- std::unique_ptr<Callback> callback) override;
-
- QuicReferenceCountedPointer<Chain> GetCertChain(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname) override;
-
- void ComputeTlsSignature(
- const QuicSocketAddress& server_address,
- const QuicSocketAddress& client_address,
- const std::string& hostname,
- uint16_t signature_algorithm,
- quiche::QuicheStringPiece in,
- std::unique_ptr<SignatureCallback> callback) override;
-
- TicketCrypter* GetTicketCrypter() override { return nullptr; }
-};
-
-// Used by QuicCryptoClientConfig to ignore the peer's credentials
-// and establish an insecure QUIC connection.
-// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible.
-class InsecureProofVerifier : public ProofVerifier {
- public:
- InsecureProofVerifier() {}
- ~InsecureProofVerifier() override {}
-
- // ProofVerifier overrides.
- QuicAsyncStatus VerifyProof(
- const std::string& hostname,
- const uint16_t port,
- const std::string& server_config,
- QuicTransportVersion transport_version,
- quiche::QuicheStringPiece chlo_hash,
- const std::vector<std::string>& certs,
- const std::string& cert_sct,
- const std::string& signature,
- const ProofVerifyContext* context,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* verify_details,
- std::unique_ptr<ProofVerifierCallback> callback) override;
-
- QuicAsyncStatus VerifyCertChain(
- const std::string& hostname,
- const uint16_t port,
- const std::vector<std::string>& certs,
- const std::string& ocsp_response,
- const std::string& cert_sct,
- const ProofVerifyContext* context,
- std::string* error_details,
- std::unique_ptr<ProofVerifyDetails>* details,
- std::unique_ptr<ProofVerifierCallback> callback) override;
-
- std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
-};
-
-// Implementation of the server-side crypto stream helper.
-class QuartcCryptoServerStreamHelper
- : public QuicCryptoServerStreamBase::Helper {
- public:
- bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
- const QuicSocketAddress& client_address,
- const QuicSocketAddress& peer_address,
- const QuicSocketAddress& self_address,
- std::string* error_details) const override;
-};
-
-std::unique_ptr<QuicCryptoClientConfig> CreateCryptoClientConfig(
- quiche::QuicheStringPiece pre_shared_key);
-
-CryptoServerConfig CreateCryptoServerConfig(
- QuicRandom* random,
- const QuicClock* clock,
- quiche::QuicheStringPiece pre_shared_key);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_CRYPTO_HELPERS_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.cc
deleted file mode 100644
index c5c4c4a742f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.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/quartc/quartc_factory.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-QuartcDispatcher::QuartcDispatcher(
- std::unique_ptr<QuicConfig> config,
- std::unique_ptr<QuicCryptoServerConfig> crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- std::unique_ptr<QuartcPacketWriter> packet_writer,
- Delegate* delegate)
- : QuicDispatcher(
- config.get(),
- crypto_config.get(),
- version_manager,
- std::move(helper),
- std::move(session_helper),
- std::move(alarm_factory),
- QuicUtils::CreateZeroConnectionId(
- version_manager->GetSupportedVersions()[0].transport_version)
- .length()),
- owned_quic_config_(std::move(config)),
- owned_crypto_config_(std::move(crypto_config)),
- delegate_(delegate),
- packet_writer_(packet_writer.get()) {
- // Allow incoming packets to set our expected connection ID length.
- SetShouldUpdateExpectedServerConnectionIdLength(true);
- // Allow incoming packets with connection ID lengths shorter than allowed.
- SetAllowShortInitialServerConnectionIds(true);
- // QuicDispatcher takes ownership of the writer.
- QuicDispatcher::InitializeWithWriter(packet_writer.release());
- // NB: This must happen *after* InitializeWithWriter. It can call us back
- // with OnTransportCanWrite() immediately, and the dispatcher needs to be
- // fully initialized to handle that.
- packet_writer_->SetPacketTransportDelegate(this);
-}
-
-QuartcDispatcher::~QuartcDispatcher() {
- packet_writer_->SetPacketTransportDelegate(nullptr);
-}
-
-std::unique_ptr<QuicSession> QuartcDispatcher::CreateQuicSession(
- QuicConnectionId connection_id,
- const QuicSocketAddress& client_address,
- quiche::QuicheStringPiece /*alpn*/,
- const ParsedQuicVersion& version) {
- // Make our expected connection ID non-mutable since we have a connection.
- SetShouldUpdateExpectedServerConnectionIdLength(false);
- std::unique_ptr<QuicConnection> connection = CreateQuicConnection(
- connection_id, client_address, helper(), alarm_factory(), writer(),
- Perspective::IS_SERVER, ParsedQuicVersionVector{version});
- auto session = std::make_unique<QuartcServerSession>(
- std::move(connection), /*visitor=*/this, config(), GetSupportedVersions(),
- helper()->GetClock(), crypto_config(), compressed_certs_cache(),
- session_helper());
- delegate_->OnSessionCreated(session.get());
- return session;
-}
-
-void QuartcDispatcher::OnTransportCanWrite() {
- OnCanWrite();
-}
-
-void QuartcDispatcher::OnTransportReceived(const char* data, size_t data_len) {
- // QuartcPacketTransport does not surface real peer addresses, so the
- // dispatcher uses a dummy address when processing incoming packets. Note that
- // the dispatcher refuses to process anything with port 0.
- static const QuicSocketAddress* dummy_address =
- new QuicSocketAddress(QuicIpAddress::Any4(), /*port=*/1);
-
- QuicReceivedPacket packet(data, data_len, helper()->GetClock()->Now());
- ProcessPacket(/*self_address=*/*dummy_address,
- /*peer_address=*/*dummy_address, packet);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h
deleted file mode 100644
index ca4fe2d6147..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_DISPATCHER_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_DISPATCHER_H_
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
-#include "net/third_party/quiche/src/quic/core/quic_config.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
-#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
-#include "net/third_party/quiche/src/quic/core/quic_version_manager.h"
-#include "net/third_party/quiche/src/quic/core/quic_versions.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-class QuartcDispatcher : public QuicDispatcher,
- QuartcPacketTransport::Delegate {
- public:
- class Delegate {
- public:
- virtual ~Delegate() = default;
- virtual void OnSessionCreated(QuartcSession* session) = 0;
- };
-
- QuartcDispatcher(
- std::unique_ptr<QuicConfig> config,
- std::unique_ptr<QuicCryptoServerConfig> crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- std::unique_ptr<QuartcPacketWriter> packet_writer,
- Delegate* delegate);
- ~QuartcDispatcher() override;
-
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& client_address,
- quiche::QuicheStringPiece alpn,
- const ParsedQuicVersion& version) override;
-
- // TODO(b/124399417): Override GenerateNewServerConnectionId and request a
- // zero-length connection id when the QUIC server perspective supports it.
-
- // QuartcPacketTransport::Delegate overrides.
- void OnTransportCanWrite() override;
- void OnTransportReceived(const char* data, size_t data_len) override;
-
- private:
- // Members owned by QuartcDispatcher but not QuicDispatcher.
- std::unique_ptr<QuicConfig> owned_quic_config_;
- std::unique_ptr<QuicCryptoServerConfig> owned_crypto_config_;
-
- // Delegate invoked when the dispatcher creates a new session.
- Delegate* delegate_;
-
- // The packet writer used by this dispatcher. Owned by the base class, but
- // the base class upcasts it to QuicPacketWriter (which prevents detaching the
- // transport delegate without a downcast).
- QuartcPacketWriter* packet_writer_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.cc
deleted file mode 100644
index ca8fad6c9c4..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_version_manager.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-namespace {
-
-// Wrapper around a QuicAlarmFactory which delegates to the wrapped factory.
-// Usee to convert an unowned pointer into an owned pointer, so that the new
-// "owner" does not delete the underlying factory. Note that this is only valid
-// when the unowned pointer is already guaranteed to outlive the new "owner".
-class QuartcAlarmFactoryWrapper : public QuicAlarmFactory {
- public:
- explicit QuartcAlarmFactoryWrapper(QuicAlarmFactory* impl) : impl_(impl) {}
-
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
-
- private:
- QuicAlarmFactory* impl_;
-};
-
-QuicAlarm* QuartcAlarmFactoryWrapper::CreateAlarm(
- QuicAlarm::Delegate* delegate) {
- return impl_->CreateAlarm(delegate);
-}
-
-QuicArenaScopedPtr<QuicAlarm> QuartcAlarmFactoryWrapper::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- return impl_->CreateAlarm(std::move(delegate), arena);
-}
-
-} // namespace
-
-QuartcClientEndpoint::QuartcClientEndpoint(
- QuicAlarmFactory* alarm_factory,
- const QuicClock* clock,
- QuicRandom* random,
- QuartcEndpoint::Delegate* delegate,
- const QuartcSessionConfig& config,
- quiche::QuicheStringPiece serialized_server_config,
- std::unique_ptr<QuicVersionManager> version_manager)
- : alarm_factory_(alarm_factory),
- clock_(clock),
- delegate_(delegate),
- serialized_server_config_(serialized_server_config),
- version_manager_(version_manager ? std::move(version_manager)
- : std::make_unique<QuicVersionManager>(
- AllSupportedVersions())),
- create_session_alarm_(QuicWrapUnique(
- alarm_factory_->CreateAlarm(new CreateSessionDelegate(this)))),
- connection_helper_(
- std::make_unique<QuartcConnectionHelper>(clock_, random)),
- config_(config) {}
-
-void QuartcClientEndpoint::Connect(QuartcPacketTransport* packet_transport) {
- packet_transport_ = packet_transport;
- // For the first attempt to connect, use any version that the client supports.
- current_versions_ = version_manager_->GetSupportedVersions();
- create_session_alarm_->Set(clock_->Now());
-}
-
-void QuartcClientEndpoint::OnCreateSessionAlarm() {
- session_ = CreateQuartcClientSession(
- config_, clock_, alarm_factory_, connection_helper_.get(),
- current_versions_, serialized_server_config_, packet_transport_);
- session_->SetDelegate(this);
- delegate_->OnSessionCreated(session_.get());
-}
-
-void QuartcClientEndpoint::OnCryptoHandshakeComplete() {
- delegate_->OnCryptoHandshakeComplete();
-}
-
-void QuartcClientEndpoint::OnConnectionWritable() {
- delegate_->OnConnectionWritable();
-}
-
-void QuartcClientEndpoint::OnIncomingStream(QuartcStream* stream) {
- delegate_->OnIncomingStream(stream);
-}
-
-void QuartcClientEndpoint::OnCongestionControlChange(
- QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) {
- delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate,
- latest_rtt);
-}
-
-void QuartcClientEndpoint::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- // First, see if we can restart the session with a mutually-supported version.
- if (frame.quic_error_code == QUIC_INVALID_VERSION && session_ &&
- session_->connection() &&
- !session_->connection()->server_supported_versions().empty()) {
- for (const auto& client_version :
- version_manager_->GetSupportedVersions()) {
- if (QuicContainsValue(session_->connection()->server_supported_versions(),
- client_version)) {
- // Found a mutually-supported version. Reconnect using that version.
- current_versions_.clear();
- current_versions_.push_back(client_version);
- create_session_alarm_->Set(clock_->Now());
- return;
- }
- }
- }
-
- // Permanent version negotiation errors are forwarded to the |delegate_|,
- // along with all other errors.
- delegate_->OnConnectionClosed(frame, source);
-}
-
-void QuartcClientEndpoint::OnMessageReceived(
- quiche::QuicheStringPiece message) {
- delegate_->OnMessageReceived(message);
-}
-
-void QuartcClientEndpoint::OnMessageSent(int64_t datagram_id) {
- delegate_->OnMessageSent(datagram_id);
-}
-
-void QuartcClientEndpoint::OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) {
- delegate_->OnMessageAcked(datagram_id, receive_timestamp);
-}
-
-void QuartcClientEndpoint::OnMessageLost(int64_t datagram_id) {
- delegate_->OnMessageLost(datagram_id);
-}
-
-QuartcServerEndpoint::QuartcServerEndpoint(
- QuicAlarmFactory* alarm_factory,
- const QuicClock* clock,
- QuicRandom* random,
- QuartcEndpoint::Delegate* delegate,
- const QuartcSessionConfig& config,
- std::unique_ptr<QuicVersionManager> version_manager)
- : alarm_factory_(alarm_factory),
- delegate_(delegate),
- config_(config),
- version_manager_(version_manager ? std::move(version_manager)
- : std::make_unique<QuicVersionManager>(
- AllSupportedVersions())),
- pre_connection_helper_(
- std::make_unique<QuartcConnectionHelper>(clock, random)),
- crypto_config_(
- CreateCryptoServerConfig(pre_connection_helper_->GetRandomGenerator(),
- clock,
- config.pre_shared_key)) {}
-
-void QuartcServerEndpoint::Connect(QuartcPacketTransport* packet_transport) {
- DCHECK(pre_connection_helper_ != nullptr);
- dispatcher_ = std::make_unique<QuartcDispatcher>(
- std::make_unique<QuicConfig>(CreateQuicConfig(config_)),
- std::move(crypto_config_.config), version_manager_.get(),
- std::move(pre_connection_helper_),
- std::make_unique<QuartcCryptoServerStreamHelper>(),
- std::make_unique<QuartcAlarmFactoryWrapper>(alarm_factory_),
- std::make_unique<QuartcPacketWriter>(packet_transport,
- config_.max_packet_size),
- this);
- // The dispatcher requires at least one call to |ProcessBufferedChlos| to
- // set the number of connections it is allowed to create.
- dispatcher_->ProcessBufferedChlos(/*max_connections_to_create=*/1);
-}
-
-void QuartcServerEndpoint::OnSessionCreated(QuartcSession* session) {
- session->SetDelegate(delegate_);
- delegate_->OnSessionCreated(session);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.h
deleted file mode 100644
index ea1a63f0e33..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint.h
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_ENDPOINT_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_
-
-#include <string>
-
-#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.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/quartc/quartc_connection_helper.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-// Endpoint (client or server) in a peer-to-peer Quartc connection.
-class QuartcEndpoint {
- public:
- class Delegate : public QuartcSession::Delegate {
- public:
- virtual ~Delegate() = default;
-
- // Called when an endpoint creates a new session, before any packets are
- // processed or sent. The callee should perform any additional
- // configuration required, such as setting up congestion control, before
- // returning. |session| is owned by the endpoint, but remains safe to use
- // until another call to |OnSessionCreated| or |OnConnectionClosed| occurs,
- // at which point previous session may be destroyed.
- //
- // Callees must not change the |session|'s delegate. The Endpoint itself
- // manages the delegate and will forward calls.
- //
- // New calls to |OnSessionCreated| will only occur prior to
- // |OnConnectionWritable|, during initial connection negotiation.
- virtual void OnSessionCreated(QuartcSession* session) = 0;
- };
-
- virtual ~QuartcEndpoint() = default;
-
- // Connects the endpoint using the given session config. After |Connect| is
- // called, the endpoint will asynchronously create a session, then call
- // |Delegate::OnSessionCreated|.
- virtual void Connect(QuartcPacketTransport* packet_transport) = 0;
-};
-
-// Implementation of QuartcEndpoint which immediately (but asynchronously)
-// creates a session by scheduling a QuicAlarm. Only suitable for use with the
-// client perspective.
-class QuartcClientEndpoint : public QuartcEndpoint,
- public QuartcSession::Delegate {
- public:
- // |alarm_factory|, |clock|, and |delegate| are owned by the caller and must
- // outlive the endpoint.
- QuartcClientEndpoint(
- QuicAlarmFactory* alarm_factory,
- const QuicClock* clock,
- QuicRandom* random,
- QuartcEndpoint::Delegate* delegate,
- const QuartcSessionConfig& config,
- quiche::QuicheStringPiece serialized_server_config,
- std::unique_ptr<QuicVersionManager> version_manager = nullptr);
-
- void Connect(QuartcPacketTransport* packet_transport) override;
-
- // QuartcSession::Delegate overrides.
- void OnCryptoHandshakeComplete() override;
- void OnConnectionWritable() override;
- void OnIncomingStream(QuartcStream* stream) override;
- void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) override;
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
- void OnMessageReceived(quiche::QuicheStringPiece message) override;
- void OnMessageSent(int64_t datagram_id) override;
- void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override;
- void OnMessageLost(int64_t datagram_id) override;
-
- private:
- friend class CreateSessionDelegate;
- class CreateSessionDelegate : public QuicAlarm::Delegate {
- public:
- CreateSessionDelegate(QuartcClientEndpoint* endpoint)
- : endpoint_(endpoint) {}
-
- void OnAlarm() override { endpoint_->OnCreateSessionAlarm(); }
-
- private:
- QuartcClientEndpoint* endpoint_;
- };
-
- // Callback which occurs when |create_session_alarm_| fires.
- void OnCreateSessionAlarm();
-
- // Implementation of QuicAlarmFactory used by this endpoint. Unowned.
- QuicAlarmFactory* alarm_factory_;
-
- // Implementation of QuicClock used by this endpoint. Unowned.
- const QuicClock* clock_;
-
- // Delegate which receives callbacks for newly created sessions.
- QuartcEndpoint::Delegate* delegate_;
-
- // Server config. If valid, used to perform a 0-RTT connection.
- const std::string serialized_server_config_;
-
- // Version manager. May be injected to control version negotiation in tests.
- std::unique_ptr<QuicVersionManager> version_manager_;
-
- // Versions to be used when the next session is created. The session will
- // choose one of these versions for its connection attempt.
- //
- // If the connection does not succeed, the client session MAY try again using
- // another version from this list, or it MAY simply fail with a
- // QUIC_INVALID_VERSION error. The latter occurs when it is not possible to
- // upgrade a connection in-place (for example, if the way stream ids are
- // allocated changes between versions). This failure mode is handled by
- // narrowing |current_versions_| to one of that is mutually-supported and
- // reconnecting (with a new session).
- ParsedQuicVersionVector current_versions_;
-
- // Alarm for creating sessions asynchronously. The alarm is set when
- // Connect() is called. When it fires, the endpoint creates a session and
- // calls the delegate.
- std::unique_ptr<QuicAlarm> create_session_alarm_;
-
- // Helper used by QuicConnection.
- std::unique_ptr<QuicConnectionHelperInterface> connection_helper_;
-
- // Config to be used for new sessions.
- QuartcSessionConfig config_;
-
- // The currently-active session. Nullptr until |Connect| and
- // |Delegate::OnSessionCreated| are called.
- std::unique_ptr<QuartcSession> session_;
-
- QuartcPacketTransport* packet_transport_;
-};
-
-// Implementation of QuartcEndpoint which uses a QuartcDispatcher to listen for
-// an incoming CHLO and create a session when one arrives. Only suitable for
-// use with the server perspective.
-class QuartcServerEndpoint : public QuartcEndpoint,
- public QuartcDispatcher::Delegate {
- public:
- QuartcServerEndpoint(
- QuicAlarmFactory* alarm_factory,
- const QuicClock* clock,
- QuicRandom* random,
- QuartcEndpoint::Delegate* delegate,
- const QuartcSessionConfig& config,
- std::unique_ptr<QuicVersionManager> version_manager = nullptr);
-
- // Implements QuartcEndpoint.
- void Connect(QuartcPacketTransport* packet_transport) override;
-
- // Implements QuartcDispatcher::Delegate.
- void OnSessionCreated(QuartcSession* session) override;
-
- // Accessor to retrieve the server crypto config. May only be called after
- // Connect().
- quiche::QuicheStringPiece server_crypto_config() const {
- return crypto_config_.serialized_crypto_config;
- }
-
- const std::vector<ParsedQuicVersion> GetSupportedQuicVersions() const {
- return version_manager_->GetSupportedVersions();
- }
-
- private:
- // Implementation of QuicAlarmFactory used by this endpoint. Unowned.
- QuicAlarmFactory* alarm_factory_;
-
- // Delegate which receives callbacks for newly created sessions.
- QuartcEndpoint::Delegate* delegate_;
-
- // Config to be used for new sessions.
- QuartcSessionConfig config_;
-
- // Version manager. May be injected to control version negotiation in tests.
- std::unique_ptr<QuicVersionManager> version_manager_;
-
- // QuartcDispatcher waits for an incoming CHLO, then either rejects it or
- // creates a session to respond to it. The dispatcher owns all sessions it
- // creates.
- std::unique_ptr<QuartcDispatcher> dispatcher_;
-
- // This field is only available before connection was started.
- std::unique_ptr<QuartcConnectionHelper> pre_connection_helper_;
-
- // A configuration, containing public key, that may need to be passed to the
- // client to enable 0rtt.
- CryptoServerConfig crypto_config_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint_test.cc
deleted file mode 100644
index d2f94202aa1..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_endpoint_test.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_versions.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
-#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
-
-namespace quic {
-namespace {
-
-class QuartcEndpointTest : public QuicTest {
- protected:
- QuartcEndpointTest()
- : client_transport_(&simulator_,
- "client_transport",
- "server_transport",
- 10 * kDefaultMaxPacketSize),
- server_transport_(&simulator_,
- "server_transport",
- "client_transport",
- 10 * kDefaultMaxPacketSize),
- client_server_link_(&client_transport_,
- &server_transport_,
- QuicBandwidth::FromKBitsPerSecond(10000),
- QuicTime::Delta::FromMilliseconds(1)),
- server_endpoint_delegate_(&server_stream_delegate_,
- simulator_.GetClock()),
- server_endpoint_(std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(),
- simulator_.GetClock(),
- simulator_.GetRandomGenerator(),
- &server_endpoint_delegate_,
- QuartcSessionConfig())),
- client_endpoint_delegate_(&client_stream_delegate_,
- simulator_.GetClock()),
- client_endpoint_(std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(),
- simulator_.GetClock(),
- simulator_.GetRandomGenerator(),
- &client_endpoint_delegate_,
- QuartcSessionConfig(),
- /*serialized_server_config=*/"")) {
- // Make sure these versions are enabled since some tests use them.
- SetQuicReloadableFlag(quic_disable_version_q043, false);
- SetQuicReloadableFlag(quic_disable_version_q046, false);
- }
-
- simulator::Simulator simulator_;
-
- simulator::SimulatedQuartcPacketTransport client_transport_;
- simulator::SimulatedQuartcPacketTransport server_transport_;
- simulator::SymmetricLink client_server_link_;
-
- FakeQuartcStreamDelegate server_stream_delegate_;
- FakeQuartcEndpointDelegate server_endpoint_delegate_;
-
- std::unique_ptr<QuartcServerEndpoint> server_endpoint_;
-
- FakeQuartcStreamDelegate client_stream_delegate_;
- FakeQuartcEndpointDelegate client_endpoint_delegate_;
-
- std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
-};
-
-// After calling Connect, the client endpoint must wait for an async callback.
-// The callback occurs after a finite amount of time and produces a session.
-TEST_F(QuartcEndpointTest, ClientCreatesSessionAsynchronously) {
- client_endpoint_->Connect(&client_transport_);
-
- EXPECT_EQ(client_endpoint_delegate_.session(), nullptr);
-
- EXPECT_TRUE(simulator_.RunUntil(
- [this] { return client_endpoint_delegate_.session() != nullptr; }));
-}
-
-// Tests that the server can negotiate for an older QUIC version if the client
-// attempts to connect using a newer version.
-TEST_F(QuartcEndpointTest,
- QUIC_TEST_DISABLED_IN_CHROME(ServerNegotiatesForOldVersion)) {
- // Reset the client endpoint to prefer version 46 but also be capable of
- // speaking version 43.
- ParsedQuicVersionVector client_versions;
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
- QuartcSessionConfig(),
- /*serialized_server_config=*/"",
- std::make_unique<QuicVersionManager>(client_versions));
-
- // Reset the server endpoint to only speak version 43.
- ParsedQuicVersionVector server_versions;
- server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
- QuartcSessionConfig(),
- std::make_unique<QuicVersionManager>(server_versions));
-
- // The endpoints should be able to establish a connection using version 46.
- server_endpoint_->Connect(&server_transport_);
- client_endpoint_->Connect(&client_transport_);
-
- ASSERT_TRUE(simulator_.RunUntil([this] {
- return client_endpoint_delegate_.session() != nullptr &&
- client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
- server_endpoint_delegate_.session() != nullptr &&
- server_endpoint_delegate_.session()->IsEncryptionEstablished();
- }));
- EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
- server_versions[0]);
- EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
- server_versions[0]);
-}
-
-// Tests that the server can accept connections from clients that use older
-// QUIC versions.
-TEST_F(QuartcEndpointTest,
- QUIC_TEST_DISABLED_IN_CHROME(ServerAcceptsOldVersion)) {
- // Reset the client endpoint to only speak version 43.
- ParsedQuicVersionVector client_versions;
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
- QuartcSessionConfig(),
- /*serialized_server_config=*/"",
- std::make_unique<QuicVersionManager>(client_versions));
-
- // Reset the server endpoint to prefer version 46 but also be capable of
- // speaking version 43.
- ParsedQuicVersionVector server_versions;
- server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
- server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
- QuartcSessionConfig(),
- std::make_unique<QuicVersionManager>(server_versions));
-
- // The endpoints should be able to establish a connection using version 46.
- server_endpoint_->Connect(&server_transport_);
- client_endpoint_->Connect(&client_transport_);
-
- ASSERT_TRUE(simulator_.RunUntil([this] {
- return client_endpoint_delegate_.session() != nullptr &&
- client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
- server_endpoint_delegate_.session() != nullptr &&
- server_endpoint_delegate_.session()->IsEncryptionEstablished();
- }));
- EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
- client_versions[0]);
- EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
- client_versions[0]);
-}
-
-// Tests that version negotiation fails when the client and server support
-// completely disjoint sets of versions.
-TEST_F(QuartcEndpointTest,
- QUIC_TEST_DISABLED_IN_CHROME(VersionNegotiationWithDisjointVersions)) {
- // Reset the client endpoint to only speak version 43.
- ParsedQuicVersionVector client_versions;
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
- QuartcSessionConfig(),
- /*serialized_server_config=*/"",
- std::make_unique<QuicVersionManager>(client_versions));
-
- // Reset the server endpoint to only speak version 46.
- ParsedQuicVersionVector server_versions;
- server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
- server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
- QuartcSessionConfig(),
- std::make_unique<QuicVersionManager>(server_versions));
-
- // The endpoints should be unable to establish a connection.
- server_endpoint_->Connect(&server_transport_);
- client_endpoint_->Connect(&client_transport_);
-
- // Note that the error is reported from the client and *not* the server. The
- // server sees an invalid version, sends a version negotiation packet, and
- // never gets a response, because the client stops sending when it can't find
- // a mutually supported versions.
- ASSERT_TRUE(simulator_.RunUntil([this] {
- return client_endpoint_delegate_.session() != nullptr &&
- client_endpoint_delegate_.session()->error() != QUIC_NO_ERROR;
- }));
- EXPECT_THAT(client_endpoint_delegate_.session()->error(),
- test::IsError(QUIC_INVALID_VERSION));
-}
-
-// Tests that the client endpoint can create a new session in order to continue
-// version negotiation.
-TEST_F(QuartcEndpointTest,
- QUIC_TEST_DISABLED_IN_CHROME(CreatesNewSessionWhenRequired)) {
- // Reset the client endpoint to prefer version 46 but also be capable of
- // speaking version 43.
- ParsedQuicVersionVector client_versions;
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
- client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
- QuartcSessionConfig(),
- /*serialized_server_config=*/"",
- std::make_unique<QuicVersionManager>(client_versions));
-
- // Reset the server endpoint to only speak version 43.
- ParsedQuicVersionVector server_versions;
- server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
- server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
- QuartcSessionConfig(),
- std::make_unique<QuicVersionManager>(server_versions));
-
- // The endpoints should be able to establish a connection using version 46.
- server_endpoint_->Connect(&server_transport_);
- client_endpoint_->Connect(&client_transport_);
-
- ASSERT_TRUE(simulator_.RunUntil([this] {
- return client_endpoint_delegate_.session() != nullptr &&
- client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
- server_endpoint_delegate_.session() != nullptr &&
- server_endpoint_delegate_.session()->IsEncryptionEstablished();
- }));
- EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
- server_versions[0]);
- EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
- server_versions[0]);
-
- EXPECT_EQ(2, client_endpoint_delegate_.num_sessions_created());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.cc
deleted file mode 100644
index 280d936b25a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
-#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
-#include "net/third_party/quiche/src/quic/core/uber_received_packet_manager.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-std::unique_ptr<QuartcSession> CreateQuartcClientSession(
- const QuartcSessionConfig& quartc_session_config,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionHelperInterface* connection_helper,
- const ParsedQuicVersionVector& supported_versions,
- quiche::QuicheStringPiece server_crypto_config,
- QuartcPacketTransport* packet_transport) {
- DCHECK(packet_transport);
-
- // QuartcSession will eventually own both |writer| and |quic_connection|.
- auto writer = std::make_unique<QuartcPacketWriter>(
- packet_transport, quartc_session_config.max_packet_size);
-
- // While the QuicConfig is not directly used by the connection, creating it
- // also sets flag values which must be set before creating the connection.
- QuicConfig quic_config = CreateQuicConfig(quartc_session_config);
-
- // |dummy_id| and |dummy_address| are used because Quartc network layer will
- // not use these two.
- QuicConnectionId dummy_id = QuicUtils::CreateZeroConnectionId(
- supported_versions[0].transport_version);
- QuicSocketAddress dummy_address(QuicIpAddress::Any4(), /*port=*/0);
- std::unique_ptr<QuicConnection> quic_connection = CreateQuicConnection(
- dummy_id, dummy_address, connection_helper, alarm_factory, writer.get(),
- Perspective::IS_CLIENT, supported_versions);
-
- // Quartc sets its own ack delay; get that ack delay and copy it over
- // to the QuicConfig so that it can be properly advertised to the peer
- // via transport parameter negotiation.
- quic_config.SetMaxAckDelayToSendMs(quic_connection->received_packet_manager()
- .max_ack_delay()
- .ToMilliseconds());
-
- return std::make_unique<QuartcClientSession>(
- std::move(quic_connection), quic_config, supported_versions, clock,
- std::move(writer),
- CreateCryptoClientConfig(quartc_session_config.pre_shared_key),
- server_crypto_config);
-}
-
-void ConfigureGlobalQuicSettings() {
- // Ensure that we don't drop data because QUIC streams refuse to buffer it.
- // TODO(b/120099046): Replace this with correct handling of WriteMemSlices().
- SetQuicFlag(FLAGS_quic_buffered_data_threshold,
- std::numeric_limits<int>::max());
-
- // Enable and request QUIC to include receive timestamps in ACK frames.
- SetQuicReloadableFlag(quic_send_timestamps, true);
-
- // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
- // false.
- SetQuicReloadableFlag(quic_enable_ack_decimation, false);
-
- // Note: flag settings have no effect for Exoblaze builds since
- // SetQuicReloadableFlag() gets stubbed out.
- SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts.
- SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9.
-}
-
-QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) {
- // TODO(b/124398962): Figure out a better way to initialize QUIC flags.
- // Creating a config shouldn't have global side-effects on flags. However,
- // this has the advantage of ensuring that flag values stay in sync with the
- // options requested by configs, so simply splitting the config and flag
- // settings doesn't seem preferable.
- ConfigureGlobalQuicSettings();
-
- QuicTagVector copt;
- copt.push_back(kNSTP);
-
- // Enable and request QUIC to include receive timestamps in ACK frames.
- copt.push_back(kSTMP);
-
- // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
- // false.
- copt.push_back(kAKD2);
-
- // Use unlimited decimation in order to reduce number of unbundled ACKs.
- copt.push_back(kAKDU);
-
- // Enable time-based loss detection.
- copt.push_back(kTIME);
-
- copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP.
- copt.push_back(kBBR5); // 40 RTT ack aggregation.
- copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight.
- copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP.
- copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP.
- copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains.
- copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd.
-
- if (!quartc_session_config.enable_tail_loss_probe) {
- copt.push_back(kNTLP);
- }
-
- // TODO(b/112192153): Test and possible enable slower startup when pipe
- // filling is ready to use. Slower startup is kBBRS.
-
- QuicConfig quic_config;
-
- // Use the limits for the session & stream flow control. The default 16KB
- // limit leads to significantly undersending (not reaching BWE on the outgoing
- // bitrate) due to blocked frames, and it leads to high latency (and one-way
- // delay). Setting it to its limits is not going to cause issues (our streams
- // are small generally, and if we were to buffer 24MB it wouldn't be the end
- // of the world). We can consider setting different limits in future (e.g. 1MB
- // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of
- // 24MB can capture approx 4 minutes of the call, and the default increase in
- // size of the window (half of the window size) is approximately 2 minutes of
- // the call.
- quic_config.SetInitialSessionFlowControlWindowToSend(
- kSessionReceiveWindowLimit);
- quic_config.SetInitialStreamFlowControlWindowToSend(
- kStreamReceiveWindowLimit);
- quic_config.SetConnectionOptionsToSend(copt);
- quic_config.SetClientConnectionOptions(copt);
- if (quartc_session_config.max_time_before_crypto_handshake >
- QuicTime::Delta::Zero()) {
- quic_config.set_max_time_before_crypto_handshake(
- quartc_session_config.max_time_before_crypto_handshake);
- }
- if (quartc_session_config.max_idle_time_before_crypto_handshake >
- QuicTime::Delta::Zero()) {
- quic_config.set_max_idle_time_before_crypto_handshake(
- quartc_session_config.max_idle_time_before_crypto_handshake);
- }
- if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) {
- quic_config.SetIdleNetworkTimeout(
- quartc_session_config.idle_network_timeout);
- }
-
- // The ICE transport provides a unique 5-tuple for each connection. Save
- // overhead by omitting the connection id.
- quic_config.SetBytesForConnectionIdToSend(0);
-
- // Allow up to 1000 incoming streams at once. Quartc streams typically contain
- // one audio or video frame and close immediately. However, when a video frame
- // becomes larger than one packet, there is some delay between the start and
- // end of each stream. The default maximum of 100 only leaves about 1 second
- // of headroom (Quartc sends ~30 video frames per second) before QUIC starts
- // to refuse incoming streams. Back-pressure should clear backlogs of
- // incomplete streams, but targets 1 second for recovery. Increasing the
- // number of open streams gives sufficient headroom to recover before QUIC
- // refuses new streams.
- quic_config.SetMaxBidirectionalStreamsToSend(1000);
-
- return quic_config;
-}
-
-std::unique_ptr<QuicConnection> CreateQuicConnection(
- QuicConnectionId connection_id,
- const QuicSocketAddress& peer_address,
- QuicConnectionHelperInterface* connection_helper,
- QuicAlarmFactory* alarm_factory,
- QuicPacketWriter* packet_writer,
- Perspective perspective,
- ParsedQuicVersionVector supported_versions) {
- auto quic_connection = std::make_unique<QuicConnection>(
- connection_id, peer_address, connection_helper, alarm_factory,
- packet_writer,
- /*owns_writer=*/false, perspective, supported_versions);
- quic_connection->SetMaxPacketLength(
- packet_writer->GetMaxPacketSize(peer_address));
-
- QuicSentPacketManager& sent_packet_manager =
- quic_connection->sent_packet_manager();
- UberReceivedPacketManager& received_packet_manager =
- quic_connection->received_packet_manager();
-
- // Default delayed ack time is 25ms.
- // If data packets are sent less often (e.g. because p-time was modified),
- // we would force acks to be sent every 25ms regardless, increasing
- // overhead. Since generally we guarantee a packet every 20ms, changing
- // this value should have miniscule effect on quality on good connections,
- // but on poor connections, changing this number significantly reduced the
- // number of ack-only packets.
- // The p-time can go up to as high as 120ms, and when it does, it's
- // when the low overhead is the most important thing. Ideally it should be
- // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms.
- received_packet_manager.set_max_ack_delay(
- QuicTime::Delta::FromMilliseconds(100));
- sent_packet_manager.set_peer_max_ack_delay(
- QuicTime::Delta::FromMilliseconds(100));
-
- quic_connection->set_fill_up_link_during_probing(true);
-
- // We start ack decimation after 15 packets. Typically, we would see
- // 1-2 crypto handshake packets, one media packet, and 10 probing packets.
- // We want to get acks for the probing packets as soon as possible,
- // but we can start using ack decimation right after first probing completes.
- // The default was to not start ack decimation for the first 100 packets.
- quic_connection->set_min_received_before_ack_decimation(15);
-
- return quic_connection;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.h
deleted file mode 100644
index 665b8e7111d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_factory.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_FACTORY_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_FACTORY_H_
-
-#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-struct QuartcSessionConfig {
- // If a pre-shared cryptographic key is available for this session, specify it
- // here. This value will only be used if non-empty.
- std::string pre_shared_key;
-
- // The maximum size of the packet can be written with the packet writer.
- // 1200 bytes by default.
- QuicPacketLength max_packet_size = 1200;
-
- // Timeouts for the crypto handshake. Set them to higher values to
- // prevent closing the session before it started on a slow network.
- // Zero entries are ignored and QUIC defaults are used in that case.
- QuicTime::Delta max_idle_time_before_crypto_handshake =
- QuicTime::Delta::Zero();
- QuicTime::Delta max_time_before_crypto_handshake = QuicTime::Delta::Zero();
- QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero();
-
- // Tail loss probes (TLP) are enabled by default, but it may be useful to
- // disable them in tests. We can also consider disabling them in production
- // if we discover that tail loss probes add overhead in low bitrate audio.
- bool enable_tail_loss_probe = true;
-};
-
-// Creates a new QuartcClientSession using the given configuration.
-std::unique_ptr<QuartcSession> CreateQuartcClientSession(
- const QuartcSessionConfig& quartc_session_config,
- const QuicClock* clock,
- QuicAlarmFactory* alarm_factory,
- QuicConnectionHelperInterface* connection_helper,
- const ParsedQuicVersionVector& supported_versions,
- quiche::QuicheStringPiece server_crypto_config,
- QuartcPacketTransport* packet_transport);
-
-// Configures global settings, such as supported quic versions.
-// Must execute on QUIC thread.
-void ConfigureGlobalQuicSettings();
-
-// Must execute on QUIC thread.
-QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config);
-
-std::unique_ptr<QuicConnection> CreateQuicConnection(
- QuicConnectionId connection_id,
- const QuicSocketAddress& peer_address,
- QuicConnectionHelperInterface* connection_helper,
- QuicAlarmFactory* alarm_factory,
- QuicPacketWriter* packet_writer,
- Perspective perspective,
- ParsedQuicVersionVector supported_versions);
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_FACTORY_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_fakes.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_fakes.h
deleted file mode 100644
index 94bf1add1e7..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_fakes.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_FAKES_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_FAKES_H_
-
-#include <string>
-
-#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_types.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-class FakeQuartcEndpointDelegate : public QuartcEndpoint::Delegate {
- public:
- explicit FakeQuartcEndpointDelegate(QuartcStream::Delegate* stream_delegate,
- const QuicClock* clock)
- : stream_delegate_(stream_delegate), clock_(clock) {}
-
- void OnSessionCreated(QuartcSession* session) override {
- CHECK_NE(session, nullptr);
- session_ = session;
- session_->StartCryptoHandshake();
- ++num_sessions_created_;
- }
-
- void OnConnectionWritable() override {
- QUIC_LOG(INFO) << "Connection writable!";
- if (!writable_time_.IsInitialized()) {
- writable_time_ = clock_->Now();
- }
- }
-
- // Called when peers have established forward-secure encryption
- void OnCryptoHandshakeComplete() override {
- QUIC_LOG(INFO) << "Crypto handshake complete!";
- crypto_handshake_time_ = clock_->Now();
- }
-
- // Called when connection closes locally, or remotely by peer.
- void OnConnectionClosed(const QuicConnectionCloseFrame& /*frame*/,
- ConnectionCloseSource /*source*/) override {
- connected_ = false;
- }
-
- // Called when an incoming QUIC stream is created.
- void OnIncomingStream(QuartcStream* quartc_stream) override {
- last_incoming_stream_ = quartc_stream;
- last_incoming_stream_->SetDelegate(stream_delegate_);
- }
-
- void OnMessageReceived(quiche::QuicheStringPiece message) override {
- incoming_messages_.emplace_back(message);
- }
-
- void OnMessageSent(int64_t datagram_id) override {
- sent_datagram_ids_.push_back(datagram_id);
- }
-
- void OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) override {
- acked_datagram_id_to_receive_timestamp_.emplace(datagram_id,
- receive_timestamp);
- }
-
- void OnMessageLost(int64_t datagram_id) override {
- lost_datagram_ids_.push_back(datagram_id);
- }
-
- void OnCongestionControlChange(QuicBandwidth /*bandwidth_estimate*/,
- QuicBandwidth /*pacing_rate*/,
- QuicTime::Delta /*latest_rtt*/) override {}
-
- QuartcSession* session() { return session_; }
-
- int num_sessions_created() const { return num_sessions_created_; }
-
- QuartcStream* last_incoming_stream() const { return last_incoming_stream_; }
-
- // Returns all received messages.
- const std::vector<std::string>& incoming_messages() const {
- return incoming_messages_;
- }
-
- // Returns all sent datagram ids in the order sent.
- const std::vector<int64_t>& sent_datagram_ids() const {
- return sent_datagram_ids_;
- }
-
- // Returns all ACKEd datagram ids in the order ACKs were received.
- const std::map<int64_t, QuicTime>& acked_datagram_id_to_receive_timestamp()
- const {
- return acked_datagram_id_to_receive_timestamp_;
- }
-
- const std::vector<int64_t>& lost_datagram_ids() const {
- return lost_datagram_ids_;
- }
-
- bool connected() const { return connected_; }
- QuicTime writable_time() const { return writable_time_; }
- QuicTime crypto_handshake_time() const { return crypto_handshake_time_; }
-
- private:
- // Current session.
- QuartcSession* session_ = nullptr;
-
- // Number of new sessions created by the endpoint.
- int num_sessions_created_ = 0;
-
- QuartcStream* last_incoming_stream_;
- std::vector<std::string> incoming_messages_;
- std::vector<int64_t> sent_datagram_ids_;
- std::map<int64_t, QuicTime> acked_datagram_id_to_receive_timestamp_;
- std::vector<int64_t> lost_datagram_ids_;
- bool connected_ = true;
- QuartcStream::Delegate* stream_delegate_;
- QuicTime writable_time_ = QuicTime::Zero();
- QuicTime crypto_handshake_time_ = QuicTime::Zero();
- const QuicClock* clock_;
-};
-
-class FakeQuartcStreamDelegate : public QuartcStream::Delegate {
- public:
- size_t OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool /*fin*/) override {
- size_t bytes_consumed = 0;
- for (size_t i = 0; i < iov_length; ++i) {
- received_data_[stream->id()] += std::string(
- static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
- bytes_consumed += iov[i].iov_len;
- }
- return bytes_consumed;
- }
-
- void OnClose(QuartcStream* stream) override {
- errors_[stream->id()] = stream->stream_error();
- }
-
- void OnBufferChanged(QuartcStream* /*stream*/) override {}
-
- bool has_data() { return !received_data_.empty(); }
- std::map<QuicStreamId, std::string> data() { return received_data_; }
-
- QuicRstStreamErrorCode stream_error(QuicStreamId id) { return errors_[id]; }
-
- private:
- std::map<QuicStreamId, std::string> received_data_;
- std::map<QuicStreamId, QuicRstStreamErrorCode> errors_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_FAKES_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h
deleted file mode 100644
index fe3b083c695..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h
+++ /dev/null
@@ -1,122 +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_QUARTC_QUARTC_INTERVAL_COUNTER_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_INTERVAL_COUNTER_H_
-
-#include <stddef.h>
-#include <vector>
-
-#include "net/third_party/quiche/src/quic/core/quic_interval.h"
-#include "net/third_party/quiche/src/quic/core/quic_interval_set.h"
-
-namespace quic {
-
-// QuartcIntervalCounter counts the number of times each value appears within
-// a set of potentially overlapping intervals.
-//
-// QuartcIntervalCounter is not intended for widespread use. Consider replacing
-// it with a full interval-map if more use cases arise.
-//
-// QuartcIntervalCounter is only suitable for cases where the maximum count is
-// expected to remain low. (For example, counting the number of times the same
-// portions of stream data are lost.) It is inefficient when the maximum count
-// becomes high.
-template <typename T>
-class QuartcIntervalCounter {
- public:
- // Adds |interval| to the counter. The count associated with each value in
- // |interval| is incremented by one. |interval| may overlap with previous
- // intervals added to the counter.
- //
- // For each possible value:
- // - If the value is present in both |interval| and the counter, the count
- // associated with that value is incremented by one.
- // - If the value is present in |interval| but not counter, the count
- // associated with that value is set to one (incremented from zero).
- // - If the value is absent from |interval|, the count is unchanged.
- //
- // Time complexity is O(|MaxCount| * the complexity of adding an interval to a
- // QuicIntervalSet).
- void AddInterval(QuicInterval<T> interval);
-
- // Removes an interval from the counter. This method may be called to prune
- // irrelevant intervals from the counter. This is useful to prevent unbounded
- // growth.
- //
- // Time complexity is O(|MaxCount| * the complexity of removing an interval
- // from a QuicIntervalSet).
- void RemoveInterval(QuicInterval<T> interval);
-
- // Returns the maximum number of times any single value has appeared in
- // intervals added to the counter.
- //
- // Time complexity is constant.
- size_t MaxCount() const { return intervals_by_count_.size(); }
-
- // Returns the maximum number of times a particular value has appeared in
- // intervals added to the counter.
- //
- // Time complexity is O(|MaxCount| * log(number of non-contiguous intervals)).
- size_t Count(const T& value) const;
-
- private:
- // Each entry in this vector represents the intervals of values counted at
- // least i + 1 times, where i is the index of the entry.
- //
- // Whenever an interval is added to the counter, each value in the interval is
- // added to the first entry which does not already contain that value. If
- // part of an interval is already present in the last entry, a new entry is
- // added containing that part.
- //
- // Note that this means each value present in one of the interval sets will be
- // present in all previous sets.
- std::vector<QuicIntervalSet<T>> intervals_by_count_;
-};
-
-template <typename T>
-void QuartcIntervalCounter<T>::AddInterval(QuicInterval<T> interval) {
- // After the Nth iteration, |leftover| contains the parts of |interval| that
- // are already present in the first N entries. These parts of |interval| have
- // been added to the counter more than N times.
- QuicIntervalSet<T> leftover(interval);
- for (auto& intervals : intervals_by_count_) {
- QuicIntervalSet<T> tmp = leftover;
- leftover.Intersection(intervals);
- intervals.Union(tmp);
- }
-
- // Whatever ranges are still in |leftover| are already in all the entries
- // Add a new entry containing |leftover|.
- if (!leftover.Empty()) {
- intervals_by_count_.push_back(leftover);
- }
-}
-
-template <typename T>
-void QuartcIntervalCounter<T>::RemoveInterval(QuicInterval<T> interval) {
- // Remove the interval from each entry in the vector, popping any entries that
- // become empty.
- for (size_t i = intervals_by_count_.size(); i > 0; --i) {
- intervals_by_count_[i - 1].Difference(interval);
- if (intervals_by_count_[i - 1].Empty()) {
- intervals_by_count_.pop_back();
- }
- }
-}
-
-template <typename T>
-size_t QuartcIntervalCounter<T>::Count(const T& value) const {
- // The index of the last entry containing |value| gives its count.
- for (size_t i = intervals_by_count_.size(); i > 0; --i) {
- if (intervals_by_count_[i - 1].Contains(value)) {
- return i;
- }
- }
- return 0;
-}
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_INTERVAL_COUNTER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter_test.cc
deleted file mode 100644
index 028aaf2dab6..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_interval_counter_test.cc
+++ /dev/null
@@ -1,108 +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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h"
-
-#include "net/third_party/quiche/src/quic/core/quic_interval.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
-
-namespace quic {
-namespace {
-
-class QuartcIntervalCounterTest : public QuicTest {
- protected:
- QuartcIntervalCounter<int> counter_;
-};
-
-void ExpectCount(const QuartcIntervalCounter<int>& counter,
- QuicInterval<int> interval,
- size_t count) {
- for (int i = interval.min(); i < interval.max(); ++i) {
- EXPECT_EQ(counter.Count(i), count) << "i=" << i;
- }
-}
-
-TEST_F(QuartcIntervalCounterTest, InitiallyEmpty) {
- EXPECT_EQ(counter_.MaxCount(), 0u);
-}
-
-TEST_F(QuartcIntervalCounterTest, SameInterval) {
- counter_.AddInterval(QuicInterval<int>(0, 6));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 6), 1);
-
- counter_.AddInterval(QuicInterval<int>(0, 6));
- EXPECT_EQ(counter_.MaxCount(), 2u);
- ExpectCount(counter_, QuicInterval<int>(0, 6), 2);
-}
-
-TEST_F(QuartcIntervalCounterTest, DisjointIntervals) {
- counter_.AddInterval(QuicInterval<int>(0, 5));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 5), 1);
- ExpectCount(counter_, QuicInterval<int>(5, 10), 0);
-
- counter_.AddInterval(QuicInterval<int>(5, 10));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 5), 1);
- ExpectCount(counter_, QuicInterval<int>(5, 10), 1);
-}
-
-TEST_F(QuartcIntervalCounterTest, OverlappingIntervals) {
- counter_.AddInterval(QuicInterval<int>(0, 6));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 6), 1);
- ExpectCount(counter_, QuicInterval<int>(6, 10), 0);
-
- counter_.AddInterval(QuicInterval<int>(5, 10));
- EXPECT_EQ(counter_.MaxCount(), 2u);
- ExpectCount(counter_, QuicInterval<int>(0, 5), 1);
- EXPECT_EQ(counter_.Count(5), 2u);
- ExpectCount(counter_, QuicInterval<int>(6, 10), 1);
-}
-
-TEST_F(QuartcIntervalCounterTest, IntervalsWithGapThenOverlap) {
- counter_.AddInterval(QuicInterval<int>(0, 4));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 4), 1);
- ExpectCount(counter_, QuicInterval<int>(4, 10), 0);
-
- counter_.AddInterval(QuicInterval<int>(7, 10));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 4), 1);
- ExpectCount(counter_, QuicInterval<int>(4, 7), 0);
- ExpectCount(counter_, QuicInterval<int>(7, 10), 1);
-
- counter_.AddInterval(QuicInterval<int>(3, 8));
- EXPECT_EQ(counter_.MaxCount(), 2u);
- ExpectCount(counter_, QuicInterval<int>(0, 3), 1);
- EXPECT_EQ(counter_.Count(3), 2u);
- ExpectCount(counter_, QuicInterval<int>(4, 7), 1);
- EXPECT_EQ(counter_.Count(7), 2u);
- ExpectCount(counter_, QuicInterval<int>(8, 10), 1);
-}
-
-TEST_F(QuartcIntervalCounterTest, RemoveIntervals) {
- counter_.AddInterval(QuicInterval<int>(0, 5));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 5), 1);
-
- counter_.AddInterval(QuicInterval<int>(4, 10));
- EXPECT_EQ(counter_.MaxCount(), 2u);
- ExpectCount(counter_, QuicInterval<int>(0, 4), 1);
- EXPECT_EQ(counter_.Count(4), 2u);
- ExpectCount(counter_, QuicInterval<int>(5, 10), 1);
-
- counter_.RemoveInterval(QuicInterval<int>(0, 5));
- EXPECT_EQ(counter_.MaxCount(), 1u);
- ExpectCount(counter_, QuicInterval<int>(0, 5), 0);
- ExpectCount(counter_, QuicInterval<int>(5, 10), 1);
-
- counter_.RemoveInterval(QuicInterval<int>(5, 10));
- EXPECT_EQ(counter_.MaxCount(), 0u);
- ExpectCount(counter_, QuicInterval<int>(0, 10), 0);
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.cc
deleted file mode 100644
index 376fac02c8c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.cc
+++ /dev/null
@@ -1,271 +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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h"
-
-#include <cstdint>
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-QuartcSendChannel::QuartcSendChannel(QuartcMultiplexer* multiplexer,
- uint64_t id,
- QuicBufferAllocator* allocator,
- Delegate* delegate)
- : multiplexer_(multiplexer),
- id_(id),
- encoded_length_(QuicDataWriter::GetVarInt62Len(id_)),
- allocator_(allocator),
- delegate_(delegate) {}
-
-QuartcStream* QuartcSendChannel::CreateOutgoingBidirectionalStream() {
- if (!session_) {
- QUIC_LOG(DFATAL) << "Session is not ready to write yet; channel_id=" << id_;
- return nullptr;
- }
- QuicMemSlice id_slice = EncodeChannelId();
-
- QuartcStream* stream = session_->CreateOutgoingBidirectionalStream();
- QuicConsumedData consumed =
- stream->WriteMemSlices(QuicMemSliceSpan(&id_slice), /*fin=*/false);
- DCHECK_EQ(consumed.bytes_consumed, encoded_length_);
- return stream;
-}
-
-bool QuartcSendChannel::SendOrQueueMessage(QuicMemSliceSpan message,
- int64_t datagram_id) {
- if (!session_) {
- QUIC_LOG(DFATAL) << "Session is not ready to write yet; channel_id=" << id_
- << "datagram size=" << message.total_length();
- return false;
- }
- QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); // Empty storage.
- storage.Append(EncodeChannelId());
-
- message.ConsumeAll(
- [&storage](QuicMemSlice slice) { storage.Append(std::move(slice)); });
-
- // Allocate a unique datagram id so that notifications can be routed back to
- // the right send channel.
- int64_t unique_datagram_id = multiplexer_->AllocateDatagramId(this);
- multiplexer_to_user_datagram_ids_[unique_datagram_id] = datagram_id;
-
- return session_->SendOrQueueMessage(storage.ToSpan(), unique_datagram_id);
-}
-
-void QuartcSendChannel::OnMessageSent(int64_t datagram_id) {
- // Map back to the caller-chosen |datagram_id|.
- datagram_id = multiplexer_to_user_datagram_ids_[datagram_id];
- delegate_->OnMessageSent(datagram_id);
-}
-
-void QuartcSendChannel::OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) {
- // Map back to the caller-chosen |datagram_id|.
- auto it = multiplexer_to_user_datagram_ids_.find(datagram_id);
- if (it == multiplexer_to_user_datagram_ids_.end()) {
- QUIC_LOG(DFATAL) << "Datagram acked/lost multiple times; datagram_id="
- << datagram_id;
- return;
- }
- delegate_->OnMessageAcked(it->second, receive_timestamp);
- multiplexer_to_user_datagram_ids_.erase(it);
-}
-
-void QuartcSendChannel::OnMessageLost(int64_t datagram_id) {
- // Map back to the caller-chosen |datagram_id|.
- auto it = multiplexer_to_user_datagram_ids_.find(datagram_id);
- if (it == multiplexer_to_user_datagram_ids_.end()) {
- QUIC_LOG(DFATAL) << "Datagram acked/lost multiple times; datagram_id="
- << datagram_id;
- return;
- }
- delegate_->OnMessageLost(it->second);
- multiplexer_to_user_datagram_ids_.erase(it);
-}
-
-void QuartcSendChannel::OnSessionCreated(QuartcSession* session) {
- session_ = session;
-}
-
-QuicMemSlice QuartcSendChannel::EncodeChannelId() {
- QuicUniqueBufferPtr buffer = MakeUniqueBuffer(allocator_, encoded_length_);
- QuicDataWriter writer(encoded_length_, buffer.get());
- writer.WriteVarInt62(id_);
- return QuicMemSlice(std::move(buffer), encoded_length_);
-}
-
-QuartcMultiplexer::QuartcMultiplexer(
- QuicBufferAllocator* allocator,
- QuartcSessionEventDelegate* session_delegate,
- QuartcReceiveChannel* default_receive_channel)
- : allocator_(allocator),
- session_delegate_(session_delegate),
- default_receive_channel_(default_receive_channel) {
- CHECK_NE(session_delegate_, nullptr);
- CHECK_NE(default_receive_channel_, nullptr);
-}
-
-QuartcSendChannel* QuartcMultiplexer::CreateSendChannel(
- uint64_t channel_id,
- QuartcSendChannel::Delegate* delegate) {
- send_channels_.push_back(std::make_unique<QuartcSendChannel>(
- this, channel_id, allocator_, delegate));
- if (session_) {
- send_channels_.back()->OnSessionCreated(session_);
- }
- return send_channels_.back().get();
-}
-
-void QuartcMultiplexer::RegisterReceiveChannel(uint64_t channel_id,
- QuartcReceiveChannel* channel) {
- if (channel == nullptr) {
- receive_channels_.erase(channel_id);
- return;
- }
- auto& registered_channel = receive_channels_[channel_id];
- if (registered_channel) {
- QUIC_LOG(DFATAL) << "Attempted to overwrite existing channel_id="
- << channel_id;
- return;
- }
- registered_channel = channel;
-}
-
-int64_t QuartcMultiplexer::AllocateDatagramId(QuartcSendChannel* channel) {
- send_channels_by_datagram_id_[next_datagram_id_] = channel;
- return next_datagram_id_++;
-}
-
-void QuartcMultiplexer::OnSessionCreated(QuartcSession* session) {
- for (auto& channel : send_channels_) {
- channel->OnSessionCreated(session);
- }
- session_ = session;
- session_delegate_->OnSessionCreated(session);
-}
-
-void QuartcMultiplexer::OnCryptoHandshakeComplete() {
- session_delegate_->OnCryptoHandshakeComplete();
-}
-
-void QuartcMultiplexer::OnConnectionWritable() {
- session_delegate_->OnConnectionWritable();
-}
-
-void QuartcMultiplexer::OnIncomingStream(QuartcStream* stream) {
- stream->SetDelegate(this);
-}
-
-void QuartcMultiplexer::OnCongestionControlChange(
- QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) {
- session_delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate,
- latest_rtt);
-}
-
-void QuartcMultiplexer::OnConnectionClosed(
- const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- session_delegate_->OnConnectionClosed(frame, source);
-}
-
-void QuartcMultiplexer::OnMessageReceived(quiche::QuicheStringPiece message) {
- QuicDataReader reader(message);
- QuicVariableLengthIntegerLength channel_id_length =
- reader.PeekVarInt62Length();
-
- uint64_t channel_id;
- if (!reader.ReadVarInt62(&channel_id)) {
- QUIC_LOG(DFATAL) << "Received message without properly encoded channel id";
- return;
- }
-
- QuartcReceiveChannel* channel = default_receive_channel_;
- auto it = receive_channels_.find(channel_id);
- if (it != receive_channels_.end()) {
- channel = it->second;
- }
-
- channel->OnMessageReceived(channel_id, message.substr(channel_id_length));
-}
-
-void QuartcMultiplexer::OnMessageSent(int64_t datagram_id) {
- auto it = send_channels_by_datagram_id_.find(datagram_id);
- if (it == send_channels_by_datagram_id_.end()) {
- return;
- }
- it->second->OnMessageSent(datagram_id);
-}
-
-void QuartcMultiplexer::OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) {
- auto it = send_channels_by_datagram_id_.find(datagram_id);
- if (it == send_channels_by_datagram_id_.end()) {
- return;
- }
- it->second->OnMessageAcked(datagram_id, receive_timestamp);
- send_channels_by_datagram_id_.erase(it);
-}
-
-void QuartcMultiplexer::OnMessageLost(int64_t datagram_id) {
- auto it = send_channels_by_datagram_id_.find(datagram_id);
- if (it == send_channels_by_datagram_id_.end()) {
- return;
- }
- it->second->OnMessageLost(datagram_id);
- send_channels_by_datagram_id_.erase(it);
-}
-
-size_t QuartcMultiplexer::OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool /*fin*/) {
- if (iov == nullptr || iov_length <= 0) {
- return 0;
- }
-
- QuicDataReader reader(static_cast<char*>(iov[0].iov_base), iov[0].iov_len);
- QuicVariableLengthIntegerLength channel_id_length =
- reader.PeekVarInt62Length();
-
- uint64_t channel_id;
- if (reader.BytesRemaining() >= channel_id_length) {
- // Fast path, have enough data to read immediately.
- if (!reader.ReadVarInt62(&channel_id)) {
- return 0;
- }
- } else {
- // Slow path, need to coalesce multiple iovecs.
- std::string data;
- for (size_t i = 0; i < iov_length; ++i) {
- data += std::string(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
- }
- QuicDataReader combined_reader(data);
- if (!combined_reader.ReadVarInt62(&channel_id)) {
- return 0;
- }
- }
-
- QuartcReceiveChannel* channel = default_receive_channel_;
- auto it = receive_channels_.find(channel_id);
- if (it != receive_channels_.end()) {
- channel = it->second;
- }
- channel->OnIncomingStream(channel_id, stream);
- return channel_id_length;
-}
-
-void QuartcMultiplexer::OnClose(QuartcStream* /*stream*/) {}
-
-void QuartcMultiplexer::OnBufferChanged(QuartcStream* /*stream*/) {}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h
deleted file mode 100644
index 1e6c2e5dbdf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h
+++ /dev/null
@@ -1,190 +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_QUARTC_QUARTC_MULTIPLEXER_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_
-
-#include <cstdint>
-
-#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_containers.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-class QuartcMultiplexer;
-
-// A single, multiplexed send channel within a Quartc session. A send channel
-// wraps send-side operations with an outgoing multiplex id.
-class QuartcSendChannel {
- public:
- class Delegate {
- public:
- virtual ~Delegate() = default;
-
- // Called when a message with |datagram_id| is sent by this channel.
- virtual void OnMessageSent(int64_t datagram_id) = 0;
-
- // Called when a message sent on this channel with |datagram_id| is acked.
- // |receive_timestamp| indicates when the peer received this message,
- // according to the peer's clock.
- virtual void OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) = 0;
-
- // Called when a message sent on this channel with |datagram_id| is lost.
- virtual void OnMessageLost(int64_t datagram_id) = 0;
- };
-
- QuartcSendChannel(QuartcMultiplexer* multiplexer,
- uint64_t id,
- QuicBufferAllocator* allocator,
- Delegate* delegate);
- virtual ~QuartcSendChannel() = default;
-
- // Creates a new, outgoing stream on this channel.
- //
- // Automatically writes the channel id to the start of the stream. The caller
- // SHOULD create a |ScopedPacketFlusher| before calling this function to
- // prevent the channel id from being sent by itself.
- QuartcStream* CreateOutgoingBidirectionalStream();
-
- // Writes |message| to the session. Prepends the channel's send id before any
- // following message data.
- bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id);
-
- // Gets the current largest message payload for this channel. Returns the
- // largest payload size supported by the session minus overhead required to
- // encode this channel's send id.
- QuicPacketLength GetCurrentLargestMessagePayload() const;
-
- // The following are called by the multiplexer to deliver message
- // notifications. The |datagram_id| passed to these is unique per-message,
- // and must be translated back to the sender's chosen datagram_id.
- void OnMessageSent(int64_t datagram_id);
- void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp);
- void OnMessageLost(int64_t datagram_id);
- void OnSessionCreated(QuartcSession* session);
-
- private:
- // Creates a mem slice containing a varint-62 encoded channel id.
- QuicMemSlice EncodeChannelId();
-
- QuartcMultiplexer* const multiplexer_;
- const uint64_t id_;
- const QuicVariableLengthIntegerLength encoded_length_;
- QuicBufferAllocator* const allocator_;
- Delegate* const delegate_;
-
- QuartcSession* session_;
-
- // Map of multiplexer-chosen to user/caller-specified datagram ids. The user
- // may specify any number as a datagram's id. This number does not have to be
- // unique across channels (nor even within a single channel). In order
- // to demux sent, acked, and lost messages, the multiplexer assigns a globally
- // unique id to each message. This map is used to restore the original caller
- // datagram id before issuing callbacks.
- QuicHashMap<int64_t, int64_t> multiplexer_to_user_datagram_ids_;
-};
-
-// A single, multiplexed receive channel within a Quartc session. A receive
-// channel is a delegate which accepts incoming streams and datagrams on one (or
-// more) channel ids.
-class QuartcReceiveChannel {
- public:
- virtual ~QuartcReceiveChannel() = default;
-
- // Called when a new incoming stream arrives on this channel.
- virtual void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) = 0;
-
- // Called when a message is recieved by this channel.
- virtual void OnMessageReceived(uint64_t channel_id,
- quiche::QuicheStringPiece message) = 0;
-};
-
-// Delegate for session-wide events.
-class QuartcSessionEventDelegate {
- public:
- virtual ~QuartcSessionEventDelegate() = default;
-
- virtual void OnSessionCreated(QuartcSession* session) = 0;
- virtual void OnCryptoHandshakeComplete() = 0;
- virtual void OnConnectionWritable() = 0;
- virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) = 0;
- virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) = 0;
-};
-
-// A multiplexer capable of sending and receiving data on multiple channels.
-class QuartcMultiplexer : public QuartcEndpoint::Delegate,
- public QuartcStream::Delegate {
- public:
- // Creates a new multiplexer. |session_delegate| handles all session-wide
- // events, while |default_receive_channel| handles incoming data on unknown
- // or unregistered channel ids. Neither |session_delegate| nor
- // |default_receive_channel| may be nullptr, and both must outlive the
- // multiplexer.
- QuartcMultiplexer(QuicBufferAllocator* allocator,
- QuartcSessionEventDelegate* session_delegate,
- QuartcReceiveChannel* default_receive_channel);
-
- // Creates a new send channel. The channel is owned by the multiplexer, and
- // references to it must not outlive the multiplexer.
- QuartcSendChannel* CreateSendChannel(uint64_t channel_id,
- QuartcSendChannel::Delegate* delegate);
-
- // Registers a receiver for incoming data on |channel_id|.
- void RegisterReceiveChannel(uint64_t channel_id,
- QuartcReceiveChannel* channel);
-
- // Allocates a datagram id to |channel|.
- int64_t AllocateDatagramId(QuartcSendChannel* channel);
-
- // QuartcEndpoint::Delegate overrides.
- void OnSessionCreated(QuartcSession* session) override;
-
- // QuartcSession::Delegate overrides.
- void OnCryptoHandshakeComplete() override;
- void OnConnectionWritable() override;
- void OnIncomingStream(QuartcStream* stream) override;
- void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) override;
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
- void OnMessageReceived(quiche::QuicheStringPiece message) override;
- void OnMessageSent(int64_t datagram_id) override;
- void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override;
- void OnMessageLost(int64_t datagram_id) override;
-
- // QuartcStream::Delegate overrides.
- size_t OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool fin) override;
- void OnClose(QuartcStream* stream) override;
- void OnBufferChanged(QuartcStream* stream) override;
-
- private:
- QuicBufferAllocator* const allocator_;
- QuartcSessionEventDelegate* const session_delegate_;
-
- QuartcSession* session_ = nullptr;
- std::vector<std::unique_ptr<QuartcSendChannel>> send_channels_;
- QuicHashMap<uint64_t, QuartcReceiveChannel*> receive_channels_;
- QuartcReceiveChannel* default_receive_channel_ = nullptr;
-
- int64_t next_datagram_id_ = 1;
- QuicHashMap<int64_t, QuartcSendChannel*> send_channels_by_datagram_id_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer_test.cc
deleted file mode 100644
index 024b67d8a94..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_multiplexer_test.cc
+++ /dev/null
@@ -1,496 +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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_multiplexer.h"
-
-#include <memory>
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h"
-#include "net/third_party/quiche/src/quic/core/quic_bandwidth.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_containers.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/platform/api/quic_test_mem_slice_vector.h"
-#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.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 {
-
-using ::testing::ElementsAreArray;
-using ::testing::Gt;
-using ::testing::IsEmpty;
-using ::testing::Pair;
-
-constexpr QuicTime::Delta kPropagationDelay =
- QuicTime::Delta::FromMilliseconds(10);
-
-class FakeSessionEventDelegate : public QuartcSessionEventDelegate {
- public:
- void OnSessionCreated(QuartcSession* session) override {
- session->StartCryptoHandshake();
- session_ = session;
- }
-
- void OnConnectionWritable() override { ++writable_count_; }
-
- void OnCryptoHandshakeComplete() override { ++handshake_count_; }
-
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override {
- error_ = frame.quic_error_code;
- close_source_ = source;
- }
-
- void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) override {
- latest_bandwidth_estimate_ = bandwidth_estimate;
- latest_pacing_rate_ = pacing_rate;
- latest_rtt_ = latest_rtt;
- }
-
- QuartcSession* session() { return session_; }
- int writable_count() const { return writable_count_; }
- int handshake_count() const { return handshake_count_; }
- QuicErrorCode error() const { return error_; }
- ConnectionCloseSource close_source() const { return close_source_; }
- QuicBandwidth latest_bandwidth_estimate() const {
- return latest_bandwidth_estimate_;
- }
- QuicBandwidth latest_pacing_rate() const { return latest_pacing_rate_; }
- QuicTime::Delta latest_rtt() const { return latest_rtt_; }
-
- private:
- QuartcSession* session_ = nullptr;
- int writable_count_ = 0;
- int handshake_count_ = 0;
- QuicErrorCode error_ = QUIC_NO_ERROR;
- ConnectionCloseSource close_source_;
- QuicBandwidth latest_bandwidth_estimate_ = QuicBandwidth::Zero();
- QuicBandwidth latest_pacing_rate_ = QuicBandwidth::Zero();
- QuicTime::Delta latest_rtt_ = QuicTime::Delta::Zero();
-};
-
-class FakeSendDelegate : public QuartcSendChannel::Delegate {
- public:
- void OnMessageSent(int64_t datagram_id) override {
- datagrams_sent_.push_back(datagram_id);
- }
-
- void OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) override {
- datagrams_acked_.push_back({datagram_id, receive_timestamp});
- }
-
- void OnMessageLost(int64_t datagram_id) override {
- datagrams_lost_.push_back(datagram_id);
- }
-
- const std::vector<int64_t>& datagrams_sent() const { return datagrams_sent_; }
- const std::vector<std::pair<int64_t, QuicTime>>& datagrams_acked() const {
- return datagrams_acked_;
- }
- const std::vector<int64_t>& datagrams_lost() const { return datagrams_lost_; }
-
- private:
- std::vector<int64_t> datagrams_sent_;
- std::vector<std::pair<int64_t, QuicTime>> datagrams_acked_;
- std::vector<int64_t> datagrams_lost_;
-};
-
-class FakeReceiveDelegate : public QuartcReceiveChannel,
- public QuartcStream::Delegate {
- public:
- const std::vector<std::pair<uint64_t, std::string>> messages_received()
- const {
- return messages_received_;
- }
-
- void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) override {
- stream->SetDelegate(this);
- stream_to_channel_id_[stream] = channel_id;
- }
-
- void OnMessageReceived(uint64_t channel_id,
- quiche::QuicheStringPiece message) override {
- messages_received_.emplace_back(channel_id, message);
- }
-
- // Stream delegate overrides.
- size_t OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool fin) override {
- if (!fin) {
- return 0;
- }
-
- size_t bytes = 0;
- std::string message;
- for (size_t i = 0; i < iov_length; ++i) {
- message +=
- std::string(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
- bytes += iov[i].iov_len;
- }
- QUIC_LOG(INFO) << "Received " << bytes << " byte message on channel "
- << stream_to_channel_id_[stream];
- messages_received_.emplace_back(stream_to_channel_id_[stream], message);
- return bytes;
- }
-
- void OnClose(QuartcStream* stream) override {
- stream_to_channel_id_.erase(stream);
- }
-
- void OnBufferChanged(QuartcStream* /*stream*/) override {}
-
- private:
- std::vector<std::pair<uint64_t, std::string>> messages_received_;
- QuicUnorderedMap<QuartcStream*, uint64_t> stream_to_channel_id_;
-};
-
-class QuartcMultiplexerTest : public QuicTest {
- public:
- QuartcMultiplexerTest()
- : simulator_(),
- client_transport_(&simulator_,
- "client_transport",
- "server_transport",
- 10 * kDefaultMaxPacketSize),
- server_transport_(&simulator_,
- "server_transport",
- "client_transport",
- 10 * kDefaultMaxPacketSize),
- client_filter_(&simulator_, "client_filter", &client_transport_),
- client_server_link_(&client_filter_,
- &server_transport_,
- QuicBandwidth::FromKBitsPerSecond(10 * 1000),
- kPropagationDelay),
- client_multiplexer_(simulator_.GetStreamSendBufferAllocator(),
- &client_session_delegate_,
- &client_default_receiver_),
- server_multiplexer_(simulator_.GetStreamSendBufferAllocator(),
- &server_session_delegate_,
- &server_default_receiver_),
- client_endpoint_(std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(),
- simulator_.GetClock(),
- simulator_.GetRandomGenerator(),
- &client_multiplexer_,
- quic::QuartcSessionConfig(),
- /*serialized_server_config=*/"")),
- server_endpoint_(std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(),
- simulator_.GetClock(),
- simulator_.GetRandomGenerator(),
- &server_multiplexer_,
- quic::QuartcSessionConfig())) {
- // TODO(b/150224094): Re-enable TLS handshake.
- // TODO(b/150236522): Parametrize by QUIC version.
- quic::test::DisableQuicVersionsWithTls();
- }
-
- void Connect() {
- client_endpoint_->Connect(&client_transport_);
- server_endpoint_->Connect(&server_transport_);
- ASSERT_TRUE(simulator_.RunUntil([this]() {
- return client_session_delegate_.writable_count() > 0 &&
- server_session_delegate_.writable_count() > 0;
- }));
- }
-
- void Disconnect() {
- client_session_delegate_.session()->CloseConnection("test");
- server_session_delegate_.session()->CloseConnection("test");
- }
-
- protected:
- QuartcMultiplexer* client_multiplexer() { return &client_multiplexer_; }
-
- QuartcMultiplexer* server_multiplexer() { return &server_multiplexer_; }
-
- simulator::Simulator simulator_;
-
- simulator::SimulatedQuartcPacketTransport client_transport_;
- simulator::SimulatedQuartcPacketTransport server_transport_;
- simulator::CountingPacketFilter client_filter_;
- simulator::SymmetricLink client_server_link_;
-
- FakeSessionEventDelegate client_session_delegate_;
- FakeSessionEventDelegate server_session_delegate_;
-
- FakeReceiveDelegate client_default_receiver_;
- FakeReceiveDelegate server_default_receiver_;
-
- QuartcMultiplexer client_multiplexer_;
- QuartcMultiplexer server_multiplexer_;
-
- std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
- std::unique_ptr<QuartcServerEndpoint> server_endpoint_;
-};
-
-TEST_F(QuartcMultiplexerTest, MultiplexMessages) {
- Connect();
-
- FakeSendDelegate send_delegate_1;
- QuartcSendChannel* send_channel_1 =
- client_multiplexer()->CreateSendChannel(1, &send_delegate_1);
- FakeSendDelegate send_delegate_2;
- QuartcSendChannel* send_channel_2 =
- client_multiplexer()->CreateSendChannel(2, &send_delegate_2);
-
- FakeReceiveDelegate receive_delegate_1;
- server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1);
-
- int num_messages = 10;
- std::vector<std::pair<uint64_t, std::string>> messages_1;
- messages_1.reserve(num_messages);
- std::vector<std::pair<uint64_t, std::string>> messages_2;
- messages_2.reserve(num_messages);
- std::vector<int64_t> messages_sent_1;
- std::vector<int64_t> messages_sent_2;
- std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers_1;
- std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers_2;
- for (int i = 0; i < num_messages; ++i) {
- messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i));
- test::QuicTestMemSliceVector slice_1(
- {std::make_pair(const_cast<char*>(messages_1.back().second.data()),
- messages_1.back().second.size())});
- send_channel_1->SendOrQueueMessage(slice_1.span(), i);
- messages_sent_1.push_back(i);
- ack_matchers_1.push_back(Pair(i, Gt(QuicTime::Zero())));
-
- messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i));
- test::QuicTestMemSliceVector slice_2(
- {std::make_pair(const_cast<char*>(messages_2.back().second.data()),
- messages_2.back().second.size())});
- // Use i + 5 as the datagram id for channel 2, so that some of the ids
- // overlap and some are disjoint.
- send_channel_2->SendOrQueueMessage(slice_2.span(), i + 5);
- messages_sent_2.push_back(i + 5);
- ack_matchers_2.push_back(Pair(i + 5, Gt(QuicTime::Zero())));
- }
-
- EXPECT_TRUE(simulator_.RunUntil([&send_delegate_1, &send_delegate_2]() {
- return send_delegate_1.datagrams_acked().size() == 10 &&
- send_delegate_2.datagrams_acked().size() == 10;
- }));
-
- EXPECT_EQ(send_delegate_1.datagrams_sent(), messages_sent_1);
- EXPECT_EQ(send_delegate_2.datagrams_sent(), messages_sent_2);
-
- EXPECT_EQ(receive_delegate_1.messages_received(), messages_1);
- EXPECT_EQ(server_default_receiver_.messages_received(), messages_2);
-
- EXPECT_THAT(send_delegate_1.datagrams_acked(),
- ElementsAreArray(ack_matchers_1));
- EXPECT_THAT(send_delegate_2.datagrams_acked(),
- ElementsAreArray(ack_matchers_2));
-}
-
-TEST_F(QuartcMultiplexerTest, MultiplexStreams) {
- FakeSendDelegate send_delegate_1;
- QuartcSendChannel* send_channel_1 =
- client_multiplexer()->CreateSendChannel(1, &send_delegate_1);
- FakeSendDelegate send_delegate_2;
- QuartcSendChannel* send_channel_2 =
- client_multiplexer()->CreateSendChannel(2, &send_delegate_2);
-
- FakeQuartcStreamDelegate fake_send_stream_delegate;
-
- FakeReceiveDelegate receive_delegate_1;
- server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1);
-
- Connect();
-
- int num_messages = 10;
- std::vector<std::pair<uint64_t, std::string>> messages_1;
- messages_1.reserve(num_messages);
- std::vector<std::pair<uint64_t, std::string>> messages_2;
- messages_2.reserve(num_messages);
- for (int i = 0; i < num_messages; ++i) {
- messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i));
- test::QuicTestMemSliceVector slice_1(
- {std::make_pair(const_cast<char*>(messages_1.back().second.data()),
- messages_1.back().second.size())});
- QuartcStream* stream_1 =
- send_channel_1->CreateOutgoingBidirectionalStream();
- stream_1->SetDelegate(&fake_send_stream_delegate);
- stream_1->WriteMemSlices(slice_1.span(), /*fin=*/true);
-
- messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i));
- test::QuicTestMemSliceVector slice_2(
- {std::make_pair(const_cast<char*>(messages_2.back().second.data()),
- messages_2.back().second.size())});
- QuartcStream* stream_2 =
- send_channel_2->CreateOutgoingBidirectionalStream();
- stream_2->SetDelegate(&fake_send_stream_delegate);
- stream_2->WriteMemSlices(slice_2.span(), /*fin=*/true);
- }
-
- EXPECT_TRUE(simulator_.RunUntilOrTimeout(
- [this, &receive_delegate_1]() {
- return receive_delegate_1.messages_received().size() == 10 &&
- server_default_receiver_.messages_received().size() == 10;
- },
- QuicTime::Delta::FromSeconds(5)));
-
- EXPECT_EQ(receive_delegate_1.messages_received(), messages_1);
- EXPECT_EQ(server_default_receiver_.messages_received(), messages_2);
-}
-
-// Tests that datagram-lost callbacks are invoked on the right send channel
-// delegate, and that they work with overlapping datagram ids.
-TEST_F(QuartcMultiplexerTest, MultiplexLostDatagrams) {
- Connect();
- ASSERT_TRUE(simulator_.RunUntil([this]() {
- return client_session_delegate_.handshake_count() > 0 &&
- server_session_delegate_.handshake_count() > 0;
- }));
-
- // Just drop everything we try to send.
- client_filter_.set_packets_to_drop(30);
-
- FakeSendDelegate send_delegate_1;
- QuartcSendChannel* send_channel_1 =
- client_multiplexer()->CreateSendChannel(1, &send_delegate_1);
- FakeSendDelegate send_delegate_2;
- QuartcSendChannel* send_channel_2 =
- client_multiplexer()->CreateSendChannel(2, &send_delegate_2);
-
- FakeQuartcStreamDelegate fake_send_stream_delegate;
-
- FakeReceiveDelegate receive_delegate_1;
- server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate_1);
-
- int num_messages = 10;
- std::vector<std::pair<uint64_t, std::string>> messages_1;
- messages_1.reserve(num_messages);
- std::vector<std::pair<uint64_t, std::string>> messages_2;
- messages_2.reserve(num_messages);
- std::vector<int64_t> messages_sent_1;
- std::vector<int64_t> messages_sent_2;
- for (int i = 0; i < num_messages; ++i) {
- messages_1.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i));
- test::QuicTestMemSliceVector slice_1(
- {std::make_pair(const_cast<char*>(messages_1.back().second.data()),
- messages_1.back().second.size())});
- send_channel_1->SendOrQueueMessage(slice_1.span(), i);
- messages_sent_1.push_back(i);
-
- messages_2.emplace_back(2, quiche::QuicheStrCat("message for 2: ", i));
- test::QuicTestMemSliceVector slice_2(
- {std::make_pair(const_cast<char*>(messages_2.back().second.data()),
- messages_2.back().second.size())});
- // Use i + 5 as the datagram id for channel 2, so that some of the ids
- // overlap and some are disjoint.
- send_channel_2->SendOrQueueMessage(slice_2.span(), i + 5);
- messages_sent_2.push_back(i + 5);
- }
-
- // Now send something retransmittable to prompt loss detection.
- // If we never send anything retransmittable, we will never get acks, and
- // never detect losses.
- messages_1.emplace_back(
- 1, quiche::QuicheStrCat("message for 1: ", num_messages));
- test::QuicTestMemSliceVector slice(
- {std::make_pair(const_cast<char*>(messages_1.back().second.data()),
- messages_1.back().second.size())});
- QuartcStream* stream_1 = send_channel_1->CreateOutgoingBidirectionalStream();
- stream_1->SetDelegate(&fake_send_stream_delegate);
- stream_1->WriteMemSlices(slice.span(), /*fin=*/true);
-
- EXPECT_TRUE(simulator_.RunUntilOrTimeout(
- [&send_delegate_1, &send_delegate_2]() {
- return send_delegate_1.datagrams_lost().size() == 10 &&
- send_delegate_2.datagrams_lost().size() == 10;
- },
- QuicTime::Delta::FromSeconds(60)));
-
- EXPECT_EQ(send_delegate_1.datagrams_lost(), messages_sent_1);
- EXPECT_EQ(send_delegate_2.datagrams_lost(), messages_sent_2);
-
- EXPECT_THAT(send_delegate_1.datagrams_acked(), IsEmpty());
- EXPECT_THAT(send_delegate_2.datagrams_acked(), IsEmpty());
-
- EXPECT_THAT(receive_delegate_1.messages_received(), IsEmpty());
- EXPECT_THAT(server_default_receiver_.messages_received(), IsEmpty());
-}
-
-TEST_F(QuartcMultiplexerTest, UnregisterReceiveChannel) {
- Connect();
-
- FakeSendDelegate send_delegate;
- QuartcSendChannel* send_channel =
- client_multiplexer()->CreateSendChannel(1, &send_delegate);
- FakeQuartcStreamDelegate fake_send_stream_delegate;
-
- FakeReceiveDelegate receive_delegate;
- server_multiplexer()->RegisterReceiveChannel(1, &receive_delegate);
- server_multiplexer()->RegisterReceiveChannel(1, nullptr);
-
- int num_messages = 10;
- std::vector<std::pair<uint64_t, std::string>> messages;
- messages.reserve(num_messages);
- std::vector<int64_t> messages_sent;
- std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers;
- for (int i = 0; i < num_messages; ++i) {
- messages.emplace_back(1, quiche::QuicheStrCat("message for 1: ", i));
- test::QuicTestMemSliceVector slice(
- {std::make_pair(const_cast<char*>(messages.back().second.data()),
- messages.back().second.size())});
- send_channel->SendOrQueueMessage(slice.span(), i);
- messages_sent.push_back(i);
- ack_matchers.push_back(Pair(i, Gt(QuicTime::Zero())));
- }
-
- EXPECT_TRUE(simulator_.RunUntil([&send_delegate]() {
- return send_delegate.datagrams_acked().size() == 10;
- }));
-
- EXPECT_EQ(send_delegate.datagrams_sent(), messages_sent);
- EXPECT_EQ(server_default_receiver_.messages_received(), messages);
- EXPECT_THAT(send_delegate.datagrams_acked(), ElementsAreArray(ack_matchers));
-}
-
-TEST_F(QuartcMultiplexerTest, CloseEvent) {
- Connect();
- Disconnect();
-
- EXPECT_THAT(client_session_delegate_.error(),
- test::IsError(QUIC_CONNECTION_CANCELLED));
- EXPECT_THAT(server_session_delegate_.error(),
- test::IsError(QUIC_CONNECTION_CANCELLED));
-}
-
-TEST_F(QuartcMultiplexerTest, CongestionEvent) {
- Connect();
- ASSERT_TRUE(simulator_.RunUntil([this]() {
- return client_session_delegate_.handshake_count() > 0 &&
- server_session_delegate_.handshake_count() > 0;
- }));
-
- EXPECT_GT(client_session_delegate_.latest_bandwidth_estimate(),
- QuicBandwidth::Zero());
- EXPECT_GT(client_session_delegate_.latest_pacing_rate(),
- QuicBandwidth::Zero());
- EXPECT_GT(client_session_delegate_.latest_rtt(), QuicTime::Delta::Zero());
-}
-
-} // namespace
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.cc
deleted file mode 100644
index f67cc774ea8..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-
-#include <utility>
-
-namespace quic {
-
-std::unique_ptr<PerPacketOptions> QuartcPerPacketOptions::Clone() const {
- return std::make_unique<QuartcPerPacketOptions>(*this);
-}
-
-QuartcPacketWriter::QuartcPacketWriter(QuartcPacketTransport* packet_transport,
- QuicByteCount max_packet_size)
- : packet_transport_(packet_transport), max_packet_size_(max_packet_size) {}
-
-WriteResult QuartcPacketWriter::WritePacket(
- const char* buffer,
- size_t buf_len,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- PerPacketOptions* options) {
- DCHECK(packet_transport_);
-
- QuartcPacketTransport::PacketInfo info;
- QuartcPerPacketOptions* quartc_options =
- static_cast<QuartcPerPacketOptions*>(options);
- if (quartc_options && quartc_options->connection) {
- info.packet_number =
- quartc_options->connection->packet_creator().packet_number();
- }
- int bytes_written = packet_transport_->Write(buffer, buf_len, info);
- if (bytes_written <= 0) {
- writable_ = false;
- return WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK);
- }
- return WriteResult(WRITE_STATUS_OK, bytes_written);
-}
-
-bool QuartcPacketWriter::IsWriteBlocked() const {
- return !writable_;
-}
-
-QuicByteCount QuartcPacketWriter::GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const {
- return max_packet_size_;
-}
-
-void QuartcPacketWriter::SetWritable() {
- writable_ = true;
-}
-
-bool QuartcPacketWriter::SupportsReleaseTime() const {
- return false;
-}
-
-bool QuartcPacketWriter::IsBatchMode() const {
- return false;
-}
-
-char* QuartcPacketWriter::GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) {
- return nullptr;
-}
-
-WriteResult QuartcPacketWriter::Flush() {
- return WriteResult(WRITE_STATUS_OK, 0);
-}
-
-void QuartcPacketWriter::SetPacketTransportDelegate(
- QuartcPacketTransport::Delegate* delegate) {
- packet_transport_->SetDelegate(delegate);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h
deleted file mode 100644
index f3eb885fd53..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
-
-#include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.h"
-
-namespace quic {
-
-// Send and receive packets, like a virtual UDP socket. For example, this
-// could be implemented by WebRTC's IceTransport.
-class QuartcPacketTransport {
- public:
- // Additional metadata provided for each packet written.
- struct PacketInfo {
- QuicPacketNumber packet_number;
- };
-
- // Delegate for packet transport callbacks. Note that the delegate is not
- // thread-safe. Packet transport implementations must ensure that callbacks
- // are synchronized with all other work done by QUIC.
- class Delegate {
- public:
- virtual ~Delegate() = default;
-
- // Called whenever the transport can write.
- virtual void OnTransportCanWrite() = 0;
-
- // Called when the transport receives a packet.
- virtual void OnTransportReceived(const char* data, size_t data_len) = 0;
- };
-
- virtual ~QuartcPacketTransport() {}
-
- // Called by the QuartcPacketWriter when writing packets to the network.
- // Return the number of written bytes. Return 0 if the write is blocked.
- virtual int Write(const char* buffer,
- size_t buf_len,
- const PacketInfo& info) = 0;
-
- // Sets the delegate which must be called when the transport can write or
- // a packet is received. QUIC sets |delegate| to a nonnull pointer when it
- // is ready to process incoming packets and sets |delegate| to nullptr before
- // QUIC is deleted. Implementations may assume |delegate| remains valid until
- // it is set to nullptr.
- virtual void SetDelegate(Delegate* delegate) = 0;
-};
-
-struct QuartcPerPacketOptions : public PerPacketOptions {
- std::unique_ptr<PerPacketOptions> Clone() const override;
-
- // The connection which is sending this packet.
- QuicConnection* connection = nullptr;
-};
-
-// Implements a QuicPacketWriter using a QuartcPacketTransport, which allows a
-// QuicConnection to use (for example), a WebRTC IceTransport.
-class QuartcPacketWriter : public QuicPacketWriter {
- public:
- QuartcPacketWriter(QuartcPacketTransport* packet_transport,
- QuicByteCount max_packet_size);
- ~QuartcPacketWriter() override {}
-
- // The QuicConnection calls WritePacket and the QuicPacketWriter writes them
- // to the QuartcSession::PacketTransport.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
-
- // Whether the underneath |transport_| is blocked. If this returns true,
- // outgoing QUIC packets are queued by QuicConnection until SetWritable() is
- // called.
- bool IsWriteBlocked() const override;
-
- // Maximum size of the QUIC packet which can be written. Users such as WebRTC
- // can set the value through the QuartcFactoryConfig without updating the QUIC
- // code.
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override;
-
- // Sets the packet writer to a writable (non-blocked) state.
- void SetWritable() override;
-
- bool SupportsReleaseTime() const override;
-
- bool IsBatchMode() const override;
-
- char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
-
- WriteResult Flush() override;
-
- void SetPacketTransportDelegate(QuartcPacketTransport::Delegate* delegate);
-
- private:
- // QuartcPacketWriter will not own the transport.
- QuartcPacketTransport* packet_transport_;
- // The maximum size of the packet can be written by this writer.
- QuicByteCount max_packet_size_;
-
- // Whether packets can be written.
- bool writable_ = false;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_PACKET_WRITER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.cc
deleted file mode 100644
index 0a7fca933bf..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.cc
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
-#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_storage.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-namespace {
-
-// Arbitrary server port number for net::QuicCryptoClientConfig.
-const int kQuicServerPort = 0;
-
-} // namespace
-
-QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection,
- Visitor* visitor,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock)
- : QuicSession(connection.get(),
- visitor,
- config,
- supported_versions,
- /*num_expected_unidirectional_static_streams = */ 0),
- connection_(std::move(connection)),
- clock_(clock),
- per_packet_options_(std::make_unique<QuartcPerPacketOptions>()) {
- per_packet_options_->connection = connection_.get();
- connection_->set_per_packet_options(per_packet_options_.get());
-}
-
-QuartcSession::~QuartcSession() {}
-
-QuartcStream* QuartcSession::CreateOutgoingBidirectionalStream() {
- // Use default priority for incoming QUIC streams.
- // TODO(zhihuang): Determine if this value is correct.
- return ActivateDataStream(CreateDataStream(
- GetNextOutgoingBidirectionalStreamId(), QuicStream::kDefaultPriority));
-}
-
-bool QuartcSession::SendOrQueueMessage(QuicMemSliceSpan message,
- int64_t datagram_id) {
- if (!CanSendMessage()) {
- QUIC_LOG(ERROR) << "Quic session does not support SendMessage";
- return false;
- }
-
- if (message.total_length() > GetCurrentLargestMessagePayload()) {
- QUIC_LOG(ERROR) << "Message is too big, message_size="
- << message.total_length()
- << ", GetCurrentLargestMessagePayload="
- << GetCurrentLargestMessagePayload();
- return false;
- }
-
- // There may be other messages in send queue, so we have to add message
- // to the queue and call queue processing helper.
- QueuedMessage queued_message;
- queued_message.datagram_id = datagram_id;
- message.ConsumeAll([&queued_message](QuicMemSlice slice) {
- queued_message.message.Append(std::move(slice));
- });
- send_message_queue_.push_back(std::move(queued_message));
-
- ProcessSendMessageQueue();
-
- return true;
-}
-
-void QuartcSession::ProcessSendMessageQueue() {
- QuicConnection::ScopedPacketFlusher flusher(connection());
- while (!send_message_queue_.empty()) {
- QueuedMessage& it = send_message_queue_.front();
- QuicMemSliceSpan span = it.message.ToSpan();
- const size_t message_size = span.total_length();
- MessageResult result = SendMessage(span);
-
- // Handle errors.
- switch (result.status) {
- case MESSAGE_STATUS_SUCCESS: {
- QUIC_VLOG(1) << "Quartc message sent, message_id=" << result.message_id
- << ", message_size=" << message_size;
-
- auto element = message_to_datagram_id_.find(result.message_id);
-
- DCHECK(element == message_to_datagram_id_.end())
- << "Mapped message_id already exists, message_id="
- << result.message_id << ", datagram_id=" << element->second;
-
- message_to_datagram_id_[result.message_id] = it.datagram_id;
-
- // Notify that datagram was sent.
- session_delegate_->OnMessageSent(it.datagram_id);
- } break;
-
- // If connection is congestion controlled or not writable yet, stop
- // send loop and we'll retry again when we get OnCanWrite notification.
- case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
- case MESSAGE_STATUS_BLOCKED:
- QUIC_VLOG(1) << "Quartc message not sent because connection is blocked"
- << ", message will be retried later, status="
- << result.status << ", message_size=" << message_size;
-
- return;
-
- // Other errors are unexpected. We do not propagate error to Quartc,
- // because writes can be delayed.
- case MESSAGE_STATUS_UNSUPPORTED:
- case MESSAGE_STATUS_TOO_LARGE:
- case MESSAGE_STATUS_INTERNAL_ERROR:
- QUIC_DLOG(DFATAL)
- << "Failed to send quartc message due to unexpected error"
- << ", message will not be retried, status=" << result.status
- << ", message_size=" << message_size;
- break;
- }
-
- send_message_queue_.pop_front();
- }
-}
-
-void QuartcSession::OnCanWrite() {
- // TODO(b/119640244): Since we currently use messages for audio and streams
- // for video, it makes sense to process queued messages first, then call quic
- // core OnCanWrite, which will resend queued streams. Long term we may need
- // better solution especially if quic connection is used for both data and
- // media.
-
- // Process quartc messages that were previously blocked.
- ProcessSendMessageQueue();
-
- QuicSession::OnCanWrite();
-}
-
-bool QuartcSession::SendProbingData() {
- if (QuicSession::SendProbingData()) {
- return true;
- }
-
- // Set transmission type to PROBING_RETRANSMISSION such that the packets will
- // be padded to full.
- SetTransmissionType(PROBING_RETRANSMISSION);
- // TODO(mellem): this sent PING will be retransmitted if it is lost which is
- // not ideal. Consider to send stream data as probing data instead.
- SendPing();
- return true;
-}
-
-void QuartcSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
- QuicSession::SetDefaultEncryptionLevel(level);
- switch (level) {
- case ENCRYPTION_INITIAL:
- break;
- case ENCRYPTION_ZERO_RTT:
- if (connection()->perspective() == Perspective::IS_CLIENT) {
- DCHECK(IsEncryptionEstablished());
- DCHECK(session_delegate_);
- session_delegate_->OnConnectionWritable();
- }
- break;
- case ENCRYPTION_HANDSHAKE:
- break;
- case ENCRYPTION_FORWARD_SECURE:
- // On the server, handshake confirmed is the first time when you can start
- // writing packets.
- DCHECK(IsEncryptionEstablished());
- DCHECK(OneRttKeysAvailable());
-
- DCHECK(session_delegate_);
- session_delegate_->OnConnectionWritable();
- session_delegate_->OnCryptoHandshakeComplete();
- break;
- default:
- QUIC_BUG << "Unknown encryption level: "
- << EncryptionLevelToString(level);
- }
-}
-
-void QuartcSession::OnOneRttKeysAvailable() {
- QuicSession::OnOneRttKeysAvailable();
- // On the server, handshake confirmed is the first time when you can start
- // writing packets.
- DCHECK(IsEncryptionEstablished());
- DCHECK(OneRttKeysAvailable());
-
- DCHECK(session_delegate_);
- session_delegate_->OnConnectionWritable();
- session_delegate_->OnCryptoHandshakeComplete();
-}
-
-void QuartcSession::CancelStream(QuicStreamId stream_id) {
- ResetQuartcStream(stream_id, QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
-}
-
-void QuartcSession::ResetQuartcStream(QuicStreamId stream_id,
- QuicRstStreamErrorCode error) {
- if (!IsOpenStream(stream_id)) {
- return;
- }
- QuicStream* stream = QuicSession::GetOrCreateStream(stream_id);
- if (stream) {
- stream->Reset(error);
- }
-}
-
-void QuartcSession::OnCongestionWindowChange(QuicTime /*now*/) {
- DCHECK(session_delegate_);
- const RttStats* rtt_stats = connection_->sent_packet_manager().GetRttStats();
-
- QuicBandwidth bandwidth_estimate =
- connection_->sent_packet_manager().BandwidthEstimate();
-
- QuicByteCount in_flight =
- connection_->sent_packet_manager().GetBytesInFlight();
- QuicBandwidth pacing_rate =
- connection_->sent_packet_manager().GetSendAlgorithm()->PacingRate(
- in_flight);
-
- session_delegate_->OnCongestionControlChange(bandwidth_estimate, pacing_rate,
- rtt_stats->latest_rtt());
-}
-
-bool QuartcSession::ShouldKeepConnectionAlive() const {
- // TODO(mellem): Quartc may want different keepalive logic than HTTP.
- return GetNumActiveStreams() > 0;
-}
-
-void QuartcSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) {
- QuicSession::OnConnectionClosed(frame, source);
- DCHECK(session_delegate_);
- session_delegate_->OnConnectionClosed(frame, source);
-}
-
-void QuartcSession::CloseConnection(const std::string& details) {
- connection_->CloseConnection(
- QuicErrorCode::QUIC_CONNECTION_CANCELLED, details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-}
-
-void QuartcSession::SetDelegate(Delegate* session_delegate) {
- if (session_delegate_) {
- QUIC_LOG(WARNING) << "The delegate for the session has already been set.";
- }
- session_delegate_ = session_delegate;
- DCHECK(session_delegate_);
-}
-
-void QuartcSession::OnTransportCanWrite() {
- connection()->writer()->SetWritable();
- if (HasDataToWrite()) {
- connection()->OnCanWrite();
- }
-}
-
-void QuartcSession::OnTransportReceived(const char* data, size_t data_len) {
- QuicReceivedPacket packet(data, data_len, clock_->Now());
- ProcessUdpPacket(connection()->self_address(), connection()->peer_address(),
- packet);
-}
-
-void QuartcSession::OnMessageReceived(quiche::QuicheStringPiece message) {
- session_delegate_->OnMessageReceived(message);
-}
-
-void QuartcSession::OnMessageAcked(QuicMessageId message_id,
- QuicTime receive_timestamp) {
- auto element = message_to_datagram_id_.find(message_id);
-
- if (element == message_to_datagram_id_.end()) {
- return;
- }
-
- session_delegate_->OnMessageAcked(/*datagram_id=*/element->second,
- receive_timestamp);
-
- // Free up space -- we should never see message_id again.
- message_to_datagram_id_.erase(element);
-}
-
-void QuartcSession::OnMessageLost(QuicMessageId message_id) {
- auto it = message_to_datagram_id_.find(message_id);
- if (it == message_to_datagram_id_.end()) {
- return;
- }
-
- session_delegate_->OnMessageLost(/*datagram_id=*/it->second);
-
- // Free up space.
- message_to_datagram_id_.erase(it);
-}
-
-QuicStream* QuartcSession::CreateIncomingStream(QuicStreamId id) {
- return ActivateDataStream(CreateDataStream(id, QuicStream::kDefaultPriority));
-}
-
-QuicStream* QuartcSession::CreateIncomingStream(PendingStream* /*pending*/) {
- QUIC_NOTREACHED();
- return nullptr;
-}
-
-std::unique_ptr<QuartcStream> QuartcSession::CreateDataStream(
- QuicStreamId id,
- spdy::SpdyPriority priority) {
- if (GetCryptoStream() == nullptr ||
- !GetCryptoStream()->encryption_established()) {
- // Encryption not active so no stream created
- return nullptr;
- }
- return InitializeDataStream(std::make_unique<QuartcStream>(id, this),
- priority);
-}
-
-std::unique_ptr<QuartcStream> QuartcSession::InitializeDataStream(
- std::unique_ptr<QuartcStream> stream,
- spdy::SpdyPriority priority) {
- // Register the stream to the QuicWriteBlockedList. |priority| is clamped
- // between 0 and 7, with 0 being the highest priority and 7 the lowest
- // priority.
- write_blocked_streams()->UpdateStreamPriority(
- stream->id(), spdy::SpdyStreamPrecedence(priority));
-
- if (IsIncomingStream(stream->id())) {
- DCHECK(session_delegate_);
- // Incoming streams need to be registered with the session_delegate_.
- session_delegate_->OnIncomingStream(stream.get());
- }
- return stream;
-}
-
-QuartcStream* QuartcSession::ActivateDataStream(
- std::unique_ptr<QuartcStream> stream) {
- // Transfer ownership of the data stream to the session via ActivateStream().
- QuartcStream* raw = stream.release();
- if (raw) {
- // Make QuicSession take ownership of the stream.
- ActivateStream(std::unique_ptr<QuicStream>(raw));
- }
- return raw;
-}
-
-QuartcClientSession::QuartcClientSession(
- std::unique_ptr<QuicConnection> connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- std::unique_ptr<QuartcPacketWriter> packet_writer,
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config,
- quiche::QuicheStringPiece server_crypto_config)
- : QuartcSession(std::move(connection),
- /*visitor=*/nullptr,
- config,
- supported_versions,
- clock),
- packet_writer_(std::move(packet_writer)),
- client_crypto_config_(std::move(client_crypto_config)),
- server_config_(server_crypto_config) {
- DCHECK_EQ(QuartcSession::connection()->perspective(), Perspective::IS_CLIENT);
-}
-
-QuartcClientSession::~QuartcClientSession() {
- // The client session is the packet transport delegate, so it must be unset
- // before the session is deleted.
- packet_writer_->SetPacketTransportDelegate(nullptr);
-}
-
-void QuartcClientSession::Initialize() {
- DCHECK(crypto_stream_) << "Do not call QuartcSession::Initialize(), call "
- "StartCryptoHandshake() instead.";
- QuartcSession::Initialize();
-
- // QUIC is ready to process incoming packets after Initialize().
- // Set the packet transport delegate to begin receiving packets.
- packet_writer_->SetPacketTransportDelegate(this);
-}
-
-const QuicCryptoStream* QuartcClientSession::GetCryptoStream() const {
- return crypto_stream_.get();
-}
-
-QuicCryptoStream* QuartcClientSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-void QuartcClientSession::StartCryptoHandshake() {
- QuicServerId server_id(/*host=*/"", kQuicServerPort,
- /*privacy_mode_enabled=*/false);
-
- if (!server_config_.empty()) {
- QuicCryptoServerConfig::ConfigOptions options;
-
- std::string error;
- QuicWallTime now = clock()->WallNow();
- QuicCryptoClientConfig::CachedState::ServerConfigState result =
- client_crypto_config_->LookupOrCreate(server_id)->SetServerConfig(
- server_config_, now,
- /*expiry_time=*/now.Add(QuicTime::Delta::Infinite()), &error);
-
- if (result == QuicCryptoClientConfig::CachedState::SERVER_CONFIG_VALID) {
- DCHECK_EQ(error, "");
- client_crypto_config_->LookupOrCreate(server_id)->SetProof(
- std::vector<std::string>{kDummyCertName}, /*cert_sct=*/"",
- /*chlo_hash=*/"", /*signature=*/"anything");
- } else {
- QUIC_LOG(DFATAL) << "Unable to set server config, error=" << error;
- }
- }
-
- crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
- server_id, this,
- client_crypto_config_->proof_verifier()->CreateDefaultContext(),
- client_crypto_config_.get(), this, /*has_application_state = */ true);
- Initialize();
- crypto_stream_->CryptoConnect();
-}
-
-void QuartcClientSession::OnProofValid(
- const QuicCryptoClientConfig::CachedState& /*cached*/) {
- // TODO(zhihuang): Handle the proof verification.
-}
-
-void QuartcClientSession::OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& /*verify_details*/) {
- // TODO(zhihuang): Handle the proof verification.
-}
-
-QuartcServerSession::QuartcServerSession(
- std::unique_ptr<QuicConnection> connection,
- Visitor* visitor,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- const QuicCryptoServerConfig* server_crypto_config,
- QuicCompressedCertsCache* const compressed_certs_cache,
- QuicCryptoServerStreamBase::Helper* const stream_helper)
- : QuartcSession(std::move(connection),
- visitor,
- config,
- supported_versions,
- clock),
- server_crypto_config_(server_crypto_config),
- compressed_certs_cache_(compressed_certs_cache),
- stream_helper_(stream_helper) {
- DCHECK_EQ(QuartcSession::connection()->perspective(), Perspective::IS_SERVER);
-}
-
-const QuicCryptoStream* QuartcServerSession::GetCryptoStream() const {
- return crypto_stream_.get();
-}
-
-QuicCryptoStream* QuartcServerSession::GetMutableCryptoStream() {
- return crypto_stream_.get();
-}
-
-void QuartcServerSession::StartCryptoHandshake() {
- crypto_stream_ = CreateCryptoServerStream(
- server_crypto_config_, compressed_certs_cache_, this, stream_helper_);
- Initialize();
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.h
deleted file mode 100644
index 66ddfc3617f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session.h
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_SESSION_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_SESSION_H_
-
-#include <memory>
-#include <string>
-
-#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.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"
-#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_mem_slice_storage.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-// QuartcSession owns and manages a QUIC connection.
-class QuartcSession : public QuicSession,
- public QuartcPacketTransport::Delegate {
- public:
- QuartcSession(std::unique_ptr<QuicConnection> connection,
- Visitor* visitor,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock);
- QuartcSession(const QuartcSession&) = delete;
- QuartcSession& operator=(const QuartcSession&) = delete;
- ~QuartcSession() override;
-
- // QuicSession overrides.
- QuartcStream* CreateOutgoingBidirectionalStream();
-
- // Sends short unreliable message using quic message frame (message must fit
- // in one quic packet). If connection is blocked by congestion control,
- // message will be queued and resent later after receiving an OnCanWrite
- // notification.
- //
- // Message size must be <= GetLargestMessagePayload().
- //
- // Supported in quic version 45 or later.
- //
- // Returns false and logs error if message is too long or session does not
- // support SendMessage API. Other unexpected errors during send will not be
- // returned, because messages can be sent later if connection is congestion
- // controlled.
- //
- // |datagram_id| is used to notify when message was sent in
- // Delegate::OnMessageSent.
- //
- // TODO(sukhanov): We can not use QUIC message ID for notifications, because
- // QUIC does not take ownership of messages and if connection is congestion
- // controlled, message is not sent and does not get message id until it is
- // sent successfully. It also creates problem of flow control between
- // messages and streams if they are used together. We discussed it with QUIC
- // team and there are multiple solutions, but for now we have to use our
- // own datagram identification.
- bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id);
-
- // Returns largest message payload acceptable in SendQuartcMessage.
- QuicPacketLength GetCurrentLargestMessagePayload() const {
- return connection()->GetCurrentLargestMessagePayload();
- }
-
- // Return true if transport support message frame.
- bool CanSendMessage() const {
- return VersionSupportsMessageFrames(transport_version());
- }
-
- void SetDefaultEncryptionLevel(EncryptionLevel level) override;
- void OnOneRttKeysAvailable() override;
-
- // QuicConnectionVisitorInterface overrides.
- void OnCongestionWindowChange(QuicTime now) override;
- bool ShouldKeepConnectionAlive() const override;
-
- void OnCanWrite() override;
- bool SendProbingData() override;
-
- void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) override;
-
- // QuartcSession methods.
- virtual void StartCryptoHandshake() = 0;
-
- // Closes the connection with the given human-readable error details.
- // The connection closes with the QUIC_CONNECTION_CANCELLED error code to
- // indicate the application closed it.
- //
- // Informs the peer that the connection has been closed. This prevents the
- // peer from waiting until the connection times out.
- //
- // Cleans up the underlying QuicConnection's state. Closing the connection
- // makes it safe to delete the QuartcSession.
- void CloseConnection(const std::string& details);
-
- // If the given stream is still open, sends a reset frame to cancel it.
- // Note: This method cancels a stream by QuicStreamId rather than by pointer
- // (or by a method on QuartcStream) because QuartcSession (and not
- // the caller) owns the streams. Streams may finish and be deleted before the
- // caller tries to cancel them, rendering the caller's pointers invalid.
- void CancelStream(QuicStreamId stream_id);
-
- // Callbacks called by the QuartcSession to notify the user of the
- // QuartcSession of certain events.
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when the crypto handshake is complete. Crypto handshake on the
- // client is only completed _after_ SHLO is received, but we can actually
- // start sending media data right after CHLO is sent.
- virtual void OnCryptoHandshakeComplete() = 0;
-
- // Connection can be writable even before crypto handshake is complete.
- // In particular, on the client, we can start sending data after sending
- // full CHLO, without waiting for SHLO. This reduces a send delay by 1-rtt.
- //
- // This may be called multiple times.
- virtual void OnConnectionWritable() = 0;
-
- // Called when a new stream is received from the remote endpoint.
- virtual void OnIncomingStream(QuartcStream* stream) = 0;
-
- // Called when network parameters change in response to an ack frame.
- virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
- QuicBandwidth pacing_rate,
- QuicTime::Delta latest_rtt) = 0;
-
- // Called when the connection is closed. This means all of the streams will
- // be closed and no new streams can be created.
- virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
- ConnectionCloseSource source) = 0;
-
- // Called when message (sent as SendMessage) is received.
- virtual void OnMessageReceived(quiche::QuicheStringPiece message) = 0;
-
- // Called when message is sent to QUIC.
- //
- // Takes into account delay due to congestion control, but does not take
- // into account any additional socket delays.
- //
- // Passed |datagram_id| is the same used in SendOrQueueMessage.
- //
- // TODO(sukhanov): We can take into account socket delay, but it's not clear
- // if it's worth doing if we eventually plan to move congestion control to
- // QUIC in QRTP model. If we need to do it, mellem@ thinks it's fairly
- // strtaightforward: QUIC does not know about socket delay, but ICE does. We
- // can tell ICE the QUIC packet number for each packet sent, and it will
- // echo it back to us when the packet actually goes out. We just need to
- // plumb that signal up to RTP's congestion control.
- virtual void OnMessageSent(int64_t datagram_id) = 0;
-
- // Called when message with |datagram_id| gets acked. |receive_timestamp|
- // indicates when the peer received this message, according to its own
- // clock.
- virtual void OnMessageAcked(int64_t datagram_id,
- QuicTime receive_timestamp) = 0;
-
- // Called when message with |datagram_id| is lost.
- virtual void OnMessageLost(int64_t datagram_id) = 0;
-
- // TODO(zhihuang): Add proof verification.
- };
-
- // The |delegate| is not owned by QuartcSession.
- void SetDelegate(Delegate* session_delegate);
-
- // Called when CanWrite() changes from false to true.
- void OnTransportCanWrite() override;
-
- // Called when a packet has been received and should be handled by the
- // QuicConnection.
- void OnTransportReceived(const char* data, size_t data_len) override;
-
- void OnMessageReceived(quiche::QuicheStringPiece message) override;
-
- // Called when message with |message_id| gets acked.
- void OnMessageAcked(QuicMessageId message_id,
- QuicTime receive_timestamp) override;
-
- void OnMessageLost(QuicMessageId message_id) override;
-
- // Returns number of queued (not sent) messages submitted by
- // SendOrQueueMessage. Messages are queued if connection is congestion
- // controlled.
- size_t send_message_queue_size() const { return send_message_queue_.size(); }
-
- protected:
- // QuicSession override.
- QuicStream* CreateIncomingStream(QuicStreamId id) override;
- QuicStream* CreateIncomingStream(PendingStream* pending) override;
-
- std::unique_ptr<QuartcStream> CreateDataStream(QuicStreamId id,
- spdy::SpdyPriority priority);
- // Activates a QuartcStream. The session takes ownership of the stream, but
- // returns an unowned pointer to the stream for convenience.
- QuartcStream* ActivateDataStream(std::unique_ptr<QuartcStream> stream);
-
- void ResetQuartcStream(QuicStreamId stream_id, QuicRstStreamErrorCode error);
-
- const QuicClock* clock() { return clock_; }
-
- private:
- std::unique_ptr<QuartcStream> InitializeDataStream(
- std::unique_ptr<QuartcStream> stream,
- spdy::SpdyPriority priority);
-
- // Holds message until it's sent.
- struct QueuedMessage {
- QueuedMessage() : message(nullptr, 0, nullptr, 0), datagram_id(0) {}
-
- QuicMemSliceStorage message;
- int64_t datagram_id;
- };
-
- void ProcessSendMessageQueue();
-
- // Take ownership of the QuicConnection. Note: if |connection_| changes,
- // the new value of |connection_| must be given to |packet_writer_| before any
- // packets are written. Otherwise, |packet_writer_| will crash.
- std::unique_ptr<QuicConnection> connection_;
-
- // For recording packet receipt time
- const QuicClock* clock_;
-
- // Not owned by QuartcSession.
- Delegate* session_delegate_ = nullptr;
-
- // Options passed to the packet writer for each packet.
- std::unique_ptr<QuartcPerPacketOptions> per_packet_options_;
-
- // Queue of pending messages sent by SendQuartcMessage that were not sent
- // yet or blocked by congestion control. Messages are queued in the order
- // of sent by SendOrQueueMessage().
- QuicCircularDeque<QueuedMessage> send_message_queue_;
-
- // Maps message ids to datagram ids, so we could translate message ACKs
- // received from QUIC to datagram ACKs that are propagated up the stack.
- QuicHashMap<QuicMessageId, int64_t> message_to_datagram_id_;
-};
-
-class QuartcClientSession : public QuartcSession,
- public QuicCryptoClientStream::ProofHandler {
- public:
- QuartcClientSession(
- std::unique_ptr<QuicConnection> connection,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- std::unique_ptr<QuartcPacketWriter> packet_writer,
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config,
- quiche::QuicheStringPiece server_crypto_config);
- QuartcClientSession(const QuartcClientSession&) = delete;
- QuartcClientSession& operator=(const QuartcClientSession&) = delete;
-
- ~QuartcClientSession() override;
-
- // Initialize should not be called on a QuartcSession. Instead, call
- // StartCryptoHandshake().
- // TODO(mellem): Move creation of the crypto stream into Initialize() and
- // remove StartCryptoHandshake() to bring QuartcSession in line with other
- // implementations of QuicSession, which can be started by calling
- // Initialize().
- void Initialize() override;
-
- // Accessors for the client crypto stream.
- QuicCryptoStream* GetMutableCryptoStream() override;
- const QuicCryptoStream* GetCryptoStream() const override;
-
- // Initializes the session and sends a handshake.
- void StartCryptoHandshake() override;
-
- // ProofHandler overrides.
- void OnProofValid(const QuicCryptoClientConfig::CachedState& cached) override;
-
- // Called by the client crypto handshake when proof verification details
- // become available, either because proof verification is complete, or when
- // cached details are used.
- void OnProofVerifyDetailsAvailable(
- const ProofVerifyDetails& verify_details) override;
-
- private:
- // Packet writer used by |connection_|.
- std::unique_ptr<QuartcPacketWriter> packet_writer_;
-
- // Config for QUIC crypto stream.
- std::unique_ptr<QuicCryptoClientConfig> client_crypto_config_;
-
- // Client perspective crypto stream.
- std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
-
- const std::string server_config_;
-};
-
-class QuartcServerSession : public QuartcSession {
- public:
- QuartcServerSession(std::unique_ptr<QuicConnection> connection,
- Visitor* visitor,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicClock* clock,
- const QuicCryptoServerConfig* server_crypto_config,
- QuicCompressedCertsCache* const compressed_certs_cache,
- QuicCryptoServerStreamBase::Helper* const stream_helper);
- QuartcServerSession(const QuartcServerSession&) = delete;
- QuartcServerSession& operator=(const QuartcServerSession&) = delete;
-
- // Accessors for the server crypto stream.
- QuicCryptoStream* GetMutableCryptoStream() override;
- const QuicCryptoStream* GetCryptoStream() const override;
-
- // Initializes the session and prepares to receive a handshake.
- void StartCryptoHandshake() override;
-
- private:
- // Config for QUIC crypto stream.
- const QuicCryptoServerConfig* server_crypto_config_;
-
- // Used by QUIC crypto server stream to track most recently compressed certs.
- QuicCompressedCertsCache* const compressed_certs_cache_;
-
- // This helper is needed to create QuicCryptoServerStream.
- QuicCryptoServerStreamBase::Helper* const stream_helper_;
-
- // Server perspective crypto stream.
- std::unique_ptr<QuicCryptoServerStreamBase> crypto_stream_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_session_test.cc
deleted file mode 100644
index 93172e7c55d..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_session_test.cc
+++ /dev/null
@@ -1,680 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_clock.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"
-#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
-#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_string_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_mem_slice_vector.h"
-#include "net/third_party/quiche/src/quic/quartc/counting_packet_filter.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.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/quic/test_tools/simulator/packet_filter.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.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 {
-
-using ::testing::ElementsAre;
-using ::testing::ElementsAreArray;
-using ::testing::Gt;
-using ::testing::Pair;
-
-constexpr QuicTime::Delta kPropagationDelay =
- QuicTime::Delta::FromMilliseconds(10);
-// Propagation delay and a bit, but no more than full RTT.
-constexpr QuicTime::Delta kPropagationDelayAndABit =
- QuicTime::Delta::FromMilliseconds(12);
-
-static QuicByteCount kDefaultMaxPacketSize = 1200;
-
-test::QuicTestMemSliceVector CreateMemSliceVector(
- quiche::QuicheStringPiece data) {
- return test::QuicTestMemSliceVector(
- {std::pair<char*, size_t>(const_cast<char*>(data.data()), data.size())});
-}
-
-class QuartcSessionTest : public QuicTest {
- public:
- ~QuartcSessionTest() override {}
-
- void Init(bool create_client_endpoint = true) {
- // TODO(b/150224094): Re-enable TLS handshake.
- // TODO(b/150236522): Parametrize by QUIC version.
- quic::test::DisableQuicVersionsWithTls();
-
- client_transport_ =
- std::make_unique<simulator::SimulatedQuartcPacketTransport>(
- &simulator_, "client_transport", "server_transport",
- 10 * kDefaultMaxPacketSize);
- server_transport_ =
- std::make_unique<simulator::SimulatedQuartcPacketTransport>(
- &simulator_, "server_transport", "client_transport",
- 10 * kDefaultMaxPacketSize);
-
- client_filter_ = std::make_unique<simulator::CountingPacketFilter>(
- &simulator_, "client_filter", client_transport_.get());
-
- client_server_link_ = std::make_unique<simulator::SymmetricLink>(
- client_filter_.get(), server_transport_.get(),
- QuicBandwidth::FromKBitsPerSecond(10 * 1000), kPropagationDelay);
-
- client_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>();
- client_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>(
- client_stream_delegate_.get(), simulator_.GetClock());
-
- server_stream_delegate_ = std::make_unique<FakeQuartcStreamDelegate>();
- server_session_delegate_ = std::make_unique<FakeQuartcEndpointDelegate>(
- server_stream_delegate_.get(), simulator_.GetClock());
-
- // No 0-rtt setup, because server config is empty.
- // CannotCreateDataStreamBeforeHandshake depends on 1-rtt setup.
- if (create_client_endpoint) {
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), client_session_delegate_.get(),
- quic::QuartcSessionConfig(),
- /*serialized_server_config=*/"");
- }
- server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), server_session_delegate_.get(),
- quic::QuartcSessionConfig());
- }
-
- // Note that input session config will apply to both server and client.
- // Perspective and packet_transport will be overwritten.
- void CreateClientAndServerSessions(
- const QuartcSessionConfig& /*session_config*/,
- bool init = true) {
- if (init) {
- Init();
- }
-
- server_endpoint_->Connect(server_transport_.get());
- client_endpoint_->Connect(client_transport_.get());
-
- CHECK(simulator_.RunUntil([this] {
- return client_session_delegate_->session() != nullptr &&
- server_session_delegate_->session() != nullptr;
- }));
-
- client_peer_ = client_session_delegate_->session();
- server_peer_ = server_session_delegate_->session();
- }
-
- // Runs all tasks scheduled in the next 200 ms.
- void RunTasks() { simulator_.RunFor(QuicTime::Delta::FromMilliseconds(200)); }
-
- void AwaitHandshake() {
- simulator_.RunUntil([this] {
- return client_peer_->OneRttKeysAvailable() &&
- server_peer_->OneRttKeysAvailable();
- });
- }
-
- // Test handshake establishment and sending/receiving of data for two
- // directions.
- void TestSendReceiveStreams() {
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
- ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
-
- // Now we can establish encrypted outgoing stream.
- QuartcStream* outgoing_stream =
- server_peer_->CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = outgoing_stream->id();
- ASSERT_NE(nullptr, outgoing_stream);
- EXPECT_TRUE(server_peer_->ShouldKeepConnectionAlive());
-
- outgoing_stream->SetDelegate(server_stream_delegate_.get());
-
- // Send a test message from peer 1 to peer 2.
- test::QuicTestMemSliceVector data = CreateMemSliceVector("Hello");
- outgoing_stream->WriteMemSlices(data.span(), /*fin=*/false);
- RunTasks();
-
- // Wait for peer 2 to receive messages.
- ASSERT_TRUE(client_stream_delegate_->has_data());
-
- QuartcStream* incoming = client_session_delegate_->last_incoming_stream();
- ASSERT_TRUE(incoming);
- EXPECT_EQ(incoming->id(), stream_id);
- EXPECT_TRUE(client_peer_->ShouldKeepConnectionAlive());
-
- EXPECT_EQ(client_stream_delegate_->data()[stream_id], "Hello");
- // Send a test message from peer 2 to peer 1.
- test::QuicTestMemSliceVector response = CreateMemSliceVector("Response");
- incoming->WriteMemSlices(response.span(), /*fin=*/false);
- RunTasks();
- // Wait for peer 1 to receive messages.
- ASSERT_TRUE(server_stream_delegate_->has_data());
-
- EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Response");
- }
-
- // Test sending/receiving of messages for two directions.
- void TestSendReceiveMessage() {
- ASSERT_TRUE(server_peer_->CanSendMessage());
- ASSERT_TRUE(client_peer_->CanSendMessage());
-
- // Disable probing retransmissions such that the first message from either
- // side can be sent without being queued.
- client_peer_->connection()->set_fill_up_link_during_probing(false);
- server_peer_->connection()->set_fill_up_link_during_probing(false);
-
- int64_t server_datagram_id = 111;
- int64_t client_datagram_id = 222;
-
- // Send message from peer 1 to peer 2.
- test::QuicTestMemSliceVector message =
- CreateMemSliceVector("Message from server");
- ASSERT_TRUE(
- server_peer_->SendOrQueueMessage(message.span(), server_datagram_id));
-
- // First message in each direction should not be queued.
- EXPECT_EQ(server_peer_->send_message_queue_size(), 0u);
-
- // Wait for peer 2 to receive message.
- RunTasks();
-
- EXPECT_THAT(client_session_delegate_->incoming_messages(),
- testing::ElementsAre("Message from server"));
-
- EXPECT_THAT(server_session_delegate_->sent_datagram_ids(),
- testing::ElementsAre(server_datagram_id));
-
- EXPECT_THAT(
- server_session_delegate_->acked_datagram_id_to_receive_timestamp(),
- ElementsAre(Pair(server_datagram_id, Gt(QuicTime::Zero()))));
-
- // Send message from peer 2 to peer 1.
- message = CreateMemSliceVector("Message from client");
- ASSERT_TRUE(
- client_peer_->SendOrQueueMessage(message.span(), client_datagram_id));
-
- // First message in each direction should not be queued.
- EXPECT_EQ(client_peer_->send_message_queue_size(), 0u);
-
- // Wait for peer 1 to receive message.
- RunTasks();
-
- EXPECT_THAT(server_session_delegate_->incoming_messages(),
- testing::ElementsAre("Message from client"));
-
- EXPECT_THAT(client_session_delegate_->sent_datagram_ids(),
- testing::ElementsAre(client_datagram_id));
-
- EXPECT_THAT(
- client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
- ElementsAre(Pair(client_datagram_id, Gt(QuicTime::Zero()))));
- }
-
- // Test for sending multiple messages that also result in queueing.
- // This is one-way test, which is run in given direction.
- void TestSendReceiveQueuedMessages(bool direction_from_server) {
- // Send until queue_size number of messages are queued.
- constexpr size_t queue_size = 10;
-
- ASSERT_TRUE(server_peer_->CanSendMessage());
- ASSERT_TRUE(client_peer_->CanSendMessage());
-
- QuartcSession* const peer_sending =
- direction_from_server ? server_peer_ : client_peer_;
-
- FakeQuartcEndpointDelegate* const delegate_receiving =
- direction_from_server ? client_session_delegate_.get()
- : server_session_delegate_.get();
-
- FakeQuartcEndpointDelegate* const delegate_sending =
- direction_from_server ? server_session_delegate_.get()
- : client_session_delegate_.get();
-
- // There should be no messages in the queue before we start sending.
- EXPECT_EQ(peer_sending->send_message_queue_size(), 0u);
-
- // Send messages from peer 1 to peer 2 until required number of messages
- // are queued in unsent message queue.
- std::vector<std::string> sent_messages;
- std::vector<int64_t> sent_datagram_ids;
- int64_t current_datagram_id = 0;
- while (peer_sending->send_message_queue_size() < queue_size) {
- sent_messages.push_back(quiche::QuicheStrCat("Sending message, index=",
- sent_messages.size()));
- ASSERT_TRUE(peer_sending->SendOrQueueMessage(
- CreateMemSliceVector(sent_messages.back()).span(),
- current_datagram_id));
-
- sent_datagram_ids.push_back(current_datagram_id);
- ++current_datagram_id;
- }
-
- // Wait for peer 2 to receive all messages.
- RunTasks();
-
- std::vector<testing::Matcher<std::pair<int64_t, QuicTime>>> ack_matchers;
- for (int64_t id : sent_datagram_ids) {
- ack_matchers.push_back(Pair(id, Gt(QuicTime::Zero())));
- }
- EXPECT_EQ(delegate_receiving->incoming_messages(), sent_messages);
- EXPECT_EQ(delegate_sending->sent_datagram_ids(), sent_datagram_ids);
- EXPECT_THAT(delegate_sending->acked_datagram_id_to_receive_timestamp(),
- ElementsAreArray(ack_matchers));
- }
-
- // Test sending long messages:
- // - message of maximum allowed length should succeed
- // - message of > maximum allowed length should fail.
- void TestSendLongMessage() {
- ASSERT_TRUE(server_peer_->CanSendMessage());
- ASSERT_TRUE(client_peer_->CanSendMessage());
-
- // Send message of maximum allowed length.
- std::string message_max_long =
- std::string(server_peer_->GetCurrentLargestMessagePayload(), 'A');
- test::QuicTestMemSliceVector message =
- CreateMemSliceVector(message_max_long);
- ASSERT_TRUE(
- server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
-
- // Send long message which should fail.
- std::string message_too_long =
- std::string(server_peer_->GetCurrentLargestMessagePayload() + 1, 'B');
- message = CreateMemSliceVector(message_too_long);
- ASSERT_FALSE(
- server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/0));
-
- // Wait for peer 2 to receive message.
- RunTasks();
-
- // Client should only receive one message of allowed length.
- EXPECT_THAT(client_session_delegate_->incoming_messages(),
- testing::ElementsAre(message_max_long));
- }
-
- // Test that client and server are not connected after handshake failure.
- void TestDisconnectAfterFailedHandshake() {
- EXPECT_TRUE(!client_session_delegate_->connected());
- EXPECT_TRUE(!server_session_delegate_->connected());
-
- EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
- EXPECT_FALSE(client_peer_->OneRttKeysAvailable());
-
- EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
- EXPECT_FALSE(server_peer_->OneRttKeysAvailable());
- }
-
- protected:
- simulator::Simulator simulator_;
-
- std::unique_ptr<simulator::SimulatedQuartcPacketTransport> client_transport_;
- std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_;
- std::unique_ptr<simulator::CountingPacketFilter> client_filter_;
- std::unique_ptr<simulator::SymmetricLink> client_server_link_;
-
- std::unique_ptr<FakeQuartcStreamDelegate> client_stream_delegate_;
- std::unique_ptr<FakeQuartcEndpointDelegate> client_session_delegate_;
- std::unique_ptr<FakeQuartcStreamDelegate> server_stream_delegate_;
- std::unique_ptr<FakeQuartcEndpointDelegate> server_session_delegate_;
-
- std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
- std::unique_ptr<QuartcServerEndpoint> server_endpoint_;
-
- QuartcSession* client_peer_ = nullptr;
- QuartcSession* server_peer_ = nullptr;
-};
-
-TEST_F(QuartcSessionTest, SendReceiveStreams) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- TestSendReceiveStreams();
-}
-
-TEST_F(QuartcSessionTest, SendReceiveMessages) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- TestSendReceiveMessage();
-}
-
-TEST_F(QuartcSessionTest, SendReceiveQueuedMessages) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- TestSendReceiveQueuedMessages(/*direction_from_server=*/true);
- TestSendReceiveQueuedMessages(/*direction_from_server=*/false);
-}
-
-TEST_F(QuartcSessionTest, SendMultiMemSliceMessage) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- ASSERT_TRUE(server_peer_->CanSendMessage());
-
- std::vector<std::pair<char*, size_t>> buffers;
- char first_piece[] = "Hello, ";
- char second_piece[] = "world!";
- buffers.emplace_back(first_piece, 7);
- buffers.emplace_back(second_piece, 6);
- test::QuicTestMemSliceVector message(buffers);
- ASSERT_TRUE(
- server_peer_->SendOrQueueMessage(message.span(), /*datagram_id=*/1));
-
- // Wait for the client to receive the message.
- RunTasks();
-
- // The message is not fragmented along MemSlice boundaries.
- EXPECT_THAT(client_session_delegate_->incoming_messages(),
- testing::ElementsAre("Hello, world!"));
-}
-
-TEST_F(QuartcSessionTest, SendMessageFails) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- TestSendLongMessage();
-}
-
-TEST_F(QuartcSessionTest, TestCryptoHandshakeCanWriteTriggers) {
- CreateClientAndServerSessions(QuartcSessionConfig());
-
- AwaitHandshake();
-
- RunTasks();
-
- ASSERT_TRUE(client_session_delegate_->writable_time().IsInitialized());
- ASSERT_TRUE(
- client_session_delegate_->crypto_handshake_time().IsInitialized());
- // On client, we are writable 1-rtt before crypto handshake is complete.
- ASSERT_LT(client_session_delegate_->writable_time(),
- client_session_delegate_->crypto_handshake_time());
-
- ASSERT_TRUE(server_session_delegate_->writable_time().IsInitialized());
- ASSERT_TRUE(
- server_session_delegate_->crypto_handshake_time().IsInitialized());
- // On server, the writable time and crypto handshake are the same. (when SHLO
- // is sent).
- ASSERT_EQ(server_session_delegate_->writable_time(),
- server_session_delegate_->crypto_handshake_time());
-}
-
-TEST_F(QuartcSessionTest, PreSharedKeyHandshake) {
- QuartcSessionConfig config;
- config.pre_shared_key = "foo";
- CreateClientAndServerSessions(config);
- AwaitHandshake();
- TestSendReceiveStreams();
- TestSendReceiveMessage();
-}
-
-// Test that data streams are not created before handshake.
-TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- EXPECT_EQ(nullptr, server_peer_->CreateOutgoingBidirectionalStream());
- EXPECT_EQ(nullptr, client_peer_->CreateOutgoingBidirectionalStream());
-}
-
-TEST_F(QuartcSessionTest, CancelQuartcStream) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
- ASSERT_NE(nullptr, stream);
-
- uint32_t id = stream->id();
- EXPECT_FALSE(client_peer_->IsClosedStream(id));
- stream->SetDelegate(client_stream_delegate_.get());
- client_peer_->CancelStream(id);
- EXPECT_EQ(stream->stream_error(),
- QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
- EXPECT_TRUE(client_peer_->IsClosedStream(id));
-}
-
-// TODO(b/112561077): This is the wrong layer for this test. We should write a
-// test specifically for QuartcPacketWriter with a stubbed-out
-// QuartcPacketTransport and remove
-// SimulatedQuartcPacketTransport::last_packet_number().
-TEST_F(QuartcSessionTest, WriterGivesPacketNumberToTransport) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
- stream->SetDelegate(client_stream_delegate_.get());
-
- test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
- stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
- RunTasks();
-
- // The transport should see the latest packet number sent by QUIC.
- EXPECT_EQ(
- client_transport_->last_packet_number(),
- client_peer_->connection()->sent_packet_manager().GetLargestSentPacket());
-}
-
-TEST_F(QuartcSessionTest, CloseConnection) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- client_peer_->CloseConnection("Connection closed by client");
- EXPECT_FALSE(client_session_delegate_->connected());
- RunTasks();
- EXPECT_FALSE(server_session_delegate_->connected());
-}
-
-TEST_F(QuartcSessionTest, StreamRetransmissionEnabled) {
- CreateClientAndServerSessions(QuartcSessionConfig());
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
- stream->SetDelegate(client_stream_delegate_.get());
- stream->set_cancel_on_loss(false);
-
- client_filter_->set_packets_to_drop(1);
-
- test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
- stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
- RunTasks();
-
- // Stream data should make it despite packet loss.
- ASSERT_TRUE(server_stream_delegate_->has_data());
- EXPECT_EQ(server_stream_delegate_->data()[stream_id], "Hello");
-}
-
-TEST_F(QuartcSessionTest, StreamRetransmissionDisabled) {
- // Disable tail loss probe, otherwise test maybe flaky because dropped
- // message will be retransmitted to detect tail loss.
- QuartcSessionConfig session_config;
- session_config.enable_tail_loss_probe = false;
- CreateClientAndServerSessions(session_config);
-
- // Disable probing retransmissions, otherwise test maybe flaky because dropped
- // message will be retransmitted to to probe for more bandwidth.
- client_peer_->connection()->set_fill_up_link_during_probing(false);
-
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- // The client sends an ACK for the crypto handshake next. This must be
- // flushed before we set the filter to drop the next packet, in order to
- // ensure that the filter drops a data-bearing packet instead of just an ack.
- RunTasks();
-
- QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
- QuicStreamId stream_id = stream->id();
- stream->SetDelegate(client_stream_delegate_.get());
- stream->set_cancel_on_loss(true);
-
- client_filter_->set_packets_to_drop(1);
-
- test::QuicTestMemSliceVector stream_data = CreateMemSliceVector("Hello");
- stream->WriteMemSlices(stream_data.span(), /*fin=*/false);
- simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
-
- // Send another packet to trigger loss detection.
- QuartcStream* stream_1 = client_peer_->CreateOutgoingBidirectionalStream();
- stream_1->SetDelegate(client_stream_delegate_.get());
-
- test::QuicTestMemSliceVector stream_data_1 =
- CreateMemSliceVector("Second message");
- stream_1->WriteMemSlices(stream_data_1.span(), /*fin=*/false);
- RunTasks();
-
- // QUIC should try to retransmit the first stream by loss detection. Instead,
- // it will cancel itself.
- EXPECT_THAT(server_stream_delegate_->data()[stream_id], testing::IsEmpty());
-
- EXPECT_TRUE(client_peer_->IsClosedStream(stream_id));
- EXPECT_TRUE(server_peer_->IsClosedStream(stream_id));
- EXPECT_THAT(client_stream_delegate_->stream_error(stream_id),
- test::IsStreamError(QUIC_STREAM_CANCELLED));
- EXPECT_THAT(server_stream_delegate_->stream_error(stream_id),
- test::IsStreamError(QUIC_STREAM_CANCELLED));
-}
-
-TEST_F(QuartcSessionTest, LostDatagramNotifications) {
- // Disable tail loss probe, otherwise test maybe flaky because dropped
- // message will be retransmitted to detect tail loss.
- QuartcSessionConfig session_config;
- session_config.enable_tail_loss_probe = false;
- CreateClientAndServerSessions(session_config);
-
- // Disable probing retransmissions, otherwise test maybe flaky because dropped
- // message will be retransmitted to to probe for more bandwidth.
- client_peer_->connection()->set_fill_up_link_during_probing(false);
- server_peer_->connection()->set_fill_up_link_during_probing(false);
-
- AwaitHandshake();
- ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
- ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
-
- // The client sends an ACK for the crypto handshake next. This must be
- // flushed before we set the filter to drop the next packet, in order to
- // ensure that the filter drops a data-bearing packet instead of just an ack.
- RunTasks();
-
- // Drop the next packet.
- client_filter_->set_packets_to_drop(1);
-
- test::QuicTestMemSliceVector message =
- CreateMemSliceVector("This message will be lost");
- ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 1));
-
- RunTasks();
-
- // Send another packet to elicit an ack and trigger loss detection.
- message = CreateMemSliceVector("This message will arrive");
- ASSERT_TRUE(client_peer_->SendOrQueueMessage(message.span(), 2));
-
- RunTasks();
-
- EXPECT_THAT(server_session_delegate_->incoming_messages(),
- ElementsAre("This message will arrive"));
- EXPECT_THAT(client_session_delegate_->sent_datagram_ids(), ElementsAre(1, 2));
- EXPECT_THAT(
- client_session_delegate_->acked_datagram_id_to_receive_timestamp(),
- ElementsAre(Pair(2, Gt(QuicTime::Zero()))));
- EXPECT_THAT(client_session_delegate_->lost_datagram_ids(), ElementsAre(1));
-}
-
-TEST_F(QuartcSessionTest, ServerRegistersAsWriteBlocked) {
- // Initialize client and server session, but with the server write-blocked.
- Init();
- server_transport_->SetWritable(false);
- CreateClientAndServerSessions(QuartcSessionConfig(), /*init=*/false);
-
- // Let the client send a few copies of the CHLO. The server can't respond, as
- // it's still write-blocked.
- RunTasks();
-
- // Making the server's transport writable should trigger a callback that
- // reaches the server session, allowing it to write packets.
- server_transport_->SetWritable(true);
-
- // Now the server should respond with the SHLO, encryption should be
- // established, and data should flow normally.
- // Note that if the server is *not* correctly registered as write-blocked,
- // it will crash here (see b/124527328 for details).
- AwaitHandshake();
- TestSendReceiveStreams();
-}
-
-TEST_F(QuartcSessionTest, PreSharedKeyHandshakeIs0RTT) {
- QuartcSessionConfig session_config;
- session_config.pre_shared_key = "foo";
-
- // Client endpoint is created below. Destructing client endpoint
- // causes issues with the simulator.
- Init(/*create_client_endpoint=*/false);
-
- server_endpoint_->Connect(server_transport_.get());
-
- client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
- simulator_.GetAlarmFactory(), simulator_.GetClock(),
- simulator_.GetRandomGenerator(), client_session_delegate_.get(),
- QuartcSessionConfig(),
- // This is the key line here. It passes through the server config
- // from the server to the client.
- server_endpoint_->server_crypto_config());
-
- client_endpoint_->Connect(client_transport_.get());
-
- // Running for 1ms. This is shorter than the RTT, so the
- // client session should be created, but server won't be created yet.
- simulator_.RunFor(QuicTime::Delta::FromMilliseconds(1));
-
- client_peer_ = client_session_delegate_->session();
- server_peer_ = server_session_delegate_->session();
-
- ASSERT_NE(client_peer_, nullptr);
- ASSERT_EQ(server_peer_, nullptr);
-
- // Write data to the client before running tasks. This should be sent by the
- // client and received by the server if the handshake is 0RTT.
- // If this test fails, add 'RunTasks()' above, and see what error is sent
- // by the server in the rejection message.
- QuartcStream* stream = client_peer_->CreateOutgoingBidirectionalStream();
- ASSERT_NE(stream, nullptr);
- QuicStreamId stream_id = stream->id();
- stream->SetDelegate(client_stream_delegate_.get());
-
- char message[] = "Hello in 0RTTs!";
- test::QuicTestMemSliceVector data({std::make_pair(message, strlen(message))});
- stream->WriteMemSlices(data.span(), /*fin=*/false);
-
- // This will now run the rest of the connection. But the
- // Server peer will receive the CHLO and message after 1 delay.
- simulator_.RunFor(kPropagationDelayAndABit);
-
- // If we can decrypt the data, it means that 0 rtt was successful.
- // This is because we waited only a propagation delay. So if the decryption
- // failed, we would send sREJ instead of SHLO, but it wouldn't be delivered to
- // the client yet.
- ASSERT_TRUE(server_stream_delegate_->has_data());
- EXPECT_EQ(server_stream_delegate_->data()[stream_id], message);
-}
-
-} // namespace
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.cc
deleted file mode 100644
index 01494c5ddf5..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-
-#include <memory>
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h"
-#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
-#include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h"
-#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
-#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.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 {
-
-QuartcStream::QuartcStream(QuicStreamId id, QuicSession* session)
- : QuicStream(id, session, /*is_static=*/false, BIDIRECTIONAL) {
- sequencer()->set_level_triggered(true);
-}
-
-QuartcStream::~QuartcStream() {}
-
-void QuartcStream::OnDataAvailable() {
- size_t bytes_consumed = 0;
- do {
- bool fin = sequencer()->ReadableBytes() + sequencer()->NumBytesConsumed() ==
- sequencer()->close_offset();
-
- // Upper bound on number of readable regions. Each complete block's worth
- // of data crosses at most one region boundary. The remainder may cross one
- // more boundary. Number of regions is one more than the number of region
- // boundaries crossed.
- size_t iov_length = sequencer()->ReadableBytes() /
- QuicStreamSequencerBuffer::kBlockSizeBytes +
- 2;
- std::unique_ptr<iovec[]> iovecs = std::make_unique<iovec[]>(iov_length);
- iov_length = sequencer()->GetReadableRegions(iovecs.get(), iov_length);
-
- bytes_consumed = delegate_->OnReceived(this, iovecs.get(), iov_length, fin);
- sequencer()->MarkConsumed(bytes_consumed);
- if (sequencer()->IsClosed()) {
- OnFinRead();
- break;
- }
- } while (bytes_consumed > 0);
-}
-
-void QuartcStream::OnClose() {
- QuicStream::OnClose();
- DCHECK(delegate_);
- delegate_->OnClose(this);
-}
-
-void QuartcStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
- QuicStream::OnStreamDataConsumed(bytes_consumed);
-
- if (delegate_) {
- delegate_->OnBufferChanged(this);
- }
-}
-
-void QuartcStream::OnDataBuffered(
- QuicStreamOffset /*offset*/,
- QuicByteCount /*data_length*/,
- const QuicReferenceCountedPointer<
- QuicAckListenerInterface>& /*ack_listener*/) {
- if (delegate_) {
- delegate_->OnBufferChanged(this);
- }
-}
-
-bool QuartcStream::OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) {
- // Previous losses of acked data are no longer relevant to the retransmission
- // count. Once data is acked, it will never be retransmitted.
- lost_frame_counter_.RemoveInterval(
- QuicInterval<QuicStreamOffset>(offset, offset + data_length));
-
- return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
- ack_delay_time, receive_timestamp,
- newly_acked_length);
-}
-
-void QuartcStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) {
- QuicStream::OnStreamFrameRetransmitted(offset, data_length,
- fin_retransmitted);
-
- DCHECK(delegate_);
- delegate_->OnBufferChanged(this);
-}
-
-void QuartcStream::OnStreamFrameLost(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_lost) {
- QuicStream::OnStreamFrameLost(offset, data_length, fin_lost);
-
- lost_frame_counter_.AddInterval(
- QuicInterval<QuicStreamOffset>(offset, offset + data_length));
-
- DCHECK(delegate_);
- delegate_->OnBufferChanged(this);
-}
-
-void QuartcStream::OnCanWrite() {
- if (lost_frame_counter_.MaxCount() >
- static_cast<size_t>(max_retransmission_count_) &&
- HasPendingRetransmission()) {
- Reset(QUIC_STREAM_CANCELLED);
- return;
- }
- QuicStream::OnCanWrite();
-}
-
-bool QuartcStream::cancel_on_loss() {
- return max_retransmission_count_ == 0;
-}
-
-void QuartcStream::set_cancel_on_loss(bool cancel_on_loss) {
- if (cancel_on_loss) {
- max_retransmission_count_ = 0;
- } else {
- max_retransmission_count_ = std::numeric_limits<int>::max();
- }
-}
-
-int QuartcStream::max_retransmission_count() const {
- return max_retransmission_count_;
-}
-
-void QuartcStream::set_max_retransmission_count(int max_retransmission_count) {
- max_retransmission_count_ = max_retransmission_count;
-}
-
-QuicByteCount QuartcStream::BytesPendingRetransmission() {
- if (lost_frame_counter_.MaxCount() >
- static_cast<size_t>(max_retransmission_count_)) {
- return 0; // Lost bytes will never be retransmitted.
- }
- QuicByteCount bytes = 0;
- for (const auto& interval : send_buffer().pending_retransmissions()) {
- bytes += interval.Length();
- }
- return bytes;
-}
-
-QuicStreamOffset QuartcStream::ReadOffset() {
- return sequencer()->NumBytesConsumed();
-}
-
-void QuartcStream::FinishWriting() {
- WriteOrBufferData(quiche::QuicheStringPiece(nullptr, 0), true, nullptr);
-}
-
-void QuartcStream::SetDelegate(Delegate* delegate) {
- delegate_ = delegate;
- DCHECK(delegate_);
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.h b/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.h
deleted file mode 100644
index 7f3c28d005c..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 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_QUIC_QUARTC_QUARTC_STREAM_H_
-#define QUICHE_QUIC_QUARTC_QUARTC_STREAM_H_
-
-#include <stddef.h>
-#include <limits>
-
-#include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.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_mem_slice_span.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h"
-#include "net/quic/platform/impl/quic_export_impl.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_interval_counter.h"
-
-namespace quic {
-
-// Sends and receives data with a particular QUIC stream ID, reliably and
-// in-order. To send/receive data out of order, use separate streams. To
-// send/receive unreliably, close a stream after reliability is no longer
-// needed.
-class QuartcStream : public QuicStream {
- public:
- QuartcStream(QuicStreamId id, QuicSession* session);
-
- ~QuartcStream() override;
-
- // QuicStream overrides.
- void OnDataAvailable() override;
-
- void OnClose() override;
-
- void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
-
- void OnDataBuffered(
- QuicStreamOffset offset,
- QuicByteCount data_length,
- const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener)
- override;
-
- bool OnStreamFrameAcked(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_acked,
- QuicTime::Delta ack_delay_time,
- QuicTime receive_timestamp,
- QuicByteCount* newly_acked_length) override;
-
- void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_retransmitted) override;
-
- void OnStreamFrameLost(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_lost) override;
-
- void OnCanWrite() override;
-
- // QuartcStream interface methods.
-
- // Whether the stream should be cancelled instead of retransmitted on loss.
- // If set to true, the stream will reset itself instead of retransmitting lost
- // stream frames. Defaults to false. Setting it to true is equivalent to
- // setting |max_retransmission_count| to zero.
- bool cancel_on_loss();
- void set_cancel_on_loss(bool cancel_on_loss);
-
- // Maximum number of times this stream's data may be retransmitted. Each byte
- // of stream data may be retransmitted this many times. If any byte (or range
- // of bytes) is lost and would be retransmitted more than this number of
- // times, the stream resets itself instead of retransmitting the data again.
- // Setting this value to zero disables retransmissions.
- //
- // Note that this limit applies only to stream data, not to the FIN bit. If
- // only the FIN bit needs to be retransmitted, there is no benefit to
- // cancelling the stream and sending a reset frame instead.
- int max_retransmission_count() const;
- void set_max_retransmission_count(int max_retransmission_count);
-
- QuicByteCount BytesPendingRetransmission();
-
- // Returns the current read offset for this stream. During a call to
- // Delegate::OnReceived, this value is the offset of the first byte read.
- QuicStreamOffset ReadOffset();
-
- // Marks this stream as finished writing. Asynchronously sends a FIN and
- // closes the write-side. It is not necessary to call FinishWriting() if the
- // last call to Write() sends a FIN.
- void FinishWriting();
-
- // Implemented by the user of the QuartcStream to receive incoming
- // data and be notified of state changes.
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called when the stream receives data. |iov| is a pointer to the first of
- // |iov_length| readable regions. |iov| points to readable data within
- // |stream|'s sequencer buffer. QUIC may modify or delete this data after
- // the application consumes it. |fin| indicates the end of stream data.
- // Returns the number of bytes consumed. May return 0 if the delegate is
- // unable to consume any bytes at this time.
- virtual size_t OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool fin) = 0;
-
- // Called when the stream is closed, either locally or by the remote
- // endpoint. Streams close when (a) fin bits are both sent and received,
- // (b) Close() is called, or (c) the stream is reset.
- // TODO(zhihuang) Creates a map from the integer error_code to WebRTC native
- // error code.
- virtual void OnClose(QuartcStream* stream) = 0;
-
- // Called when the contents of the stream's buffer changes.
- virtual void OnBufferChanged(QuartcStream* stream) = 0;
- };
-
- // The |delegate| is not owned by QuartcStream.
- void SetDelegate(Delegate* delegate);
-
- private:
- Delegate* delegate_ = nullptr;
-
- // Maximum number of times this stream's data may be retransmitted.
- int max_retransmission_count_ = std::numeric_limits<int>::max();
-
- // Counter which tracks the number of times each frame has been lost
- // (accounting for the possibility of overlapping frames).
- //
- // If the maximum count of any lost frame exceeds |max_retransmission_count_|,
- // the stream will cancel itself on the next attempt to retransmit data (the
- // next call to |OnCanWrite|).
- QuartcIntervalCounter<QuicStreamOffset> lost_frame_counter_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_QUARTC_STREAM_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream_test.cc
deleted file mode 100644
index b387e7f9723..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/quartc_stream_test.cc
+++ /dev/null
@@ -1,656 +0,0 @@
-// Copyright (c) 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.
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
-
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
-#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
-#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
-#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_clock.h"
-#include "net/third_party/quiche/src/quic/core/quic_config.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
-#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
-#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
-#include "net/third_party/quiche/src/quic/core/quic_packet_writer.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"
-#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/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/core/quic_versions.h"
-#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_flags.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/platform/api/quic_test_mem_slice_vector.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_factory.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_endian.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-
-using ::quic::test::IsQuicStreamNoError;
-using ::quic::test::IsStreamError;
-
-namespace quic {
-
-namespace {
-
-static const QuicStreamId kStreamId = 5;
-
-// MockQuicSession that does not create streams and writes data from
-// QuicStream to a string.
-class MockQuicSession : public QuicSession {
- public:
- MockQuicSession(QuicConnection* connection,
- const QuicConfig& config,
- std::string* write_buffer)
- : QuicSession(connection,
- nullptr /*visitor*/,
- config,
- CurrentSupportedVersions(),
- /*num_expected_unidirectional_static_streams = */ 0),
- write_buffer_(write_buffer) {}
-
- ~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 {
- if (!writable_) {
- return QuicConsumedData(0, false);
- }
-
- // WritevData does not pass down a iovec, data is saved in stream before
- // data is consumed. Retrieve data from stream.
- char* buf = new char[write_length];
- QuicDataWriter writer(write_length, buf, quiche::NETWORK_BYTE_ORDER);
- QuicStream* stream = GetOrCreateStream(id);
- DCHECK(stream);
- if (write_length > 0) {
- stream->WriteStreamData(offset, write_length, &writer);
- }
- write_buffer_->append(buf, write_length);
- delete[] buf;
- return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
- }
-
- QuartcStream* CreateIncomingStream(QuicStreamId /*id*/) override {
- return nullptr;
- }
-
- QuartcStream* CreateIncomingStream(PendingStream* /*pending*/) override {
- return nullptr;
- }
-
- const QuicCryptoStream* GetCryptoStream() const override { return nullptr; }
- QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; }
- bool ShouldKeepConnectionAlive() const override {
- return GetNumActiveStreams() > 0;
- }
-
- // Called by QuicStream when they want to close stream.
- void SendRstStream(QuicStreamId /*id*/,
- QuicRstStreamErrorCode /*error*/,
- QuicStreamOffset /*bytes_written*/) override {}
-
- // Sets whether data is written to buffer, or else if this is write blocked.
- void set_writable(bool writable) { writable_ = writable; }
-
- // Tracks whether the stream is write blocked and its priority.
- void RegisterReliableStream(QuicStreamId stream_id,
- spdy::SpdyPriority priority) {
- write_blocked_streams()->RegisterStream(
- stream_id,
- /*is_static_stream=*/false, spdy::SpdyStreamPrecedence(priority));
- }
-
- // The session take ownership of the stream.
- void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
- ActivateStream(std::move(stream));
- }
-
- private:
- // Stores written data from ReliableQuicStreamAdapter.
- std::string* write_buffer_;
- // Whether data is written to write_buffer_.
- bool writable_ = true;
-};
-
-// Packet writer that does nothing. This is required for QuicConnection but
-// isn't used for writing data.
-class DummyPacketWriter : public QuicPacketWriter {
- public:
- DummyPacketWriter() {}
-
- // QuicPacketWriter overrides.
- WriteResult WritePacket(const char* /*buffer*/,
- size_t /*buf_len*/,
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/,
- PerPacketOptions* /*options*/) override {
- return WriteResult(WRITE_STATUS_ERROR, 0);
- }
-
- bool IsWriteBlocked() const override { return false; }
-
- void SetWritable() override {}
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& /*peer_address*/) const override {
- return 0;
- }
-
- bool SupportsReleaseTime() const override { return false; }
-
- bool IsBatchMode() const override { return false; }
-
- char* GetNextWriteLocation(
- const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/) override {
- return nullptr;
- }
-
- WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-};
-
-class MockQuartcStreamDelegate : public QuartcStream::Delegate {
- public:
- MockQuartcStreamDelegate(QuicStreamId id, std::string* read_buffer)
- : id_(id), read_buffer_(read_buffer) {}
-
- void OnBufferChanged(QuartcStream* stream) override {
- last_bytes_buffered_ = stream->BufferedDataBytes();
- last_bytes_pending_retransmission_ = stream->BytesPendingRetransmission();
- }
-
- size_t OnReceived(QuartcStream* stream,
- iovec* iov,
- size_t iov_length,
- bool /*fin*/) override {
- EXPECT_EQ(id_, stream->id());
- EXPECT_EQ(stream->ReadOffset(), read_buffer_->size());
- size_t bytes_consumed = 0;
- for (size_t i = 0; i < iov_length; ++i) {
- read_buffer_->append(static_cast<const char*>(iov[i].iov_base),
- iov[i].iov_len);
- bytes_consumed += iov[i].iov_len;
- }
- return bytes_consumed;
- }
-
- void OnClose(QuartcStream* /*stream*/) override { closed_ = true; }
-
- bool closed() { return closed_; }
-
- QuicByteCount last_bytes_buffered() { return last_bytes_buffered_; }
- QuicByteCount last_bytes_pending_retransmission() {
- return last_bytes_pending_retransmission_;
- }
-
- protected:
- QuicStreamId id_;
- // Data read by the QuicStream.
- std::string* read_buffer_;
- // Whether the QuicStream is closed.
- bool closed_ = false;
-
- // Last amount of data observed as buffered.
- QuicByteCount last_bytes_buffered_ = 0;
- QuicByteCount last_bytes_pending_retransmission_ = 0;
-};
-
-class QuartcStreamTest : public QuicTestWithParam<ParsedQuicVersion>,
- public QuicConnectionHelperInterface {
- public:
- QuartcStreamTest() : version_(GetParam()) {}
-
- ~QuartcStreamTest() override = default;
-
- void CreateReliableQuicStream() {
- // Arbitrary values for QuicConnection.
- Perspective perspective = Perspective::IS_SERVER;
- QuicIpAddress ip;
- ip.FromString("0.0.0.0");
- bool owns_writer = true;
-
- alarm_factory_ = std::make_unique<test::MockAlarmFactory>();
-
- connection_ = std::make_unique<QuicConnection>(
- QuicUtils::CreateZeroConnectionId(version_.transport_version),
- QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/,
- alarm_factory_.get(), new DummyPacketWriter(), owns_writer, perspective,
- ParsedQuicVersionVector{version_});
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_ = std::make_unique<MockQuicSession>(connection_.get(),
- QuicConfig(), &write_buffer_);
- mock_stream_delegate_ =
- std::make_unique<MockQuartcStreamDelegate>(kStreamId, &read_buffer_);
- stream_ = new QuartcStream(kStreamId, session_.get());
- stream_->SetDelegate(mock_stream_delegate_.get());
- session_->ActivateReliableStream(std::unique_ptr<QuartcStream>(stream_));
- }
-
- const QuicClock* GetClock() const override { return &clock_; }
-
- QuicRandom* GetRandomGenerator() override {
- return QuicRandom::GetInstance();
- }
-
- QuicBufferAllocator* GetStreamSendBufferAllocator() override {
- return &buffer_allocator_;
- }
-
- protected:
- const ParsedQuicVersion version_;
- // The QuicSession will take the ownership.
- QuartcStream* stream_;
- std::unique_ptr<MockQuartcStreamDelegate> mock_stream_delegate_;
- std::unique_ptr<MockQuicSession> session_;
- // Data written by the ReliableQuicStreamAdapterTest.
- std::string write_buffer_;
- // Data read by the ReliableQuicStreamAdapterTest.
- std::string read_buffer_;
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
- std::unique_ptr<QuicConnection> connection_;
- // Used to implement the QuicConnectionHelperInterface.
- SimpleBufferAllocator buffer_allocator_;
- MockClock clock_;
-};
-
-// TODO(b/150224094): Enable versions with TLS handshake.
-INSTANTIATE_TEST_SUITE_P(
- Tests,
- QuartcStreamTest,
- ::testing::ValuesIn(CurrentSupportedVersionsWithQuicCrypto()),
- ::testing::PrintToStringParamName());
-
-// Write an entire string.
-TEST_P(QuartcStreamTest, WriteDataWhole) {
- CreateReliableQuicStream();
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
- EXPECT_EQ("Foo bar", write_buffer_);
-}
-
-// Write part of a string.
-TEST_P(QuartcStreamTest, WriteDataPartial) {
- CreateReliableQuicStream();
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 5)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
- EXPECT_EQ("Foo b", write_buffer_);
-}
-
-// Test that a QuartcStream buffers writes correctly.
-TEST_P(QuartcStreamTest, StreamBuffersData) {
- CreateReliableQuicStream();
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
-
- // The stream is not yet writable, so data will be buffered.
- session_->set_writable(false);
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- // Check that data is buffered.
- EXPECT_TRUE(stream_->HasBufferedData());
- EXPECT_EQ(7u, stream_->BufferedDataBytes());
-
- // Check that the stream told its delegate about the buffer change.
- EXPECT_EQ(7u, mock_stream_delegate_->last_bytes_buffered());
-
- // Check that none of the data was written yet.
- // Note that |write_buffer_| actually holds data written by the QuicSession
- // (not data buffered by the stream).
- EXPECT_EQ(0ul, write_buffer_.size());
-
- char message1[] = "xyzzy";
- test::QuicTestMemSliceVector data1({std::make_pair(message1, 5)});
-
- // More writes go into the buffer.
- stream_->WriteMemSlices(data1.span(), /*fin=*/false);
-
- EXPECT_TRUE(stream_->HasBufferedData());
- EXPECT_EQ(12u, stream_->BufferedDataBytes());
- EXPECT_EQ(12u, mock_stream_delegate_->last_bytes_buffered());
- EXPECT_EQ(0ul, write_buffer_.size());
-
- // The stream becomes writable, so it sends the buffered data.
- session_->set_writable(true);
- stream_->OnCanWrite();
-
- EXPECT_FALSE(stream_->HasBufferedData());
- EXPECT_EQ(0u, stream_->BufferedDataBytes());
- EXPECT_EQ(0u, mock_stream_delegate_->last_bytes_buffered());
- EXPECT_EQ("Foo barxyzzy", write_buffer_);
-}
-
-// Finish writing to a stream.
-// It delivers the fin bit and closes the write-side as soon as possible.
-TEST_P(QuartcStreamTest, FinishWriting) {
- CreateReliableQuicStream();
-
- session_->set_writable(false);
- stream_->FinishWriting();
- EXPECT_FALSE(stream_->fin_sent());
-
- // Fin is sent as soon as the stream becomes writable.
- session_->set_writable(true);
- stream_->OnCanWrite();
- EXPECT_TRUE(stream_->fin_sent());
- EXPECT_TRUE(stream_->write_side_closed());
-}
-
-// Read an entire string.
-TEST_P(QuartcStreamTest, ReadDataWhole) {
- CreateReliableQuicStream();
- QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
- stream_->OnStreamFrame(frame);
-
- EXPECT_EQ("Hello, World!", read_buffer_);
-}
-
-// Read part of a string.
-TEST_P(QuartcStreamTest, ReadDataPartial) {
- CreateReliableQuicStream();
- QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
- frame.data_length = 5;
- stream_->OnStreamFrame(frame);
-
- EXPECT_EQ("Hello", read_buffer_);
-}
-
-// Streams do not call OnReceived() after StopReading().
-// Note: this is tested here because Quartc relies on this behavior.
-TEST_P(QuartcStreamTest, StopReading) {
- CreateReliableQuicStream();
- stream_->StopReading();
-
- QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
- stream_->OnStreamFrame(frame);
-
- EXPECT_EQ(0ul, read_buffer_.size());
-
- QuicStreamFrame frame2(kStreamId, true, 0, "Hello, World!");
- stream_->OnStreamFrame(frame2);
-
- EXPECT_EQ(0ul, read_buffer_.size());
- EXPECT_TRUE(stream_->fin_received());
-}
-
-// Test that closing the stream results in a callback.
-TEST_P(QuartcStreamTest, CloseStream) {
- CreateReliableQuicStream();
- EXPECT_FALSE(mock_stream_delegate_->closed());
- if (GetQuicReloadableFlag(quic_break_session_stream_close_loop)) {
- stream_->CloseWriteSide();
- stream_->CloseReadSide();
- } else {
- stream_->OnClose();
- }
- EXPECT_TRUE(mock_stream_delegate_->closed());
-}
-
-// Both sending and receiving fin automatically closes a stream.
-TEST_P(QuartcStreamTest, CloseOnFins) {
- CreateReliableQuicStream();
- QuicStreamFrame frame(kStreamId, true, 0, 0);
- stream_->OnStreamFrame(frame);
-
- test::QuicTestMemSliceVector data({});
- stream_->WriteMemSlices(data.span(), /*fin=*/true);
-
- // Check that the OnClose() callback occurred.
- EXPECT_TRUE(mock_stream_delegate_->closed());
-}
-
-TEST_P(QuartcStreamTest, TestCancelOnLossDisabled) {
- CreateReliableQuicStream();
-
- // This should be the default state.
- EXPECT_FALSE(stream_->cancel_on_loss());
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-}
-
-TEST_P(QuartcStreamTest, TestCancelOnLossEnabled) {
- CreateReliableQuicStream();
- stream_->set_cancel_on_loss(true);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QuartcStreamTest, MaxRetransmissionsAbsent) {
- CreateReliableQuicStream();
-
- // This should be the default state.
- EXPECT_EQ(stream_->max_retransmission_count(),
- std::numeric_limits<int>::max());
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-}
-
-TEST_P(QuartcStreamTest, MaxRetransmissionsSet) {
- CreateReliableQuicStream();
- stream_->set_max_retransmission_count(2);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QuartcStreamTest, MaxRetransmissionsDisjointFrames) {
- CreateReliableQuicStream();
- stream_->set_max_retransmission_count(2);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- // Retransmit bytes [0, 3].
- stream_->OnStreamFrameLost(0, 4, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo ", write_buffer_);
-
- // Retransmit bytes [4, 6]. Everything has been retransmitted once.
- stream_->OnStreamFrameLost(4, 3, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
-
- // Retransmit bytes [0, 6]. Everything can be retransmitted a second time.
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
-}
-
-TEST_P(QuartcStreamTest, MaxRetransmissionsOverlappingFrames) {
- CreateReliableQuicStream();
- stream_->set_max_retransmission_count(2);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- // Retransmit bytes 0 to 3.
- stream_->OnStreamFrameLost(0, 4, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo ", write_buffer_);
-
- // Retransmit bytes 3 to 6. Byte 3 has been retransmitted twice.
- stream_->OnStreamFrameLost(3, 4, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
-
- // Retransmit byte 3 a third time. This should cause cancellation.
- stream_->OnStreamFrameLost(3, 1, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-}
-
-TEST_P(QuartcStreamTest, MaxRetransmissionsWithAckedFrame) {
- CreateReliableQuicStream();
- stream_->set_max_retransmission_count(1);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- // Retransmit bytes [0, 7).
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
-
- // Ack bytes [0, 7). These bytes should be pruned from the data tracked by
- // the stream.
- QuicByteCount newly_acked_length = 0;
- stream_->OnStreamFrameAcked(0, 7, false, QuicTime::Delta::FromMilliseconds(1),
- QuicTime::Zero(), &newly_acked_length);
- EXPECT_EQ(7u, newly_acked_length);
- stream_->OnCanWrite();
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
-
- // Retransmit bytes [0, 7) again.
- // QUIC will never mark frames as lost after they've been acked, but this lets
- // us test that QuartcStream stopped tracking these bytes after the acked.
- stream_->OnStreamFrameLost(0, 7, false);
- stream_->OnCanWrite();
-
- // QuartcStream should be cancelled, but it stopped tracking the lost bytes
- // after they were acked, so it's not.
- EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-}
-
-TEST_P(QuartcStreamTest, TestBytesPendingRetransmission) {
- CreateReliableQuicStream();
- stream_->set_cancel_on_loss(false);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 4, false);
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 4u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 4u);
-
- stream_->OnStreamFrameLost(4, 3, false);
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 7u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 7u);
-
- stream_->OnCanWrite();
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
-
- EXPECT_EQ("Foo barFoo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
-}
-
-TEST_P(QuartcStreamTest, TestBytesPendingRetransmissionWithCancelOnLoss) {
- CreateReliableQuicStream();
- stream_->set_cancel_on_loss(true);
-
- char message[] = "Foo bar";
- test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
- stream_->WriteMemSlices(data.span(), /*fin=*/false);
-
- EXPECT_EQ("Foo bar", write_buffer_);
-
- stream_->OnStreamFrameLost(0, 4, false);
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
-
- stream_->OnStreamFrameLost(4, 3, false);
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
-
- stream_->OnCanWrite();
- EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
- EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
-
- EXPECT_EQ("Foo bar", write_buffer_);
- EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_CANCELLED));
-}
-
-} // namespace
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.cc b/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.cc
deleted file mode 100644
index 263c21395e0..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.cc
+++ /dev/null
@@ -1,98 +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.
-
-#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
-
-namespace quic {
-namespace simulator {
-
-SimulatedQuartcPacketTransport::SimulatedQuartcPacketTransport(
- Simulator* simulator,
- const std::string& name,
- const std::string& peer_name,
- QuicByteCount queue_capacity)
- : Endpoint(simulator, name),
- peer_name_(peer_name),
- egress_queue_(simulator,
- quiche::QuicheStringPrintf("%s (TX Queue)", name.c_str()),
- queue_capacity) {
- egress_queue_.set_listener_interface(this);
-}
-
-int SimulatedQuartcPacketTransport::Write(const char* buffer,
- size_t buf_len,
- const PacketInfo& info) {
- if (!writable_) {
- return 0;
- }
- if (egress_queue_.bytes_queued() + buf_len > egress_queue_.capacity()) {
- return 0;
- }
-
- last_packet_number_ = info.packet_number;
-
- auto packet = std::make_unique<Packet>();
- packet->contents = std::string(buffer, buf_len);
- packet->size = buf_len;
- packet->tx_timestamp = clock_->Now();
- packet->source = name();
- packet->destination = peer_name_;
-
- egress_queue_.AcceptPacket(std::move(packet));
- return buf_len;
-}
-
-void SimulatedQuartcPacketTransport::SetDelegate(Delegate* delegate) {
- delegate_ = delegate;
- Schedule(clock_->Now());
-}
-
-UnconstrainedPortInterface* SimulatedQuartcPacketTransport::GetRxPort() {
- return this;
-}
-
-void SimulatedQuartcPacketTransport::SetTxPort(ConstrainedPortInterface* port) {
- egress_queue_.set_tx_port(port);
- Schedule(clock_->Now());
-}
-
-void SimulatedQuartcPacketTransport::AcceptPacket(
- std::unique_ptr<Packet> packet) {
- // Simulated switches broadcast packets to all ports if the cannot determine
- // the recipient, so we need to drop packets that aren't intended for us.
- if (packet->destination != name()) {
- return;
- }
-
- if (delegate_) {
- delegate_->OnTransportReceived(packet->contents.data(), packet->size);
- }
-}
-
-void SimulatedQuartcPacketTransport::OnPacketDequeued() {
- if (delegate_ && writable_) {
- delegate_->OnTransportCanWrite();
- }
-}
-
-void SimulatedQuartcPacketTransport::Act() {
- if (delegate_ && writable_) {
- delegate_->OnTransportCanWrite();
- }
-}
-
-void SimulatedQuartcPacketTransport::SetWritable(bool writable) {
- writable_ = writable;
- if (writable_) {
- // May need to call |Delegate::OnTransportCanWrite|.
- Schedule(clock_->Now());
- }
-}
-
-} // namespace simulator
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h b/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h
deleted file mode 100644
index 185668b528a..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h
+++ /dev/null
@@ -1,84 +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_QUARTC_SIMULATED_PACKET_TRANSPORT_H_
-#define QUICHE_QUIC_QUARTC_SIMULATED_PACKET_TRANSPORT_H_
-
-#include <string>
-
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/port.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/queue.h"
-
-namespace quic {
-namespace simulator {
-
-// Simulated implementation of QuartcPacketTransport. This packet transport
-// implementation connects Quartc to a QUIC simulator's network fabric.
-// Assumes that its caller and delegate run on the same thread as the network
-// simulation and therefore require no additional synchronization.
-class SimulatedQuartcPacketTransport : public Endpoint,
- public QuartcPacketTransport,
- public UnconstrainedPortInterface,
- public Queue::ListenerInterface {
- public:
- SimulatedQuartcPacketTransport(Simulator* simulator,
- const std::string& name,
- const std::string& peer_name,
- QuicByteCount queue_capacity);
-
- // QuartcPacketTransport methods.
- int Write(const char* buffer,
- size_t buf_len,
- const PacketInfo& info) override;
- void SetDelegate(Delegate* delegate) override;
-
- // Simulation methods below. These are implementation details.
-
- // Endpoint methods. Called by the simulation to connect the transport.
- UnconstrainedPortInterface* GetRxPort() override;
- void SetTxPort(ConstrainedPortInterface* port) override;
-
- // UnconstrainedPortInterface method. Called by the simulation to deliver a
- // packet to this transport.
- void AcceptPacket(std::unique_ptr<Packet> packet) override;
-
- // Queue::ListenerInterface method. Called when the internal egress queue has
- // dispatched a packet and may have room for more.
- void OnPacketDequeued() override;
-
- // Actor method. The transport schedules this to run when the delegate is set
- // in order to trigger an initial call to |Delegate::OnTransportCanWrite()|.
- // (The Quartc packet writer starts in a blocked state and needs an initial
- // callback to unblock it.)
- void Act() override;
-
- // Changes whether the transport is writable. If |writable| is false, the
- // transport will reject calls to |Write| and will not call
- // |Delegate::OnTransportCanWrite|. If |writable| is true, the transport will
- // allow calls to |Write| and will call |Delegate::OnTransportCanWrite|
- // whenever it is able to write another packet.
- void SetWritable(bool writable);
-
- // Last packet number sent over this simulated transport.
- // TODO(b/112561077): Reorganize tests so that this method can be deleted.
- // This exists purely for use by quartc_session_test.cc, to test that the
- // packet writer passes packet numbers to the transport.
- QuicPacketNumber last_packet_number() { return last_packet_number_; }
-
- private:
- std::string peer_name_;
- Delegate* delegate_ = nullptr;
- Queue egress_queue_;
- QuicPacketNumber last_packet_number_;
-
- // Controls whether the transport is considered to be writable. Used to
- // simulate behavior that arises when the transport is blocked.
- bool writable_ = true;
-};
-
-} // namespace simulator
-} // namespace quic
-
-#endif // QUICHE_QUIC_QUARTC_SIMULATED_PACKET_TRANSPORT_H_
diff --git a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport_test.cc b/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport_test.cc
deleted file mode 100644
index 24a4f4fc49f..00000000000
--- a/chromium/net/third_party/quiche/src/quic/quartc/simulated_packet_transport_test.cc
+++ /dev/null
@@ -1,163 +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.
-
-#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
-
-#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
-#include "net/third_party/quiche/src/quic/quartc/quartc_packet_writer.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
-#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
-
-namespace quic {
-namespace simulator {
-namespace {
-
-using ::testing::ElementsAre;
-
-const QuicBandwidth kDefaultBandwidth =
- QuicBandwidth::FromKBitsPerSecond(10 * 1000);
-const QuicTime::Delta kDefaultPropagationDelay =
- QuicTime::Delta::FromMilliseconds(20);
-const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
-const QuicByteCount kDefaultPacketSize = 1200;
-const QuicPacketCount kDefaultQueueLength = 10;
-
-class FakeDelegate : public QuartcPacketTransport::Delegate {
- public:
- explicit FakeDelegate(QuartcPacketTransport* transport)
- : transport_(transport) {
- transport_->SetDelegate(this);
- }
-
- ~FakeDelegate() { transport_->SetDelegate(nullptr); }
-
- void OnTransportCanWrite() override {
- while (!packets_to_send_.empty()) {
- const std::string& packet = packets_to_send_.front();
- if (transport_->Write(packet.data(), packet.size(),
- QuartcPacketTransport::PacketInfo()) <
- static_cast<int>(packet.size())) {
- ++write_blocked_count_;
- return;
- }
- packets_to_send_.pop();
- }
- }
-
- void OnTransportReceived(const char* data, size_t data_len) override {
- packets_received_.emplace_back(data, data_len);
- }
-
- void AddPacketToSend(const std::string& packet) {
- packets_to_send_.push(packet);
- }
-
- size_t packets_to_send() { return packets_to_send_.size(); }
- const std::vector<std::string>& packets_received() {
- return packets_received_;
- }
- int write_blocked_count() { return write_blocked_count_; }
-
- private:
- QuartcPacketTransport* const transport_ = nullptr;
- std::queue<std::string> packets_to_send_;
- std::vector<std::string> packets_received_;
- int write_blocked_count_ = 0;
-};
-
-class SimulatedPacketTransportTest : public QuicTest {
- protected:
- SimulatedPacketTransportTest()
- : switch_(&simulator_, "Switch", /*port_count=*/8, 2 * kDefaultBdp),
- client_(&simulator_,
- "sender",
- "receiver",
- kDefaultQueueLength * kDefaultPacketSize),
- server_(&simulator_,
- "receiver",
- "sender",
- kDefaultQueueLength * kDefaultPacketSize),
- client_link_(&client_,
- switch_.port(1),
- kDefaultBandwidth,
- kDefaultPropagationDelay),
- server_link_(&server_,
- switch_.port(2),
- kDefaultBandwidth,
- kDefaultPropagationDelay),
- client_delegate_(&client_),
- server_delegate_(&server_) {}
-
- Simulator simulator_;
- Switch switch_;
-
- SimulatedQuartcPacketTransport client_;
- SimulatedQuartcPacketTransport server_;
-
- SymmetricLink client_link_;
- SymmetricLink server_link_;
-
- FakeDelegate client_delegate_;
- FakeDelegate server_delegate_;
-};
-
-TEST_F(SimulatedPacketTransportTest, OneWayTransmission) {
- std::string packet_1(kDefaultPacketSize, 'a');
- std::string packet_2(kDefaultPacketSize, 'b');
- client_delegate_.AddPacketToSend(packet_1);
- client_delegate_.AddPacketToSend(packet_2);
-
- simulator_.RunUntil(
- [this] { return client_delegate_.packets_to_send() == 0; });
- simulator_.RunFor(3 * kDefaultPropagationDelay);
-
- EXPECT_THAT(server_delegate_.packets_received(),
- ElementsAre(packet_1, packet_2));
- EXPECT_THAT(client_delegate_.packets_received(), ElementsAre());
-}
-
-TEST_F(SimulatedPacketTransportTest, TwoWayTransmission) {
- std::string packet_1(kDefaultPacketSize, 'a');
- std::string packet_2(kDefaultPacketSize, 'b');
- std::string packet_3(kDefaultPacketSize, 'c');
- std::string packet_4(kDefaultPacketSize, 'd');
-
- client_delegate_.AddPacketToSend(packet_1);
- client_delegate_.AddPacketToSend(packet_2);
- server_delegate_.AddPacketToSend(packet_3);
- server_delegate_.AddPacketToSend(packet_4);
-
- simulator_.RunUntil(
- [this] { return client_delegate_.packets_to_send() == 0; });
- simulator_.RunUntil(
- [this] { return server_delegate_.packets_to_send() == 0; });
- simulator_.RunFor(3 * kDefaultPropagationDelay);
-
- EXPECT_THAT(server_delegate_.packets_received(),
- ElementsAre(packet_1, packet_2));
- EXPECT_THAT(client_delegate_.packets_received(),
- ElementsAre(packet_3, packet_4));
-}
-
-TEST_F(SimulatedPacketTransportTest, TestWriteBlocked) {
- // Add 10 packets beyond what fits in the egress queue.
- std::vector<std::string> packets;
- for (unsigned int i = 0; i < kDefaultQueueLength + 10; ++i) {
- packets.push_back(std::string(kDefaultPacketSize, 'a' + i));
- client_delegate_.AddPacketToSend(packets.back());
- }
-
- simulator_.RunUntil(
- [this] { return client_delegate_.packets_to_send() == 0; });
- simulator_.RunFor(3 * kDefaultPropagationDelay);
-
- // Each of the 10 packets in excess of the sender's egress queue length will
- // block the first time |client_delegate_| tries to write them.
- EXPECT_EQ(client_delegate_.write_blocked_count(), 10);
- EXPECT_EQ(server_delegate_.packets_received(), packets);
-}
-
-} // namespace
-} // namespace simulator
-} // namespace quic
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 401ae7e4278..0fb988aed37 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
@@ -23,7 +23,8 @@ QuicTransportStream::QuicTransportStream(
/*is_static=*/false,
QuicUtils::GetStreamType(id,
session->connection()->perspective(),
- session->IsIncomingStream(id))),
+ session->IsIncomingStream(id),
+ session->version())),
session_interface_(session_interface) {}
size_t QuicTransportStream::Read(char* buffer, size_t buffer_size) {
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
new file mode 100644
index 00000000000..81466de1240
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
@@ -0,0 +1,221 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
+
+#include <cstdint>
+#include <memory>
+
+#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 {
+namespace {
+
+constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;
+
+constexpr std::array<char, 16> kHexDigits = {'0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f'};
+
+// Assumes that the character is normalized to lowercase beforehand.
+bool IsNormalizedHexDigit(char c) {
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
+}
+
+void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
+ fingerprint.fingerprint =
+ quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
+}
+
+} // namespace
+
+constexpr char CertificateFingerprint::kSha256[];
+
+std::string ComputeSha256Fingerprint(quiche::QuicheStringPiece input) {
+ std::vector<uint8_t> raw_hash;
+ raw_hash.resize(SHA256_DIGEST_LENGTH);
+ SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
+ raw_hash.data());
+
+ std::string output;
+ output.resize(kFingerprintLength);
+ for (size_t i = 0; i < output.size(); i++) {
+ uint8_t hash_byte = raw_hash[i / 3];
+ switch (i % 3) {
+ case 0:
+ output[i] = kHexDigits[hash_byte >> 4];
+ break;
+ case 1:
+ output[i] = kHexDigits[hash_byte & 0xf];
+ break;
+ case 2:
+ output[i] = ':';
+ break;
+ }
+ }
+ return output;
+}
+
+ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
+ const {
+ return new Details(*this);
+}
+
+WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
+ const QuicClock* clock,
+ int max_validity_days)
+ : clock_(clock),
+ max_validity_days_(max_validity_days),
+ // Add an extra second to max validity to accomodate various edge cases.
+ max_validity_(
+ QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}
+
+bool WebTransportFingerprintProofVerifier::AddFingerprint(
+ CertificateFingerprint fingerprint) {
+ NormalizeFingerprint(fingerprint);
+ if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
+ QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
+ return false;
+ }
+ if (fingerprint.fingerprint.size() != kFingerprintLength) {
+ QUIC_DLOG(WARNING) << "Invalid fingerprint length";
+ return false;
+ }
+ for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
+ char current = fingerprint.fingerprint[i];
+ if (i % 3 == 2) {
+ if (current != ':') {
+ QUIC_DLOG(WARNING)
+ << "Missing colon separator between the bytes of the hash";
+ return false;
+ }
+ } else {
+ if (!IsNormalizedHexDigit(current)) {
+ QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
+ return false;
+ }
+ }
+ }
+
+ fingerprints_.push_back(fingerprint);
+ return true;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof(
+ const std::string& /*hostname*/,
+ const uint16_t /*port*/,
+ const std::string& /*server_config*/,
+ QuicTransportVersion /*transport_version*/,
+ quiche::QuicheStringPiece /*chlo_hash*/,
+ const std::vector<std::string>& /*certs*/,
+ const std::string& /*cert_sct*/,
+ const std::string& /*signature*/,
+ const ProofVerifyContext* /*context*/,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* details,
+ std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+ *error_details =
+ "QUIC crypto certificate verification is not supported in "
+ "WebTransportFingerprintProofVerifier";
+ QUIC_BUG << *error_details;
+ *details = std::make_unique<Details>(Status::kInternalError);
+ return QUIC_FAILURE;
+}
+
+QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
+ const std::string& /*hostname*/,
+ const uint16_t /*port*/,
+ const std::vector<std::string>& certs,
+ const std::string& /*ocsp_response*/,
+ const std::string& /*cert_sct*/,
+ const ProofVerifyContext* /*context*/,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* details,
+ std::unique_ptr<ProofVerifierCallback> /*callback*/) {
+ if (certs.empty()) {
+ *details = std::make_unique<Details>(Status::kInternalError);
+ *error_details = "No certificates provided";
+ return QUIC_FAILURE;
+ }
+
+ if (!HasKnownFingerprint(certs[0])) {
+ *details = std::make_unique<Details>(Status::kUnknownFingerprint);
+ *error_details = "Certificate does not match any fingerprint";
+ return QUIC_FAILURE;
+ }
+
+ std::unique_ptr<CertificateView> view =
+ CertificateView::ParseSingleCertificate(certs[0]);
+ if (view == nullptr) {
+ *details = std::make_unique<Details>(Status::kCertificateParseFailure);
+ *error_details = "Failed to parse the certificate";
+ return QUIC_FAILURE;
+ }
+
+ if (!HasValidExpiry(*view)) {
+ *details = std::make_unique<Details>(Status::kExpiryTooLong);
+ *error_details = quiche::QuicheStrCat(
+ "Certificate expiry exceeds the configured limit of ",
+ max_validity_days_, " days");
+ return QUIC_FAILURE;
+ }
+
+ if (!IsWithinValidityPeriod(*view)) {
+ *details = std::make_unique<Details>(Status::kExpired);
+ *error_details =
+ "Certificate has expired or has validity listed in the future";
+ return QUIC_FAILURE;
+ }
+
+ *details = std::make_unique<Details>(Status::kValidCertificate);
+ return QUIC_SUCCESS;
+}
+
+std::unique_ptr<ProofVerifyContext>
+WebTransportFingerprintProofVerifier::CreateDefaultContext() {
+ return nullptr;
+}
+
+bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
+ quiche::QuicheStringPiece der_certificate) {
+ // https://wicg.github.io/web-transport/#verify-a-certificate-fingerprint
+ const std::string fingerprint = ComputeSha256Fingerprint(der_certificate);
+ for (const CertificateFingerprint& reference : fingerprints_) {
+ if (reference.algorithm != CertificateFingerprint::kSha256) {
+ QUIC_BUG << "Unexpected non-SHA-256 hash";
+ continue;
+ }
+ if (fingerprint == reference.fingerprint) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WebTransportFingerprintProofVerifier::HasValidExpiry(
+ const CertificateView& certificate) {
+ if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
+ return false;
+ }
+
+ const QuicTime::Delta duration_seconds =
+ certificate.validity_end() - certificate.validity_start();
+ return duration_seconds <= max_validity_;
+}
+
+bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
+ const CertificateView& certificate) {
+ QuicWallTime now = clock_->WallNow();
+ return now.IsAfter(certificate.validity_start()) &&
+ now.IsBefore(certificate.validity_end());
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
new file mode 100644
index 00000000000..7e4358de60d
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
@@ -0,0 +1,119 @@
+// 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.
+
+#ifndef QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+#define QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
+
+#include <vector>
+
+#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 {
+
+// Represents a fingerprint of an X.509 certificate in a format based on
+// https://w3c.github.io/webrtc-pc/#dom-rtcdtlsfingerprint.
+struct QUIC_EXPORT_PRIVATE CertificateFingerprint {
+ static constexpr char kSha256[] = "sha-256";
+
+ // An algorithm described by one of the names in
+ // https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml
+ std::string algorithm;
+ // Hex-encoded, colon-separated fingerprint of the certificate. For example,
+ // "12:3d:5b:71:8c:54:df:85:7e:bd:e3:7c:66:da:f9:db:6a:94:8f:85:cb:6e:44:7f:09:3e:05:f2:dd:d4:f7:86"
+ std::string fingerprint;
+};
+
+// 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);
+
+// WebTransportFingerprintProofVerifier verifies the server leaf certificate
+// against a supplied list of certificate fingerprints following the procedure
+// described in the WebTransport specification. The certificate is deemed
+// trusted if it matches a fingerprint in the list, has expiry dates that are
+// not too long and has not expired. Only the leaf is checked, the rest of the
+// chain is ignored. Reference specification:
+// https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
+class QUIC_EXPORT_PRIVATE WebTransportFingerprintProofVerifier
+ : public ProofVerifier {
+ public:
+ // Note: the entries in this list may be logged into a UMA histogram, and thus
+ // should not be renumbered.
+ enum class Status {
+ kValidCertificate = 0,
+ kUnknownFingerprint = 1,
+ kCertificateParseFailure = 2,
+ kExpiryTooLong = 3,
+ kExpired = 4,
+ kInternalError = 5,
+
+ kMaxValue = kInternalError,
+ };
+
+ class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails {
+ public:
+ explicit Details(Status status) : status_(status) {}
+ Status status() const { return status_; }
+
+ ProofVerifyDetails* Clone() const override;
+
+ private:
+ const Status status_;
+ };
+
+ // |clock| is used to check if the certificate has expired. It is not owned
+ // and must outlive the object. |max_validity_days| is the maximum time for
+ // which the certificate is allowed to be valid.
+ WebTransportFingerprintProofVerifier(const QuicClock* clock,
+ int max_validity_days);
+
+ // Adds a certificate fingerprint to be trusted. The fingerprints are
+ // case-insensitive and are validated internally; the function returns true if
+ // the validation passes.
+ bool AddFingerprint(CertificateFingerprint fingerprint);
+
+ // ProofVerifier implementation.
+ QuicAsyncStatus VerifyProof(
+ const std::string& hostname,
+ const uint16_t port,
+ const std::string& server_config,
+ QuicTransportVersion transport_version,
+ quiche::QuicheStringPiece chlo_hash,
+ const std::vector<std::string>& certs,
+ const std::string& cert_sct,
+ const std::string& signature,
+ const ProofVerifyContext* context,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* details,
+ std::unique_ptr<ProofVerifierCallback> callback) override;
+ QuicAsyncStatus VerifyCertChain(
+ const std::string& hostname,
+ const uint16_t port,
+ const std::vector<std::string>& certs,
+ const std::string& ocsp_response,
+ const std::string& cert_sct,
+ const ProofVerifyContext* context,
+ std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* details,
+ std::unique_ptr<ProofVerifierCallback> callback) override;
+ std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override;
+
+ private:
+ bool HasKnownFingerprint(quiche::QuicheStringPiece der_certificate);
+ bool HasValidExpiry(const CertificateView& certificate);
+ bool IsWithinValidityPeriod(const CertificateView& certificate);
+
+ const QuicClock* clock_; // Unowned.
+ const int max_validity_days_;
+ const QuicTime::Delta max_validity_;
+ std::vector<CertificateFingerprint> fingerprints_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_QUIC_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
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
new file mode 100644
index 00000000000..f9f27e5db69
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier_test.cc
@@ -0,0 +1,183 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
+
+#include <memory>
+
+#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 {
+namespace {
+
+using ::testing::HasSubstr;
+
+// 2020-02-01 12:35:56 UTC
+constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
+
+struct VerifyResult {
+ QuicAsyncStatus status;
+ WebTransportFingerprintProofVerifier::Status detailed_status;
+ std::string error;
+};
+
+class WebTransportFingerprintProofVerifierTest : public QuicTest {
+ public:
+ WebTransportFingerprintProofVerifierTest() {
+ clock_.AdvanceTime(kValidTime);
+ verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+ &clock_, /*max_validity_days=*/365);
+ AddTestCertificate();
+ }
+
+ protected:
+ VerifyResult Verify(quiche::QuicheStringPiece certificate) {
+ VerifyResult result;
+ std::unique_ptr<ProofVerifyDetails> details;
+ result.status = verifier_->VerifyCertChain(
+ /*hostname=*/"", /*port=*/0,
+ std::vector<std::string>{std::string(certificate)},
+ /*ocsp_response=*/"",
+ /*cert_sct=*/"",
+ /*context=*/nullptr, &result.error, &details,
+ /*callback=*/nullptr);
+ result.detailed_status =
+ static_cast<WebTransportFingerprintProofVerifier::Details*>(
+ details.get())
+ ->status();
+ return result;
+ }
+
+ void AddTestCertificate() {
+ EXPECT_TRUE(verifier_->AddFingerprint(
+ CertificateFingerprint{CertificateFingerprint::kSha256,
+ ComputeSha256Fingerprint(kTestCertificate)}));
+ }
+
+ MockClock clock_;
+ std::unique_ptr<WebTransportFingerprintProofVerifier> verifier_;
+};
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Sha256Fingerprint) {
+ // Computed using `openssl x509 -fingerprint -sha256`.
+ EXPECT_EQ(ComputeSha256Fingerprint(kTestCertificate),
+ "f2:e5:46:5e:2b:f7:ec:d6:f6:30:66:a5:a3:75:11:73:4a:a0:eb:7c:47:01:"
+ "0e:86:d6:75:8e:d4:f4:fa:1b:0f");
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
+ VerifyResult result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_SUCCESS);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+ result = Verify(kWildcardCertificate);
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kUnknownFingerprint);
+
+ result = Verify("Some random text");
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, Validity) {
+ // Validity periods of kTestCertificate, according to `openssl x509 -text`:
+ // Not Before: Jan 30 18:13:59 2020 GMT
+ // Not After : Feb 2 18:13:59 2020 GMT
+
+ // 2020-01-29 19:00:00 UTC
+ constexpr QuicTime::Delta kStartTime =
+ QuicTime::Delta::FromSeconds(1580324400);
+ clock_.Reset();
+ clock_.AdvanceTime(kStartTime);
+
+ VerifyResult result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kExpired);
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400));
+ result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_SUCCESS);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(4 * 86400));
+ result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kExpired);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, MaxValidity) {
+ verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+ &clock_, /*max_validity_days=*/2);
+ AddTestCertificate();
+ VerifyResult result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kExpiryTooLong);
+ EXPECT_THAT(result.error, HasSubstr("limit of 2 days"));
+
+ // kTestCertificate is valid for exactly four days.
+ verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+ &clock_, /*max_validity_days=*/4);
+ AddTestCertificate();
+ result = Verify(kTestCertificate);
+ EXPECT_EQ(result.status, QUIC_SUCCESS);
+ EXPECT_EQ(result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
+ constexpr quiche::QuicheStringPiece kInvalidCertificate = "Hello, world!";
+ ASSERT_TRUE(verifier_->AddFingerprint(
+ {CertificateFingerprint::kSha256,
+ ComputeSha256Fingerprint(kInvalidCertificate)}));
+
+ VerifyResult result = Verify(kInvalidCertificate);
+ EXPECT_EQ(result.status, QUIC_FAILURE);
+ EXPECT_EQ(
+ result.detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
+}
+
+TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {
+ // Accept all-uppercase fingerprints.
+ verifier_ = std::make_unique<WebTransportFingerprintProofVerifier>(
+ &clock_, /*max_validity_days=*/365);
+ EXPECT_TRUE(verifier_->AddFingerprint(
+ {CertificateFingerprint::kSha256,
+ "F2:E5:46:5E:2B:F7:EC:D6:F6:30:66:A5:A3:75:11:73:4A:A0:EB:"
+ "7C:47:01:0E:86:D6:75:8E:D4:F4:FA:1B:0F"}));
+ EXPECT_EQ(Verify(kTestCertificate).detailed_status,
+ WebTransportFingerprintProofVerifier::Status::kValidCertificate);
+
+ // Reject unknown hash algorithms.
+ EXPECT_FALSE(verifier_->AddFingerprint(
+ {"sha-1",
+ "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"}));
+ // Reject invalid length.
+ EXPECT_FALSE(verifier_->AddFingerprint(
+ {CertificateFingerprint::kSha256, "00:00:00:00"}));
+ // Reject missing colons.
+ EXPECT_FALSE(verifier_->AddFingerprint(
+ {CertificateFingerprint::kSha256,
+ "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00."
+ "00.00.00.00.00.00.00.00.00.00.00.00.00"}));
+ // Reject non-hex symbols.
+ EXPECT_FALSE(verifier_->AddFingerprint(
+ {CertificateFingerprint::kSha256,
+ "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:"
+ "zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz"}));
+}
+
+} // namespace
+} // namespace test
+} // namespace quic
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 486444183c9..eacbca5287c 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
@@ -242,7 +242,12 @@ int HandshakeWithFakeServer(QuicConfig* server_quic_config,
TestQuicSpdyServerSession server_session(
server_conn, *server_quic_config, client_conn->supported_versions(),
crypto_config, &compressed_certs_cache);
+ // Call SetServerApplicationStateForResumption so that the fake server
+ // supports 0-RTT in TLS.
server_session.Initialize();
+ server_session.GetMutableCryptoStream()
+ ->SetServerApplicationStateForResumption(
+ std::make_unique<ApplicationState>());
EXPECT_CALL(*server_session.helper(),
CanAcceptClientHello(testing::_, testing::_, testing::_,
testing::_, testing::_))
@@ -404,9 +409,6 @@ std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
QUIC_LOG(INFO) << "Processing "
<< server_conn->encrypted_packets_.size() - server_i
<< " packets server->client";
- if (server_conn->encrypted_packets_.size() - server_i == 2) {
- QUIC_LOG(INFO) << "here";
- }
MovePackets(server_conn, &server_i, client, client_conn,
Perspective::IS_CLIENT);
@@ -574,7 +576,7 @@ void CompareCrypters(const QuicEncrypter* encrypter,
std::string label) {
if (encrypter == nullptr || decrypter == nullptr) {
ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
- << decrypter;
+ << decrypter << " for " << label;
return;
}
quiche::QuicheStringPiece encrypter_key = encrypter->GetKey();
@@ -605,7 +607,8 @@ void CompareClientAndServerKeys(QuicCryptoClientStream* client,
const QuicDecrypter* server_decrypter(
QuicFramerPeer::GetDecrypter(server_framer, level));
if (level == ENCRYPTION_FORWARD_SECURE ||
- !((level == ENCRYPTION_HANDSHAKE || client_encrypter == nullptr) &&
+ !((level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
+ client_encrypter == nullptr) &&
server_decrypter == nullptr)) {
CompareCrypters(client_encrypter, server_decrypter,
"client " + EncryptionLevelString(level) + " write");
@@ -616,7 +619,8 @@ void CompareClientAndServerKeys(QuicCryptoClientStream* client,
QuicFramerPeer::GetDecrypter(client_framer, level));
if (level == ENCRYPTION_FORWARD_SECURE ||
!(server_encrypter == nullptr &&
- (level == ENCRYPTION_HANDSHAKE || client_decrypter == nullptr))) {
+ (level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_ZERO_RTT ||
+ client_decrypter == nullptr))) {
CompareCrypters(server_encrypter, client_decrypter,
"server " + EncryptionLevelString(level) + " write");
}
@@ -748,10 +752,11 @@ void MovePackets(PacketSavingConnection* source_conn,
QuicConnectionPeer::AddBytesReceived(
dest_conn, source_conn->encrypted_packets_[index]->length());
if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
- // The framer will be unable to decrypt forward-secure packets sent after
- // the handshake is complete. Don't treat them as handshake packets.
+ // The framer will be unable to decrypt zero-rtt packets sent during
+ // handshake or forward-secure packets sent after the handshake is
+ // complete. Don't treat them as handshake packets.
QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
- break;
+ continue;
}
QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
dest_conn->OnDecryptedPacket(framer.last_decrypted_level());
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h
index b2a4ebd36be..ad5f792e0b9 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/first_flight.h
@@ -49,10 +49,10 @@ class QUIC_NO_EXPORT DelegatedPacketWriter : public QuicPacketWriter {
}
bool SupportsReleaseTime() const override { return false; }
bool IsBatchMode() const override { return false; }
- char* GetNextWriteLocation(
+ QuicPacketBuffer GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) override {
- return nullptr;
+ return {nullptr, nullptr};
}
WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc
index 1761dd9af32..21c080a3c4c 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.cc
@@ -14,6 +14,10 @@ void MockClock::AdvanceTime(QuicTime::Delta delta) {
now_ = now_ + delta;
}
+void MockClock::Reset() {
+ now_ = QuicTime::Zero();
+}
+
QuicTime MockClock::Now() const {
return now_;
}
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h
index 4bd51e9d6d6..2ce2e966a9c 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/mock_clock.h
@@ -24,6 +24,8 @@ class MockClock : public QuicClock {
// Advances the current time by |delta|, which may be negative.
void AdvanceTime(QuicTime::Delta delta);
+ // Resets time back to zero.
+ void Reset();
private:
QuicTime now_;
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 75b9a5dcb30..f066e9191e4 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
@@ -54,12 +54,12 @@ class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
void SetWritable() override;
- char* GetNextWriteLocation(
+ QuicPacketBuffer GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) override {
// If the wrapped writer supports zero-copy, disable it, because it is not
// compatible with delayed writes in this class.
- return nullptr;
+ return {nullptr, nullptr};
}
// Writes out any packet which should have been sent by now
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 3e752154f27..52325d16650 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
@@ -94,8 +94,8 @@ void QuicConfigPeer::SetReceivedStatelessResetToken(QuicConfig* config,
// static
void QuicConfigPeer::SetReceivedMaxPacketSize(QuicConfig* config,
- uint32_t max_packet_size) {
- config->max_packet_size_.SetReceivedValue(max_packet_size);
+ uint32_t max_udp_payload_size) {
+ config->max_udp_payload_size_.SetReceivedValue(max_udp_payload_size);
}
// static
@@ -106,8 +106,23 @@ void QuicConfigPeer::SetNegotiated(QuicConfig* config, bool negotiated) {
// static
void QuicConfigPeer::SetReceivedOriginalConnectionId(
QuicConfig* config,
- const QuicConnectionId& original_connection_id) {
- config->received_original_connection_id_ = original_connection_id;
+ const QuicConnectionId& original_destination_connection_id) {
+ config->received_original_destination_connection_id_ =
+ original_destination_connection_id;
+}
+
+// static
+void QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ QuicConfig* config,
+ const QuicConnectionId& initial_source_connection_id) {
+ config->received_initial_source_connection_id_ = initial_source_connection_id;
+}
+
+// static
+void QuicConfigPeer::SetReceivedRetrySourceConnectionId(
+ QuicConfig* config,
+ const QuicConnectionId& retry_source_connection_id) {
+ config->received_retry_source_connection_id_ = retry_source_connection_id;
}
// static
@@ -117,5 +132,10 @@ void QuicConfigPeer::SetReceivedMaxDatagramFrameSize(
config->max_datagram_frame_size_.SetReceivedValue(max_datagram_frame_size);
}
+// static
+void QuicConfigPeer::DisableSupportHandshakeDone(QuicConfig* config) {
+ config->support_handshake_done_.SetSendValue(0);
+}
+
} // namespace test
} // namespace quic
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 c435f2282da..109bd6453b3 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
@@ -58,16 +58,25 @@ class QuicConfigPeer {
QuicUint128 token);
static void SetReceivedMaxPacketSize(QuicConfig* config,
- uint32_t max_packet_size);
+ uint32_t max_udp_payload_size);
static void SetNegotiated(QuicConfig* config, bool negotiated);
static void SetReceivedOriginalConnectionId(
QuicConfig* config,
- const QuicConnectionId& original_connection_id);
+ const QuicConnectionId& original_destination_connection_id);
+
+ static void SetReceivedInitialSourceConnectionId(
+ QuicConfig* config,
+ const QuicConnectionId& initial_source_connection_id);
+
+ static void SetReceivedRetrySourceConnectionId(
+ QuicConfig* config,
+ const QuicConnectionId& retry_source_connection_id);
static void SetReceivedMaxDatagramFrameSize(QuicConfig* config,
uint64_t max_datagram_frame_size);
+ static void DisableSupportHandshakeDone(QuicConfig* config);
};
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_connection_peer.cc
index d276f6327ea..54616b2e407 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
@@ -377,5 +377,10 @@ void QuicConnectionPeer::SetServerConnectionId(
connection->InstallInitialCrypters(server_connection_id);
}
+// static
+size_t QuicConnectionPeer::NumUndecryptablePackets(QuicConnection* connection) {
+ return connection->undecryptable_packets_.size();
+}
+
} // 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 9882f62ee35..a5b94ef2c53 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
@@ -147,6 +147,8 @@ class QuicConnectionPeer {
static void SetServerConnectionId(
QuicConnection* connection,
const QuicConnectionId& server_connection_id);
+
+ static size_t NumUndecryptablePackets(QuicConnection* connection);
};
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc
new file mode 100644
index 00000000000..3cce97eed80
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.cc
@@ -0,0 +1,22 @@
+// 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.
+
+#include "net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h"
+
+using testing::_;
+using testing::Invoke;
+
+namespace quic {
+namespace test {
+
+MockQuicSyscallWrapper::MockQuicSyscallWrapper(QuicSyscallWrapper* delegate) {
+ ON_CALL(*this, Sendmsg(_, _, _))
+ .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmsg));
+
+ ON_CALL(*this, Sendmmsg(_, _, _, _))
+ .WillByDefault(Invoke(delegate, &QuicSyscallWrapper::Sendmmsg));
+}
+
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h
new file mode 100644
index 00000000000..8dac5ad00c9
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h
@@ -0,0 +1,37 @@
+// 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_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
+#define QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
+
+#include "net/third_party/quiche/src/quic/core/quic_syscall_wrapper.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class MockQuicSyscallWrapper : public QuicSyscallWrapper {
+ public:
+ // Create a standard mock object.
+ MockQuicSyscallWrapper() = default;
+
+ // Create a 'mockable' object that delegates everything to |delegate| by
+ // default.
+ explicit MockQuicSyscallWrapper(QuicSyscallWrapper* delegate);
+
+ MOCK_METHOD(ssize_t,
+ Sendmsg,
+ (int sockfd, const msghdr*, int flags),
+ (override));
+
+ MOCK_METHOD(int,
+ Sendmmsg,
+ (int sockfd, mmsghdr*, unsigned int vlen, int flags),
+ (override));
+};
+
+} // namespace test
+} // namespace quic
+
+#endif // QUICHE_QUIC_PLATFORM_IMPL_QUIC_MOCK_SYSCALL_WRAPPER_H_
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc
index 44fed8809ec..151575a0db0 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.cc
@@ -111,7 +111,7 @@ SerializedPacket QuicPacketCreatorPeer::SerializeAllFrames(
bool success = creator->AddFrame(frame, NOT_RETRANSMISSION);
DCHECK(success);
}
- creator->SerializePacket(buffer, buffer_len);
+ creator->SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len);
SerializedPacket packet = std::move(creator->packet_);
// The caller takes ownership of the QuicEncryptedPacket.
creator->packet_.encrypted_buffer = nullptr;
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 ab28828cc14..ea9dc062fd1 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
@@ -242,12 +242,17 @@ size_t QuicSessionPeer::GetNumOpenDynamicStreams(QuicSession* session) {
}
}
// Exclude draining streams.
- result -= session->GetNumDrainingStreams();
+ result -= session->num_draining_streams_;
// Add locally closed streams.
result += session->locally_closed_streams_highest_offset_.size();
return result;
}
+// static
+size_t QuicSessionPeer::GetNumDrainingStreams(QuicSession* session) {
+ return session->num_draining_streams_;
+}
+
} // namespace test
} // namespace quic
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 ffb6a46446d..061f16da3a7 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
@@ -82,6 +82,7 @@ class QuicSessionPeer {
static void set_is_configured(QuicSession* session, bool value);
static void SetPerspective(QuicSession* session, Perspective perspective);
static size_t GetNumOpenDynamicStreams(QuicSession* session);
+ static size_t GetNumDrainingStreams(QuicSession* session);
};
} // namespace test
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 22e65b822ee..503f58539b2 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
@@ -210,6 +210,22 @@ MockableQuicClient::MockableQuicClient(
const ParsedQuicVersionVector& supported_versions,
QuicEpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier)
+ : MockableQuicClient(server_address,
+ server_id,
+ config,
+ supported_versions,
+ epoll_server,
+ std::move(proof_verifier),
+ nullptr) {}
+
+MockableQuicClient::MockableQuicClient(
+ QuicSocketAddress server_address,
+ const QuicServerId& server_id,
+ const QuicConfig& config,
+ const ParsedQuicVersionVector& supported_versions,
+ QuicEpollServer* epoll_server,
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ std::unique_ptr<SessionCache> session_cache)
: QuicClient(
server_address,
server_id,
@@ -218,8 +234,8 @@ MockableQuicClient::MockableQuicClient(
epoll_server,
std::make_unique<MockableQuicClientEpollNetworkHelper>(epoll_server,
this),
- QuicWrapUnique(
- new RecordingProofVerifier(std::move(proof_verifier)))),
+ QuicWrapUnique(new RecordingProofVerifier(std::move(proof_verifier))),
+ std::move(session_cache)),
override_server_connection_id_(EmptyQuicConnectionId()),
server_connection_id_overridden_(false),
override_client_connection_id_(EmptyQuicConnectionId()),
@@ -342,6 +358,24 @@ QuicTestClient::QuicTestClient(
Initialize();
}
+QuicTestClient::QuicTestClient(
+ QuicSocketAddress server_address,
+ const std::string& server_hostname,
+ const QuicConfig& config,
+ const ParsedQuicVersionVector& supported_versions,
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ std::unique_ptr<SessionCache> session_cache)
+ : client_(new MockableQuicClient(
+ server_address,
+ QuicServerId(server_hostname, server_address.port(), false),
+ config,
+ supported_versions,
+ &epoll_server_,
+ std::move(proof_verifier),
+ std::move(session_cache))) {
+ Initialize();
+}
+
QuicTestClient::QuicTestClient() = default;
QuicTestClient::~QuicTestClient() {
@@ -390,13 +424,8 @@ ssize_t QuicTestClient::SendRequestAndRstTogether(const std::string& uri) {
QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(
session->transport_version(), 0);
QuicStream* stream = session->GetOrCreateStream(stream_id);
- if (session->break_close_loop()) {
- session->ResetStream(stream_id, QUIC_STREAM_CANCELLED,
- stream->stream_bytes_written());
- } else {
- session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED,
- stream->stream_bytes_written());
- }
+ session->ResetStream(stream_id, QUIC_STREAM_CANCELLED,
+ stream->stream_bytes_written());
return ret;
}
@@ -962,7 +991,7 @@ void QuicTestClient::WaitForDelayedAcks() {
const QuicClock* clock = client()->client_session()->connection()->clock();
QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
- while (clock->ApproximateNow() < wait_until) {
+ while (connected() && clock->ApproximateNow() < wait_until) {
// This waits for up to 50 ms.
client()->WaitForEvents();
}
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 f74974f4231..41e30b13dbb 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
@@ -49,6 +49,14 @@ class MockableQuicClient : public QuicClient {
const ParsedQuicVersionVector& supported_versions,
QuicEpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier);
+
+ MockableQuicClient(QuicSocketAddress server_address,
+ const QuicServerId& server_id,
+ const QuicConfig& config,
+ const ParsedQuicVersionVector& supported_versions,
+ QuicEpollServer* epoll_server,
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ std::unique_ptr<SessionCache> session_cache);
MockableQuicClient(const MockableQuicClient&) = delete;
MockableQuicClient& operator=(const MockableQuicClient&) = delete;
@@ -100,6 +108,12 @@ class QuicTestClient : public QuicSpdyStream::Visitor,
const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
std::unique_ptr<ProofVerifier> proof_verifier);
+ QuicTestClient(QuicSocketAddress server_address,
+ const std::string& server_hostname,
+ const QuicConfig& config,
+ const ParsedQuicVersionVector& supported_versions,
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ std::unique_ptr<SessionCache> session_cache);
~QuicTestClient() override;
@@ -188,9 +202,10 @@ class QuicTestClient : public QuicSpdyStream::Visitor,
void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); }
// Returns once at least one complete response or a connection close has been
- // received from the server, or once the timeout expires. -1 means no timeout.
- // If responses are received for multiple (say 2) streams, next
- // WaitForResponseForMs will return immediately.
+ // received from the server, or once the timeout expires.
+ // Passing in a timeout value of -1 disables the timeout. If multiple
+ // responses are received while the client is waiting, subsequent calls to
+ // this function will return immediately.
void WaitForResponseForMs(int timeout_ms) {
WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); });
if (response_complete()) {
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 7d88ccdaae7..41fb995e5e3 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
@@ -419,6 +419,11 @@ bool NoOpFramerVisitor::OnHandshakeDoneFrame(
return true;
}
+bool NoOpFramerVisitor::OnAckFrequencyFrame(
+ const QuicAckFrequencyFrame& /*frame*/) {
+ return true;
+}
+
bool NoOpFramerVisitor::IsValidStatelessResetToken(
QuicUint128 /*token*/) const {
return false;
@@ -566,6 +571,7 @@ void PacketSavingConnection::SendOrQueuePacket(SerializedPacket packet) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
// Transfer ownership of the packet to the SentPacketManager and the
// ack notifier to the AckNotifierManager.
+ OnPacketSent(packet.encryption_level, packet.transmission_type);
QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
&packet, clock_.ApproximateNow(), NOT_RETRANSMISSION,
HAS_RETRANSMITTABLE_DATA);
@@ -755,8 +761,8 @@ TestQuicSpdyClientSession::TestQuicSpdyClientSession(
&push_promise_index_,
config,
supported_versions) {
- // TODO(b/153726130): Consider adding OnApplicationState calls in tests and
- // set |has_application_state| to true.
+ // TODO(b/153726130): Consider adding SetServerApplicationStateForResumption
+ // calls in tests and set |has_application_state| to true.
crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
server_id, this, crypto_test_utils::ProofVerifyContextForTesting(),
crypto_config, this, /*has_application_state = */ false);
@@ -799,7 +805,7 @@ MockPacketWriter::MockPacketWriter() {
.WillByDefault(testing::Return(kMaxOutgoingPacketSize));
ON_CALL(*this, IsBatchMode()).WillByDefault(testing::Return(false));
ON_CALL(*this, GetNextWriteLocation(_, _))
- .WillByDefault(testing::Return(nullptr));
+ .WillByDefault(testing::Return(QuicPacketBuffer()));
ON_CALL(*this, Flush())
.WillByDefault(testing::Return(WriteResult(WRITE_STATUS_OK, 0)));
ON_CALL(*this, SupportsReleaseTime()).WillByDefault(testing::Return(false));
@@ -841,9 +847,9 @@ ParsedQuicVersion QuicVersionMin() {
}
void DisableQuicVersionsWithTls() {
- SetQuicReloadableFlag(quic_enable_version_draft_27, false);
- SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
- SetQuicReloadableFlag(quic_enable_version_t050_v2, false);
+ for (const ParsedQuicVersion& version : AllSupportedVersionsWithTls()) {
+ QuicDisableVersion(version);
+ }
}
QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -1255,12 +1261,12 @@ QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
}
StreamType DetermineStreamType(QuicStreamId id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
Perspective perspective,
bool is_incoming,
StreamType default_type) {
- return VersionHasIetfQuicFrames(version)
- ? QuicUtils::GetStreamType(id, perspective, is_incoming)
+ return version.HasIetfQuicFrames()
+ ? QuicUtils::GetStreamType(id, perspective, is_incoming, version)
: default_type;
}
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 7d1d9db4459..2af8aeb3224 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
@@ -15,6 +15,7 @@
#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"
#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_server_session_base.h"
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_session.h"
@@ -395,6 +396,10 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
OnHandshakeDoneFrame,
(const QuicHandshakeDoneFrame& frame),
(override));
+ MOCK_METHOD(bool,
+ OnAckFrequencyFrame,
+ (const QuicAckFrequencyFrame& frame),
+ (override));
MOCK_METHOD(void, OnPacketComplete, (), (override));
MOCK_METHOD(bool,
IsValidStatelessResetToken,
@@ -459,6 +464,7 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
bool OnMessageFrame(const QuicMessageFrame& frame) override;
bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
void OnPacketComplete() override {}
bool IsValidStatelessResetToken(QuicUint128 token) const override;
void OnAuthenticatedIetfStatelessResetPacket(
@@ -498,14 +504,18 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
MOCK_METHOD(void, OnWriteBlocked, (), (override));
MOCK_METHOD(void, OnCanWrite, (), (override));
MOCK_METHOD(bool, SendProbingData, (), (override));
+ MOCK_METHOD(bool,
+ ValidateStatelessReset,
+ (const quic::QuicSocketAddress&, const quic::QuicSocketAddress&),
+ (override));
MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
MOCK_METHOD(void,
OnConnectionMigration,
(AddressChangeType type),
(override));
MOCK_METHOD(void, OnPathDegrading, (), (override));
+ MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
- MOCK_METHOD(bool, HasPendingHandshake, (), (const, override));
MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
MOCK_METHOD(void,
OnSuccessfulVersionNegotiation,
@@ -521,7 +531,6 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
MOCK_METHOD(void, SendPing, (), (override));
MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override));
MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override));
- MOCK_METHOD(void, OnForwardProgressConfirmed, (), (override));
MOCK_METHOD(bool,
OnMaxStreamsFrame,
(const QuicMaxStreamsFrame& frame),
@@ -672,6 +681,8 @@ class MockQuicConnection : public QuicConnection {
QuicConnection::OnError(framer);
}
+ void ReallyOnCanWrite() { QuicConnection::OnCanWrite(); }
+
void ReallyCloseConnection(
QuicErrorCode error,
const std::string& details,
@@ -738,6 +749,8 @@ class PacketSavingConnection : public MockQuicConnection {
void SendOrQueuePacket(SerializedPacket packet) override;
+ MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));
+
std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
MockClock clock_;
};
@@ -797,7 +810,6 @@ class MockQuicSession : public QuicSession {
MOCK_METHOD(void, OnAlpnSelected, (quiche::QuicheStringPiece), (override));
using QuicSession::ActivateStream;
- using QuicSession::GetNumDrainingStreams;
// Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
// if set) has been consumed.
@@ -834,6 +846,8 @@ class MockQuicCryptoStream : public QuicCryptoStream {
void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
+ void SetServerApplicationStateForResumption(
+ std::unique_ptr<ApplicationState> /*application_state*/) override {}
private:
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
@@ -1182,7 +1196,7 @@ class MockPacketWriter : public QuicPacketWriter {
(const, override));
MOCK_METHOD(bool, SupportsReleaseTime, (), (const, override));
MOCK_METHOD(bool, IsBatchMode, (), (const, override));
- MOCK_METHOD(char*,
+ MOCK_METHOD(QuicPacketBuffer,
GetNextWriteLocation,
(const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address),
@@ -1285,6 +1299,7 @@ class MockLossAlgorithm : public LossDetectionInterface {
MOCK_METHOD(void, OnConfigNegotiated, (), (override));
MOCK_METHOD(void, OnMinRttAvailable, (), (override));
+ MOCK_METHOD(void, OnUserAgentIdKnown, (), (override));
MOCK_METHOD(void, OnConnectionClosed, (), (override));
};
@@ -1415,6 +1430,16 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
OnVersionNegotiationPacket,
(const QuicVersionNegotiationPacket&),
(override));
+
+ MOCK_METHOD(void,
+ OnTransportParametersSent,
+ (const TransportParameters&),
+ (override));
+
+ MOCK_METHOD(void,
+ OnTransportParametersReceived,
+ (const TransportParameters&),
+ (override));
};
class MockReceivedPacketManager : public QuicReceivedPacketManager {
@@ -1443,7 +1468,7 @@ class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
delete;
~MockPacketCreatorDelegate() override;
- MOCK_METHOD(char*, GetPacketBuffer, (), (override));
+ MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
MOCK_METHOD(void,
OnUnrecoverableError,
@@ -1600,7 +1625,7 @@ QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
int n);
StreamType DetermineStreamType(QuicStreamId id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
Perspective perspective,
bool is_incoming,
StreamType default_type);
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 3d2652fa7ed..8ec56dc9ed8 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
@@ -204,6 +204,11 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
return true;
}
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+ ack_frequency_frames_.push_back(frame);
+ return true;
+ }
+
void OnPacketComplete() override {}
bool IsValidStatelessResetToken(QuicUint128 /*token*/) const override {
@@ -295,6 +300,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
std::vector<QuicNewTokenFrame> new_token_frames_;
std::vector<QuicMessageFrame> message_frames_;
std::vector<QuicHandshakeDoneFrame> handshake_done_frames_;
+ std::vector<QuicAckFrequencyFrame> ack_frequency_frames_;
std::vector<std::unique_ptr<std::string>> stream_data_;
std::vector<std::unique_ptr<std::string>> crypto_data_;
EncryptionLevel last_decrypted_level_;
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc
index 6a0cafb4177..94b8764a7bf 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.cc
@@ -34,6 +34,12 @@ std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup(
if (it == cache_entries_.end()) {
return nullptr;
}
+
+ if (!it->second.session) {
+ cache_entries_.erase(it);
+ return nullptr;
+ }
+
auto state = std::make_unique<QuicResumptionState>();
state->tls_session = std::move(it->second.session);
state->application_state = it->second.application_state.get();
@@ -41,5 +47,10 @@ std::unique_ptr<QuicResumptionState> SimpleSessionCache::Lookup(
return state;
}
+void SimpleSessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
+ // The simple session cache only stores 1 SSL ticket per entry, so no need to
+ // do anything here.
+}
+
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h
index cfe3f4a5454..6043a439e4d 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_cache.h
@@ -28,6 +28,7 @@ class SimpleSessionCache : public SessionCache {
const ApplicationState* application_state) override;
std::unique_ptr<QuicResumptionState> Lookup(const QuicServerId& server_id,
const SSL_CTX* ctx) override;
+ void ClearEarlyData(const QuicServerId& server_id) override;
private:
struct Entry {
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
index 1237f424499..65afacebf3c 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
@@ -78,6 +78,7 @@ class SimpleSessionNotifier : public SessionNotifierInterface {
bool IsFrameOutstanding(const QuicFrame& frame) const override;
bool HasUnackedCryptoData() const override;
bool HasUnackedStreamData() const override;
+ bool HasLostStreamData() const;
private:
struct StreamState {
@@ -124,8 +125,6 @@ class SimpleSessionNotifier : public SessionNotifierInterface {
bool HasBufferedControlFrames() const;
- bool HasLostStreamData() const;
-
bool StreamHasBufferedData(QuicStreamId id) const;
QuicCircularDeque<QuicFrame> control_frames_;
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc
index 3816fd4b0c0..52f7fe683b7 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/queue.cc
@@ -20,6 +20,7 @@ Queue::Queue(Simulator* simulator, std::string name, QuicByteCount capacity)
aggregation_timeout_(QuicTime::Delta::Infinite()),
current_bundle_(0),
current_bundle_bytes_(0),
+ tx_port_(nullptr),
listener_(nullptr) {
aggregation_timeout_alarm_.reset(simulator_->GetAlarmFactory()->CreateAlarm(
new AggregationAlarmDelegate(this)));
@@ -116,7 +117,12 @@ void Queue::ScheduleNextPacketDequeue() {
return;
}
- Schedule(clock_->Now() + tx_port_->TimeUntilAvailable());
+ QuicTime::Delta time_until_available = QuicTime::Delta::Zero();
+ if (tx_port_) {
+ time_until_available = tx_port_->TimeUntilAvailable();
+ }
+
+ Schedule(clock_->Now() + time_until_available);
}
} // namespace simulator
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 c908f982abd..aba7b46a649 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
@@ -11,6 +11,7 @@
#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_test_output.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/quic/test_tools/quic_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
@@ -55,6 +56,7 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator,
// Skip version negotiation.
test::QuicConnectionPeer::SetNegotiatedVersion(connection_.get());
}
+ test::QuicConnectionPeer::SetAddressValidated(connection_.get());
connection_->SetDataProducer(&producer_);
connection_->SetSessionNotifier(this);
notifier_ = std::make_unique<test::SimpleSessionNotifier>(connection_.get());
@@ -74,6 +76,17 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator,
peer_hello, perspective == Perspective::IS_CLIENT ? SERVER : CLIENT,
&error);
DCHECK_EQ(error_code, QUIC_NO_ERROR) << "Configuration failed: " << error;
+ if (connection_->version().AuthenticatesHandshakeConnectionIds()) {
+ if (connection_->perspective() == Perspective::IS_CLIENT) {
+ test::QuicConfigPeer::SetReceivedOriginalConnectionId(
+ &config, connection_->connection_id());
+ test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_->connection_id());
+ } else {
+ test::QuicConfigPeer::SetReceivedInitialSourceConnectionId(
+ &config, connection_->client_connection_id());
+ }
+ }
connection_->SetFromConfig(config);
}
@@ -153,9 +166,6 @@ bool QuicEndpoint::WillingAndAbleToWrite() const {
}
return bytes_to_transfer_ != 0;
}
-bool QuicEndpoint::HasPendingHandshake() const {
- return false;
-}
bool QuicEndpoint::ShouldKeepConnectionAlive() const {
return true;
}
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 8b9fd1f480d..cb3c38644f7 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
@@ -51,8 +51,12 @@ class QuicEndpoint : public QuicEndpointBase,
void OnCryptoFrame(const QuicCryptoFrame& frame) override;
void OnCanWrite() override;
bool SendProbingData() override;
+ bool ValidateStatelessReset(
+ const quic::QuicSocketAddress& /*self_address*/,
+ const quic::QuicSocketAddress& /*peer_address*/) override {
+ return true;
+ }
bool WillingAndAbleToWrite() const override;
- bool HasPendingHandshake() const override;
bool ShouldKeepConnectionAlive() const override;
void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {}
@@ -72,11 +76,11 @@ class QuicEndpoint : public QuicEndpointBase,
void OnCongestionWindowChange(QuicTime /*now*/) override {}
void OnConnectionMigration(AddressChangeType /*type*/) override {}
void OnPathDegrading() override {}
+ void OnForwardProgressMadeAfterPathDegrading() override {}
void OnAckNeedsRetransmittableFrame() override {}
void SendPing() override {}
bool AllowSelfAddressChange() const override;
HandshakeState GetHandshakeState() const override;
- void OnForwardProgressConfirmed() override {}
bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
return true;
}
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc
index 21815d8fe31..c05740d6f00 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.cc
@@ -178,10 +178,10 @@ bool QuicEndpointBase::Writer::IsBatchMode() const {
return false;
}
-char* QuicEndpointBase::Writer::GetNextWriteLocation(
+QuicPacketBuffer QuicEndpointBase::Writer::GetNextWriteLocation(
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/) {
- return nullptr;
+ return {nullptr, nullptr};
}
WriteResult QuicEndpointBase::Writer::Flush() {
diff --git a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h
index f4fe33be429..c9be24eb089 100644
--- a/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h
+++ b/chromium/net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h
@@ -87,8 +87,9 @@ class QuicEndpointBase : public Endpoint,
const QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
- char* GetNextWriteLocation(const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override;
+ QuicPacketBuffer GetNextWriteLocation(
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address) override;
WriteResult Flush() override;
private:
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 2a733b43ae9..d179d006329 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
@@ -249,6 +249,34 @@ hTXMooR/wD7an6gtnXD8ixCh7bP0TyPiBhNsUb12WrvSEAm/UyciQbQlR7P+K0Z7
Cmn1Mj4hQ+pT0t+pw/DMOw==
-----END CERTIFICATE-----)";
+QUIC_CONST_INIT const char kTestCertWithUnknownSanTypePem[] =
+ R"(-----BEGIN CERTIFICATE-----
+MIIEYTCCA0mgAwIBAgIJAILStmLgUUcVMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp
+c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRAw
+DgYDVQQDDAdUZXN0IENBMB4XDTE4MTIxNzIwMTgwMFoXDTIwMTIxNjIwMTgwMFow
+gaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T
+YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu
+ZWVyaW5nMRowGAYDVQQDDBFUZXN0IEJhY2tlbmQgVGVhbTEkMCIGCSqGSIb3DQEJ
+ARYVYmFja2VuZC10ZWFtQGx5ZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuvPdQdmwZongPAgQho/Vipd3PZWrQ6BKxIb4l/RvqtVP321IUTLs
+4vVwpXoYJ+12L+XOO3jCInszs53tHjFpTI1GE8/sasmgR6LRr2krwSoVRHPqUoc9
+tzkDG1SzKP2TRTi1MTI3FO+TnLFahntO9Zstxhv1Epz5GZ/xQLE0/LLoRYzcynL/
+iflk18iL1KM8i0Hy4cKjclOaUdnh2nh753iJfxCSb5wJfx4FH1qverYHHT6FopYR
+V40Cg0yYXcYo8yNwrg+EBY8QAT2JOMDokXNKbZpmVKiBlh0QYMX6BBiW249v3sYl
+3Ve+fZvCkle3W0xP0xJw8PdX0NRbvGOrBQIDAQABo4HAMIG9MAwGA1UdEwEB/wQC
+MAAwCwYDVR0PBAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBB
+BgNVHREEOjA4hh5zcGlmZmU6Ly9seWZ0LmNvbS9iYWNrZW5kLXRlYW2CCGx5ZnQu
+Y29tggx3d3cubHlmdC5jb20wHQYDVR0OBBYEFLHmMm0DV9jCHJSWVRwyPYpBw62r
+MB8GA1UdIwQYMBaAFBQz1vaSbPuePL++7GTMqLAMtk3kMA0GCSqGSIb3DQEBCwUA
+A4IBAQAwx3/M2o00W8GlQ3OT4y/hQGb5K2aytxx8QeSmJaaZTJbvaHhe0x3/fLgq
+uWrW3WEWFtwasilySjOrFOtB9UNmJmNOHSJD3Bslbv5htRaWnoFPCXdwZtVMdoTq
+IHIQqLoos/xj3kVD5sJSYySrveMeKaeUILTkb5ZubSivye1X2yiJLR7AtuwuiMio
+CdIOqhn6xJqYhT7z0IhdKpLNPk4w1tBZSKOXqzrXS4uoJgTC67hWslWWZ2VC6IvZ
+FmKuuGZamCCj6F1QF2IjMVM8evl84hEnN0ajdkA/QWnil9kcWvBm15Ho+oTvvJ7s
+M8MD3RDSq/90FSiME4vbyNEyTmj0
+-----END CERTIFICATE-----)";
+
QUIC_CONST_INIT const char kTestCertificatePrivateKeyRaw[] = {
'\x30', '\x82', '\x04', '\xbc', '\x02', '\x01', '\x00', '\x30', '\x0d',
'\x06', '\x09', '\x2a', '\x86', '\x48', '\x86', '\xf7', '\x0d', '\x01',
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 ec4a4d407d5..e7d3035a610 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
@@ -20,6 +20,10 @@ QUIC_CONST_INIT extern const char kTestCertificatePem[];
// |kTestCertificatePem| with a PEM-encoded root appended to the end.
QUIC_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[];
+
// DER-encoded private key for |kTestCertificate|.
QUIC_CONST_INIT extern const quiche::QuicheStringPiece
kTestCertificatePrivateKey;
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 11edb195a9d..82b549faeef 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
@@ -235,7 +235,7 @@ void QuicClientBase::WaitForStreamToClose(QuicStreamId id) {
}
}
-bool QuicClientBase::WaitForCryptoHandshakeConfirmed() {
+bool QuicClientBase::WaitForOneRttKeysAvailable() {
DCHECK(connected());
while (connected() && !session_->OneRttKeysAvailable()) {
@@ -247,6 +247,19 @@ bool QuicClientBase::WaitForCryptoHandshakeConfirmed() {
return connected();
}
+bool QuicClientBase::WaitForHandshakeConfirmed() {
+ if (!session_->connection()->version().HasHandshakeDone()) {
+ return WaitForOneRttKeysAvailable();
+ }
+ while (connected() && session_->GetHandshakeState() < HANDSHAKE_CONFIRMED) {
+ WaitForEvents();
+ }
+
+ // If the handshake fails due to a timeout, the connection will be closed.
+ QUIC_LOG_IF(ERROR, !connected()) << "Handshake with server failed.";
+ return connected();
+}
+
bool QuicClientBase::connected() const {
return session_.get() && session_->connection() &&
session_->connection()->connected();
@@ -290,21 +303,7 @@ QuicErrorCode QuicClientBase::connection_error() const {
}
QuicConnectionId QuicClientBase::GetNextConnectionId() {
- QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId();
- return !server_designated_id.IsEmpty() ? server_designated_id
- : GenerateNewConnectionId();
-}
-
-QuicConnectionId QuicClientBase::GetNextServerDesignatedConnectionId() {
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_.LookupOrCreate(server_id_);
- // If the cached state indicates that we should use a server-designated
- // connection ID, then return that connection ID.
- CHECK(cached != nullptr) << "QuicClientCryptoConfig::LookupOrCreate returned "
- << "unexpected nullptr.";
- return cached->has_server_designated_connection_id()
- ? cached->GetNextServerDesignatedConnectionId()
- : EmptyQuicConnectionId();
+ return GenerateNewConnectionId();
}
QuicConnectionId QuicClientBase::GenerateNewConnectionId() {
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 0a40b82d64a..842afc6f14c 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
@@ -102,9 +102,14 @@ class QuicClientBase {
// Wait for events until the stream with the given ID is closed.
void WaitForStreamToClose(QuicStreamId id);
- // Wait for events until the handshake is confirmed.
- // Returns true if the crypto handshake succeeds, false otherwise.
- QUIC_MUST_USE_RESULT bool WaitForCryptoHandshakeConfirmed();
+ // Wait for 1-RTT keys become available.
+ // Returns true once 1-RTT keys are available, false otherwise.
+ QUIC_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();
// Wait up to 50ms, and handle any events which occur.
// Returns true if there are any outstanding requests.
@@ -271,10 +276,6 @@ class QuicClientBase {
// returned. Otherwise, the next random ID will be returned.
QuicConnectionId GetNextConnectionId();
- // Returns the next server-designated ConnectionId from the cached config for
- // |server_id_|, if it exists. Otherwise, returns 0.
- QuicConnectionId GetNextServerDesignatedConnectionId();
-
// Generates a new, random connection ID (as opposed to a server-designated
// connection ID).
virtual QuicConnectionId GenerateNewConnectionId();
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 803e313ea24..e6b9e73d473 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
@@ -41,8 +41,13 @@ enum class Feature {
kConnectionClose,
// The connection was established using TLS resumption.
kResumption,
+ // 0-RTT data is being sent and acted on.
+ kZeroRtt,
// A RETRY packet was successfully processed.
kRetry,
+ // A handshake using a ClientHello that spans multiple packets completed
+ // successfully.
+ kQuantum,
// Second row of features (anything else protocol-related)
// We switched to a different port and the server migrated to it.
@@ -68,8 +73,12 @@ char MatrixLetter(Feature f) {
return 'C';
case Feature::kResumption:
return 'R';
+ case Feature::kZeroRtt:
+ return 'Z';
case Feature::kRetry:
return 'S';
+ case Feature::kQuantum:
+ return 'Q';
case Feature::kRebinding:
return 'B';
case Feature::kHttp3:
@@ -90,14 +99,23 @@ class QuicClientInteropRunner : QuicConnectionDebugVisitor {
// Attempts a resumption using |client| by disconnecting and reconnecting. If
// resumption is successful, |features_| is modified to add
// Feature::kResumption to it, otherwise it is left unmodified.
- void AttemptResumption(QuicClient* client);
+ void AttemptResumption(QuicClient* client, const std::string& authority);
void AttemptRequest(QuicSocketAddress addr,
std::string authority,
QuicServerId server_id,
ParsedQuicVersion version,
bool test_version_negotiation,
- bool attempt_rebind);
+ bool attempt_rebind,
+ bool attempt_multi_packet_chlo);
+
+ // 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);
+
+ // Sends an HTTP request represented by |header_block| using |client|.
+ void SendRequest(QuicClient* client,
+ const spdy::SpdyHeaderBlock& header_block);
void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
switch (frame.close_type) {
@@ -134,20 +152,37 @@ class QuicClientInteropRunner : QuicConnectionDebugVisitor {
std::set<Feature> features_;
};
-void QuicClientInteropRunner::AttemptResumption(QuicClient* client) {
+void QuicClientInteropRunner::AttemptResumption(QuicClient* client,
+ const std::string& authority) {
client->Disconnect();
if (!client->Initialize()) {
QUIC_LOG(ERROR) << "Failed to reinitialize client";
return;
}
- if (!client->Connect() || !client->session()->OneRttKeysAvailable()) {
+ if (!client->Connect()) {
+ return;
+ }
+
+ bool zero_rtt_attempt = !client->session()->OneRttKeysAvailable();
+
+ spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority);
+ SendRequest(client, header_block);
+
+ if (!client->session()->OneRttKeysAvailable()) {
return;
}
+
if (static_cast<QuicCryptoClientStream*>(
test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
->IsResumption()) {
InsertFeature(Feature::kResumption);
}
+ if (static_cast<QuicCryptoClientStream*>(
+ test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
+ ->EarlyDataAccepted() &&
+ zero_rtt_attempt && client->latest_response_code() != -1) {
+ InsertFeature(Feature::kZeroRtt);
+ }
}
void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
@@ -155,7 +190,8 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
QuicServerId server_id,
ParsedQuicVersion version,
bool test_version_negotiation,
- bool attempt_rebind) {
+ bool attempt_rebind,
+ bool attempt_multi_packet_chlo) {
ParsedQuicVersionVector versions = {version};
if (test_version_negotiation) {
versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
@@ -168,6 +204,15 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
QuicConfig config;
QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
config.SetIdleNetworkTimeout(timeout);
+ if (attempt_multi_packet_chlo) {
+ // Make the ClientHello span multiple packets by adding a custom transport
+ // parameter.
+ constexpr auto kCustomParameter =
+ static_cast<TransportParameters::TransportParameterId>(0x173E);
+ std::string custom_value(2000, '?');
+ config.custom_transport_parameters_to_send()[kCustomParameter] =
+ custom_value;
+ }
auto client = std::make_unique<QuicClient>(
addr, server_id, versions, config, &epoll_server,
std::move(proof_verifier), std::move(session_cache));
@@ -192,34 +237,28 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
if (test_version_negotiation && !connect_result) {
// Failed to negotiate version, retry without version negotiation.
AttemptRequest(addr, authority, server_id, version,
- /*test_version_negotiation=*/false, attempt_rebind);
+ /*test_version_negotiation=*/false, attempt_rebind,
+ attempt_multi_packet_chlo);
return;
}
if (!client->session()->OneRttKeysAvailable()) {
+ if (attempt_multi_packet_chlo) {
+ // 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);
+ return;
+ }
return;
}
InsertFeature(Feature::kHandshake);
-
- // Construct and send a request.
- spdy::SpdyHeaderBlock header_block;
- header_block[":method"] = "GET";
- header_block[":scheme"] = "https";
- header_block[":authority"] = authority;
- header_block[":path"] = "/";
- client->set_store_response(true);
- client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
-
- client_stats = connection->GetStats();
- QuicSentPacketManager* sent_packet_manager =
- test::QuicConnectionPeer::GetSentPacketManager(connection);
- const bool received_forward_secure_ack =
- sent_packet_manager != nullptr &&
- sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
- .IsInitialized();
- if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
- InsertFeature(Feature::kStreamData);
+ if (attempt_multi_packet_chlo) {
+ InsertFeature(Feature::kQuantum);
}
+ spdy::SpdyHeaderBlock header_block = ConstructHeaderBlock(authority);
+ SendRequest(client.get(), header_block);
+
if (!client->connected()) {
return;
}
@@ -238,7 +277,8 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
if (!client->connected()) {
// Rebinding does not work, retry without attempting it.
AttemptRequest(addr, authority, server_id, version,
- test_version_negotiation, /*attempt_rebind=*/false);
+ test_version_negotiation, /*attempt_rebind=*/false,
+ attempt_multi_packet_chlo);
return;
}
InsertFeature(Feature::kRebinding);
@@ -259,7 +299,41 @@ void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
InsertFeature(Feature::kConnectionClose);
}
- AttemptResumption(client.get());
+ AttemptResumption(client.get(), authority);
+}
+
+spdy::SpdyHeaderBlock QuicClientInteropRunner::ConstructHeaderBlock(
+ const std::string& authority) {
+ // Construct and send a request.
+ spdy::SpdyHeaderBlock header_block;
+ header_block[":method"] = "GET";
+ header_block[":scheme"] = "https";
+ header_block[":authority"] = authority;
+ header_block[":path"] = "/";
+ return header_block;
+}
+
+void QuicClientInteropRunner::SendRequest(
+ QuicClient* client,
+ const spdy::SpdyHeaderBlock& header_block) {
+ client->set_store_response(true);
+ client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
+
+ QuicConnection* connection = client->session()->connection();
+ if (connection == nullptr) {
+ QUIC_LOG(ERROR) << "No QuicConnection object";
+ return;
+ }
+ QuicConnectionStats client_stats = connection->GetStats();
+ QuicSentPacketManager* sent_packet_manager =
+ test::QuicConnectionPeer::GetSentPacketManager(connection);
+ const bool received_forward_secure_ack =
+ sent_packet_manager != nullptr &&
+ sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
+ .IsInitialized();
+ if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
+ InsertFeature(Feature::kStreamData);
+ }
}
std::set<Feature> ServerSupport(std::string dns_host,
@@ -293,7 +367,8 @@ std::set<Feature> ServerSupport(std::string dns_host,
runner.AttemptRequest(addr, authority, server_id, version,
/*test_version_negotiation=*/true,
- /*attempt_rebind=*/true);
+ /*attempt_rebind=*/true,
+ /*attempt_multi_packet_chlo=*/true);
return runner.features();
}
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc
index 1751f4173ed..38dc582c1f3 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.cc
@@ -22,6 +22,7 @@ std::unique_ptr<QuicSpdyClientBase> QuicEpollClientFactory::CreateClient(
std::string host_for_lookup,
uint16_t port,
ParsedQuicVersionVector versions,
+ const QuicConfig& config,
std::unique_ptr<ProofVerifier> verifier) {
QuicSocketAddress addr =
tools::LookupAddress(host_for_lookup, quiche::QuicheStrCat(port));
@@ -30,8 +31,9 @@ std::unique_ptr<QuicSpdyClientBase> QuicEpollClientFactory::CreateClient(
return nullptr;
}
QuicServerId server_id(host_for_handshake, port, false);
- return std::make_unique<QuicClient>(addr, server_id, versions, &epoll_server_,
- std::move(verifier));
+ return std::make_unique<QuicClient>(addr, server_id, versions, config,
+ &epoll_server_, std::move(verifier),
+ nullptr);
}
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h
index 2ee26d9703c..392bd6cc47c 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_epoll_client_factory.h
@@ -18,6 +18,7 @@ class QuicEpollClientFactory : public QuicToyClient::ClientFactory {
std::string host_for_lookup,
uint16_t port,
ParsedQuicVersionVector versions,
+ const QuicConfig& config,
std::unique_ptr<ProofVerifier> verifier) override;
private:
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 798b66e418e..3192d303c96 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
@@ -207,6 +207,10 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface {
std::cerr << "OnHandshakeDoneFrame: " << frame;
return true;
}
+ bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
+ std::cerr << "OnAckFrequencyFrame: " << frame;
+ return true;
+ }
void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
bool IsValidStatelessResetToken(QuicUint128 /*token*/) const override {
std::cerr << "IsValidStatelessResetToken\n";
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 f84a248cda8..387b3135d4d 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
@@ -158,7 +158,7 @@ void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
// index for it in promised_streams_ can be calculated.
QuicStreamId next_stream_id = next_outgoing_unidirectional_stream_id();
if (VersionHasIetfQuicFrames(transport_version())) {
- DCHECK(!QuicUtils::IsBidirectionalStreamId(frame.stream_id));
+ DCHECK(!QuicUtils::IsBidirectionalStreamId(frame.stream_id, version()));
}
DCHECK_GE(frame.stream_id, next_stream_id);
size_t index = (frame.stream_id - next_stream_id) /
@@ -243,9 +243,9 @@ void QuicSimpleServerSession::OnCanCreateNewOutgoingStream(
}
void QuicSimpleServerSession::MaybeInitializeHttp3UnidirectionalStreams() {
- size_t previous_static_stream_count = num_outgoing_static_streams();
+ size_t previous_static_stream_count = num_static_streams();
QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams();
- size_t current_static_stream_count = num_outgoing_static_streams();
+ size_t current_static_stream_count = num_static_streams();
DCHECK_GE(current_static_stream_count, previous_static_stream_count);
highest_promised_stream_id_ +=
QuicUtils::StreamIdDelta(transport_version()) *
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 3dfaa1e3d22..5c8408428e7 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
@@ -18,6 +18,7 @@
#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_config_peer.h"
+#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_spdy_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
@@ -239,6 +240,9 @@ class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
session_.config()->SetInitialSessionFlowControlWindowToSend(
kInitialSessionFlowControlWindowForTest);
session_.Initialize();
+ if (connection_->version().SupportsAntiAmplificationLimit()) {
+ QuicConnectionPeer::SetAddressValidated(connection_);
+ }
stream_ = new StrictMock<TestStream>(
GetNthClientInitiatedBidirectionalStreamId(
connection_->transport_version(), 0),
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc
index 3301ef5d014..1e6cc54043a 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.cc
@@ -5,6 +5,7 @@
#include "net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.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"
namespace quic {
@@ -24,20 +25,40 @@ QuicTcpLikeTraceConverter::StreamOffsetSegment::StreamOffsetSegment(
QuicTcpLikeTraceConverter::StreamInfo::StreamInfo() : fin(false) {}
+QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnCryptoFrameSent(
+ EncryptionLevel level,
+ QuicStreamOffset offset,
+ QuicByteCount data_length) {
+ if (level >= NUM_ENCRYPTION_LEVELS) {
+ QUIC_BUG << "Invalid encryption level";
+ return {};
+ }
+ return OnFrameSent(offset, data_length, /*fin=*/false,
+ &crypto_frames_info_[level]);
+}
+
QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
QuicStreamId stream_id,
QuicStreamOffset offset,
QuicByteCount data_length,
bool fin) {
+ return OnFrameSent(
+ offset, data_length, fin,
+ &streams_info_.emplace(stream_id, StreamInfo()).first->second);
+}
+
+QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnFrameSent(
+ QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin,
+ StreamInfo* info) {
QuicIntervalSet<uint64_t> connection_offsets;
if (fin) {
// Stream fin consumes a connection offset.
++data_length;
}
- StreamInfo* stream_info =
- &streams_info_.emplace(stream_id, StreamInfo()).first->second;
// Get connection offsets of retransmission data in this frame.
- for (const auto& segment : stream_info->segments) {
+ for (const auto& segment : info->segments) {
QuicInterval<QuicStreamOffset> retransmission(offset, offset + data_length);
retransmission.IntersectWith(segment.stream_data);
if (retransmission.Empty()) {
@@ -50,15 +71,13 @@ QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
connection_offset + retransmission.Length());
}
- if (stream_info->fin) {
+ if (info->fin) {
return connection_offsets;
}
// Get connection offsets of new data in this frame.
QuicStreamOffset least_unsent_offset =
- stream_info->segments.empty()
- ? 0
- : stream_info->segments.back().stream_data.max();
+ info->segments.empty() ? 0 : info->segments.back().stream_data.max();
if (least_unsent_offset >= offset + data_length) {
return connection_offsets;
}
@@ -68,20 +87,17 @@ QuicIntervalSet<uint64_t> QuicTcpLikeTraceConverter::OnStreamFrameSent(
QuicByteCount new_data_length = offset + data_length - new_data_offset;
connection_offsets.Add(connection_offset_,
connection_offset_ + new_data_length);
- if (!stream_info->segments.empty() &&
- new_data_offset == least_unsent_offset &&
- connection_offset_ ==
- stream_info->segments.back().connection_offset +
- stream_info->segments.back().stream_data.Length()) {
+ if (!info->segments.empty() && new_data_offset == least_unsent_offset &&
+ connection_offset_ == info->segments.back().connection_offset +
+ info->segments.back().stream_data.Length()) {
// Extend the last segment if both stream and connection offsets are
// contiguous.
- stream_info->segments.back().stream_data.SetMax(new_data_offset +
- new_data_length);
+ info->segments.back().stream_data.SetMax(new_data_offset + new_data_length);
} else {
- stream_info->segments.emplace_back(new_data_offset, connection_offset_,
- new_data_length);
+ info->segments.emplace_back(new_data_offset, connection_offset_,
+ new_data_length);
}
- stream_info->fin = fin;
+ info->fin = fin;
connection_offset_ += new_data_length;
return connection_offsets;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h
index 46dd7954a25..1380296e0ea 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter.h
@@ -37,6 +37,12 @@ class QuicTcpLikeTraceConverter {
~QuicTcpLikeTraceConverter() {}
+ // Called when a crypto frame is sent. Returns the corresponding connection
+ // offsets.
+ QuicIntervalSet<uint64_t> OnCryptoFrameSent(EncryptionLevel level,
+ QuicStreamOffset offset,
+ QuicByteCount data_length);
+
// Called when a stream frame is sent. Returns the corresponding connection
// offsets.
QuicIntervalSet<uint64_t> OnStreamFrameSent(QuicStreamId stream_id,
@@ -59,6 +65,14 @@ class QuicTcpLikeTraceConverter {
bool fin;
};
+ // Called when frame with |offset|, |data_length| and |fin| has been sent.
+ // Update |info| and returns connection offsets.
+ QuicIntervalSet<uint64_t> OnFrameSent(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin,
+ StreamInfo* info);
+
+ StreamInfo crypto_frames_info_[NUM_ENCRYPTION_LEVELS];
QuicHashMap<QuicStreamId, StreamInfo> streams_info_;
QuicHashMap<QuicControlFrameId, QuicInterval<uint64_t>> control_frames_info_;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc
index a6ce81a8dcd..fa751ae885e 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_tcp_like_trace_converter_test.cc
@@ -98,6 +98,27 @@ TEST(QuicTcpLikeTraceConverterTest, FuzzerTest) {
EXPECT_EQ(expected, converter.OnStreamFrameSent(1, 50, 600, false));
}
+TEST(QuicTcpLikeTraceConverterTest, OnCryptoFrameSent) {
+ QuicTcpLikeTraceConverter converter;
+
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+ converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(100, 200),
+ converter.OnStreamFrameSent(1, 0, 100, false));
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(200, 300),
+ converter.OnStreamFrameSent(1, 100, 100, false));
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(300, 400),
+ converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 0, 100));
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
+ converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
+
+ // Verify crypto frame retransmission works as intended.
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(0, 100),
+ converter.OnCryptoFrameSent(ENCRYPTION_INITIAL, 0, 100));
+ EXPECT_EQ(QuicIntervalSet<uint64_t>(400, 500),
+ converter.OnCryptoFrameSent(ENCRYPTION_HANDSHAKE, 100, 100));
+}
+
} // namespace
} // namespace test
} // namespace quic
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 0018f0524b7..b42f967caf0 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
@@ -109,6 +109,20 @@ DEFINE_QUIC_COMMAND_LINE_FLAG(
"versions are offered in the handshake. Also supports wire versions "
"such as Q043 or T099.");
+DEFINE_QUIC_COMMAND_LINE_FLAG(
+ std::string,
+ connection_options,
+ "",
+ "Connection options as ASCII tags separated by commas, "
+ "e.g. \"ABCD,EFGH\"");
+
+DEFINE_QUIC_COMMAND_LINE_FLAG(
+ std::string,
+ client_connection_options,
+ "",
+ "Client connection options as ASCII tags separated by commas, "
+ "e.g. \"ABCD,EFGH\"");
+
DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
quic_ietf_draft,
false,
@@ -232,9 +246,22 @@ int QuicToyClient::SendRequestsAndPrintResponses(
proof_verifier = quic::CreateDefaultProofVerifier(url.host());
}
+ QuicConfig config;
+ std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
+ if (!connection_options_string.empty()) {
+ config.SetConnectionOptionsToSend(
+ ParseQuicTagVector(connection_options_string));
+ }
+ std::string client_connection_options_string =
+ GetQuicFlag(FLAGS_client_connection_options);
+ if (!client_connection_options_string.empty()) {
+ config.SetClientConnectionOptions(
+ ParseQuicTagVector(client_connection_options_string));
+ }
+
// Build the client, and try to connect.
std::unique_ptr<QuicSpdyClientBase> client = client_factory_->CreateClient(
- url.host(), host, port, versions, std::move(proof_verifier));
+ url.host(), host, port, versions, config, std::move(proof_verifier));
if (client == nullptr) {
std::cerr << "Failed to create client." << std::endl;
diff --git a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h
index 1a201225a58..d9d8ecaf87a 100644
--- a/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h
+++ b/chromium/net/third_party/quiche/src/quic/tools/quic_toy_client.h
@@ -26,6 +26,7 @@ class QuicToyClient {
std::string host_for_lookup,
uint16_t port,
ParsedQuicVersionVector versions,
+ const QuicConfig& config,
std::unique_ptr<ProofVerifier> verifier) = 0;
};
diff --git a/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler.h b/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler.h
index a2c69890459..7b318911007 100644
--- a/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler.h
+++ b/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler.h
@@ -29,6 +29,8 @@ class FifoWriteScheduler : public WriteScheduler<StreamIdType> {
const StreamPrecedenceType& precedence) override;
void UnregisterStream(StreamIdType stream_id) override;
bool StreamRegistered(StreamIdType stream_id) const override;
+ // Stream precedence is available but note that it is not used for scheduling
+ // in this scheduler.
StreamPrecedenceType GetStreamPrecedence(
StreamIdType stream_id) const override;
void UpdateStreamPrecedence(StreamIdType stream_id,
@@ -51,20 +53,26 @@ class FifoWriteScheduler : public WriteScheduler<StreamIdType> {
std::string DebugString() const override;
private:
+ struct StreamInfo {
+ SpdyPriority priority;
+ int64_t event_time; // read/write event time (us since Unix epoch).
+ };
+
std::set<StreamIdType> ready_streams_;
- // This map maps stream ID to read/write event time (us since Unix epoch).
- std::map<StreamIdType, int64_t> registered_streams_;
+ std::map<StreamIdType, StreamInfo> registered_streams_;
};
template <typename StreamIdType>
void FifoWriteScheduler<StreamIdType>::RegisterStream(
StreamIdType stream_id,
- const StreamPrecedenceType& /*precedence*/) {
+ const StreamPrecedenceType& precedence) {
if (StreamRegistered(stream_id)) {
SPDY_BUG << "Stream " << stream_id << " already registered";
return;
}
- registered_streams_.emplace_hint(registered_streams_.end(), stream_id, 0);
+ registered_streams_.emplace_hint(
+ registered_streams_.end(), stream_id,
+ StreamInfo{/*priority=*/precedence.spdy3_priority(), /*event_time=*/0});
}
template <typename StreamIdType>
@@ -88,14 +96,26 @@ bool FifoWriteScheduler<StreamIdType>::StreamRegistered(
template <typename StreamIdType>
typename FifoWriteScheduler<StreamIdType>::StreamPrecedenceType
FifoWriteScheduler<StreamIdType>::GetStreamPrecedence(
- StreamIdType /*stream_id*/) const {
- return StreamPrecedenceType(kV3LowestPriority);
+ StreamIdType stream_id) const {
+ auto it = registered_streams_.find(stream_id);
+ if (it == registered_streams_.end()) {
+ SPDY_DVLOG(1) << "Stream " << stream_id << " not registered";
+ return StreamPrecedenceType(kV3LowestPriority);
+ }
+ return StreamPrecedenceType(it->second.priority);
}
template <typename StreamIdType>
void FifoWriteScheduler<StreamIdType>::UpdateStreamPrecedence(
- StreamIdType /*stream_id*/,
- const StreamPrecedenceType& /*precedence*/) {}
+ StreamIdType stream_id,
+ const StreamPrecedenceType& precedence) {
+ auto it = registered_streams_.find(stream_id);
+ if (it == registered_streams_.end()) {
+ SPDY_DVLOG(1) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ it->second.priority = precedence.spdy3_priority();
+}
template <typename StreamIdType>
std::vector<StreamIdType> FifoWriteScheduler<StreamIdType>::GetStreamChildren(
@@ -109,7 +129,7 @@ void FifoWriteScheduler<StreamIdType>::RecordStreamEventTime(
int64_t now_in_usec) {
auto it = registered_streams_.find(stream_id);
if (it != registered_streams_.end()) {
- it->second = now_in_usec;
+ it->second.event_time = now_in_usec;
} else {
SPDY_BUG << "Stream " << stream_id << " is not registered";
}
@@ -128,7 +148,8 @@ int64_t FifoWriteScheduler<StreamIdType>::GetLatestEventWithPrecedence(
if (stream_id <= it->first) {
break;
}
- latest_event_time_us = std::max(latest_event_time_us, it->second);
+ latest_event_time_us =
+ std::max(latest_event_time_us, it->second.event_time);
}
return latest_event_time_us;
}
diff --git a/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler_test.cc b/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler_test.cc
index 950b6414d1d..d1dd066d6e9 100644
--- a/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler_test.cc
+++ b/chromium/net/third_party/quiche/src/spdy/core/fifo_write_scheduler_test.cc
@@ -80,6 +80,24 @@ TEST(FifoWriteSchedulerTest, GetLatestEventTest) {
EXPECT_EQ(0, fifo.GetLatestEventWithPrecedence(1));
}
+TEST(FifoWriteSchedulerTest, GetStreamPrecedence) {
+ FifoWriteScheduler<SpdyStreamId> fifo;
+ // Return lowest priority for unknown stream.
+ EXPECT_EQ(kV3LowestPriority, fifo.GetStreamPrecedence(1).spdy3_priority());
+
+ fifo.RegisterStream(1, SpdyStreamPrecedence(3));
+ EXPECT_TRUE(fifo.GetStreamPrecedence(1).is_spdy3_priority());
+ EXPECT_EQ(3, fifo.GetStreamPrecedence(1).spdy3_priority());
+
+ // Redundant registration shouldn't change stream priority.
+ EXPECT_SPDY_BUG(fifo.RegisterStream(1, SpdyStreamPrecedence(4)),
+ "Stream 1 already registered");
+ EXPECT_EQ(3, fifo.GetStreamPrecedence(1).spdy3_priority());
+
+ fifo.UpdateStreamPrecedence(1, SpdyStreamPrecedence(5));
+ EXPECT_EQ(5, fifo.GetStreamPrecedence(1).spdy3_priority());
+}
+
} // namespace test
} // namespace spdy
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 e3bf8f64c15..71b94a37f3f 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
@@ -176,16 +176,9 @@ void HpackEncoder::EmitNonIndexedLiteral(const Representation& representation,
SPDY_DVLOG(2) << "Emitting nonindexed literal: (" << representation.first
<< ", " << representation.second << ")";
output_stream_.AppendPrefix(kLiteralNoIndexOpcode);
- if (GetSpdyReloadableFlag(spdy_hpack_use_indexed_name)) {
- SPDY_CODE_COUNT(spdy_hpack_use_indexed_name);
- const HpackEntry* name_entry =
- header_table_.GetByName(representation.first);
- if (enable_compression && name_entry != nullptr) {
- output_stream_.AppendUint32(header_table_.IndexOf(name_entry));
- } else {
- output_stream_.AppendUint32(0);
- EmitString(representation.first);
- }
+ const HpackEntry* name_entry = header_table_.GetByName(representation.first);
+ if (enable_compression && name_entry != nullptr) {
+ output_stream_.AppendUint32(header_table_.IndexOf(name_entry));
} else {
output_stream_.AppendUint32(0);
EmitString(representation.first);
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 2b1efe973b8..f6f9f87a1c0 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
@@ -274,12 +274,8 @@ TEST_F(HpackEncoderTestBase, EncodeRepresentations) {
{"accept", "text/html, text/plain,application/xml"},
{"cookie", "val4"},
{"withnul", quiche::QuicheStringPiece("one\0two", 7)}};
- if (GetSpdyReloadableFlag(spdy_hpack_use_indexed_name)) {
- ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
- "/home");
- } else {
- ExpectNonIndexedLiteral(":path", "/home");
- }
+ ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
+ "/home");
ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val1");
ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val2");
ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "val3");
@@ -566,12 +562,8 @@ TEST_P(HpackEncoderTest, PseudoHeadersFirst) {
// Headers are indexed in the order in which they were added.
// This entry pushes "cookie: a=bb" back to 63.
- if (GetSpdyReloadableFlag(spdy_hpack_use_indexed_name)) {
- ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
- "/spam/eggs.html");
- } else {
- ExpectNonIndexedLiteral(":path", "/spam/eggs.html");
- }
+ ExpectNonIndexedLiteralWithNameIndex(peer_.table()->GetByName(":path"),
+ "/spam/eggs.html");
ExpectIndexedLiteral(peer_.table()->GetByName(":authority"),
"www.example.com");
ExpectIndexedLiteral("-foo", "bar");
diff --git a/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h b/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h
index 405ccf5387b..d2e7fcfb847 100644
--- a/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h
+++ b/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h
@@ -5,6 +5,7 @@
#ifndef QUICHE_SPDY_CORE_LIFO_WRITE_SCHEDULER_H_
#define QUICHE_SPDY_CORE_LIFO_WRITE_SCHEDULER_H_
+#include <cstdint>
#include <map>
#include <set>
#include <string>
@@ -40,15 +41,13 @@ class LifoWriteScheduler : public WriteScheduler<StreamIdType> {
return registered_streams_.find(stream_id) != registered_streams_.end();
}
- // Stream precedence is not supported by this scheduler.
+ // Stream precedence is available but note that it is not used for scheduling
+ // in this scheduler.
StreamPrecedenceType GetStreamPrecedence(
- StreamIdType /*stream_id*/) const override {
- return StreamPrecedenceType(kV3LowestPriority);
- }
+ StreamIdType stream_id) const override;
- void UpdateStreamPrecedence(
- StreamIdType /*stream_id*/,
- const StreamPrecedenceType& /*precedence*/) override {}
+ void UpdateStreamPrecedence(StreamIdType stream_id,
+ const StreamPrecedenceType& precedence) override;
std::vector<StreamIdType> GetStreamChildren(
StreamIdType /*stream_id*/) const override {
@@ -85,19 +84,26 @@ class LifoWriteScheduler : public WriteScheduler<StreamIdType> {
private:
friend class test::LifoWriteSchedulerPeer<StreamIdType>;
+ struct StreamInfo {
+ SpdyPriority priority;
+ int64_t event_time; // read/write event time (us since Unix epoch).
+ };
+
std::set<StreamIdType> ready_streams_;
- std::map<StreamIdType, int64_t> registered_streams_;
+ std::map<StreamIdType, StreamInfo> registered_streams_;
};
template <typename StreamIdType>
void LifoWriteScheduler<StreamIdType>::RegisterStream(
StreamIdType stream_id,
- const StreamPrecedenceType& /*precedence*/) {
+ const StreamPrecedenceType& precedence) {
if (StreamRegistered(stream_id)) {
SPDY_BUG << "Stream " << stream_id << " already registered";
return;
}
- registered_streams_.emplace_hint(registered_streams_.end(), stream_id, 0);
+ registered_streams_.emplace_hint(
+ registered_streams_.end(), stream_id,
+ StreamInfo{/*priority=*/precedence.spdy3_priority(), /*event_time=*/0});
}
template <typename StreamIdType>
@@ -112,12 +118,36 @@ void LifoWriteScheduler<StreamIdType>::UnregisterStream(
}
template <typename StreamIdType>
+typename LifoWriteScheduler<StreamIdType>::StreamPrecedenceType
+LifoWriteScheduler<StreamIdType>::GetStreamPrecedence(
+ StreamIdType stream_id) const {
+ auto it = registered_streams_.find(stream_id);
+ if (it == registered_streams_.end()) {
+ SPDY_DVLOG(1) << "Stream " << stream_id << " not registered";
+ return StreamPrecedenceType(kV3LowestPriority);
+ }
+ return StreamPrecedenceType(it->second.priority);
+}
+
+template <typename StreamIdType>
+void LifoWriteScheduler<StreamIdType>::UpdateStreamPrecedence(
+ StreamIdType stream_id,
+ const StreamPrecedenceType& precedence) {
+ auto it = registered_streams_.find(stream_id);
+ if (it == registered_streams_.end()) {
+ SPDY_DVLOG(1) << "Stream " << stream_id << " not registered";
+ return;
+ }
+ it->second.priority = precedence.spdy3_priority();
+}
+
+template <typename StreamIdType>
void LifoWriteScheduler<StreamIdType>::RecordStreamEventTime(
StreamIdType stream_id,
int64_t now_in_usec) {
auto it = registered_streams_.find(stream_id);
if (it != registered_streams_.end()) {
- it->second = now_in_usec;
+ it->second.event_time = now_in_usec;
} else {
SPDY_BUG << "Stream " << stream_id << " is not registered";
}
@@ -134,8 +164,8 @@ int64_t LifoWriteScheduler<StreamIdType>::GetLatestEventWithPrecedence(
for (auto it = registered_streams_.rbegin(); it != registered_streams_.rend();
++it) {
if (stream_id < it->first) {
- if (it->second > latest_event_time_us) {
- latest_event_time_us = it->second;
+ if (it->second.event_time > latest_event_time_us) {
+ latest_event_time_us = it->second.event_time;
}
} else {
break;
diff --git a/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc b/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc
index 1d7ecbf8e32..744ee136521 100644
--- a/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc
+++ b/chromium/net/third_party/quiche/src/spdy/core/lifo_write_scheduler_test.cc
@@ -151,6 +151,24 @@ TEST(LifoWriteSchedulerTest, GetLatestEventTest) {
"Stream 11 is not registered");
}
+TEST(LifoWriteSchedulerTest, GetStreamPrecedence) {
+ LifoWriteScheduler<SpdyStreamId> lifo;
+ // Return lowest priority for unknown stream.
+ EXPECT_EQ(kV3LowestPriority, lifo.GetStreamPrecedence(1).spdy3_priority());
+
+ lifo.RegisterStream(1, SpdyStreamPrecedence(3));
+ EXPECT_TRUE(lifo.GetStreamPrecedence(1).is_spdy3_priority());
+ EXPECT_EQ(3, lifo.GetStreamPrecedence(1).spdy3_priority());
+
+ // Redundant registration shouldn't change stream priority.
+ EXPECT_SPDY_BUG(lifo.RegisterStream(1, SpdyStreamPrecedence(4)),
+ "Stream 1 already registered");
+ EXPECT_EQ(3, lifo.GetStreamPrecedence(1).spdy3_priority());
+
+ lifo.UpdateStreamPrecedence(1, SpdyStreamPrecedence(5));
+ EXPECT_EQ(5, lifo.GetStreamPrecedence(1).spdy3_priority());
+}
+
} // namespace test
} // namespace spdy
diff --git a/chromium/net/tools/cert_verify_tool/cert_verify_tool_util.cc b/chromium/net/tools/cert_verify_tool/cert_verify_tool_util.cc
index 95aa01c6e5a..f2b09c1551f 100644
--- a/chromium/net/tools/cert_verify_tool/cert_verify_tool_util.cc
+++ b/chromium/net/tools/cert_verify_tool/cert_verify_tool_util.cc
@@ -7,6 +7,7 @@
#include <iostream>
#include "base/files/file_util.h"
+#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "net/cert/pem.h"
diff --git a/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc b/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
index cd3f9a39d29..7abb217e250 100644
--- a/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
+++ b/chromium/net/tools/dns_fuzz_stub/dns_fuzz_stub.cc
@@ -14,6 +14,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
+#include "base/logging.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/address_list.h"
diff --git a/chromium/net/tools/epoll_server/platform/impl/epoll_logging_impl.h b/chromium/net/tools/epoll_server/platform/impl/epoll_logging_impl.h
index 9f9b8ab05b6..9487e1d2cbd 100644
--- a/chromium/net/tools/epoll_server/platform/impl/epoll_logging_impl.h
+++ b/chromium/net/tools/epoll_server/platform/impl/epoll_logging_impl.h
@@ -5,7 +5,9 @@
#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_LOGGING_IMPL_H_
#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_LOGGING_IMPL_H_
+#include "base/check_op.h"
#include "base/logging.h"
+#include "base/notreached.h"
#define EPOLL_CHROMIUM_LOG_INFO VLOG(1)
#define EPOLL_CHROMIUM_LOG_WARNING DLOG(WARNING)
diff --git a/chromium/net/tools/quic/quic_http_proxy_backend.h b/chromium/net/tools/quic/quic_http_proxy_backend.h
index 0852d70a557..32d9d6bb4bf 100644
--- a/chromium/net/tools/quic/quic_http_proxy_backend.h
+++ b/chromium/net/tools/quic/quic_http_proxy_backend.h
@@ -26,7 +26,6 @@
#include "base/base64.h"
#include "base/callback.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
diff --git a/chromium/net/tools/quic/quic_http_proxy_backend_stream.h b/chromium/net/tools/quic/quic_http_proxy_backend_stream.h
index 6d87391eb8a..80f8e2bc9a5 100644
--- a/chromium/net/tools/quic/quic_http_proxy_backend_stream.h
+++ b/chromium/net/tools/quic/quic_http_proxy_backend_stream.h
@@ -24,7 +24,6 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "net/base/request_priority.h"
#include "net/base/upload_data_stream.h"
diff --git a/chromium/net/tools/quic/quic_simple_client.cc b/chromium/net/tools/quic/quic_simple_client.cc
index 5d8bf33b2a1..25fcab0a909 100644
--- a/chromium/net/tools/quic/quic_simple_client.cc
+++ b/chromium/net/tools/quic/quic_simple_client.cc
@@ -37,11 +37,12 @@ QuicSimpleClient::QuicSimpleClient(
quic::QuicSocketAddress server_address,
const quic::QuicServerId& server_id,
const quic::ParsedQuicVersionVector& supported_versions,
+ const quic::QuicConfig& config,
std::unique_ptr<quic::ProofVerifier> proof_verifier)
: quic::QuicSpdyClientBase(
server_id,
supported_versions,
- quic::QuicConfig(),
+ config,
CreateQuicConnectionHelper(),
CreateQuicAlarmFactory(),
quic::QuicWrapUnique(
diff --git a/chromium/net/tools/quic/quic_simple_client.h b/chromium/net/tools/quic/quic_simple_client.h
index c791adefd75..3ac2841a68d 100644
--- a/chromium/net/tools/quic/quic_simple_client.h
+++ b/chromium/net/tools/quic/quic_simple_client.h
@@ -41,6 +41,7 @@ class QuicSimpleClient : public quic::QuicSpdyClientBase {
QuicSimpleClient(quic::QuicSocketAddress server_address,
const quic::QuicServerId& server_id,
const quic::ParsedQuicVersionVector& supported_versions,
+ const quic::QuicConfig& config,
std::unique_ptr<quic::ProofVerifier> proof_verifier);
~QuicSimpleClient() override;
diff --git a/chromium/net/tools/quic/quic_simple_client_bin.cc b/chromium/net/tools/quic/quic_simple_client_bin.cc
index dae728bc0a0..1de449b8af6 100644
--- a/chromium/net/tools/quic/quic_simple_client_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_client_bin.cc
@@ -61,6 +61,7 @@ class QuicSimpleClientFactory : public quic::QuicToyClient::ClientFactory {
std::string host_for_lookup,
uint16_t port,
quic::ParsedQuicVersionVector versions,
+ const quic::QuicConfig& config,
std::unique_ptr<quic::ProofVerifier> verifier) override {
net::AddressList addresses;
int rv = net::SynchronousHostResolver::Resolve(host_for_lookup, &addresses);
@@ -85,7 +86,7 @@ class QuicSimpleClientFactory : public quic::QuicToyClient::ClientFactory {
quic::QuicServerId server_id(host_for_handshake, port, false);
return std::make_unique<net::QuicSimpleClient>(
- quic::QuicSocketAddress(ip_addr, port), server_id, versions,
+ quic::QuicSocketAddress(ip_addr, port), server_id, versions, config,
std::move(verifier));
}
};
diff --git a/chromium/net/tools/quic/quic_simple_client_test.cc b/chromium/net/tools/quic/quic_simple_client_test.cc
index a36102e5ad9..b522460bcd3 100644
--- a/chromium/net/tools/quic/quic_simple_client_test.cc
+++ b/chromium/net/tools/quic/quic_simple_client_test.cc
@@ -19,7 +19,7 @@ TEST(QuicSimpleClientTest, Initialize) {
quic::QuicServerId server_id("hostname", server_address.port(), false);
quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
QuicSimpleClient client(
- server_address, server_id, versions,
+ server_address, server_id, versions, quic::QuicConfig(),
quic::test::crypto_test_utils::ProofVerifierForTesting());
EXPECT_TRUE(client.Initialize());
}
diff --git a/chromium/net/tools/quic/quic_simple_server.cc b/chromium/net/tools/quic/quic_simple_server.cc
index 9c397b57c98..01c3e63a084 100644
--- a/chromium/net/tools/quic/quic_simple_server.cc
+++ b/chromium/net/tools/quic/quic_simple_server.cc
@@ -125,6 +125,7 @@ bool QuicSimpleServer::Listen(const IPEndPoint& address) {
}
void QuicSimpleServer::Shutdown() {
+ LOG(WARNING) << "QuicSimpleServer is shutting down";
// Before we shut down the epoll server, give all active sessions a chance to
// notify clients that they're closing.
dispatcher_->Shutdown();
@@ -177,20 +178,24 @@ void QuicSimpleServer::StartReading() {
void QuicSimpleServer::OnReadComplete(int result) {
read_pending_ = false;
- if (result == 0)
- result = ERR_CONNECTION_CLOSED;
- if (result < 0) {
+ if (result > 0) {
+ quic::QuicReceivedPacket packet(read_buffer_->data(), result,
+ helper_->GetClock()->Now(), false);
+ dispatcher_->ProcessPacket(ToQuicSocketAddress(server_address_),
+ ToQuicSocketAddress(client_address_), packet);
+ } else {
LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result);
- Shutdown();
- return;
+ // Do not act on ERR_MSG_TOO_BIG as that indicates that we received a UDP
+ // packet whose payload is larger than our receive buffer. Do not act on 0
+ // as that indicates that we received a UDP packet with an empty payload.
+ // In both cases, the socket should still be usable.
+ if (result != ERR_MSG_TOO_BIG && result != 0) {
+ Shutdown();
+ return;
+ }
}
- quic::QuicReceivedPacket packet(read_buffer_->data(), result,
- helper_->GetClock()->Now(), false);
- dispatcher_->ProcessPacket(ToQuicSocketAddress(server_address_),
- ToQuicSocketAddress(client_address_), packet);
-
StartReading();
}
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
index b4599eba584..5978b7922a8 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
@@ -88,10 +88,10 @@ bool QuicSimpleServerPacketWriter::IsBatchMode() const {
return false;
}
-char* QuicSimpleServerPacketWriter::GetNextWriteLocation(
+quic::QuicPacketBuffer QuicSimpleServerPacketWriter::GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) {
- return nullptr;
+ return {nullptr, nullptr};
}
quic::WriteResult QuicSimpleServerPacketWriter::Flush() {
diff --git a/chromium/net/tools/quic/quic_simple_server_packet_writer.h b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
index 76f8b8e82f9..c8ba2227ba5 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.h
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.h
@@ -50,7 +50,7 @@ class QuicSimpleServerPacketWriter : public quic::QuicPacketWriter {
const quic::QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
- char* GetNextWriteLocation(
+ quic::QuicPacketBuffer GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) override;
quic::WriteResult Flush() override;
diff --git a/chromium/net/tools/testserver/testserver_base.py b/chromium/net/tools/testserver/testserver_base.py
index 7be34a3fac3..25cb7af9e8a 100644
--- a/chromium/net/tools/testserver/testserver_base.py
+++ b/chromium/net/tools/testserver/testserver_base.py
@@ -2,14 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import BaseHTTPServer
+from six.moves import BaseHTTPServer
import errno
import json
import optparse
import os
import re
import socket
-import SocketServer
+from six.moves import socketserver as SocketServer
import struct
import sys
import warnings
@@ -74,7 +74,7 @@ class BrokenPipeHandlerMixIn:
def handle_error(self, request, client_address):
value = sys.exc_info()[1]
if isinstance(value, tlslite.errors.TLSClosedConnectionError):
- print "testserver.py: Closed connection"
+ print("testserver.py: Closed connection")
return
if isinstance(value, socket.error):
err = value.args[0]
@@ -84,10 +84,10 @@ class BrokenPipeHandlerMixIn:
else:
pipe_err = errno.EPIPE
if err == pipe_err:
- print "testserver.py: Broken pipe"
+ print("testserver.py: Broken pipe")
return
if err == errno.ECONNRESET:
- print "testserver.py: Connection reset by peer"
+ print("testserver.py: Connection reset by peer")
return
SocketServer.BaseServer.handle_error(self, request, client_address)
@@ -219,7 +219,7 @@ class TestServerRunner(object):
try:
self.server.serve_forever()
except KeyboardInterrupt:
- print 'shutting down server'
+ print('shutting down server')
self.server.stop = True
def add_options(self):
@@ -256,15 +256,15 @@ class TestServerRunner(object):
# Notify the parent that we've started. (BaseServer subclasses
# bind their sockets on construction.)
if self.options.startup_pipe is not None:
- server_data_json = json.dumps(server_data)
+ server_data_json = json.dumps(server_data).encode()
server_data_len = len(server_data_json)
- print 'sending server_data: %s (%d bytes)' % (
- server_data_json, server_data_len)
+ print('sending server_data: %s (%d bytes)' %
+ (server_data_json, server_data_len))
if sys.platform == 'win32':
fd = msvcrt.open_osfhandle(self.options.startup_pipe, 0)
else:
fd = self.options.startup_pipe
- startup_pipe = os.fdopen(fd, "w")
+ startup_pipe = os.fdopen(fd, "wb")
# First write the data length as an unsigned 4-byte value. This
# is _not_ using network byte ordering since the other end of the
# pipe is on the same machine.
diff --git a/chromium/net/traffic_annotation/network_traffic_annotation.h b/chromium/net/traffic_annotation/network_traffic_annotation.h
index 6319a81fd10..e91a4c6f29b 100644
--- a/chromium/net/traffic_annotation/network_traffic_annotation.h
+++ b/chromium/net/traffic_annotation/network_traffic_annotation.h
@@ -5,7 +5,10 @@
#ifndef NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
#define NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
-#include "base/logging.h"
+#include <cstdint>
+
+#include "base/check.h"
+#include "base/notreached.h"
#include "build/build_config.h"
namespace {
diff --git a/chromium/net/url_request/url_fetcher_response_writer.cc b/chromium/net/url_request/url_fetcher_response_writer.cc
index adfbcb1c370..7a96f12458a 100644
--- a/chromium/net/url_request/url_fetcher_response_writer.cc
+++ b/chromium/net/url_request/url_fetcher_response_writer.cc
@@ -166,8 +166,7 @@ void URLFetcherFileWriter::CloseAndDeleteFile() {
file_stream_.reset();
DisownFile();
file_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(base::IgnoreResult(&base::DeleteFile),
- file_path_, false /* recursive */));
+ FROM_HERE, base::BindOnce(base::GetDeleteFileCallback(), file_path_));
}
void URLFetcherFileWriter::DidCreateTempFile(base::FilePath* temp_file_path,
diff --git a/chromium/net/url_request/url_request.cc b/chromium/net/url_request/url_request.cc
index 40927b586fa..cbed158f16b 100644
--- a/chromium/net/url_request/url_request.cc
+++ b/chromium/net/url_request/url_request.cc
@@ -395,7 +395,7 @@ int URLRequest::GetResponseCode() const {
return job_->GetResponseCode();
}
-void URLRequest::set_maybe_sent_cookies(CookieStatusList cookies) {
+void URLRequest::set_maybe_sent_cookies(CookieAccessResultList cookies) {
maybe_sent_cookies_ = std::move(cookies);
}
@@ -983,13 +983,12 @@ void URLRequest::NotifySSLCertificateError(int net_error,
delegate_->OnSSLCertificateError(this, net_error, ssl_info, fatal);
}
-bool URLRequest::CanGetCookies(const CookieList& cookie_list) const {
+bool URLRequest::CanGetCookies() const {
DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES));
bool can_get_cookies = g_default_can_use_cookies;
if (network_delegate_) {
can_get_cookies =
- network_delegate_->CanGetCookies(*this, cookie_list,
- /*allowed_from_caller=*/true);
+ network_delegate_->CanGetCookies(*this, /*allowed_from_caller=*/true);
}
if (!can_get_cookies)
@@ -1015,7 +1014,10 @@ net::PrivacyMode URLRequest::DeterminePrivacyMode() const {
// Enable privacy mode if flags tell us not send or save cookies.
if ((load_flags_ & LOAD_DO_NOT_SEND_COOKIES) ||
(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES)) {
- return PRIVACY_MODE_ENABLED;
+ // TODO(https://crbug.com/775438): Client certs should always be
+ // affirmatively omitted for these requests.
+ return send_client_certs_ ? PRIVACY_MODE_ENABLED
+ : PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS;
}
// Otherwise, check with the delegate if present, or base it off of
diff --git a/chromium/net/url_request/url_request.h b/chromium/net/url_request/url_request.h
index e967a680d6e..643ab4ae8f0 100644
--- a/chromium/net/url_request/url_request.h
+++ b/chromium/net/url_request/url_request.h
@@ -11,8 +11,6 @@
#include <string>
#include <vector>
-#include "base/debug/leak_tracker.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
@@ -542,7 +540,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// Returns whether secure DNS should be disabled for the request.
bool disable_secure_dns() { return disable_secure_dns_; }
- void set_maybe_sent_cookies(CookieStatusList cookies);
+ void set_maybe_sent_cookies(CookieAccessResultList cookies);
void set_maybe_stored_cookies(CookieAndLineStatusList cookies);
// These lists contain a list of cookies that are associated with the given
@@ -556,7 +554,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// and only contain the cookies relevant to the most recent roundtrip.
// Populated while the http request is being built.
- const CookieStatusList& maybe_sent_cookies() const {
+ const CookieAccessResultList& maybe_sent_cookies() const {
return maybe_sent_cookies_;
}
// Populated after the response headers are received.
@@ -724,6 +722,20 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
}
bool upgrade_if_insecure() const { return upgrade_if_insecure_; }
+ // By default, client certs will be sent (provided via
+ // Delegate::OnCertificateRequested) when cookies are disabled
+ // (LOAD_DO_NOT_SEND_COOKIES / LOAD_DO_NOT_SAVE_COOKIES). As described at
+ // https://crbug.com/775438, this is not the desired behavior. When
+ // |send_client_certs| is set to false, this will suppress the
+ // Delegate::OnCertificateRequested callback when cookies/credentials are also
+ // suppressed. This method has no effect if credentials are enabled (cookies
+ // saved and sent).
+ // TODO(https://crbug.com/775438): Remove this when the underlying
+ // issue is fixed.
+ void set_send_client_certs(bool send_client_certs) {
+ send_client_certs_ = send_client_certs;
+ }
+
base::WeakPtr<URLRequest> GetWeakPtr();
protected:
@@ -815,7 +827,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// These functions delegate to |network_delegate_| if it is not NULL.
// If |network_delegate_| is NULL, cookies can be used unless
// SetDefaultCookiePolicyToBlock() has been called.
- bool CanGetCookies(const CookieList& cookie_list) const;
+ bool CanGetCookies() const;
bool CanSetCookie(const net::CanonicalCookie& cookie,
CookieOptions* options) const;
PrivacyMode DeterminePrivacyMode() const;
@@ -865,7 +877,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
PrivacyMode privacy_mode_;
bool disable_secure_dns_;
- CookieStatusList maybe_sent_cookies_;
+ CookieAccessResultList maybe_sent_cookies_;
CookieAndLineStatusList maybe_stored_cookies_;
#if BUILDFLAG(ENABLE_REPORTING)
@@ -928,8 +940,6 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
std::string blocked_by_;
bool use_blocked_by_as_load_param_;
- base::debug::LeakTracker<URLRequest> leak_tracker_;
-
// Safe-guard to ensure that we do not send multiple "I am completed"
// messages to network delegate.
// TODO(battre): Remove this. http://crbug.com/89049
@@ -959,6 +969,8 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
bool upgrade_if_insecure_;
+ bool send_client_certs_ = true;
+
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<URLRequest> weak_factory_{this};
diff --git a/chromium/net/url_request/url_request_context_builder.cc b/chromium/net/url_request/url_request_context_builder.cc
index 943423b3f81..4a71bd3364e 100644
--- a/chromium/net/url_request/url_request_context_builder.cc
+++ b/chromium/net/url_request/url_request_context_builder.cc
@@ -107,7 +107,6 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
}
bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) override {
return allowed_from_caller;
}
diff --git a/chromium/net/url_request/url_request_context_builder_unittest.cc b/chromium/net/url_request/url_request_context_builder_unittest.cc
index bb98fa97c86..3b1922c2fab 100644
--- a/chromium/net/url_request/url_request_context_builder_unittest.cc
+++ b/chromium/net/url_request/url_request_context_builder_unittest.cc
@@ -58,6 +58,7 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
HttpAuth::Target target,
const SSLInfo& ssl_info,
+ const NetworkIsolationKey& network_isolation_key,
const GURL& origin,
CreateReason reason,
int nonce_count,
@@ -131,10 +132,11 @@ TEST_F(URLRequestContextBuilderTest, DefaultHttpAuthHandlerFactory) {
SSLInfo null_ssl_info;
// Verify that the default basic handler is present
- EXPECT_EQ(OK,
- context->http_auth_handler_factory()->CreateAuthHandlerFromString(
- "basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resolver_.get(), &handler));
+ EXPECT_EQ(
+ OK,
+ context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resolver_.get(), &handler));
}
TEST_F(URLRequestContextBuilderTest, CustomHttpAuthHandlerFactory) {
@@ -149,20 +151,23 @@ TEST_F(URLRequestContextBuilderTest, CustomHttpAuthHandlerFactory) {
// Verify that a handler is returned for a custom scheme.
EXPECT_EQ(kBasicReturnCode,
context->http_auth_handler_factory()->CreateAuthHandlerFromString(
- "ExtraScheme", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resolver_.get(), &handler));
+ "ExtraScheme", HttpAuth::AUTH_SERVER, null_ssl_info,
+ NetworkIsolationKey(), gurl, NetLogWithSource(),
+ host_resolver_.get(), &handler));
// Verify that the default basic handler isn't present
- EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
- context->http_auth_handler_factory()->CreateAuthHandlerFromString(
- "basic", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resolver_.get(), &handler));
+ EXPECT_EQ(
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resolver_.get(), &handler));
// Verify that a handler isn't returned for a bogus scheme.
- EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
- context->http_auth_handler_factory()->CreateAuthHandlerFromString(
- "Bogus", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
- NetLogWithSource(), host_resolver_.get(), &handler));
+ EXPECT_EQ(
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+ "Bogus", HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(),
+ gurl, NetLogWithSource(), host_resolver_.get(), &handler));
}
#if BUILDFLAG(ENABLE_REPORTING)
@@ -226,7 +231,8 @@ TEST_F(URLRequestContextBuilderTest, ShutdownHostResolverWithPendingRequest) {
std::unique_ptr<HostResolver::ResolveHostRequest> request =
context->host_resolver()->CreateRequest(
- HostPortPair("example.com", 1234), NetLogWithSource(), base::nullopt);
+ HostPortPair("example.com", 1234), NetworkIsolationKey(),
+ NetLogWithSource(), base::nullopt);
TestCompletionCallback callback;
int rv = request->Start(callback.callback());
ASSERT_TRUE(mock_host_resolver->has_pending_requests());
diff --git a/chromium/net/url_request/url_request_http_job.cc b/chromium/net/url_request/url_request_http_job.cc
index 0e88cd83a0c..5590bd226c9 100644
--- a/chromium/net/url_request/url_request_http_job.cc
+++ b/chromium/net/url_request/url_request_http_job.cc
@@ -88,7 +88,7 @@ base::Value CookieInclusionStatusNetLogParams(
const std::string& cookie_name,
const std::string& cookie_domain,
const std::string& cookie_path,
- const net::CanonicalCookie::CookieInclusionStatus& status,
+ const net::CookieInclusionStatus& status,
net::NetLogCaptureMode capture_mode) {
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetStringKey("operation", operation);
@@ -160,6 +160,58 @@ void RecordCTHistograms(const net::SSLInfo& ssl_info) {
}
}
+template <typename CookieWithMetadata>
+bool ShouldMarkSameSiteCompatPairs(
+ const std::vector<CookieWithMetadata>& cookie_list,
+ const net::CookieOptions& options) {
+ // If the context is same-site then there cannot be any SameSite-by-default
+ // warnings, so the compat pair warning is irrelevant.
+ if (options.same_site_cookie_context().GetContextForCookieInclusion() >
+ net::CookieOptions::SameSiteCookieContext::ContextType::
+ SAME_SITE_LAX_METHOD_UNSAFE) {
+ return false;
+ }
+ return cookie_list.size() >= 2;
+}
+
+void MarkSameSiteCompatPairs(
+ std::vector<net::CookieWithAccessResult>& cookie_list,
+ const net::CookieOptions& options) {
+ for (size_t i = 0; i < cookie_list.size() - 1; ++i) {
+ const net::CanonicalCookie& c1 = cookie_list[i].cookie;
+ for (size_t j = i + 1; j < cookie_list.size(); ++j) {
+ const net::CanonicalCookie& c2 = cookie_list[j].cookie;
+ if (net::cookie_util::IsSameSiteCompatPair(c1, c2, options)) {
+ cookie_list[i].access_result.status.AddWarningReason(
+ net::CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ cookie_list[j].access_result.status.AddWarningReason(
+ net::CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ }
+ }
+ }
+}
+
+void MarkSameSiteCompatPairs(
+ std::vector<net::CookieAndLineWithStatus>& cookie_list,
+ const net::CookieOptions& options) {
+ for (size_t i = 0; i < cookie_list.size() - 1; ++i) {
+ if (!cookie_list[i].cookie.has_value())
+ continue;
+ const net::CanonicalCookie& c1 = cookie_list[i].cookie.value();
+ for (size_t j = i + 1; j < cookie_list.size(); ++j) {
+ if (!cookie_list[j].cookie.has_value())
+ continue;
+ const net::CanonicalCookie& c2 = cookie_list[j].cookie.value();
+ if (net::cookie_util::IsSameSiteCompatPair(c1, c2, options)) {
+ cookie_list[i].status.AddWarningReason(
+ net::CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ cookie_list[j].status.AddWarningReason(
+ net::CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ }
+ }
+ }
+}
+
} // namespace
namespace net {
@@ -279,18 +331,10 @@ void URLRequestHttpJob::Start() {
// plugin could set a referrer although sending the referrer is inhibited.
request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer);
- // Our consumer should have made sure that this is a safe referrer. See for
- // instance WebCore::FrameLoader::HideReferrer.
+ // Our consumer should have made sure that this is a safe referrer (e.g. via
+ // URLRequestJob::ComputeReferrerForPolicy).
if (referrer.is_valid()) {
std::string referer_value = referrer.spec();
- // We limit the `referer` header to 4k: see step 6 of
- // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
- // and https://github.com/whatwg/fetch/issues/903.
- if (referer_value.length() > 4096) {
- // Strip the referrer down to its origin, but ensure that it's serialized
- // as a URL (e.g. retaining a trailing `/` character).
- referer_value = url::Origin::Create(referrer).GetURL().spec();
- }
request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
referer_value);
}
@@ -552,21 +596,14 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
void URLRequestHttpJob::SetCookieHeaderAndStart(
const CookieOptions& options,
- const CookieStatusList& cookies_with_status_list,
- const CookieStatusList& excluded_list) {
+ const CookieAccessResultList& cookies_with_access_result_list,
+ const CookieAccessResultList& excluded_list) {
DCHECK(request_->maybe_sent_cookies().empty());
- // TODO(chlily): This is just for passing to CanGetCookies(), however the
- // CookieList parameter of CanGetCookies(), which eventually gets passed to
- // the NetworkDelegate, never actually gets used anywhere except in tests. The
- // parameter should be removed.
- CookieList cookie_list =
- net::cookie_util::StripStatuses(cookies_with_status_list);
-
- bool can_get_cookies = CanGetCookies(cookie_list);
- if (!cookies_with_status_list.empty() && can_get_cookies) {
+ bool can_get_cookies = CanGetCookies();
+ if (!cookies_with_access_result_list.empty() && can_get_cookies) {
std::string cookie_line =
- CanonicalCookie::BuildCookieLine(cookies_with_status_list);
+ CanonicalCookie::BuildCookieLine(cookies_with_access_result_list);
UMA_HISTOGRAM_COUNTS_10000("Cookie.HeaderLength", cookie_line.length());
request_info_.extra_headers.SetHeader(HttpRequestHeaders::kCookie,
cookie_line);
@@ -576,7 +613,7 @@ void URLRequestHttpJob::SetCookieHeaderAndStart(
// TODO(crbug.com/1031664): Reduce the number of times the cookie list is
// iterated over. Get metrics for every cookie which is included.
- for (const auto& c : cookies_with_status_list) {
+ for (const auto& c : cookies_with_access_result_list) {
bool request_is_secure = request_->url().SchemeIsCryptographic();
net::CookieSourceScheme cookie_scheme = c.cookie.SourceScheme();
CookieRequestScheme cookie_request_schemes;
@@ -606,43 +643,49 @@ void URLRequestHttpJob::SetCookieHeaderAndStart(
}
}
- // Report status for things in |excluded_list| and |cookies_with_status_list|
+ // Report status for things in |excluded_list| and
+ // |cookies_with_access_result_list|
// after the delegate got a chance to block them.
- CookieStatusList maybe_sent_cookies = excluded_list;
- // CanGetCookies only looks at the fields of the URLRequest, not the cookies
- // it is passed, so if CanGetCookies(cookie_list) is false, then
- // CanGetCookies(excluded_list) would also be false, so tag also the
- // excluded cookies as having been blocked by user preferences.
+ CookieAccessResultList maybe_sent_cookies = excluded_list;
+
if (!can_get_cookies) {
- for (CookieStatusList::iterator it = maybe_sent_cookies.begin();
+ for (CookieAccessResultList::iterator it = maybe_sent_cookies.begin();
it != maybe_sent_cookies.end(); ++it) {
- it->status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
+ it->access_result.status.AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
}
}
- for (const auto& cookie_with_status : cookies_with_status_list) {
- CanonicalCookie::CookieInclusionStatus status = cookie_with_status.status;
+
+ for (const auto& cookie_with_access_result :
+ cookies_with_access_result_list) {
+ CookieAccessResult access_result = cookie_with_access_result.access_result;
if (!can_get_cookies) {
- status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
+ access_result.status.AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
}
- maybe_sent_cookies.push_back({cookie_with_status.cookie, status});
+ maybe_sent_cookies.push_back(
+ {cookie_with_access_result.cookie, access_result});
}
if (request_->net_log().IsCapturing()) {
- for (const auto& cookie_and_status : maybe_sent_cookies) {
+ for (const auto& cookie_with_access_result : maybe_sent_cookies) {
request_->net_log().AddEvent(
NetLogEventType::COOKIE_INCLUSION_STATUS,
[&](NetLogCaptureMode capture_mode) {
return CookieInclusionStatusNetLogParams(
- "send", cookie_and_status.cookie.Name(),
- cookie_and_status.cookie.Domain(),
- cookie_and_status.cookie.Path(), cookie_and_status.status,
- capture_mode);
+ "send", cookie_with_access_result.cookie.Name(),
+ cookie_with_access_result.cookie.Domain(),
+ cookie_with_access_result.cookie.Path(),
+ cookie_with_access_result.access_result.status, capture_mode);
});
}
}
+ // Mark the CookieInclusionStatuses of items in |maybe_sent_cookies| if they
+ // are part of a presumed SameSite compatibility pair.
+ if (ShouldMarkSameSiteCompatPairs(maybe_sent_cookies, options))
+ MarkSameSiteCompatPairs(maybe_sent_cookies, options);
+
request_->set_maybe_sent_cookies(std::move(maybe_sent_cookies));
StartTransaction();
@@ -707,7 +750,7 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) {
// it reaches 0 in the callback itself.
num_cookie_lines_left_ = 1;
while (headers->EnumerateHeader(&iter, name, &cookie_string)) {
- CanonicalCookie::CookieInclusionStatus returned_status;
+ CookieInclusionStatus returned_status;
num_cookie_lines_left_++;
@@ -723,7 +766,7 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) {
}
if (cookie && !CanSetCookie(*cookie, &options)) {
returned_status.AddExclusionReason(
- CanonicalCookie::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
+ CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
}
if (!returned_status.IsInclude()) {
OnSetCookieResult(options, cookie_to_return, std::move(cookie_string),
@@ -741,15 +784,21 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) {
// loop has been exited.
num_cookie_lines_left_--;
- if (num_cookie_lines_left_ == 0)
+ if (num_cookie_lines_left_ == 0) {
+ // Mark the CookieInclusionStatuses of items in |set_cookie_status_list_| if
+ // they are part of a presumed SameSite compatibility pair.
+ if (ShouldMarkSameSiteCompatPairs(set_cookie_status_list_, options))
+ MarkSameSiteCompatPairs(set_cookie_status_list_, options);
+
NotifyHeadersComplete();
+ }
}
void URLRequestHttpJob::OnSetCookieResult(
const CookieOptions& options,
base::Optional<CanonicalCookie> cookie,
std::string cookie_string,
- CanonicalCookie::CookieInclusionStatus status) {
+ CookieInclusionStatus status) {
if (request_->net_log().IsCapturing()) {
request_->net_log().AddEvent(
NetLogEventType::COOKIE_INCLUSION_STATUS,
@@ -768,8 +817,14 @@ void URLRequestHttpJob::OnSetCookieResult(
// If all the cookie lines have been handled, |set_cookie_status_list_| now
// reflects the result of all Set-Cookie lines, and the request can be
// continued.
- if (num_cookie_lines_left_ == 0)
+ if (num_cookie_lines_left_ == 0) {
+ // Mark the CookieInclusionStatuses of items in |set_cookie_status_list_| if
+ // they are part of a presumed SameSite compatibility pair.
+ if (ShouldMarkSameSiteCompatPairs(set_cookie_status_list_, options))
+ MarkSameSiteCompatPairs(set_cookie_status_list_, options);
+
NotifyHeadersComplete();
+ }
}
void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() {
@@ -817,7 +872,8 @@ void URLRequestHttpJob::ProcessExpectCTHeader() {
std::string value;
if (headers->GetNormalizedHeader("Expect-CT", &value)) {
security_state->ProcessExpectCTHeader(
- value, HostPortPair::FromURL(request_info_.url), ssl_info);
+ value, HostPortPair::FromURL(request_info_.url), ssl_info,
+ request_->isolation_info().network_isolation_key());
}
}
diff --git a/chromium/net/url_request/url_request_http_job.h b/chromium/net/url_request/url_request_http_job.h
index f214aef293c..cc6eecb5b3e 100644
--- a/chromium/net/url_request/url_request_http_job.h
+++ b/chromium/net/url_request/url_request_http_job.h
@@ -22,6 +22,7 @@
#include "net/base/ip_endpoint.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/http/http_request_info.h"
#include "net/socket/connection_attempts.h"
#include "net/url_request/url_request_job.h"
@@ -167,14 +168,14 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
// Callback functions for Cookie Monster
void SetCookieHeaderAndStart(const CookieOptions& options,
- const CookieStatusList& cookie_list,
- const CookieStatusList& excluded_list);
+ const CookieAccessResultList& cookie_list,
+ const CookieAccessResultList& excluded_list);
// Another Cookie Monster callback
void OnSetCookieResult(const CookieOptions& options,
base::Optional<CanonicalCookie> cookie,
std::string cookie_string,
- CanonicalCookie::CookieInclusionStatus status);
+ CookieInclusionStatus status);
int num_cookie_lines_left_;
CookieAndLineStatusList set_cookie_status_list_;
diff --git a/chromium/net/url_request/url_request_http_job_unittest.cc b/chromium/net/url_request/url_request_http_job_unittest.cc
index f70cf685f69..65fc278295b 100644
--- a/chromium/net/url_request/url_request_http_job_unittest.cc
+++ b/chromium/net/url_request/url_request_http_job_unittest.cc
@@ -22,6 +22,7 @@
#include "base/test/metrics/histogram_tester.h"
#include "net/base/auth.h"
#include "net/base/isolation_info.h"
+#include "net/base/network_isolation_key.h"
#include "net/base/request_priority.h"
#include "net/cert/ct_policy_status.h"
#include "net/cookies/cookie_monster.h"
@@ -1012,6 +1013,84 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest,
kGTSRootR3HistogramID, 1);
}
+namespace {
+
+// An ExpectCTReporter that records the number of times OnExpectCTFailed() was
+// called.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+ MockExpectCTReporter() = default;
+ ~MockExpectCTReporter() override = default;
+
+ void OnExpectCTFailed(
+ const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ base::Time expiration,
+ const X509Certificate* validated_certificate_chain,
+ const X509Certificate* served_certificate_chain,
+ const SignedCertificateTimestampAndStatusList&
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) override {
+ num_failures_++;
+ network_isolation_key_ = network_isolation_key;
+ }
+
+ int num_failures() const { return num_failures_; }
+ const NetworkIsolationKey& network_isolation_key() const {
+ return network_isolation_key_;
+ }
+
+ private:
+ int num_failures_ = 0;
+ NetworkIsolationKey network_isolation_key_;
+};
+
+} // namespace
+
+TEST_F(URLRequestHttpJobWithMockSocketsTest,
+ TestHttpJobSendsNetworkIsolationKeyWhenProcessingExpectCTHeader) {
+ SSLSocketDataProvider ssl_socket_data(net::ASYNC, net::OK);
+ ssl_socket_data.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
+ ssl_socket_data.ssl_info.is_issued_by_known_root = true;
+ ssl_socket_data.ssl_info.ct_policy_compliance_required = false;
+ ssl_socket_data.ssl_info.ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
+
+ socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+ MockWrite writes[] = {MockWrite(kSimpleGetMockWrite)};
+ MockRead reads[] = {
+ MockRead(
+ "HTTP/1.1 200 OK\r\n"
+ "Expect-CT: max-age=100, enforce, report-uri=https://example.test\r\n"
+ "Content-Length: 12\r\n\r\n"),
+ MockRead("Test Content")};
+ StaticSocketDataProvider socket_data(reads, writes);
+ socket_factory_.AddSocketDataProvider(&socket_data);
+
+ base::HistogramTester histograms;
+
+ MockExpectCTReporter reporter;
+ TransportSecurityState transport_security_state;
+ transport_security_state.SetExpectCTReporter(&reporter);
+ context_->set_transport_security_state(&transport_security_state);
+
+ TestDelegate delegate;
+ std::unique_ptr<URLRequest> request = context_->CreateRequest(
+ GURL("https://www.example.com/"), DEFAULT_PRIORITY, &delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ IsolationInfo isolation_info = IsolationInfo::CreateTransient();
+ request->set_isolation_info(isolation_info);
+ request->Start();
+ delegate.RunUntilComplete();
+ EXPECT_THAT(delegate.request_status(), IsOk());
+
+ ASSERT_EQ(1, reporter.num_failures());
+ EXPECT_EQ(isolation_info.network_isolation_key(),
+ reporter.network_isolation_key());
+}
+
// Tests that the CT compliance histogram is recorded, even if CT is not
// required.
TEST_F(URLRequestHttpJobWithMockSocketsTest,
@@ -1646,7 +1725,7 @@ TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) {
bool SetAllCookies(CookieMonster* cm, const CookieList& list) {
DCHECK(cm);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cm->SetAllCookiesAsync(list, callback.MakeCallback());
callback.WaitUntilDone();
return callback.result().IsInclude();
@@ -1660,7 +1739,7 @@ bool CreateAndSetCookie(CookieStore* cs,
if (!cookie)
return false;
DCHECK(cs);
- ResultSavingCookieCallback<CanonicalCookie::CookieInclusionStatus> callback;
+ ResultSavingCookieCallback<CookieInclusionStatus> callback;
cs->SetCanonicalCookieAsync(std::move(cookie), url,
CookieOptions::MakeAllInclusive(),
callback.MakeCallback());
diff --git a/chromium/net/url_request/url_request_job.cc b/chromium/net/url_request/url_request_job.cc
index 3430a8dd62f..e490bd69b85 100644
--- a/chromium/net/url_request/url_request_job.cc
+++ b/chromium/net/url_request/url_request_job.cc
@@ -16,6 +16,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/base/auth.h"
+#include "net/base/features.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/load_states.h"
@@ -271,49 +272,111 @@ void URLRequestJob::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
+namespace {
+
+// Assuming |url| has already been stripped for use as a referrer, if
+// |should_strip_to_origin| is true, this method returns the output of the
+// "Strip `url` for use as a referrer" algorithm from the Referrer Policy spec
+// with its "origin-only" flag set to true:
+// https://w3c.github.io/webappsec-referrer-policy/#strip-url
+GURL MaybeStripToOrigin(GURL url, bool should_strip_to_origin) {
+ if (!should_strip_to_origin)
+ return url;
+
+ return url.GetOrigin();
+}
+
+} // namespace
+
// static
GURL URLRequestJob::ComputeReferrerForPolicy(
URLRequest::ReferrerPolicy policy,
const GURL& original_referrer,
const GURL& destination,
bool* same_origin_out_for_metrics) {
+ // Here and below, numbered lines are from the Referrer Policy spec's
+ // "Determine request's referrer" algorithm:
+ // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
+ //
+ // 4. Let referrerURL be the result of stripping referrerSource for use as a
+ // referrer.
+ GURL stripped_referrer = original_referrer.GetAsReferrer();
+
+ // 5. Let referrerOrigin be the result of stripping referrerSource for use as
+ // a referrer, with the origin-only flag set to true.
+ //
+ // (We use a boolean instead of computing the URL right away in order to avoid
+ // constructing a new GURL when it's not necessary.)
+ bool should_strip_to_origin = false;
+
+ // 6. If the result of serializing referrerURL is a string whose length is
+ // greater than 4096, set referrerURL to referrerOrigin.
+ if (stripped_referrer.spec().size() > 4096)
+ should_strip_to_origin = true;
+
+ bool same_origin = url::Origin::Create(original_referrer)
+ .IsSameOriginWith(url::Origin::Create(destination));
+
+ if (same_origin_out_for_metrics)
+ *same_origin_out_for_metrics = same_origin;
+
+ // 7. The user agent MAY alter referrerURL or referrerOrigin at this point to
+ // enforce arbitrary policy considerations in the interests of minimizing data
+ // leakage. For example, the user agent could strip the URL down to an origin,
+ // modify its host, replace it with an empty string, etc.
+ if (base::FeatureList::IsEnabled(
+ features::kCapReferrerToOriginOnCrossOrigin) &&
+ !same_origin) {
+ should_strip_to_origin = true;
+ }
+
bool secure_referrer_but_insecure_destination =
original_referrer.SchemeIsCryptographic() &&
!destination.SchemeIsCryptographic();
- url::Origin referrer_origin = url::Origin::Create(original_referrer);
- bool same_origin =
- referrer_origin.IsSameOriginWith(url::Origin::Create(destination));
- if (same_origin_out_for_metrics)
- *same_origin_out_for_metrics = same_origin;
+
switch (policy) {
case URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
- return secure_referrer_but_insecure_destination ? GURL()
- : original_referrer;
+ if (secure_referrer_but_insecure_destination)
+ return GURL();
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
case URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN:
- if (same_origin) {
- return original_referrer;
- } else if (secure_referrer_but_insecure_destination) {
+ if (secure_referrer_but_insecure_destination)
return GURL();
- } else {
- return referrer_origin.GetURL();
- }
+ if (!same_origin)
+ should_strip_to_origin = true;
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
case URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN:
- return same_origin ? original_referrer : referrer_origin.GetURL();
+ if (!same_origin)
+ should_strip_to_origin = true;
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
case URLRequest::NEVER_CLEAR_REFERRER:
- return original_referrer;
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
+
case URLRequest::ORIGIN:
- return referrer_origin.GetURL();
+ should_strip_to_origin = true;
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
+
case URLRequest::CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN:
- if (same_origin)
- return original_referrer;
- return GURL();
+ if (!same_origin)
+ return GURL();
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
+
case URLRequest::ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
if (secure_referrer_but_insecure_destination)
return GURL();
- return referrer_origin.GetURL();
+ should_strip_to_origin = true;
+ return MaybeStripToOrigin(std::move(stripped_referrer),
+ should_strip_to_origin);
+
case URLRequest::NO_REFERRER:
return GURL();
}
@@ -333,8 +396,8 @@ void URLRequestJob::NotifySSLCertificateError(int net_error,
request_->NotifySSLCertificateError(net_error, ssl_info, fatal);
}
-bool URLRequestJob::CanGetCookies(const CookieList& cookie_list) const {
- return request_->CanGetCookies(cookie_list);
+bool URLRequestJob::CanGetCookies() const {
+ return request_->CanGetCookies();
}
bool URLRequestJob::CanSetCookie(const net::CanonicalCookie& cookie,
diff --git a/chromium/net/url_request/url_request_job.h b/chromium/net/url_request/url_request_job.h
index caabaeab232..e7b13cc3942 100644
--- a/chromium/net/url_request/url_request_job.h
+++ b/chromium/net/url_request/url_request_job.h
@@ -265,7 +265,7 @@ class NET_EXPORT URLRequestJob {
bool fatal);
// Delegates to URLRequest.
- bool CanGetCookies(const CookieList& cookie_list) const;
+ bool CanGetCookies() const;
// Delegates to URLRequest.
bool CanSetCookie(const net::CanonicalCookie& cookie,
diff --git a/chromium/net/url_request/url_request_job_unittest.cc b/chromium/net/url_request/url_request_job_unittest.cc
index 4056dd8742c..4f6ed2d87b3 100644
--- a/chromium/net/url_request/url_request_job_unittest.cc
+++ b/chromium/net/url_request/url_request_job_unittest.cc
@@ -7,6 +7,8 @@
#include <memory>
#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
+#include "net/base/features.h"
#include "net/base/request_priority.h"
#include "net/http/http_transaction_test_util.h"
#include "net/test/cert_test_util.h"
@@ -18,6 +20,7 @@
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/url_util.h"
using net::test::IsError;
using net::test::IsOk;
@@ -658,4 +661,116 @@ TEST(URLRequestJobComputeReferrer, AcceptsNullptrInput) {
GURL(), nullptr);
}
+TEST(URLRequestJobComputeReferrer, FilesystemDestination) {
+ EXPECT_EQ(
+ URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, GURL("https://referrer.example"),
+ GURL("filesystem:https://destination.example"), nullptr),
+ GURL("https://referrer.example"));
+}
+
+TEST(URLRequestJobComputeReferrer, TruncatesLongReferrer) {
+ std::string original_spec = "https://referrer.example/";
+ original_spec.resize(4097, 'a');
+ const GURL kOriginalReferrer(original_spec);
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://google.com")),
+ GURL("https://referrer.example/"));
+}
+
+TEST(URLRequestJobComputeReferrer, DoesntTruncateShortReferrer) {
+ std::string original_spec = "https://referrer.example/";
+ original_spec.resize(4096, 'a');
+ const GURL kOriginalReferrer(original_spec);
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://google.com")),
+ kOriginalReferrer);
+}
+
+TEST(URLRequestJobComputeReferrer, DoesntTruncateEvenShorterReferrer) {
+ std::string original_spec = "https://referrer.example/";
+ original_spec.resize(4095, 'a');
+ const GURL kOriginalReferrer(original_spec);
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://google.com")),
+ kOriginalReferrer);
+}
+
+TEST(URLRequestJobComputeReferrer, DoesntTruncateReferrerWithLongRef) {
+ // Because the "is the length greater than 4096?" check comes *after*
+ // stripping the ref in the Referrer Policy spec, a URL that is short except
+ // for having a very long ref should not be stripped to an origin by the "if
+ // the length is too long, strip to the origin" check.
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER,
+ GURL(std::string("https://referrer.example/path#") +
+ std::string(5000, 'a')),
+ GURL("https://google.com")),
+ GURL("https://referrer.example/path"));
+}
+
+TEST(URLRequestJobComputeReferrer, InvalidSchemeReferrer) {
+ const GURL kOriginalReferrer("about:blank");
+ ASSERT_FALSE(url::IsReferrerScheme(
+ kOriginalReferrer.spec().data(),
+ kOriginalReferrer.parsed_for_possibly_invalid_spec().scheme));
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://google.com")),
+ GURL());
+
+ EXPECT_EQ(
+ URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::ORIGIN, kOriginalReferrer, GURL("https://google.com")),
+ GURL());
+}
+
+TEST(URLRequestJobComputeReferrer, CapReferrerOnCrossOrigin) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ features::kCapReferrerToOriginOnCrossOrigin);
+
+ const GURL kOriginalReferrer("https://boggle.com/path");
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://google.com")),
+ GURL("https://boggle.com/"));
+}
+
+TEST(URLRequestJobComputeReferrer,
+ CapReferrerOnCrossOriginRespectsStricterPolicy) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ features::kCapReferrerToOriginOnCrossOrigin);
+
+ const GURL kOriginalReferrer("https://boggle.com/path");
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(URLRequest::NO_REFERRER,
+ kOriginalReferrer,
+ GURL("https://google.com")),
+ GURL());
+}
+
+TEST(URLRequestJobComputeReferrer,
+ CapReferrerOnCrossOriginDoesntCapOnSameOrigin) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ features::kCapReferrerToOriginOnCrossOrigin);
+
+ const GURL kOriginalReferrer("https://boggle.com/path");
+
+ EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
+ URLRequest::NEVER_CLEAR_REFERRER, kOriginalReferrer,
+ GURL("https://boggle.com")),
+ kOriginalReferrer);
+}
+
} // namespace net
diff --git a/chromium/net/url_request/url_request_netlog_params.cc b/chromium/net/url_request/url_request_netlog_params.cc
index 2a88f066683..d6473f26e52 100644
--- a/chromium/net/url_request/url_request_netlog_params.cc
+++ b/chromium/net/url_request/url_request_netlog_params.cc
@@ -16,6 +16,22 @@
namespace net {
+namespace {
+
+std::string PrivacyModeDebugString(PrivacyMode privacy_mode) {
+ switch (privacy_mode) {
+ case PRIVACY_MODE_DISABLED:
+ return "disabled";
+ case PRIVACY_MODE_ENABLED:
+ return "enabled";
+ case PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS:
+ return "enabled without client certs";
+ }
+ return "";
+}
+
+} // namespace
+
base::Value NetLogURLRequestConstructorParams(
const GURL& url,
RequestPriority priority,
@@ -40,7 +56,7 @@ base::Value NetLogURLRequestStartParams(
dict.SetStringKey("url", url.possibly_invalid_spec());
dict.SetStringKey("method", method);
dict.SetIntKey("load_flags", load_flags);
- dict.SetIntKey("privacy_mode", privacy_mode == PRIVACY_MODE_ENABLED);
+ dict.SetStringKey("privacy_mode", PrivacyModeDebugString(privacy_mode));
dict.SetStringKey("network_isolation_key",
network_isolation_key.ToDebugString());
dict.SetStringKey("site_for_cookies", site_for_cookies.ToDebugString());
diff --git a/chromium/net/url_request/url_request_quic_unittest.cc b/chromium/net/url_request/url_request_quic_unittest.cc
index c282944895a..3860e68196d 100644
--- a/chromium/net/url_request/url_request_quic_unittest.cc
+++ b/chromium/net/url_request/url_request_quic_unittest.cc
@@ -11,11 +11,15 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "net/base/features.h"
#include "net/base/isolation_info.h"
#include "net/base/load_timing_info.h"
#include "net/base/network_delegate.h"
+#include "net/base/network_isolation_key.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/ct_policy_status.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/dns/mock_host_resolver.h"
@@ -64,6 +68,53 @@ const char kIndexPath[] = "/index2.html";
const char kIndexBodyValue[] = "Hello from QUIC Server";
const int kIndexStatus = 200;
+class MockCTPolicyEnforcerNonCompliant : public CTPolicyEnforcer {
+ public:
+ MockCTPolicyEnforcerNonCompliant() = default;
+ ~MockCTPolicyEnforcerNonCompliant() override = default;
+
+ ct::CTPolicyCompliance CheckCompliance(
+ X509Certificate* cert,
+ const ct::SCTList& verified_scts,
+ const NetLogWithSource& net_log) override {
+ return ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS;
+ }
+};
+
+// An ExpectCTReporter that records the number of times OnExpectCTFailed() was
+// called.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+ MockExpectCTReporter() = default;
+ ~MockExpectCTReporter() override = default;
+
+ void OnExpectCTFailed(
+ const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ base::Time expiration,
+ const X509Certificate* validated_certificate_chain,
+ const X509Certificate* served_certificate_chain,
+ const SignedCertificateTimestampAndStatusList&
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) override {
+ num_failures_++;
+ report_uri_ = report_uri;
+ network_isolation_key_ = network_isolation_key;
+ }
+
+ int num_failures() const { return num_failures_; }
+ const GURL& report_uri() const { return report_uri_; }
+ const NetworkIsolationKey& network_isolation_key() const {
+ return network_isolation_key_;
+ }
+
+ private:
+ int num_failures_ = 0;
+
+ GURL report_uri_;
+ NetworkIsolationKey network_isolation_key_;
+};
+
class URLRequestQuicTest
: public TestWithTaskEnvironment,
public ::testing::WithParamInterface<quic::ParsedQuicVersion> {
@@ -78,8 +129,7 @@ class URLRequestQuicTest
verify_result.verified_cert = ImportCertFromFile(
GetTestCertsDirectory(), "quic-chain.pem");
cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
- "test.example.com", verify_result,
- OK);
+ kTestServerHost, verify_result, OK);
// To simplify the test, and avoid the race with the HTTP request, we force
// QUIC for these requests.
context_->set_quic_context(&quic_context_);
@@ -92,6 +142,8 @@ class URLRequestQuicTest
context_->set_http_network_session_params(std::move(params));
context_->set_cert_verifier(&cert_verifier_);
context_->set_net_log(&net_log_);
+ transport_security_state_.SetExpectCTReporter(&expect_ct_reporter_);
+ context_->set_transport_security_state(&transport_security_state_);
}
void TearDown() override {
@@ -108,6 +160,10 @@ class URLRequestQuicTest
context_->set_network_delegate(network_delegate);
}
+ // Can be used to modify |context_|. Only safe to modify before Init() is
+ // called.
+ TestURLRequestContext* context() { return context_.get(); }
+
// Initializes the TestURLRequestContext |context_|.
void Init() { context_->Init(); }
@@ -155,6 +211,12 @@ class URLRequestQuicTest
quic::ParsedQuicVersion version() { return GetParam(); }
+ MockExpectCTReporter* expect_ct_reporter() { return &expect_ct_reporter_; }
+
+ TransportSecurityState* transport_security_state() {
+ return &transport_security_state_;
+ }
+
protected:
// Returns a fully-qualified URL for |path| on the test server.
std::string UrlFromPath(base::StringPiece path) {
@@ -219,6 +281,9 @@ class URLRequestQuicTest
return path.MaybeAsASCII();
}
+ MockExpectCTReporter expect_ct_reporter_;
+ TransportSecurityState transport_security_state_;
+
std::unique_ptr<MappedHostResolver> host_resolver_;
std::unique_ptr<QuicSimpleServer> server_;
std::unique_ptr<TestURLRequestContext> context_;
@@ -513,9 +578,10 @@ TEST_P(URLRequestQuicTest, CancelPushIfCached_AllCached) {
EXPECT_FALSE(end_entry_2->HasParams());
EXPECT_FALSE(GetOptionalNetErrorCodeFromParams(*end_entry_2));
-#if !defined(OS_FUCHSIA) && !defined(OS_IOS)
+#if !defined(OS_FUCHSIA) && !defined(OS_IOS) && !defined(OS_MACOSX)
// TODO(crbug.com/813631): Make this work on Fuchsia.
// TODO(crbug.com/1032568): Make this work on iOS.
+ // TODO(crbug.com/1087378): Flaky on Mac.
// Verify the reset error count received on the server side.
EXPECT_LE(2u, GetRstErrorCountReceivedByServer(quic::QUIC_STREAM_CANCELLED));
#endif
@@ -636,4 +702,42 @@ TEST_P(URLRequestQuicTest, RequestHeadersCallback) {
EXPECT_EQ(OK, delegate.request_status());
}
+// Tests that if there's an Expect-CT failure at the QUIC layer, a report is
+// generated.
+TEST_P(URLRequestQuicTest, ExpectCT) {
+ TransportSecurityState::SetRequireCTForTesting(true);
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ // enabled_features
+ {features::kPartitionConnectionsByNetworkIsolationKey,
+ features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
+ features::kPartitionSSLSessionsByNetworkIsolationKey},
+ // disabled_features
+ {});
+
+ MockCTPolicyEnforcerNonCompliant ct_enforcer;
+ context()->set_ct_policy_enforcer(&ct_enforcer);
+ Init();
+
+ GURL report_uri("https://report.test/");
+ IsolationInfo isolation_info = IsolationInfo::CreateTransient();
+ transport_security_state()->AddExpectCT(
+ kTestServerHost, base::Time::Now() + base::TimeDelta::FromDays(1),
+ true /* enforce */, report_uri, isolation_info.network_isolation_key());
+
+ base::RunLoop run_loop;
+ TestDelegate delegate;
+ std::unique_ptr<URLRequest> request =
+ CreateRequest(GURL(UrlFromPath(kHelloPath)), DEFAULT_PRIORITY, &delegate);
+ request->set_isolation_info(isolation_info);
+ request->Start();
+ delegate.RunUntilComplete();
+
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate.request_status());
+ ASSERT_EQ(1, expect_ct_reporter()->num_failures());
+ EXPECT_EQ(report_uri, expect_ct_reporter()->report_uri());
+ EXPECT_EQ(isolation_info.network_isolation_key(),
+ expect_ct_reporter()->network_isolation_key());
+}
+
} // namespace net
diff --git a/chromium/net/url_request/url_request_test_util.cc b/chromium/net/url_request/url_request_test_util.cc
index 702f6a8d0de..b06d7924f46 100644
--- a/chromium/net/url_request/url_request_test_util.cc
+++ b/chromium/net/url_request/url_request_test_util.cc
@@ -594,7 +594,6 @@ void TestNetworkDelegate::OnPACScriptError(int line_number,
}
bool TestNetworkDelegate::OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) {
bool allow = allowed_from_caller;
if (cookie_options_bit_mask_ & NO_GET_COOKIES)
diff --git a/chromium/net/url_request/url_request_test_util.h b/chromium/net/url_request/url_request_test_util.h
index 064be87739f..5d6da89e066 100644
--- a/chromium/net/url_request/url_request_test_util.h
+++ b/chromium/net/url_request/url_request_test_util.h
@@ -342,7 +342,6 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
void OnURLRequestDestroyed(URLRequest* request) override;
void OnPACScriptError(int line_number, const base::string16& error) override;
bool OnCanGetCookies(const URLRequest& request,
- const CookieList& cookie_list,
bool allowed_from_caller) override;
bool OnCanSetCookie(const URLRequest& request,
const net::CanonicalCookie& cookie,
diff --git a/chromium/net/url_request/url_request_unittest.cc b/chromium/net/url_request/url_request_unittest.cc
index c9d24bfe0a3..e2ef3cadd5e 100644
--- a/chromium/net/url_request/url_request_unittest.cc
+++ b/chromium/net/url_request/url_request_unittest.cc
@@ -84,6 +84,7 @@
#include "net/cert/x509_util.h"
#include "net/cert_net/cert_net_fetcher_url_request.h"
#include "net/cookies/canonical_cookie_test_helpers.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store_test_helpers.h"
#include "net/cookies/test_cookie_access_delegate.h"
@@ -115,6 +116,7 @@
#include "net/ssl/ssl_server_config.h"
#include "net/ssl/test_ssl_config_service.h"
#include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
#include "net/test/embedded_test_server/http_request.h"
@@ -161,6 +163,7 @@
using net::test::IsError;
using net::test::IsOk;
+using net::test_server::RegisterDefaultHandlers;
using testing::AnyOf;
using base::ASCIIToUTF16;
@@ -324,7 +327,7 @@ class HttpTestServer : public EmbeddedTestServer {
AddDefaultHandlers(document_root);
}
- HttpTestServer() { AddDefaultHandlers(base::FilePath()); }
+ HttpTestServer() { RegisterDefaultHandlers(this); }
};
// Job that allows monitoring of its priority.
@@ -1569,7 +1572,6 @@ class FilteringTestNetworkDelegate : public TestNetworkDelegate {
void ResetBlockedSetCookieCount() { blocked_set_cookie_count_ = 0; }
bool OnCanGetCookies(const URLRequest& request,
- const net::CookieList& cookie_list,
bool allowed_from_caller) override {
// Filter out cookies if |block_get_cookies_| is set and
// combine with |allowed_from_caller|.
@@ -1580,7 +1582,7 @@ class FilteringTestNetworkDelegate : public TestNetworkDelegate {
if (!allowed)
++blocked_get_cookie_count_;
- return TestNetworkDelegate::OnCanGetCookies(request, cookie_list, allowed);
+ return TestNetworkDelegate::OnCanGetCookies(request, allowed);
}
void set_block_get_cookies() { block_get_cookies_ = true; }
@@ -2398,10 +2400,10 @@ TEST_F(URLRequestTest, SameSiteCookiesSpecialScheme) {
url::AddStandardScheme("chrome", url::SchemeType::SCHEME_WITH_HOST);
EmbeddedTestServer https_test_server(EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.AddDefaultHandlers(base::FilePath());
+ RegisterDefaultHandlers(&https_test_server);
ASSERT_TRUE(https_test_server.Start());
EmbeddedTestServer http_test_server(EmbeddedTestServer::TYPE_HTTP);
- http_test_server.AddDefaultHandlers(base::FilePath());
+ RegisterDefaultHandlers(&http_test_server);
// Ensure they are on different ports.
ASSERT_TRUE(http_test_server.Start(https_test_server.port() + 1));
// Both hostnames should be 127.0.0.1 (so that we can use the same set of
@@ -2488,11 +2490,9 @@ TEST_F(URLRequestTest, SameSiteCookiesSpecialScheme) {
// Tests that __Secure- cookies can't be set on non-secure origins.
TEST_F(URLRequestTest, SecureCookiePrefixOnNonsecureOrigin) {
EmbeddedTestServer http_server;
- http_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&http_server);
EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&https_server);
ASSERT_TRUE(http_server.Start());
ASSERT_TRUE(https_server.Start());
@@ -2531,8 +2531,7 @@ TEST_F(URLRequestTest, SecureCookiePrefixOnNonsecureOrigin) {
TEST_F(URLRequestTest, SecureCookiePrefixNonsecure) {
EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&https_server);
ASSERT_TRUE(https_server.Start());
TestNetworkDelegate network_delegate;
@@ -2570,8 +2569,7 @@ TEST_F(URLRequestTest, SecureCookiePrefixNonsecure) {
TEST_F(URLRequestTest, SecureCookiePrefixSecure) {
EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&https_server);
ASSERT_TRUE(https_server.Start());
TestNetworkDelegate network_delegate;
@@ -2610,11 +2608,9 @@ TEST_F(URLRequestTest, SecureCookiePrefixSecure) {
// cookies are enabled.
TEST_F(URLRequestTest, StrictSecureCookiesOnNonsecureOrigin) {
EmbeddedTestServer http_server;
- http_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&http_server);
EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&https_server);
ASSERT_TRUE(http_server.Start());
ASSERT_TRUE(https_server.Start());
@@ -3728,76 +3724,132 @@ TEST_F(URLRequestTestHTTP, GetTestLoadTiming) {
}
}
-// TODO(svaldez): Update tests to use EmbeddedTestServer.
-#if !defined(OS_IOS)
-TEST_F(URLRequestTestHTTP, GetZippedTest) {
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
- base::FilePath(kTestFilePath));
+namespace {
- ASSERT_TRUE(test_server.Start());
+// Sends the correct Content-Length matching the compressed length.
+const char kZippedContentLengthCompressed[] = "C";
+// Sends an incorrect Content-Length matching the uncompressed length.
+const char kZippedContentLengthUncompressed[] = "U";
+// Sends an incorrect Content-Length shorter than the compressed length.
+const char kZippedContentLengthShort[] = "S";
+// Sends an incorrect Content-Length between the compressed and uncompressed
+// lengths.
+const char kZippedContentLengthMedium[] = "M";
+// Sends an incorrect Content-Length larger than both compressed and
+// uncompressed lengths.
+const char kZippedContentLengthLong[] = "L";
+
+// Sends |compressed_content| which, when decoded with deflate, should have
+// length |uncompressed_length|. The Content-Length header will be sent based on
+// which of the constants above is sent in the query string.
+std::unique_ptr<test_server::HttpResponse> HandleZippedRequest(
+ const std::string& compressed_content,
+ size_t uncompressed_length,
+ const test_server::HttpRequest& request) {
+ GURL url = request.GetURL();
+ if (url.path_piece() != "/compressedfiles/BullRunSpeech.txt")
+ return nullptr;
- // Parameter that specifies the Content-Length field in the response:
- // C - Compressed length.
- // U - Uncompressed length.
- // L - Large length (larger than both C & U).
- // M - Medium length (between C & U).
- // S - Small length (smaller than both C & U).
- const char test_parameters[] = "CULMS";
- const int num_tests = base::size(test_parameters) - 1; // Skip NULL.
- // C & U should be OK.
- // L & M are larger than the data sent, and show an error.
- // S has too little data, but we seem to accept it.
- const bool test_expect_success[num_tests] =
- { true, true, false, false, true };
+ size_t length;
+ if (url.query_piece() == kZippedContentLengthCompressed) {
+ length = compressed_content.size();
+ } else if (url.query_piece() == kZippedContentLengthUncompressed) {
+ length = uncompressed_length;
+ } else if (url.query_piece() == kZippedContentLengthShort) {
+ length = compressed_content.size() / 2;
+ } else if (url.query_piece() == kZippedContentLengthMedium) {
+ length = (compressed_content.size() + uncompressed_length) / 2;
+ } else if (url.query_piece() == kZippedContentLengthLong) {
+ length = compressed_content.size() + uncompressed_length;
+ } else {
+ return nullptr;
+ }
+
+ std::string headers = "HTTP/1.1 200 OK\r\n";
+ headers += "Content-Encoding: deflate\r\n";
+ base::StringAppendF(&headers, "Content-Length: %zu\r\n", length);
+ return std::make_unique<test_server::RawHttpResponse>(headers,
+ compressed_content);
+}
+} // namespace
+
+TEST_F(URLRequestTestHTTP, GetZippedTest) {
base::FilePath file_path;
base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
file_path = file_path.Append(kTestFilePath);
- file_path = file_path.Append(FILE_PATH_LITERAL("BullRunSpeech.txt"));
- std::string expected_content;
- ASSERT_TRUE(base::ReadFileToString(file_path, &expected_content));
+ std::string expected_content, compressed_content;
+ ASSERT_TRUE(base::ReadFileToString(
+ file_path.Append(FILE_PATH_LITERAL("BullRunSpeech.txt")),
+ &expected_content));
+ // This file is the output of the Python zlib.compress function on
+ // |expected_content|.
+ ASSERT_TRUE(base::ReadFileToString(
+ file_path.Append(FILE_PATH_LITERAL("BullRunSpeech.txt.deflate")),
+ &compressed_content));
+
+ http_test_server()->RegisterRequestHandler(base::BindRepeating(
+ &HandleZippedRequest, compressed_content, expected_content.size()));
+ ASSERT_TRUE(http_test_server()->Start());
+
+ static const struct {
+ const char* parameter;
+ bool expect_success;
+ } kTests[] = {
+ // Sending the compressed Content-Length is correct.
+ {kZippedContentLengthCompressed, true},
+ // Sending the uncompressed Content-Length is incorrect, but we accept it
+ // to workaround some broken servers.
+ {kZippedContentLengthUncompressed, true},
+ // Sending too long of Content-Length is rejected.
+ {kZippedContentLengthLong, false},
+ {kZippedContentLengthMedium, false},
+ // Sending too short of Content-Length successfully fetches a response
+ // body, but it will be truncated.
+ {kZippedContentLengthShort, true},
+ };
- for (int i = 0; i < num_tests; i++) {
+ for (const auto& test : kTests) {
+ SCOPED_TRACE(test.parameter);
TestDelegate d;
- {
- std::string test_file = base::StringPrintf(
- "compressedfiles/BullRunSpeech.txt?%c", test_parameters[i]);
+ std::string test_file = base::StringPrintf(
+ "/compressedfiles/BullRunSpeech.txt?%s", test.parameter);
- TestNetworkDelegate network_delegate; // Must outlive URLRequest.
- TestURLRequestContext context(true);
- context.set_network_delegate(&network_delegate);
- context.Init();
+ TestNetworkDelegate network_delegate; // Must outlive URLRequest.
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.Init();
- std::unique_ptr<URLRequest> r(
- context.CreateRequest(test_server.GetURL(test_file), DEFAULT_PRIORITY,
- &d, TRAFFIC_ANNOTATION_FOR_TESTS));
- r->Start();
- EXPECT_TRUE(r->is_pending());
+ std::unique_ptr<URLRequest> r(context.CreateRequest(
+ http_test_server()->GetURL(test_file), DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ r->Start();
+ EXPECT_TRUE(r->is_pending());
- d.RunUntilComplete();
+ d.RunUntilComplete();
- EXPECT_EQ(1, d.response_started_count());
- EXPECT_FALSE(d.received_data_before_response());
- VLOG(1) << " Received " << d.bytes_received() << " bytes"
- << " error = " << d.request_status();
- if (test_expect_success[i]) {
- EXPECT_EQ(OK, d.request_status()) << " Parameter = \"" << test_file
- << "\"";
- if (test_parameters[i] == 'S') {
- // When content length is smaller than both compressed length and
- // uncompressed length, HttpStreamParser might not read the full
- // response body.
- continue;
- }
- EXPECT_EQ(expected_content, d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_FALSE(d.received_data_before_response());
+ VLOG(1) << " Received " << d.bytes_received() << " bytes"
+ << " error = " << d.request_status();
+ if (test.expect_success) {
+ EXPECT_EQ(OK, d.request_status())
+ << " Parameter = \"" << test_file << "\"";
+ if (strcmp(test.parameter, kZippedContentLengthShort) == 0) {
+ // When content length is smaller than both compressed length and
+ // uncompressed length, HttpStreamParser might not read the full
+ // response body.
+ EXPECT_EQ(expected_content.substr(0, d.data_received().size()),
+ d.data_received());
} else {
- EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, d.request_status())
- << " Parameter = \"" << test_file << "\"";
+ EXPECT_EQ(expected_content, d.data_received());
}
+ } else {
+ EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, d.request_status())
+ << " Parameter = \"" << test_file << "\"";
}
}
}
-#endif // !defined(OS_IOS)
TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
ASSERT_TRUE(http_test_server()->Start());
@@ -4997,8 +5049,8 @@ TEST_F(URLRequestTestHTTP, ProcessSTS) {
default_context().transport_security_state();
TransportSecurityState::STSState sts_state;
TransportSecurityState::PKPState pkp_state;
- EXPECT_TRUE(security_state->GetDynamicSTSState(test_server_hostname,
- &sts_state, nullptr));
+ EXPECT_TRUE(
+ security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
EXPECT_FALSE(
security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
@@ -5031,8 +5083,8 @@ TEST_F(URLRequestTestHTTP, STSNotProcessedOnIP) {
TransportSecurityState* security_state =
default_context().transport_security_state();
TransportSecurityState::STSState sts_state;
- EXPECT_FALSE(security_state->GetDynamicSTSState(test_server_hostname,
- &sts_state, nullptr));
+ EXPECT_FALSE(
+ security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
}
namespace {
@@ -5245,8 +5297,8 @@ TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
TransportSecurityState* security_state =
default_context().transport_security_state();
TransportSecurityState::STSState sts_state;
- EXPECT_TRUE(security_state->GetDynamicSTSState(test_server_hostname,
- &sts_state, nullptr));
+ EXPECT_TRUE(
+ security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
sts_state.upgrade_mode);
EXPECT_FALSE(sts_state.include_subdomains);
@@ -5260,13 +5312,15 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
MockExpectCTReporter() : num_failures_(0) {}
~MockExpectCTReporter() override = default;
- void OnExpectCTFailed(const HostPortPair& host_port_pair,
- const GURL& report_uri,
- base::Time expiration,
- const X509Certificate* validated_certificate_chain,
- const X509Certificate* served_certificate_chain,
- const SignedCertificateTimestampAndStatusList&
- signed_certificate_timestamps) override {
+ void OnExpectCTFailed(
+ const HostPortPair& host_port_pair,
+ const GURL& report_uri,
+ base::Time expiration,
+ const X509Certificate* validated_certificate_chain,
+ const X509Certificate* served_certificate_chain,
+ const SignedCertificateTimestampAndStatusList&
+ signed_certificate_timestamps,
+ const NetworkIsolationKey& network_isolation_key) override {
num_failures_++;
}
@@ -5414,8 +5468,8 @@ TEST_F(URLRequestTestHTTP, ExpectCTHeader) {
d.RunUntilComplete();
TransportSecurityState::ExpectCTState state;
- ASSERT_TRUE(
- transport_security_state.GetDynamicExpectCTState(url.host(), &state));
+ ASSERT_TRUE(transport_security_state.GetDynamicExpectCTState(
+ url.host(), NetworkIsolationKey(), &state));
EXPECT_TRUE(state.enforce);
EXPECT_EQ(GURL("https://example.test"), state.report_uri);
}
@@ -5476,8 +5530,8 @@ TEST_F(URLRequestTestHTTP, MultipleExpectCTHeaders) {
d.RunUntilComplete();
TransportSecurityState::ExpectCTState state;
- ASSERT_TRUE(
- transport_security_state.GetDynamicExpectCTState(url.host(), &state));
+ ASSERT_TRUE(transport_security_state.GetDynamicExpectCTState(
+ url.host(), NetworkIsolationKey(), &state));
EXPECT_TRUE(state.enforce);
EXPECT_EQ(GURL("https://example.test"), state.report_uri);
}
@@ -5488,7 +5542,7 @@ TEST_F(URLRequestTestHTTP, MultipleExpectCTHeaders) {
TEST_F(URLRequestTestHTTP, NetworkErrorLogging_DontReportIfNetworkNotAccessed) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+ RegisterDefaultHandlers(&https_test_server);
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/cachetime");
@@ -5552,7 +5606,7 @@ TEST_F(URLRequestTestHTTP, NetworkErrorLogging_BasicSuccess) {
TEST_F(URLRequestTestHTTP, NetworkErrorLogging_BasicError) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+ RegisterDefaultHandlers(&https_test_server);
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/close-socket");
@@ -5636,7 +5690,7 @@ TEST_F(URLRequestTestHTTP, NetworkErrorLogging_RedirectWithoutLocationHeader) {
TEST_F(URLRequestTestHTTP, NetworkErrorLogging_Auth) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+ RegisterDefaultHandlers(&https_test_server);
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/auth-basic");
@@ -5667,7 +5721,7 @@ TEST_F(URLRequestTestHTTP, NetworkErrorLogging_Auth) {
TEST_F(URLRequestTestHTTP, NetworkErrorLogging_304Response) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.AddDefaultHandlers(base::FilePath(kTestFilePath));
+ RegisterDefaultHandlers(&https_test_server);
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/auth-basic");
@@ -6127,7 +6181,12 @@ TEST_F(URLRequestTestHTTP, CapRefererHeaderLength) {
req->Start();
d.RunUntilComplete();
- EXPECT_EQ("http://example.com/", d.data_received());
+ // The request's referrer will be stripped since (1) there will be a
+ // mismatch between the request's referrer and the output of
+ // URLRequestJob::ComputeReferrerForPolicy and (2) the delegate, when
+ // offered the opportunity to cancel the request for this reason, will
+ // decline.
+ EXPECT_EQ("None", d.data_received());
}
{
std::string original_header = "http://example.com/";
@@ -6729,8 +6788,7 @@ TEST_F(URLRequestTest, ReportCookieActivity) {
req->maybe_stored_cookies()[0].cookie->Name());
EXPECT_TRUE(req->maybe_stored_cookies()[0]
.status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ {CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
EXPECT_EQ("stored_cookie", req->maybe_stored_cookies()[1].cookie->Name());
EXPECT_TRUE(req->maybe_stored_cookies()[1].status.IsInclude());
EXPECT_EQ("stored_cookie", req->maybe_stored_cookies()[1].cookie->Name());
@@ -6769,17 +6827,16 @@ TEST_F(URLRequestTest, ReportCookieActivity) {
ASSERT_EQ(2u, req->maybe_sent_cookies().size());
EXPECT_EQ("path_cookie", req->maybe_sent_cookies()[0].cookie.Name());
- EXPECT_TRUE(req->maybe_sent_cookies()[0]
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NOT_ON_PATH,
- net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ req->maybe_sent_cookies()[0]
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
+ net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
EXPECT_EQ("stored_cookie", req->maybe_sent_cookies()[1].cookie.Name());
- EXPECT_TRUE(req->maybe_sent_cookies()[1]
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ req->maybe_sent_cookies()[1]
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
auto entries =
net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS);
EXPECT_EQ(2u, entries.size());
@@ -6842,11 +6899,10 @@ TEST_F(URLRequestTest, ReportCookieActivity) {
ASSERT_EQ(2u, req->maybe_sent_cookies().size());
EXPECT_EQ("path_cookie", req->maybe_sent_cookies()[0].cookie.Name());
EXPECT_TRUE(req->maybe_sent_cookies()[0]
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_NOT_ON_PATH}));
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
EXPECT_EQ("stored_cookie", req->maybe_sent_cookies()[1].cookie.Name());
- EXPECT_TRUE(req->maybe_sent_cookies()[1].status.IsInclude());
+ EXPECT_TRUE(req->maybe_sent_cookies()[1].access_result.status.IsInclude());
auto entries =
net_log.GetEntriesWithType(NetLogEventType::COOKIE_INCLUSION_STATUS);
EXPECT_EQ(2u, entries.size());
@@ -6863,6 +6919,200 @@ TEST_F(URLRequestTest, ReportCookieActivity) {
}
}
+// Test that CookieInclusionStatus warnings for SameSite cookie compatibility
+// pairs are applied correctly.
+TEST_F(URLRequestTest, SameSiteCookieCompatPairWarnings) {
+ EmbeddedTestServer https_test_server(EmbeddedTestServer::TYPE_HTTPS);
+ RegisterDefaultHandlers(&https_test_server);
+ ASSERT_TRUE(https_test_server.Start());
+
+ GURL set_pair_url = https_test_server.GetURL(
+ "/set-cookie?name=value;SameSite=None;Secure&"
+ "name_legacy=value");
+ GURL set_httponly_pair_url = https_test_server.GetURL(
+ "/set-cookie?name=value;SameSite=None;Secure;HttpOnly&"
+ "name_legacy=value;HttpOnly");
+ GURL set_pair_and_other_url = https_test_server.GetURL(
+ "/set-cookie?name=value;SameSite=None;Secure&"
+ "name_legacy=value&"
+ "name2=value;SameSite=None;Secure");
+ GURL set_two_pairs_url = https_test_server.GetURL(
+ "/set-cookie?name=value;SameSite=None;Secure&"
+ "name_legacy=value&"
+ "name2=value;SameSite=None;Secure&"
+ "compat-name2=value");
+ GURL get_cookies_url = https_test_server.GetURL("/echoheader?Cookie");
+
+ struct TestCase {
+ // URL used to set cookies.
+ // Note: This test works because each URL uses a superset of the cookies
+ // used by URLs before it.
+ GURL set_cookies_url;
+ // Names of cookies and whether they are expected to be included for a
+ // cross-site get/set. (All are expected for a same-site request.)
+ std::map<std::string, bool> expected_cookies;
+ // Names of cookies expected to have a compat pair warning for a cross-site
+ // request.
+ std::set<std::string> expected_compat_warning_cookies;
+ // Whether all cookies should be HttpOnly.
+ bool expected_httponly = false;
+ } kTestCases[] = {
+ // Basic case with a single compat pair.
+ {set_pair_url,
+ {{"name", true}, {"name_legacy", false}},
+ {"name", "name_legacy"}},
+ // Compat pair with HttpOnly cookies (should not change behavior because
+ // this is an HTTP request).
+ {set_httponly_pair_url,
+ {{"name", true}, {"name_legacy", false}},
+ {"name", "name_legacy"},
+ true},
+ // Pair should be marked, but extra cookie (not part of a pair) should
+ // not.
+ {set_pair_and_other_url,
+ {{"name", true}, {"name_legacy", false}, {"name2", true}},
+ {"name", "name_legacy"}},
+ // Two separate pairs should all be marked.
+ {set_two_pairs_url,
+ {{"name", true},
+ {"name_legacy", false},
+ {"name2", true},
+ {"compat-name2", false}},
+ {"name", "name_legacy", "name2", "compat-name2"}}};
+
+ // For each test case, this exercises:
+ // 1. Set cookies in a cross-site context to trigger compat pair warnings.
+ // 2. Set cookies in a same-site context and check that no compat pair
+ // warnings are applied (and also make sure the cookies are actually
+ // present for the subsequent tests).
+ // 3. Get cookies in a same-site context and check that no compat pair
+ // warnings are applied.
+ // 4. Get cookies in a cross-site context to trigger compat pair warnings.
+ for (const auto& test : kTestCases) {
+ {
+ // Set cookies in a cross-site context.
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(default_context().CreateRequest(
+ test.set_cookies_url, DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ d.RunUntilComplete();
+
+ ASSERT_EQ(test.expected_cookies.size(),
+ req->maybe_stored_cookies().size());
+ for (const auto& cookie : req->maybe_stored_cookies()) {
+ ASSERT_TRUE(cookie.cookie.has_value());
+ EXPECT_EQ(cookie.cookie->IsHttpOnly(), test.expected_httponly);
+
+ const std::string& cookie_name = cookie.cookie->Name();
+ auto it = test.expected_cookies.find(cookie_name);
+ ASSERT_NE(test.expected_cookies.end(), it);
+ bool included = cookie.status.IsInclude();
+ EXPECT_EQ(it->second, included);
+
+ std::vector<CookieInclusionStatus::ExclusionReason> exclusions;
+ std::vector<CookieInclusionStatus::WarningReason> warnings;
+ if (!included) {
+ exclusions.push_back(CookieInclusionStatus::
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+ warnings.push_back(CookieInclusionStatus::
+ WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ }
+ if (base::Contains(test.expected_compat_warning_cookies, cookie_name)) {
+ warnings.push_back(CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ }
+ EXPECT_TRUE(
+ cookie.status.HasExactlyExclusionReasonsForTesting(exclusions));
+ EXPECT_TRUE(cookie.status.HasExactlyWarningReasonsForTesting(warnings));
+ }
+ }
+ {
+ // Set cookies in a same-site context.
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(default_context().CreateFirstPartyRequest(
+ test.set_cookies_url, DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ d.RunUntilComplete();
+
+ ASSERT_EQ(test.expected_cookies.size(),
+ req->maybe_stored_cookies().size());
+ for (const auto& cookie : req->maybe_stored_cookies()) {
+ ASSERT_TRUE(cookie.cookie.has_value());
+ EXPECT_EQ(cookie.cookie->IsHttpOnly(), test.expected_httponly);
+ EXPECT_TRUE(
+ base::Contains(test.expected_cookies, cookie.cookie->Name()));
+ // Cookie was included and there are no warnings.
+ EXPECT_EQ(CookieInclusionStatus(), cookie.status);
+ }
+ }
+ {
+ // Get cookies in a same-site context.
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(default_context().CreateFirstPartyRequest(
+ get_cookies_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ d.RunUntilComplete();
+
+ ASSERT_EQ(test.expected_cookies.size(), req->maybe_sent_cookies().size());
+ for (const auto& cookie : req->maybe_sent_cookies()) {
+ EXPECT_EQ(cookie.cookie.IsHttpOnly(), test.expected_httponly);
+ EXPECT_TRUE(
+ base::Contains(test.expected_cookies, cookie.cookie.Name()));
+ EXPECT_THAT(d.data_received(),
+ ::testing::HasSubstr(cookie.cookie.Name() + "=value"));
+ // Cookie was included and there are no warnings.
+ EXPECT_EQ(CookieInclusionStatus(), cookie.access_result.status);
+ }
+ }
+ {
+ // Get cookies in a cross-site context.
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(default_context().CreateRequest(
+ get_cookies_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ d.RunUntilComplete();
+
+ ASSERT_EQ(test.expected_cookies.size(), req->maybe_sent_cookies().size());
+ for (const auto& cookie : req->maybe_sent_cookies()) {
+ EXPECT_EQ(cookie.cookie.IsHttpOnly(), test.expected_httponly);
+
+ const std::string& cookie_name = cookie.cookie.Name();
+ auto it = test.expected_cookies.find(cookie_name);
+ ASSERT_NE(test.expected_cookies.end(), it);
+ bool included = cookie.access_result.status.IsInclude();
+ EXPECT_EQ(it->second, included);
+
+ if (included) {
+ EXPECT_THAT(d.data_received(),
+ ::testing::HasSubstr(cookie.cookie.Name() + "=value"));
+ } else {
+ EXPECT_THAT(d.data_received(), ::testing::Not(::testing::HasSubstr(
+ cookie.cookie.Name() + "=value")));
+ }
+
+ std::vector<CookieInclusionStatus::ExclusionReason> exclusions;
+ std::vector<CookieInclusionStatus::WarningReason> warnings;
+ if (!included) {
+ exclusions.push_back(CookieInclusionStatus::
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX);
+ warnings.push_back(CookieInclusionStatus::
+ WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT);
+ }
+ if (base::Contains(test.expected_compat_warning_cookies, cookie_name)) {
+ warnings.push_back(CookieInclusionStatus::WARN_SAMESITE_COMPAT_PAIR);
+ }
+ EXPECT_TRUE(
+ cookie.access_result.status.HasExactlyExclusionReasonsForTesting(
+ exclusions));
+ EXPECT_TRUE(
+ cookie.access_result.status.HasExactlyWarningReasonsForTesting(
+ warnings));
+ }
+ }
+ }
+}
+
// Test that the SameSite-by-default CookieInclusionStatus warnings do not get
// set if the cookie would have been rejected for other reasons.
// Regression test for https://crbug.com/1027318.
@@ -6908,8 +7158,7 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
// doesn't even make it to the cookie store (it is filtered out beforehand).
EXPECT_TRUE(req->maybe_stored_cookies()[0]
.status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ {CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
EXPECT_FALSE(req->maybe_stored_cookies()[0].status.ShouldWarn());
// Cookie that would be included had it not been for the new SameSite rules
@@ -6918,22 +7167,21 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
req->maybe_stored_cookies()[1].cookie->Name());
EXPECT_TRUE(req->maybe_stored_cookies()[1]
.status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ {CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_TRUE(req->maybe_stored_cookies()[1]
.status.HasExactlyWarningReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ {CookieInclusionStatus::
WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
// Cookie that is blocked because of invalid Secure attribute is not warned
// about.
EXPECT_EQ("invalidsecure", req->maybe_stored_cookies()[2].cookie->Name());
- EXPECT_TRUE(
- req->maybe_stored_cookies()[2]
- .status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
+ EXPECT_TRUE(req->maybe_stored_cookies()[2]
+ .status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
+ CookieInclusionStatus::
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
EXPECT_FALSE(req->maybe_stored_cookies()[2].status.ShouldWarn());
}
@@ -6944,14 +7192,13 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
auto cookie1 = CanonicalCookie::Create(url, "cookienosamesite=1",
base::Time::Now(), base::nullopt);
base::RunLoop run_loop;
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
cm.SetCanonicalCookieAsync(
std::move(cookie1), url, CookieOptions::MakeAllInclusive(),
- base::BindLambdaForTesting(
- [&](CanonicalCookie::CookieInclusionStatus result) {
- status = result;
- run_loop.Quit();
- }));
+ base::BindLambdaForTesting([&](CookieInclusionStatus result) {
+ status = result;
+ run_loop.Quit();
+ }));
run_loop.Run();
EXPECT_TRUE(status.IsInclude());
@@ -6970,14 +7217,14 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
ASSERT_EQ(1u, req->maybe_sent_cookies().size());
EXPECT_EQ("cookienosamesite", req->maybe_sent_cookies()[0].cookie.Name());
EXPECT_TRUE(req->maybe_sent_cookies()[0]
- .status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES,
- CanonicalCookie::CookieInclusionStatus::
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_USER_PREFERENCES,
+ CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
// Cookie should not be warned about because it was blocked because of user
// preferences.
- EXPECT_FALSE(req->maybe_sent_cookies()[0].status.ShouldWarn());
+ EXPECT_FALSE(
+ req->maybe_sent_cookies()[0].access_result.status.ShouldWarn());
}
network_delegate.unset_block_get_cookies();
@@ -6988,14 +7235,13 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
base::Time::Now(), base::nullopt);
base::RunLoop run_loop;
// Note: cookie1 from the previous testcase is still in the cookie store.
- CanonicalCookie::CookieInclusionStatus status;
+ CookieInclusionStatus status;
cm.SetCanonicalCookieAsync(
std::move(cookie2), url, CookieOptions::MakeAllInclusive(),
- base::BindLambdaForTesting(
- [&](CanonicalCookie::CookieInclusionStatus result) {
- status = result;
- run_loop.Quit();
- }));
+ base::BindLambdaForTesting([&](CookieInclusionStatus result) {
+ status = result;
+ run_loop.Quit();
+ }));
run_loop.Run();
EXPECT_TRUE(status.IsInclude());
@@ -7017,24 +7263,24 @@ TEST_F(URLRequestTest, NoCookieInclusionStatusWarningIfWouldBeExcludedAnyway) {
// Note: this cookie is first because the cookies are sorted by path length
// with longest first. See CookieSorter() in cookie_monster.cc.
EXPECT_EQ("cookiewithpath", req->maybe_sent_cookies()[0].cookie.Name());
- EXPECT_TRUE(
- req->maybe_sent_cookies()[0]
- .status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
- CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
- EXPECT_FALSE(req->maybe_sent_cookies()[0].status.ShouldWarn());
+ EXPECT_TRUE(req->maybe_sent_cookies()[0]
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
+ CookieInclusionStatus::
+ EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
+ EXPECT_FALSE(
+ req->maybe_sent_cookies()[0].access_result.status.ShouldWarn());
// Cookie that was only blocked because of unspecified SameSite should be
// warned about.
EXPECT_EQ("cookienosamesite", req->maybe_sent_cookies()[1].cookie.Name());
EXPECT_TRUE(req->maybe_sent_cookies()[1]
- .status.HasExactlyExclusionReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
- EXPECT_TRUE(
- req->maybe_sent_cookies()[1].status.HasExactlyWarningReasonsForTesting(
- {CanonicalCookie::CookieInclusionStatus::
- WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
+ EXPECT_TRUE(req->maybe_sent_cookies()[1]
+ .access_result.status.HasExactlyWarningReasonsForTesting(
+ {CookieInclusionStatus::
+ WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT}));
}
}
@@ -7060,8 +7306,7 @@ TEST_F(URLRequestTestHTTP, AuthChallengeCancelCookieCollect) {
ASSERT_EQ(1u, request->maybe_stored_cookies().size());
EXPECT_TRUE(request->maybe_stored_cookies()[0]
.status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
EXPECT_EQ("got_challenged=true",
request->maybe_stored_cookies()[0].cookie_string);
@@ -7099,11 +7344,11 @@ TEST_F(URLRequestTestHTTP, AuthChallengeWithFilteredCookies) {
// The number of cookies blocked from the most recent round trip.
ASSERT_EQ(1u, request->maybe_stored_cookies().size());
- EXPECT_TRUE(request->maybe_stored_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_stored_cookies()
+ .front()
+ .status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
// Now check the second round trip
request->SetAuth(AuthCredentials(kUser, kSecret));
@@ -7153,11 +7398,11 @@ TEST_F(URLRequestTestHTTP, AuthChallengeWithFilteredCookies) {
EXPECT_EQ("another_cookie",
request->maybe_sent_cookies().front().cookie.Name());
EXPECT_EQ("true", request->maybe_sent_cookies().front().cookie.Value());
- EXPECT_TRUE(request->maybe_sent_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_sent_cookies()
+ .front()
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
// Check maybe_sent_cookies on second roundtrip.
request->set_maybe_sent_cookies({});
@@ -7188,11 +7433,11 @@ TEST_F(URLRequestTestHTTP, AuthChallengeWithFilteredCookies) {
ASSERT_EQ(1u, request->maybe_sent_cookies().size());
EXPECT_EQ("one_more_cookie",
request->maybe_sent_cookies().front().cookie.Name());
- EXPECT_TRUE(request->maybe_sent_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_sent_cookies()
+ .front()
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
}
}
@@ -7503,11 +7748,11 @@ TEST_F(URLRequestTestHTTP, RedirectWithFilteredCookies) {
EXPECT_EQ("server-redirect",
request->maybe_stored_cookies().front().cookie->Name());
EXPECT_EQ("true", request->maybe_stored_cookies().front().cookie->Value());
- EXPECT_TRUE(request->maybe_stored_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_stored_cookies()
+ .front()
+ .status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
// Check maybe_stored_cookies on second round trip (and clearing from the
// first).
@@ -7526,11 +7771,11 @@ TEST_F(URLRequestTestHTTP, RedirectWithFilteredCookies) {
EXPECT_EQ("server-redirect",
request->maybe_stored_cookies().front().cookie->Name());
EXPECT_EQ("other", request->maybe_stored_cookies().front().cookie->Value());
- EXPECT_TRUE(request->maybe_stored_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_stored_cookies()
+ .front()
+ .status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
}
// Check maybe_sent_cookies on first round trip.
@@ -7561,11 +7806,11 @@ TEST_F(URLRequestTestHTTP, RedirectWithFilteredCookies) {
ASSERT_EQ(1u, request->maybe_sent_cookies().size());
EXPECT_EQ("another_cookie",
request->maybe_sent_cookies().front().cookie.Name());
- EXPECT_TRUE(request->maybe_sent_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_sent_cookies()
+ .front()
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
// Check maybe_sent_cookies on second round trip
request->set_maybe_sent_cookies({});
@@ -7592,11 +7837,11 @@ TEST_F(URLRequestTestHTTP, RedirectWithFilteredCookies) {
EXPECT_EQ("one_more_cookie",
request->maybe_sent_cookies().front().cookie.Name());
EXPECT_EQ("true", request->maybe_sent_cookies().front().cookie.Value());
- EXPECT_TRUE(request->maybe_sent_cookies()
- .front()
- .status.HasExactlyExclusionReasonsForTesting(
- {net::CanonicalCookie::CookieInclusionStatus::
- EXCLUDE_USER_PREFERENCES}));
+ EXPECT_TRUE(
+ request->maybe_sent_cookies()
+ .front()
+ .access_result.status.HasExactlyExclusionReasonsForTesting(
+ {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}));
}
}
@@ -8123,34 +8368,19 @@ class URLRequestTestReferrerPolicy : public URLRequestTest {
URLRequestTestReferrerPolicy() = default;
void InstantiateSameOriginServers(net::EmbeddedTestServer::Type type) {
- origin_server_.reset(new EmbeddedTestServer(type));
- if (type == net::EmbeddedTestServer::TYPE_HTTPS) {
- origin_server_->AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- } else {
- origin_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
- }
+ origin_server_ = std::make_unique<EmbeddedTestServer>(type);
+ RegisterDefaultHandlers(origin_server_.get());
ASSERT_TRUE(origin_server_->Start());
}
void InstantiateCrossOriginServers(net::EmbeddedTestServer::Type origin_type,
net::EmbeddedTestServer::Type dest_type) {
- origin_server_.reset(new EmbeddedTestServer(origin_type));
- if (origin_type == net::EmbeddedTestServer::TYPE_HTTPS) {
- origin_server_->AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- } else {
- origin_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
- }
+ origin_server_ = std::make_unique<EmbeddedTestServer>(origin_type);
+ RegisterDefaultHandlers(origin_server_.get());
ASSERT_TRUE(origin_server_->Start());
- destination_server_.reset(new EmbeddedTestServer(dest_type));
- if (dest_type == net::EmbeddedTestServer::TYPE_HTTPS) {
- destination_server_->AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- } else {
- destination_server_->AddDefaultHandlers(base::FilePath(kTestFilePath));
- }
+ destination_server_ = std::make_unique<EmbeddedTestServer>(dest_type);
+ RegisterDefaultHandlers(destination_server_.get());
ASSERT_TRUE(destination_server_->Start());
}
@@ -8454,8 +8684,7 @@ class HTTPSRequestTest : public TestWithTaskEnvironment {
TEST_F(HTTPSRequestTest, HTTPSGetTest) {
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
TestDelegate d;
@@ -8482,8 +8711,7 @@ TEST_F(HTTPSRequestTest, HTTPSGetTest) {
TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
bool err_allowed = true;
@@ -8516,8 +8744,7 @@ TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
// Iterate from false to true, just so that we do the opposite of the
@@ -8578,8 +8805,7 @@ class SSLNetErrorTestDelegate : public TestDelegate {
TEST_F(HTTPSRequestTest, SSLNetErrorReportedToDelegate) {
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
SSLNetErrorTestDelegate d;
@@ -8675,7 +8901,7 @@ TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
TransportSecurityState::STSState dynamic_sts_state;
TransportSecurityState::PKPState dynamic_pkp_state;
EXPECT_FALSE(transport_security_state.GetDynamicSTSState(
- "hsts-hpkp-preloaded.test", &dynamic_sts_state, nullptr));
+ "hsts-hpkp-preloaded.test", &dynamic_sts_state));
EXPECT_FALSE(transport_security_state.GetDynamicPKPState(
"hsts-hpkp-preloaded.test", &dynamic_pkp_state));
@@ -8704,7 +8930,7 @@ TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
TransportSecurityState::STSState new_dynamic_sts_state;
TransportSecurityState::PKPState new_dynamic_pkp_state;
EXPECT_FALSE(transport_security_state.GetDynamicSTSState(
- "hsts-hpkp-preloaded.test", &new_dynamic_sts_state, nullptr));
+ "hsts-hpkp-preloaded.test", &new_dynamic_sts_state));
EXPECT_FALSE(transport_security_state.GetDynamicPKPState(
"hsts-hpkp-preloaded.test", &new_dynamic_pkp_state));
@@ -8723,8 +8949,7 @@ TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
static const char kData[] = "hello world";
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
@@ -8909,8 +9134,7 @@ TEST_F(HTTPSRequestTest, ClientAuthNoCertificate) {
ssl_config.client_cert_type =
SSLServerConfig::ClientCertType::OPTIONAL_CLIENT_CERT;
test_server.SetSSLConfig(EmbeddedTestServer::CERT_OK, ssl_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
SSLClientAuthTestDelegate d;
@@ -8956,8 +9180,7 @@ TEST_F(HTTPSRequestTest, ClientAuth) {
ssl_config.client_cert_type =
SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
test_server.SetSSLConfig(EmbeddedTestServer::CERT_OK, ssl_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
{
@@ -9038,8 +9261,7 @@ TEST_F(HTTPSRequestTest, ClientAuthFailSigning) {
ssl_config.client_cert_type =
SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
test_server.SetSSLConfig(EmbeddedTestServer::CERT_OK, ssl_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
{
@@ -9119,8 +9341,7 @@ TEST_F(HTTPSRequestTest, ClientAuthFailSigningRetry) {
ssl_config.client_cert_type =
SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
test_server.SetSSLConfig(EmbeddedTestServer::CERT_OK, ssl_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
// Connect with a client certificate to put it in the client auth cache.
@@ -9587,8 +9808,7 @@ class HTTPSCertNetFetchingTest : public HTTPSRequestTest {
EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(cert_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
delegate->set_allow_certificate_errors(true);
@@ -10287,8 +10507,7 @@ TEST_F(HTTPSAIATest, AIAFetching) {
EmbeddedTestServer::ServerCertificateConfig cert_config;
cert_config.intermediate = EmbeddedTestServer::IntermediateType::kByAIA;
test_server.SetSSLConfig(cert_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
TestDelegate d;
@@ -10589,8 +10808,7 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
{{OCSPRevocationStatus::GOOD,
EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}});
test_server.SetSSLConfig(cert_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
CertVerifier::Config cert_verifier_config = GetCertVerifierConfig();
@@ -10629,8 +10847,7 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevokedBySubject) {
{{OCSPRevocationStatus::GOOD,
EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}});
test_server.SetSSLConfig(cert_config);
- test_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server);
ASSERT_TRUE(test_server.Start());
std::string common_name = test_server.GetCertificate()->subject().common_name;
@@ -10705,8 +10922,7 @@ TEST_F(HTTPSLocalCRLSetTest, KnownInterceptionBlocked) {
// Verify the connection succeeds without being flagged.
EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&https_server);
https_server.SetSSLConfig(EmbeddedTestServer::CERT_OK_BY_INTERMEDIATE);
ASSERT_TRUE(https_server.Start());
@@ -11770,8 +11986,7 @@ class HTTPSEarlyDataTest : public TestWithTaskEnvironment {
ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
ssl_config_.early_data_enabled = true;
test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config_);
- test_server_.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ RegisterDefaultHandlers(&test_server_);
test_server_.RegisterRequestHandler(
base::BindRepeating(&HandleZeroRTTRequest));
test_server_.SetConnectionListener(&listener_);
diff --git a/chromium/net/websockets/websocket_channel.cc b/chromium/net/websockets/websocket_channel.cc
index dea22fcf40c..67365d39c64 100644
--- a/chromium/net/websockets/websocket_channel.cc
+++ b/chromium/net/websockets/websocket_channel.cc
@@ -44,8 +44,6 @@ namespace {
using base::StreamingUtf8Validator;
-const int kDefaultSendQuotaLowWaterMark = 1 << 16;
-const int kDefaultSendQuotaHighWaterMark = 1 << 17;
const size_t kWebSocketCloseCodeLength = 2;
// Timeout for waiting for the server to acknowledge a closing handshake.
const int kClosingHandshakeTimeoutSeconds = 60;
@@ -286,9 +284,6 @@ WebSocketChannel::WebSocketChannel(
URLRequestContext* url_request_context)
: event_interface_(std::move(event_interface)),
url_request_context_(url_request_context),
- send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark),
- send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark),
- current_send_quota_(0),
closing_handshake_timeout_(
base::TimeDelta::FromSeconds(kClosingHandshakeTimeoutSeconds)),
underlying_connection_close_timeout_(base::TimeDelta::FromSeconds(
@@ -354,12 +349,6 @@ WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
}
DCHECK_EQ(state_, CONNECTED);
- if (buffer_size > base::checked_cast<size_t>(current_send_quota_)) {
- // TODO(ricea): Kill renderer.
- FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, "");
- return CHANNEL_DELETED;
- // |this| has been deleted.
- }
DCHECK(WebSocketFrameHeader::IsKnownDataOpCode(op_code))
<< "Got SendFrame with bogus op_code " << op_code << " fin=" << fin
@@ -381,11 +370,7 @@ WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
sending_text_message_ = !fin;
DCHECK(!fin || state == StreamingUtf8Validator::VALID_ENDPOINT);
}
- current_send_quota_ -= buffer_size;
- // TODO(ricea): If current_send_quota_ has dropped below
- // send_quota_low_water_mark_, it might be good to increase the "low
- // water mark" and "high water mark", but only if the link to the WebSocket
- // server is not saturated.
+
return SendFrameInternal(fin, op_code, std::move(buffer), buffer_size);
// |this| may have been deleted.
}
@@ -519,12 +504,8 @@ void WebSocketChannel::OnConnectSuccess(
// |stream_request_| is not used once the connection has succeeded.
stream_request_.reset();
- // TODO(ricea): Get flow control information from the WebSocketStream once we
- // have a multiplexing WebSocketStream.
- current_send_quota_ = send_quota_high_water_mark_;
event_interface_->OnAddChannelResponse(
- std::move(response), stream_->GetSubProtocol(), stream_->GetExtensions(),
- send_quota_high_water_mark_);
+ std::move(response), stream_->GetSubProtocol(), stream_->GetExtensions());
// |this| may have been deleted after OnAddChannelResponse.
}
@@ -599,21 +580,7 @@ ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) {
return WriteFrames();
} else {
data_being_sent_.reset();
- if (current_send_quota_ < send_quota_low_water_mark_) {
- // TODO(ricea): Increase low_water_mark and high_water_mark if
- // throughput is high, reduce them if throughput is low. Low water
- // mark needs to be >= the bandwidth delay product *of the IPC
- // channel*. Because factors like context-switch time, thread wake-up
- // time, and bus speed come into play it is complex and probably needs
- // to be determined empirically.
- DCHECK_LE(send_quota_low_water_mark_, send_quota_high_water_mark_);
- // TODO(ricea): Truncate quota by the quota specified by the remote
- // server, if the protocol in use supports quota.
- int fresh_quota = send_quota_high_water_mark_ - current_send_quota_;
- current_send_quota_ += fresh_quota;
- event_interface_->OnSendFlowControlQuotaAdded(fresh_quota);
- return CHANNEL_ALIVE;
- }
+ event_interface_->OnSendDataFrameDone();
}
return CHANNEL_ALIVE;
@@ -961,8 +928,6 @@ ChannelState WebSocketChannel::SendFrameInternal(
if (data_being_sent_) {
// Either the link to the WebSocket server is saturated, or several messages
// are being sent in a batch.
- // TODO(ricea): Keep some statistics to work out the situation and adjust
- // quota appropriately.
if (!data_to_send_next_)
data_to_send_next_ = std::make_unique<SendBuffer>();
data_to_send_next_->AddFrame(std::move(frame), std::move(buffer));
@@ -1016,6 +981,7 @@ ChannelState WebSocketChannel::SendClose(uint16_t code,
std::copy(
reason.begin(), reason.end(), body->data() + kWebSocketCloseCodeLength);
}
+
return SendFrameInternal(true, WebSocketFrameHeader::kOpCodeClose,
std::move(body), size);
}
diff --git a/chromium/net/websockets/websocket_channel.h b/chromium/net/websockets/websocket_channel.h
index d05207e8bc3..d5e78537456 100644
--- a/chromium/net/websockets/websocket_channel.h
+++ b/chromium/net/websockets/websocket_channel.h
@@ -118,12 +118,6 @@ class NET_EXPORT WebSocketChannel {
ChannelState StartClosingHandshake(uint16_t code, const std::string& reason)
WARN_UNUSED_RESULT;
- // Returns the current send quota. This value is unsafe to use outside of the
- // browser IO thread because it changes asynchronously. The value is only
- // valid for the execution of the current Task or until SendFrame() is called,
- // whichever happens sooner.
- int current_send_quota() const { return current_send_quota_; }
-
// Starts the connection process, using a specified creator callback rather
// than the default. This is exposed for testing.
void SendAddChannelRequestForTesting(
@@ -359,17 +353,6 @@ class NET_EXPORT WebSocketChannel {
// during the connection process.
std::unique_ptr<WebSocketStreamRequest> stream_request_;
- // If the renderer's send quota reaches this level, it is sent a quota
- // refresh. "quota units" are currently bytes. TODO(ricea): Update the
- // definition of quota units when necessary.
- int send_quota_low_water_mark_;
- // The level the quota is refreshed to when it reaches the low_water_mark
- // (quota units).
- int send_quota_high_water_mark_;
- // The current amount of quota that the renderer has available for sending
- // on this logical channel (quota units).
- int current_send_quota_;
-
// Timer for the closing handshake.
base::OneShotTimer close_timer_;
diff --git a/chromium/net/websockets/websocket_channel_test.cc b/chromium/net/websockets/websocket_channel_test.cc
index 07f90d5b23b..b0c3478692a 100644
--- a/chromium/net/websockets/websocket_channel_test.cc
+++ b/chromium/net/websockets/websocket_channel_test.cc
@@ -131,15 +131,6 @@ const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL
};
const size_t kBinaryBlobSize = base::size(kBinaryBlob);
-// The amount of quota a new connection gets by default.
-// TODO(ricea): If kDefaultSendQuotaHighWaterMark changes, then this value will
-// need to be updated.
-const size_t kDefaultInitialQuota = 1 << 17;
-// The amount of bytes we need to send after the initial connection to trigger a
-// quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or
-// kDefaultSendQuotaLowWaterMark change.
-const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1;
-
const int kVeryBigTimeoutMillis = 60 * 60 * 24 * 1000;
// TestTimeouts::tiny_timeout() is 100ms! I could run halfway around the world
@@ -167,17 +158,16 @@ class MockWebSocketEventInterface : public WebSocketEventInterface {
}
MOCK_METHOD1(OnCreateURLRequest, void(URLRequest*));
- MOCK_METHOD4(OnAddChannelResponse,
+ MOCK_METHOD3(OnAddChannelResponse,
void(std::unique_ptr<WebSocketHandshakeResponseInfo> response,
const std::string&,
- const std::string&,
- int64_t)); // NOLINT
+ const std::string&)); // NOLINT
MOCK_METHOD3(OnDataFrameVector,
void(bool,
WebSocketMessageType,
const std::vector<char>&)); // NOLINT
MOCK_METHOD0(HasPendingDataFrames, bool(void)); // NOLINT
- MOCK_METHOD1(OnSendFlowControlQuotaAdded, void(int64_t)); // NOLINT
+ MOCK_METHOD0(OnSendDataFrameDone, void(void)); // NOLINT
MOCK_METHOD0(OnClosingHandshake, void(void)); // NOLINT
MOCK_METHOD1(OnFailChannel, void(const std::string&)); // NOLINT
MOCK_METHOD3(OnDropChannel,
@@ -225,13 +215,12 @@ class FakeWebSocketEventInterface : public WebSocketEventInterface {
void OnAddChannelResponse(
std::unique_ptr<WebSocketHandshakeResponseInfo> response,
const std::string& selected_protocol,
- const std::string& extensions,
- int64_t send_flow_control_quota) override {}
+ const std::string& extensions) override {}
void OnDataFrame(bool fin,
WebSocketMessageType type,
base::span<const char> data_span) override {}
+ void OnSendDataFrameDone() override {}
bool HasPendingDataFrames() override { return false; }
- void OnSendFlowControlQuotaAdded(int64_t quota) override {}
void OnClosingHandshake() override {}
void OnFailChannel(const std::string& message) override {}
void OnDropChannel(bool was_clean,
@@ -930,11 +919,12 @@ class WebSocketChannelStreamTest : public WebSocketChannelEventInterfaceTest {
// whether these methods are called or not.
EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber());
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _))
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _))
.Times(AnyNumber());
EXPECT_CALL(*event_interface_, OnDataFrameVector(_, _, _))
.Times(AnyNumber());
EXPECT_CALL(*event_interface_, OnClosingHandshake()).Times(AnyNumber());
+ EXPECT_CALL(*event_interface_, OnSendDataFrameDone()).Times(AnyNumber());
EXPECT_CALL(*event_interface_, OnFailChannel(_)).Times(AnyNumber());
EXPECT_CALL(*event_interface_, OnDropChannel(_, _, _)).Times(AnyNumber());
}
@@ -961,8 +951,9 @@ class WebSocketChannelSendUtf8Test
set_stream(std::make_unique<WriteableFakeWebSocketStream>());
// For the purpose of the tests using this fixture, it doesn't matter
// whether these methods are called or not.
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _))
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _))
.Times(AnyNumber());
+ EXPECT_CALL(*event_interface_, OnSendDataFrameDone()).Times(AnyNumber());
}
};
@@ -1006,7 +997,7 @@ TEST_F(WebSocketChannelTest, EverythingIsPassedToTheCreatorFunction) {
TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) {
// false means success.
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, "", "", _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, "", ""));
CreateChannelAndConnect();
@@ -1031,7 +1022,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) {
}
TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) {
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, "Bob", "", _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, "Bob", ""));
CreateChannelAndConnect();
@@ -1044,7 +1035,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) {
TEST_F(WebSocketChannelEventInterfaceTest, ExtensionsPassed) {
EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, "", "extension1, extension2", _));
+ OnAddChannelResponse(_, "", "extension1, extension2"));
CreateChannelAndConnect();
@@ -1066,7 +1057,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText,
AsVector("HELLO")));
@@ -1088,7 +1079,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnClosingHandshake());
EXPECT_CALL(
*event_interface_,
@@ -1112,7 +1103,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ShouldCloseWhileNoDataFrames) {
Checkpoint checkpoint;
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, HasPendingDataFrames())
.WillOnce(Return(false))
.WillOnce(Return(true))
@@ -1142,7 +1133,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _));
}
@@ -1161,7 +1152,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(checkpoint, Call(1));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText,
@@ -1188,7 +1179,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText,
AsVector("HELLO")));
@@ -1226,7 +1217,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(false, WebSocketFrameHeader::kOpCodeText,
AsVector("THREE")));
@@ -1259,7 +1250,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, nullptr}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText, AsVector("")));
@@ -1274,7 +1265,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _));
}
@@ -1291,7 +1282,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _));
}
@@ -1310,7 +1301,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnFailChannel(
@@ -1331,7 +1322,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnFailChannel("Unrecognized frame opcode: 4"));
}
@@ -1360,7 +1351,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(false, WebSocketFrameHeader::kOpCodeText,
AsVector("SPLIT ")));
@@ -1382,7 +1373,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, nullptr}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
CreateChannelAndConnectSuccessfully();
base::RunLoop().RunUntilIdle();
@@ -1400,7 +1391,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnFailChannel(
@@ -1411,105 +1402,13 @@ TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) {
base::RunLoop().RunUntilIdle();
}
-// If the renderer sends lots of small writes, we don't want to update the quota
-// for each one.
-TEST_F(WebSocketChannelEventInterfaceTest, SmallWriteDoesntUpdateQuota) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- {
- InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
- }
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer("B"), 1U),
- WebSocketChannel::CHANNEL_ALIVE);
-}
-
-// If we send enough to go below |send_quota_low_water_mark_| we should get our
-// quota refreshed.
-TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- // We use this checkpoint object to verify that the quota update comes after
- // the write.
- Checkpoint checkpoint;
- {
- InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
- EXPECT_CALL(checkpoint, Call(1));
- EXPECT_CALL(*event_interface_, OnSendFlowControlQuotaAdded(_));
- EXPECT_CALL(checkpoint, Call(2));
- }
-
- CreateChannelAndConnectSuccessfully();
- checkpoint.Call(1);
- EXPECT_EQ(
- channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultInitialQuota, 'B')),
- kDefaultInitialQuota),
- WebSocketChannel::CHANNEL_ALIVE);
- checkpoint.Call(2);
-}
-
-// Verify that our quota actually is refreshed when we are told it is.
-TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- Checkpoint checkpoint;
- {
- InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
- EXPECT_CALL(checkpoint, Call(1));
- EXPECT_CALL(*event_interface_, OnSendFlowControlQuotaAdded(_));
- EXPECT_CALL(checkpoint, Call(2));
- // If quota was not really refreshed, we would get an OnDropChannel()
- // message.
- EXPECT_CALL(*event_interface_, OnSendFlowControlQuotaAdded(_));
- EXPECT_CALL(checkpoint, Call(3));
- }
-
- CreateChannelAndConnectSuccessfully();
- checkpoint.Call(1);
- EXPECT_EQ(channel_->SendFrame(
- true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultQuotaRefreshTrigger, 'D')),
- kDefaultQuotaRefreshTrigger),
- WebSocketChannel::CHANNEL_ALIVE);
- checkpoint.Call(2);
- // We should have received more quota at this point.
- EXPECT_EQ(channel_->SendFrame(
- true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultQuotaRefreshTrigger, 'E')),
- kDefaultQuotaRefreshTrigger),
- WebSocketChannel::CHANNEL_ALIVE);
- checkpoint.Call(3);
-}
-
-// If we send more than the available quota then the connection will be closed
-// with an error.
-TEST_F(WebSocketChannelEventInterfaceTest, WriteOverQuotaIsRejected) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- {
- InSequence s;
- EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, _, _, kDefaultInitialQuota));
- EXPECT_CALL(*event_interface_, OnFailChannel("Send quota exceeded"));
- }
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(channel_->SendFrame(
- true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultInitialQuota + 1, 'C')),
- kDefaultInitialQuota + 1),
- WebSocketChannel::CHANNEL_DELETED);
-}
-
// If a write fails, the channel is dropped.
TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) {
set_stream(std::make_unique<UnWriteableFakeWebSocketStream>());
Checkpoint checkpoint;
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(checkpoint, Call(1));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _));
@@ -1530,7 +1429,8 @@ TEST_F(WebSocketChannelEventInterfaceTest, SendCloseDropsChannel) {
set_stream(std::make_unique<EchoeyFakeWebSocketStream>());
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
+ EXPECT_CALL(*event_interface_, OnSendDataFrameDone());
EXPECT_CALL(*event_interface_,
OnDropChannel(true, kWebSocketNormalClosure, "Fred"));
}
@@ -1557,7 +1457,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseDuringConnection) {
// connection reset.
TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) {
set_stream(std::make_unique<ResetOnWriteFakeWebSocketStream>());
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, ""))
@@ -1581,7 +1481,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) {
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnClosingHandshake());
EXPECT_CALL(*event_interface_,
OnDropChannel(true, kWebSocketErrorNoStatusReceived, _));
@@ -1599,7 +1499,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnClosingHandshake());
EXPECT_CALL(*event_interface_,
OnDropChannel(true, kWebSocketErrorNoStatusReceived, _));
@@ -1614,7 +1514,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) {
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_WS_PROTOCOL_ERROR);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnFailChannel("Invalid frame header"));
@@ -1627,7 +1527,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) {
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_WS_PROTOCOL_ERROR);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnFailChannel("Invalid frame header"));
CreateChannelAndConnectSuccessfully();
@@ -1637,7 +1537,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) {
TEST_F(WebSocketChannelEventInterfaceTest, StartHandshakeRequest) {
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, OnStartOpeningHandshakeCalled());
}
@@ -1685,7 +1585,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataAfterCloseIsRejected) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "Payload"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
{
InSequence s;
@@ -1705,7 +1605,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OneByteClosePayloadMessage) {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, "\x03"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnFailChannel(
@@ -1723,7 +1623,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadReservedStatusMessage) {
NOT_MASKED, CLOSE_DATA(ABNORMAL_CLOSURE, "Not valid on wire")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnFailChannel(
@@ -1741,7 +1641,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) {
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnFailChannel(
@@ -1765,7 +1665,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) {
stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
std::move(raw_frames));
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnFailChannel(
"One or more reserved bits are on: reserved1 = 1, "
@@ -1782,7 +1682,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_IO_PENDING);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
// This checkpoint object verifies that the OnDropChannel message comes after
// the timeout.
Checkpoint checkpoint;
@@ -1818,7 +1718,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
Checkpoint checkpoint;
TestClosure completion;
{
@@ -1877,7 +1777,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, SingleFrameMessage) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText,
AsVector("FOUR")));
@@ -1899,7 +1799,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, EmptyMessage) {
set_stream(std::move(stream));
{
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText,
AsVector("FIRST MESSAGE")));
@@ -1933,7 +1833,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
set_stream(std::move(stream));
Checkpoint checkpoint;
InSequence s;
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_, HasPendingDataFrames()).WillOnce(Return(true));
EXPECT_CALL(checkpoint, Call(1));
EXPECT_CALL(*event_interface_, HasPendingDataFrames())
@@ -2283,26 +2183,6 @@ TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) {
std::move(write_callback).Run(OK);
}
-// When the renderer sends more on a channel than it has quota for, we send the
-// remote server a kWebSocketErrorGoingAway error code.
-TEST_F(WebSocketChannelStreamTest, SendGoingAwayOnRendererQuotaExceeded) {
- static const InitFrame expected[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
- MASKED, CLOSE_DATA(GOING_AWAY, "")}};
- EXPECT_CALL(*mock_stream_, ReadFramesInternal(_, _))
- .WillOnce(Return(ERR_IO_PENDING));
- EXPECT_CALL(*mock_stream_, WriteFramesInternal(EqualsFrames(expected), _))
- .WillOnce(Return(OK));
- EXPECT_CALL(*mock_stream_, Close());
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(channel_->SendFrame(
- true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultInitialQuota + 1, 'C')),
- kDefaultInitialQuota + 1),
- WebSocketChannel::CHANNEL_DELETED);
-}
-
// For convenience, most of these tests use Text frames. However, the WebSocket
// protocol also has Binary frames and those need to be 8-bit clean. For the
// sake of completeness, this test verifies that they are.
@@ -2345,7 +2225,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) {
stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
std::move(frames));
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _, _));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnDataFrameVector(
@@ -2477,8 +2357,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReceivedInvalidUtf8) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, _, _, kDefaultInitialQuota));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnFailChannel("Could not decode a text frame as UTF-8."));
@@ -2667,8 +2546,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, BogusContinuation) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, _, _, kDefaultInitialQuota));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnDataFrameVector(false, WebSocketFrameHeader::kOpCodeBinary,
AsVector("frame1")));
@@ -2689,8 +2567,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MessageStartingWithContinuation) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, _, _, kDefaultInitialQuota));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(*event_interface_,
OnFailChannel("Received unexpected continuation frame."));
@@ -2709,8 +2586,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataFramesNonEmptyOrFinal) {
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
set_stream(std::move(stream));
- EXPECT_CALL(*event_interface_,
- OnAddChannelResponse(_, _, _, kDefaultInitialQuota));
+ EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _));
EXPECT_CALL(
*event_interface_,
OnDataFrameVector(true, WebSocketFrameHeader::kOpCodeText, AsVector("")));
@@ -2925,30 +2801,5 @@ TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) {
completion.WaitForResult();
}
-// Verify that current_send_quota() returns a non-zero value for a newly
-// connected channel.
-TEST_F(WebSocketChannelTest, CurrentSendQuotaNonZero) {
- CreateChannelAndConnectSuccessfully();
- EXPECT_GT(channel_->current_send_quota(), 0);
-}
-
-// Verify that current_send_quota() is updated when SendFrame() is called.
-TEST_F(WebSocketChannelTest, CurrentSendQuotaUpdated) {
- const int kMessageSize = 5;
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- CreateChannelAndConnectSuccessfully();
-
- int initial_send_quota = channel_->current_send_quota();
- EXPECT_GE(initial_send_quota, kMessageSize);
-
- EXPECT_EQ(channel_->SendFrame(
- true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(static_cast<size_t>(kMessageSize), 'a')),
- static_cast<size_t>(kMessageSize)),
- WebSocketChannel::CHANNEL_ALIVE);
- int new_send_quota = channel_->current_send_quota();
- EXPECT_EQ(kMessageSize, initial_send_quota - new_send_quota);
-}
-
} // namespace
} // namespace net
diff --git a/chromium/net/websockets/websocket_deflate_parameters.h b/chromium/net/websockets/websocket_deflate_parameters.h
index 1898e1d7a12..f5653e28006 100644
--- a/chromium/net/websockets/websocket_deflate_parameters.h
+++ b/chromium/net/websockets/websocket_deflate_parameters.h
@@ -9,7 +9,7 @@
#include <string>
-#include "base/logging.h"
+#include "base/check.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_deflater.h"
#include "net/websockets/websocket_extension.h"
diff --git a/chromium/net/websockets/websocket_end_to_end_test.cc b/chromium/net/websockets/websocket_end_to_end_test.cc
index caf50d9e26d..27e9cc34aa0 100644
--- a/chromium/net/websockets/websocket_end_to_end_test.cc
+++ b/chromium/net/websockets/websocket_end_to_end_test.cc
@@ -100,8 +100,7 @@ class ConnectTestingEventInterface : public WebSocketEventInterface {
void OnAddChannelResponse(
std::unique_ptr<WebSocketHandshakeResponseInfo> response,
const std::string& selected_subprotocol,
- const std::string& extensions,
- int64_t send_flow_control_quota) override;
+ const std::string& extensions) override;
void OnDataFrame(bool fin,
WebSocketMessageType type,
@@ -109,7 +108,7 @@ class ConnectTestingEventInterface : public WebSocketEventInterface {
bool HasPendingDataFrames() override { return false; }
- void OnSendFlowControlQuotaAdded(int64_t quota) override;
+ void OnSendDataFrameDone() override;
void OnClosingHandshake() override;
@@ -170,8 +169,7 @@ std::string ConnectTestingEventInterface::extensions() const {
void ConnectTestingEventInterface::OnAddChannelResponse(
std::unique_ptr<WebSocketHandshakeResponseInfo> response,
const std::string& selected_subprotocol,
- const std::string& extensions,
- int64_t send_flow_control_quota) {
+ const std::string& extensions) {
selected_subprotocol_ = selected_subprotocol;
extensions_ = extensions;
QuitNestedEventLoop();
@@ -182,7 +180,7 @@ void ConnectTestingEventInterface::OnDataFrame(bool fin,
base::span<const char> payload) {
}
-void ConnectTestingEventInterface::OnSendFlowControlQuotaAdded(int64_t quota) {}
+void ConnectTestingEventInterface::OnSendDataFrameDone() {}
void ConnectTestingEventInterface::OnClosingHandshake() {}
diff --git a/chromium/net/websockets/websocket_event_interface.h b/chromium/net/websockets/websocket_event_interface.h
index 63eb1b4fa4b..df55472067e 100644
--- a/chromium/net/websockets/websocket_event_interface.h
+++ b/chromium/net/websockets/websocket_event_interface.h
@@ -48,8 +48,7 @@ class NET_EXPORT WebSocketEventInterface {
virtual void OnAddChannelResponse(
std::unique_ptr<WebSocketHandshakeResponseInfo> response,
const std::string& selected_subprotocol,
- const std::string& extensions,
- int64_t send_flow_control_quota) = 0;
+ const std::string& extensions) = 0;
// Called when a data frame has been received from the remote host and needs
// to be forwarded to the renderer process.
@@ -64,9 +63,9 @@ class NET_EXPORT WebSocketEventInterface {
// out. The network service should not read more from network until that.
virtual bool HasPendingDataFrames() = 0;
- // Called to provide more send quota for this channel to the renderer
- // process.
- virtual void OnSendFlowControlQuotaAdded(int64_t quota) = 0;
+ // Called once for each call to SendFrame() once the frame has been passed to
+ // the OS.
+ virtual void OnSendDataFrameDone() = 0;
// Called when the remote server has Started the WebSocket Closing
// Handshake. The client should not attempt to send any more messages after
diff --git a/chromium/net/websockets/websocket_stream_cookie_test.cc b/chromium/net/websockets/websocket_stream_cookie_test.cc
index d1e9aca194d..f2e105f23d2 100644
--- a/chromium/net/websockets/websocket_stream_cookie_test.cc
+++ b/chromium/net/websockets/websocket_stream_cookie_test.cc
@@ -15,6 +15,7 @@
#include "net/base/isolation_info.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/canonical_cookie_test_helpers.h"
+#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_util.h"
#include "net/http/http_request_headers.h"
@@ -85,11 +86,10 @@ class WebSocketStreamClientUseCookieTest
base::RunLoop().RunUntilIdle();
}
- static void SetCookieHelperFunction(
- const base::RepeatingClosure& task,
- base::WeakPtr<bool> weak_is_called,
- base::WeakPtr<bool> weak_result,
- CanonicalCookie::CookieInclusionStatus status) {
+ static void SetCookieHelperFunction(const base::RepeatingClosure& task,
+ base::WeakPtr<bool> weak_is_called,
+ base::WeakPtr<bool> weak_result,
+ CookieInclusionStatus status) {
*weak_is_called = true;
*weak_result = status.IsInclude();
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
@@ -122,10 +122,10 @@ class WebSocketStreamServerSetCookieTest
base::OnceClosure task,
base::WeakPtr<bool> weak_is_called,
base::WeakPtr<CookieList> weak_result,
- const CookieStatusList& cookie_list,
- const CookieStatusList& excluded_cookies) {
+ const CookieAccessResultList& cookie_list,
+ const CookieAccessResultList& excluded_cookies) {
*weak_is_called = true;
- *weak_result = cookie_util::StripStatuses(cookie_list);
+ *weak_result = cookie_util::StripAccessResults(cookie_list);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
}
};
diff --git a/chromium/net/websockets/websocket_stream_test.cc b/chromium/net/websockets/websocket_stream_test.cc
index d4dfb6f582b..7784392afa2 100644
--- a/chromium/net/websockets/websocket_stream_test.cc
+++ b/chromium/net/websockets/websocket_stream_test.cc
@@ -1749,5 +1749,45 @@ TEST_P(WebSocketStreamCreateTest, ContinueSSLRequestAfterDelete) {
ssl_error_callbacks_->ContinueSSLRequest();
}
+TEST_P(WebSocketStreamCreateTest, HandleConnectionCloseInFirstSegment) {
+ std::string request =
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
+
+ // The response headers are immediately followed by a close frame, length 11,
+ // code 1013, reason "Try Again".
+ std::string close_body = "\x03\xf5Try Again";
+ std::string response = WebSocketStandardResponse(std::string()) + "\x88" +
+ static_cast<char>(close_body.size()) + close_body;
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, response.data(), response.size(), 1),
+ MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2),
+ };
+ MockWrite writes[] = {MockWrite(SYNCHRONOUS, 0, request.c_str())};
+ std::unique_ptr<SequencedSocketData> socket_data(
+ BuildSocketData(reads, writes));
+ socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(),
+ HttpRequestHeaders(), std::move(socket_data));
+ WaitUntilConnectDone();
+ ASSERT_TRUE(stream_);
+
+ std::vector<std::unique_ptr<WebSocketFrame>> frames;
+ TestCompletionCallback callback1;
+ int rv1 = stream_->ReadFrames(&frames, callback1.callback());
+ rv1 = callback1.GetResult(rv1);
+ ASSERT_THAT(rv1, IsOk());
+ ASSERT_EQ(1U, frames.size());
+ EXPECT_EQ(frames[0]->header.opcode, WebSocketFrameHeader::kOpCodeClose);
+ EXPECT_TRUE(frames[0]->header.final);
+ EXPECT_EQ(close_body,
+ std::string(frames[0]->payload, frames[0]->header.payload_length));
+
+ std::vector<std::unique_ptr<WebSocketFrame>> empty_frames;
+ TestCompletionCallback callback2;
+ int rv2 = stream_->ReadFrames(&empty_frames, callback2.callback());
+ rv2 = callback2.GetResult(rv2);
+ ASSERT_THAT(rv2, IsError(ERR_CONNECTION_CLOSED));
+}
+
} // namespace
} // namespace net