summaryrefslogtreecommitdiff
path: root/chromium/net
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-31 16:33:43 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-06 16:33:22 +0000
commitda51f56cc21233c2d30f0fe0d171727c3102b2e0 (patch)
tree4e579ab70ce4b19bee7984237f3ce05a96d59d83 /chromium/net
parentc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (diff)
downloadqtwebengine-chromium-da51f56cc21233c2d30f0fe0d171727c3102b2e0.tar.gz
BASELINE: Update Chromium to 65.0.3525.40
Also imports missing submodules Change-Id: I36901b7c6a325cda3d2c10cedb2186c25af3b79b Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/net')
-rw-r--r--chromium/net/BUILD.gn92
-rw-r--r--chromium/net/android/network_library.cc16
-rw-r--r--chromium/net/base/fuzzer_test_support.cc5
-rw-r--r--chromium/net/base/hash_value.cc84
-rw-r--r--chromium/net/base/hash_value.h49
-rw-r--r--chromium/net/base/hex_utils.cc2
-rw-r--r--chromium/net/base/mime_sniffer_fuzzer.cc23
-rw-r--r--chromium/net/base/net_error_list.h7
-rw-r--r--chromium/net/base/network_change_notifier.cc12
-rw-r--r--chromium/net/base/network_change_notifier.h3
-rw-r--r--chromium/net/base/network_throttle_manager_impl.cc9
-rw-r--r--chromium/net/base/network_throttle_manager_impl.h4
-rw-r--r--chromium/net/base/network_throttle_manager_impl_unittest.cc12
-rw-r--r--chromium/net/base/platform_mime_util_win.cc2
-rw-r--r--chromium/net/base/port_util.cc3
-rw-r--r--chromium/net/base/prioritized_dispatcher_unittest.cc6
-rw-r--r--chromium/net/base/proxy_delegate.h33
-rw-r--r--chromium/net/base/test_proxy_delegate.cc73
-rw-r--r--chromium/net/base/test_proxy_delegate.h56
-rw-r--r--chromium/net/base/upload_element_reader.h5
-rw-r--r--chromium/net/base/url_util.cc6
-rw-r--r--chromium/net/base/url_util.h8
-rw-r--r--chromium/net/base/url_util_unittest.cc86
-rw-r--r--chromium/net/cert/asn1_util.cc29
-rw-r--r--chromium/net/cert/asn1_util.h7
-rw-r--r--chromium/net/cert/caching_cert_verifier_unittest.cc19
-rw-r--r--chromium/net/cert/cert_verifier.cc16
-rw-r--r--chromium/net/cert/cert_verifier.h4
-rw-r--r--chromium/net/cert/cert_verifier_unittest.cc8
-rw-r--r--chromium/net/cert/cert_verify_proc.cc94
-rw-r--r--chromium/net/cert/cert_verify_proc_android.cc13
-rw-r--r--chromium/net/cert/cert_verify_proc_android_unittest.cc17
-rw-r--r--chromium/net/cert/cert_verify_proc_builtin.cc39
-rw-r--r--chromium/net/cert/cert_verify_proc_mac.cc32
-rw-r--r--chromium/net/cert/cert_verify_proc_mac_unittest.cc26
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.cc48
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.h9
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc442
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc20
-rw-r--r--chromium/net/cert/cert_verify_result.h6
-rw-r--r--chromium/net/cert/crl_set.cc72
-rw-r--r--chromium/net/cert/crl_set.h31
-rw-r--r--chromium/net/cert/crl_set_storage.cc128
-rw-r--r--chromium/net/cert/crl_set_storage.h10
-rw-r--r--chromium/net/cert/crl_set_unittest.cc55
-rw-r--r--chromium/net/cert/ct_log_response_parser.cc5
-rw-r--r--chromium/net/cert/ct_objects_extractor.cc46
-rw-r--r--chromium/net/cert/ct_objects_extractor.h16
-rw-r--r--chromium/net/cert/ct_objects_extractor_unittest.cc28
-rw-r--r--chromium/net/cert/ct_verifier.h20
-rw-r--r--chromium/net/cert/do_nothing_ct_verifier.cc5
-rw-r--r--chromium/net/cert/do_nothing_ct_verifier.h4
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.cc39
-rw-r--r--chromium/net/cert/ev_root_ca_metadata.h9
-rw-r--r--chromium/net/cert/internal/revocation_checker.cc6
-rw-r--r--chromium/net/cert/internal/system_trust_store.cc3
-rw-r--r--chromium/net/cert/internal/trust_store_mac.cc2
-rw-r--r--chromium/net/cert/internal/trust_store_mac_unittest.cc2
-rw-r--r--chromium/net/cert/internal/verify_name_match_unittest.cc12
-rw-r--r--chromium/net/cert/known_roots.cc6
-rw-r--r--chromium/net/cert/known_roots_mac.cc2
-rw-r--r--chromium/net/cert/known_roots_nss.cc69
-rw-r--r--chromium/net/cert/merkle_tree_leaf.cc8
-rw-r--r--chromium/net/cert/merkle_tree_leaf_unittest.cc2
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.cc34
-rw-r--r--chromium/net/cert/multi_log_ct_verifier.h10
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc39
-rw-r--r--chromium/net/cert/nss_cert_database_unittest.cc7
-rw-r--r--chromium/net/cert/nss_profile_filter_chromeos_unittest.cc5
-rw-r--r--chromium/net/cert/symantec_certs.cc23
-rw-r--r--chromium/net/cert/symantec_certs.h17
-rw-r--r--chromium/net/cert/symantec_certs_unittest.cc12
-rw-r--r--chromium/net/cert/test_root_certs_android.cc8
-rw-r--r--chromium/net/cert/test_root_certs_fuchsia.cc4
-rw-r--r--chromium/net/cert/test_root_certs_mac.cc6
-rw-r--r--chromium/net/cert/test_root_certs_win.cc9
-rw-r--r--chromium/net/cert/x509_certificate.cc273
-rw-r--r--chromium/net/cert/x509_certificate.h136
-rw-r--r--chromium/net/cert/x509_certificate_unittest.cc207
-rw-r--r--chromium/net/cert/x509_util.cc118
-rw-r--r--chromium/net/cert/x509_util.h20
-rw-r--r--chromium/net/cert/x509_util_android.cc14
-rw-r--r--chromium/net/cert/x509_util_ios.cc15
-rw-r--r--chromium/net/cert/x509_util_ios_and_mac.cc11
-rw-r--r--chromium/net/cert/x509_util_ios_and_mac_unittest.cc84
-rw-r--r--chromium/net/cert/x509_util_mac.cc15
-rw-r--r--chromium/net/cert/x509_util_nss.cc30
-rw-r--r--chromium/net/cert/x509_util_nss_unittest.cc61
-rw-r--r--chromium/net/cert/x509_util_win.cc22
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc1
-rwxr-xr-xchromium/net/data/gencerts/__init__.py525
-rwxr-xr-xchromium/net/data/gencerts/openssl_conf.py136
-rw-r--r--chromium/net/data/ssl/certificates/README23
-rw-r--r--chromium/net/data/ssl/certificates/common_name_only.pem109
-rw-r--r--chromium/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.rawbin0 -> 182 bytes
-rw-r--r--chromium/net/data/ssl/certificates/crlset_by_root_subject.rawbin0 -> 228 bytes
-rw-r--r--chromium/net/data/ssl/certificates/crlset_by_root_subject_no_spki.rawbin0 -> 182 bytes
-rw-r--r--chromium/net/data/ssl/certificates/dec_2017.pem84
-rw-r--r--chromium/net/data/ssl/certificates/quic-chain.pem147
-rw-r--r--chromium/net/data/ssl/certificates/quic-leaf-cert.keybin0 -> 1219 bytes
-rw-r--r--chromium/net/data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem28
-rw-r--r--chromium/net/data/ssl/certificates/quic-leaf-cert.key.sct (renamed from chromium/net/data/ssl/certificates/quic_test.example.com.key.sct)bin33 -> 33 bytes
-rw-r--r--chromium/net/data/ssl/certificates/quic-root.pem18
-rw-r--r--chromium/net/data/ssl/certificates/quic_chain.crt226
-rw-r--r--chromium/net/data/ssl/certificates/quic_intermediate.crt75
-rw-r--r--chromium/net/data/ssl/certificates/quic_intermediate.key27
-rw-r--r--chromium/net/data/ssl/certificates/quic_root.crt74
-rw-r--r--chromium/net/data/ssl/certificates/quic_root.key27
-rw-r--r--chromium/net/data/ssl/certificates/quic_test.example.com.crt77
-rw-r--r--chromium/net/data/ssl/certificates/quic_test.example.com.key27
-rw-r--r--chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8bin1218 -> 0 bytes
-rw-r--r--chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8.pem28
-rw-r--r--chromium/net/data/ssl/certificates/quic_test_ecc.example.com.crt60
-rw-r--r--chromium/net/data/ssl/certificates/quic_test_ecc.example.com.key5
-rw-r--r--chromium/net/data/ssl/certificates/quic_test_ecc.example.com.sctbin37 -> 0 bytes
-rw-r--r--chromium/net/data/ssl/certificates/sha1_leaf.pem112
-rwxr-xr-xchromium/net/data/ssl/scripts/crlsetutil.py41
-rw-r--r--chromium/net/data/ssl/scripts/ee.cnf3
-rwxr-xr-xchromium/net/data/ssl/scripts/generate-quic-chain.sh97
-rwxr-xr-xchromium/net/data/ssl/scripts/generate-test-certs.sh87
-rw-r--r--chromium/net/data/ssl/scripts/quic-test.cnf.txt54
-rw-r--r--chromium/net/data/ssl/symantec/README.md30
-rw-r--r--chromium/net/data/ssl/symantec/excluded/8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem103
-rw-r--r--chromium/net/data/ssl/symantec/excluded/b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem76
-rw-r--r--chromium/net/data/ssl/symantec/managed/7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem73
-rw-r--r--chromium/net/data/ssl/symantec/managed/ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem103
-rw-r--r--chromium/net/der/parser.cc31
-rw-r--r--chromium/net/der/parser_unittest.cc21
-rw-r--r--chromium/net/der/tag.cc7
-rw-r--r--chromium/net/der/tag.h73
-rw-r--r--chromium/net/disk_cache/OWNERS2
-rw-r--r--chromium/net/disk_cache/backend_unittest.cc11
-rw-r--r--chromium/net/disk_cache/blockfile/file.h2
-rw-r--r--chromium/net/disk_cache/blockfile/file_posix.cc59
-rw-r--r--chromium/net/disk_cache/blockfile/file_win.cc42
-rw-r--r--chromium/net/disk_cache/blockfile/mapped_file_win.cc2
-rw-r--r--chromium/net/disk_cache/blockfile/rankings.cc5
-rw-r--r--chromium/net/disk_cache/blockfile/sparse_control.cc115
-rw-r--r--chromium/net/disk_cache/disk_cache_perftest.cc406
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.cc4
-rw-r--r--chromium/net/disk_cache/disk_cache_test_base.h3
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.cc3
-rw-r--r--chromium/net/disk_cache/disk_cache_test_util.h4
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc179
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.cc80
-rw-r--r--chromium/net/disk_cache/simple/simple_backend_impl.h19
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc42
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.h11
-rw-r--r--chromium/net/disk_cache/simple/simple_histogram_macros.h1
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.cc7
-rw-r--r--chromium/net/disk_cache/simple/simple_synchronous_entry.h4
-rw-r--r--chromium/net/dns/address_sorter_posix_unittest.cc7
-rw-r--r--chromium/net/dns/dns_config_service.h2
-rw-r--r--chromium/net/dns/dns_config_service_posix.cc48
-rw-r--r--chromium/net/dns/dns_config_service_win.cc3
-rw-r--r--chromium/net/dns/dns_hosts.cc5
-rw-r--r--chromium/net/dns/dns_hosts.h5
-rw-r--r--chromium/net/dns/dns_transaction.cc82
-rw-r--r--chromium/net/dns/dns_transaction_unittest.cc73
-rw-r--r--chromium/net/dns/host_cache.cc36
-rw-r--r--chromium/net/dns/host_cache.h10
-rw-r--r--chromium/net/dns/host_resolver.h19
-rw-r--r--chromium/net/dns/host_resolver_impl.cc27
-rw-r--r--chromium/net/dns/host_resolver_impl.h16
-rw-r--r--chromium/net/dns/host_resolver_mojo.cc18
-rw-r--r--chromium/net/dns/host_resolver_mojo.h7
-rw-r--r--chromium/net/dns/mapped_host_resolver.cc19
-rw-r--r--chromium/net/dns/mapped_host_resolver.h9
-rw-r--r--chromium/net/dns/mdns_client_impl.cc13
-rw-r--r--chromium/net/dns/mdns_client_impl.h4
-rw-r--r--chromium/net/dns/mdns_client_unittest.cc15
-rw-r--r--chromium/net/dns/mock_host_resolver.cc49
-rw-r--r--chromium/net/dns/mock_host_resolver.h20
-rw-r--r--chromium/net/dns/mojo_host_struct_traits.cc37
-rw-r--r--chromium/net/dns/mojo_host_struct_traits.h9
-rw-r--r--chromium/net/dns/serial_worker_unittest.cc11
-rw-r--r--chromium/net/ftp/ftp_network_transaction.cc14
-rw-r--r--chromium/net/ftp/ftp_network_transaction.h5
-rw-r--r--chromium/net/ftp/ftp_network_transaction_unittest.cc36
-rw-r--r--chromium/net/ftp/ftp_transaction.h4
-rw-r--r--chromium/net/http/OWNERS3
-rw-r--r--chromium/net/http/http_basic_state.cc8
-rw-r--r--chromium/net/http/http_basic_state.h4
-rw-r--r--chromium/net/http/http_basic_state_unittest.cc8
-rw-r--r--chromium/net/http/http_basic_stream.cc8
-rw-r--r--chromium/net/http/http_basic_stream.h1
-rw-r--r--chromium/net/http/http_cache.cc78
-rw-r--r--chromium/net/http/http_cache.h51
-rw-r--r--chromium/net/http/http_cache_transaction.cc44
-rw-r--r--chromium/net/http/http_cache_transaction.h7
-rw-r--r--chromium/net/http/http_cache_unittest.cc181
-rw-r--r--chromium/net/http/http_cache_writers.cc30
-rw-r--r--chromium/net/http/http_cache_writers.h17
-rw-r--r--chromium/net/http/http_cache_writers_unittest.cc60
-rw-r--r--chromium/net/http/http_network_session.cc38
-rw-r--r--chromium/net/http/http_network_session.h17
-rw-r--r--chromium/net/http/http_network_session_peer.cc5
-rw-r--r--chromium/net/http/http_network_session_peer.h2
-rw-r--r--chromium/net/http/http_network_transaction.cc22
-rw-r--r--chromium/net/http/http_network_transaction.h3
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc356
-rw-r--r--chromium/net/http/http_proxy_client_socket.cc43
-rw-r--r--chromium/net/http/http_proxy_client_socket.h15
-rw-r--r--chromium/net/http/http_proxy_client_socket_fuzzer.cc7
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.cc55
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.h39
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool_unittest.cc243
-rw-r--r--chromium/net/http/http_proxy_client_socket_unittest.cc44
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.cc52
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.h12
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc46
-rw-r--r--chromium/net/http/http_request_info.h4
-rw-r--r--chromium/net/http/http_response_body_drainer_unittest.cc1
-rw-r--r--chromium/net/http/http_security_headers_unittest.cc4
-rw-r--r--chromium/net/http/http_server_properties.h7
-rw-r--r--chromium/net/http/http_server_properties_impl.cc11
-rw-r--r--chromium/net/http/http_server_properties_impl.h5
-rw-r--r--chromium/net/http/http_server_properties_impl_unittest.cc24
-rw-r--r--chromium/net/http/http_server_properties_manager.cc43
-rw-r--r--chromium/net/http/http_server_properties_manager.h20
-rw-r--r--chromium/net/http/http_server_properties_manager_unittest.cc31
-rw-r--r--chromium/net/http/http_stream.h5
-rw-r--r--chromium/net/http/http_stream_factory_impl.cc78
-rw-r--r--chromium/net/http/http_stream_factory_impl.h16
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.cc105
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.h33
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller.cc69
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller.h12
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc383
-rw-r--r--chromium/net/http/http_stream_factory_impl_request_unittest.cc1
-rw-r--r--chromium/net/http/http_stream_factory_impl_unittest.cc91
-rw-r--r--chromium/net/http/http_stream_factory_test_util.cc14
-rw-r--r--chromium/net/http/http_stream_factory_test_util.h4
-rw-r--r--chromium/net/http/http_stream_parser.cc25
-rw-r--r--chromium/net/http/http_stream_parser.h4
-rw-r--r--chromium/net/http/http_stream_parser_fuzzer.cc7
-rw-r--r--chromium/net/http/http_stream_parser_unittest.cc52
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.cc1
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.h1
-rw-r--r--chromium/net/http/transport_security_persister_unittest.cc2
-rw-r--r--chromium/net/http/transport_security_state.cc34
-rw-r--r--chromium/net/http/transport_security_state_ct_policies.inc13
-rw-r--r--chromium/net/http/transport_security_state_static.json2736
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc110
-rw-r--r--chromium/net/http2/decoder/decode_buffer_test.cc2
-rw-r--r--chromium/net/http2/decoder/http2_frame_decoder_listener_test_util.cc6
-rw-r--r--chromium/net/http2/decoder/http2_frame_decoder_test.cc48
-rw-r--r--chromium/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h14
-rw-r--r--chromium/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc4
-rw-r--r--chromium/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc4
-rw-r--r--chromium/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_block_collector.cc4
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_listener.cc8
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_state.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_state_test.cc1
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc4
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_tables.cc11
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_tables.h3
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_tables_test.cc3
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_test.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_entry_collector.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc2
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc4
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_whole_entry_listener.cc4
-rw-r--r--chromium/net/http2/hpack/hpack_string.cc4
-rw-r--r--chromium/net/http2/hpack/http2_hpack_constants.h3
-rw-r--r--chromium/net/http2/hpack/huffman/hpack_huffman_decoder.cc4
-rw-r--r--chromium/net/http2/test_tools/frame_parts.cc340
-rw-r--r--chromium/net/http2/test_tools/frame_parts.h147
-rw-r--r--chromium/net/http2/test_tools/frame_parts_collector.cc6
-rw-r--r--chromium/net/http2/tools/random_decoder_test.cc2
-rw-r--r--chromium/net/interfaces/BUILD.gn4
-rw-r--r--chromium/net/interfaces/address_family.mojom12
-rw-r--r--chromium/net/interfaces/address_family.typemap14
-rw-r--r--chromium/net/interfaces/address_family_traits.cc45
-rw-r--r--chromium/net/interfaces/address_family_traits.h23
-rw-r--r--chromium/net/interfaces/host_resolver.typemap1
-rw-r--r--chromium/net/interfaces/host_resolver_service.mojom8
-rw-r--r--chromium/net/interfaces/typemaps.gni1
-rw-r--r--chromium/net/log/file_net_log_observer.cc4
-rw-r--r--chromium/net/log/net_log.cc3
-rw-r--r--chromium/net/log/net_log_entry.cc4
-rw-r--r--chromium/net/log/net_log_event_type_list.h12
-rw-r--r--chromium/net/log/net_log_unittest.cc8
-rw-r--r--chromium/net/log/net_log_util.cc2
-rw-r--r--chromium/net/log/test_net_log.cc7
-rw-r--r--chromium/net/log/test_net_log_entry.cc3
-rw-r--r--chromium/net/log/trace_net_log_observer.cc2
-rw-r--r--chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc232
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.cc40
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.h7
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service_unittest.cc44
-rw-r--r--chromium/net/nqe/OWNERS5
-rw-r--r--chromium/net/nqe/cached_network_quality.h2
-rw-r--r--chromium/net/nqe/network_id.cc31
-rw-r--r--chromium/net/nqe/network_id.h12
-rw-r--r--chromium/net/nqe/network_id_unittest.cc3
-rw-r--r--chromium/net/nqe/network_qualities_prefs_manager.cc16
-rw-r--r--chromium/net/nqe/network_qualities_prefs_manager_unittest.cc115
-rw-r--r--chromium/net/nqe/network_quality.cc24
-rw-r--r--chromium/net/nqe/network_quality.h29
-rw-r--r--chromium/net/nqe/network_quality_estimator.cc472
-rw-r--r--chromium/net/nqe/network_quality_estimator.h44
-rw-r--r--chromium/net/nqe/network_quality_estimator_params.cc133
-rw-r--r--chromium/net/nqe/network_quality_estimator_params.h62
-rw-r--r--chromium/net/nqe/network_quality_estimator_params_unittest.cc83
-rw-r--r--chromium/net/nqe/network_quality_estimator_test_util.cc37
-rw-r--r--chromium/net/nqe/network_quality_estimator_test_util.h23
-rw-r--r--chromium/net/nqe/network_quality_estimator_unittest.cc599
-rw-r--r--chromium/net/nqe/network_quality_store.cc72
-rw-r--r--chromium/net/nqe/network_quality_store.h14
-rw-r--r--chromium/net/nqe/network_quality_store_unittest.cc109
-rw-r--r--chromium/net/nqe/observation_buffer_unittest.cc5
-rw-r--r--chromium/net/nqe/proto/network_id_proto.proto10
-rw-r--r--chromium/net/nqe/throughput_analyzer.cc47
-rw-r--r--chromium/net/nqe/throughput_analyzer.h6
-rw-r--r--chromium/net/nqe/throughput_analyzer_unittest.cc82
-rw-r--r--chromium/net/ntlm/ntlm_buffer_reader.cc2
-rw-r--r--chromium/net/ntlm/ntlm_buffer_writer.cc2
-rw-r--r--chromium/net/ntlm/ntlm_client.cc2
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher.cc8
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc4
-rw-r--r--chromium/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc2
-rw-r--r--chromium/net/proxy/dhcpcsvc_init_win.cc2
-rw-r--r--chromium/net/proxy/mock_proxy_resolver.cc10
-rw-r--r--chromium/net/proxy/mock_proxy_script_fetcher.cc2
-rw-r--r--chromium/net/proxy/multi_threaded_proxy_resolver.cc6
-rw-r--r--chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc2
-rw-r--r--chromium/net/proxy/network_delegate_error_observer.cc3
-rw-r--r--chromium/net/proxy/network_delegate_error_observer_unittest.cc2
-rw-r--r--chromium/net/proxy/pac_js_library.h282
-rw-r--r--chromium/net/proxy/polling_proxy_config_service.cc2
-rw-r--r--chromium/net/proxy/proxy_bypass_rules.cc9
-rw-r--r--chromium/net/proxy/proxy_config.cc6
-rw-r--r--chromium/net/proxy/proxy_config_service_fixed.cc2
-rw-r--r--chromium/net/proxy/proxy_config_service_linux.cc465
-rw-r--r--chromium/net/proxy/proxy_config_service_linux_unittest.cc20
-rw-r--r--chromium/net/proxy/proxy_config_source.cc1
-rw-r--r--chromium/net/proxy/proxy_config_source.h1
-rw-r--r--chromium/net/proxy/proxy_info.cc13
-rw-r--r--chromium/net/proxy/proxy_info.h15
-rw-r--r--chromium/net/proxy/proxy_list.cc6
-rw-r--r--chromium/net/proxy/proxy_resolver_factory.cc3
-rw-r--r--chromium/net/proxy/proxy_resolver_script.h278
-rw-r--r--chromium/net/proxy/proxy_resolver_script_data.cc2
-rw-r--r--chromium/net/proxy/proxy_resolver_v8.cc12
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc15
-rw-r--r--chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc15
-rw-r--r--chromium/net/proxy/proxy_script_decider_unittest.cc8
-rw-r--r--chromium/net/proxy/proxy_script_fetcher_impl.cc16
-rw-r--r--chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc12
-rw-r--r--chromium/net/proxy/proxy_service.cc61
-rw-r--r--chromium/net/proxy/proxy_service.h35
-rw-r--r--chromium/net/proxy/proxy_service_unittest.cc62
-rw-r--r--chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc138
-rw-r--r--chromium/net/quic/chromium/crypto/proof_source_chromium.cc9
-rw-r--r--chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc18
-rw-r--r--chromium/net/quic/chromium/crypto/proof_verifier_chromium.h4
-rw-r--r--chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc84
-rw-r--r--chromium/net/quic/chromium/crypto_test_utils_chromium.cc14
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session.cc195
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session.h55
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session_test.cc128
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_stream_test.cc14
-rw-r--r--chromium/net/quic/chromium/quic_connection_logger.cc44
-rw-r--r--chromium/net/quic/chromium/quic_connection_logger.h2
-rw-r--r--chromium/net/quic/chromium/quic_end_to_end_unittest.cc10
-rw-r--r--chromium/net/quic/chromium/quic_http_stream.cc17
-rw-r--r--chromium/net/quic/chromium/quic_http_stream.h4
-rw-r--r--chromium/net/quic/chromium/quic_http_stream_test.cc178
-rw-r--r--chromium/net/quic/chromium/quic_http_utils.cc5
-rw-r--r--chromium/net/quic/chromium/quic_http_utils_test.cc6
-rw-r--r--chromium/net/quic/chromium/quic_network_transaction_unittest.cc320
-rw-r--r--chromium/net/quic/chromium/quic_proxy_client_socket.cc28
-rw-r--r--chromium/net/quic/chromium/quic_proxy_client_socket.h9
-rw-r--r--chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc68
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory.cc130
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory.h45
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory_fuzzer.cc56
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory_peer.cc7
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory_test.cc403
-rw-r--r--chromium/net/quic/chromium/quic_test_packet_maker.cc96
-rw-r--r--chromium/net/quic/chromium/quic_test_packet_maker.h24
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender.cc62
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender.h3
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender_test.cc61
-rw-r--r--chromium/net/quic/core/congestion_control/cubic.cc227
-rw-r--r--chromium/net/quic/core/congestion_control/cubic.h144
-rw-r--r--chromium/net/quic/core/congestion_control/cubic_bytes.cc75
-rw-r--r--chromium/net/quic/core/congestion_control/cubic_bytes.h40
-rw-r--r--chromium/net/quic/core/congestion_control/cubic_bytes_test.cc203
-rw-r--r--chromium/net/quic/core/congestion_control/cubic_test.cc367
-rw-r--r--chromium/net/quic/core/congestion_control/general_loss_algorithm.cc2
-rw-r--r--chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc2
-rw-r--r--chromium/net/quic/core/congestion_control/send_algorithm_interface.cc2
-rw-r--r--chromium/net/quic/core/congestion_control/send_algorithm_test.cc62
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.cc262
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.h158
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc234
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h87
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc11
-rw-r--r--chromium/net/quic/core/crypto/aead_base_decrypter.cc11
-rw-r--r--chromium/net/quic/core/crypto/aead_base_decrypter.h2
-rw-r--r--chromium/net/quic/core/crypto/aead_base_encrypter.cc7
-rw-r--r--chromium/net/quic/core/crypto/aead_base_encrypter.h1
-rw-r--r--chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter.cc8
-rw-r--r--chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc5
-rw-r--r--chromium/net/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc3
-rw-r--r--chromium/net/quic/core/crypto/aes_128_gcm_decrypter_test.cc5
-rw-r--r--chromium/net/quic/core/crypto/aes_128_gcm_encrypter_test.cc3
-rw-r--r--chromium/net/quic/core/crypto/aes_256_gcm_decrypter_test.cc5
-rw-r--r--chromium/net/quic/core/crypto/aes_256_gcm_encrypter_test.cc3
-rw-r--r--chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc8
-rw-r--r--chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc2
-rw-r--r--chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc9
-rw-r--r--chromium/net/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc2
-rw-r--r--chromium/net/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc9
-rw-r--r--chromium/net/quic/core/crypto/common_cert_set.cc8
-rw-r--r--chromium/net/quic/core/crypto/crypto_framer_test.cc25
-rw-r--r--chromium/net/quic/core/crypto/crypto_handshake_message.cc32
-rw-r--r--chromium/net/quic/core/crypto/crypto_protocol.h5
-rw-r--r--chromium/net/quic/core/crypto/crypto_server_test.cc124
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils.cc40
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils.h17
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils_test.cc22
-rw-r--r--chromium/net/quic/core/crypto/null_decrypter.cc8
-rw-r--r--chromium/net/quic/core/crypto/null_decrypter.h2
-rw-r--r--chromium/net/quic/core/crypto/null_decrypter_test.cc13
-rw-r--r--chromium/net/quic/core/crypto/null_encrypter.cc4
-rw-r--r--chromium/net/quic/core/crypto/null_encrypter.h1
-rw-r--r--chromium/net/quic/core/crypto/null_encrypter_test.cc9
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_client_config.cc17
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_client_config.h8
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc69
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_server_config.cc39
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_server_config.h12
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc19
-rw-r--r--chromium/net/quic/core/crypto/quic_decrypter.cc37
-rw-r--r--chromium/net/quic/core/crypto/quic_decrypter.h13
-rw-r--r--chromium/net/quic/core/crypto/quic_encrypter.cc31
-rw-r--r--chromium/net/quic/core/crypto/quic_encrypter.h11
-rw-r--r--chromium/net/quic/core/crypto/quic_tls_adapter_test.cc15
-rw-r--r--chromium/net/quic/core/frames/quic_ack_frame.cc369
-rw-r--r--chromium/net/quic/core/frames/quic_ack_frame.h183
-rw-r--r--chromium/net/quic/core/frames/quic_frame.cc26
-rw-r--r--chromium/net/quic/core/frames/quic_frame.h4
-rw-r--r--chromium/net/quic/core/frames/quic_frames_test.cc155
-rw-r--r--chromium/net/quic/core/quic_client_promised_info_test.cc4
-rw-r--r--chromium/net/quic/core/quic_client_push_promise_index_test.cc4
-rw-r--r--chromium/net/quic/core/quic_config.cc2
-rw-r--r--chromium/net/quic/core/quic_connection.cc85
-rw-r--r--chromium/net/quic/core/quic_connection.h34
-rw-r--r--chromium/net/quic/core/quic_connection_test.cc205
-rw-r--r--chromium/net/quic/core/quic_constants.h11
-rw-r--r--chromium/net/quic/core/quic_control_frame_manager.cc27
-rw-r--r--chromium/net/quic/core/quic_crypto_client_handshaker.cc26
-rw-r--r--chromium/net/quic/core/quic_crypto_client_stream.cc19
-rw-r--r--chromium/net/quic/core/quic_crypto_client_stream_test.cc53
-rw-r--r--chromium/net/quic/core/quic_crypto_handshaker.cc2
-rw-r--r--chromium/net/quic/core/quic_crypto_server_handshaker.cc11
-rw-r--r--chromium/net/quic/core/quic_crypto_server_handshaker.h2
-rw-r--r--chromium/net/quic/core/quic_crypto_server_stream.cc20
-rw-r--r--chromium/net/quic/core/quic_crypto_server_stream.h1
-rw-r--r--chromium/net/quic/core/quic_crypto_server_stream_test.cc37
-rw-r--r--chromium/net/quic/core/quic_crypto_stream.cc61
-rw-r--r--chromium/net/quic/core/quic_crypto_stream.h15
-rw-r--r--chromium/net/quic/core/quic_crypto_stream_test.cc77
-rw-r--r--chromium/net/quic/core/quic_data_writer_test.cc19
-rw-r--r--chromium/net/quic/core/quic_error_codes.cc3
-rw-r--r--chromium/net/quic/core/quic_error_codes.h9
-rw-r--r--chromium/net/quic/core/quic_flags_list.h99
-rw-r--r--chromium/net/quic/core/quic_framer.cc235
-rw-r--r--chromium/net/quic/core/quic_framer.h36
-rw-r--r--chromium/net/quic/core/quic_framer_test.cc300
-rw-r--r--chromium/net/quic/core/quic_headers_stream.cc6
-rw-r--r--chromium/net/quic/core/quic_headers_stream.h3
-rw-r--r--chromium/net/quic/core/quic_headers_stream_test.cc89
-rw-r--r--chromium/net/quic/core/quic_packet_creator.cc9
-rw-r--r--chromium/net/quic/core/quic_packet_creator.h2
-rw-r--r--chromium/net/quic/core/quic_packet_creator_test.cc26
-rw-r--r--chromium/net/quic/core/quic_packet_generator.cc2
-rw-r--r--chromium/net/quic/core/quic_packet_generator.h2
-rw-r--r--chromium/net/quic/core/quic_packet_generator_test.cc17
-rw-r--r--chromium/net/quic/core/quic_packets.cc5
-rw-r--r--chromium/net/quic/core/quic_packets.h4
-rw-r--r--chromium/net/quic/core/quic_received_packet_manager.cc2
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager.cc21
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager.h2
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager_test.cc65
-rw-r--r--chromium/net/quic/core/quic_server_id.h3
-rw-r--r--chromium/net/quic/core/quic_server_id_test.cc18
-rw-r--r--chromium/net/quic/core/quic_server_session_base_test.cc27
-rw-r--r--chromium/net/quic/core/quic_session.cc135
-rw-r--r--chromium/net/quic/core/quic_session.h27
-rw-r--r--chromium/net/quic/core/quic_session_test.cc126
-rw-r--r--chromium/net/quic/core/quic_socket_address_coder_test.cc3
-rw-r--r--chromium/net/quic/core/quic_spdy_session.cc50
-rw-r--r--chromium/net/quic/core/quic_spdy_session.h25
-rw-r--r--chromium/net/quic/core/quic_spdy_stream_test.cc41
-rw-r--r--chromium/net/quic/core/quic_stream.cc180
-rw-r--r--chromium/net/quic/core/quic_stream.h50
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer.cc141
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer.h51
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer_test.cc134
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer.cc8
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_buffer.cc138
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_buffer.h31
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc75
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_test.cc74
-rw-r--r--chromium/net/quic/core/quic_stream_test.cc335
-rw-r--r--chromium/net/quic/core/quic_tag.cc6
-rw-r--r--chromium/net/quic/core/quic_unacked_packet_map.cc32
-rw-r--r--chromium/net/quic/core/quic_unacked_packet_map.h15
-rw-r--r--chromium/net/quic/core/quic_unacked_packet_map_test.cc145
-rw-r--r--chromium/net/quic/core/quic_utils.cc15
-rw-r--r--chromium/net/quic/core/quic_version_manager.cc38
-rw-r--r--chromium/net/quic/core/quic_version_manager.h26
-rw-r--r--chromium/net/quic/core/quic_version_manager_test.cc29
-rw-r--r--chromium/net/quic/core/quic_versions.cc126
-rw-r--r--chromium/net/quic/core/quic_versions.h63
-rw-r--r--chromium/net/quic/core/quic_versions_test.cc132
-rw-r--r--chromium/net/quic/core/session_notifier_interface.h32
-rw-r--r--chromium/net/quic/core/stream_notifier_interface.h33
-rw-r--r--chromium/net/quic/core/tls_client_handshaker.cc40
-rw-r--r--chromium/net/quic/core/tls_client_handshaker.h9
-rw-r--r--chromium/net/quic/core/tls_handshaker.cc87
-rw-r--r--chromium/net/quic/core/tls_handshaker.h27
-rw-r--r--chromium/net/quic/core/tls_handshaker_test.cc33
-rw-r--r--chromium/net/quic/core/tls_server_handshaker.cc34
-rw-r--r--chromium/net/quic/core/tls_server_handshaker.h5
-rw-r--r--chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc15
-rw-r--r--chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.h4
-rw-r--r--chromium/net/quic/platform/api/quic_aligned.h1
-rw-r--r--chromium/net/quic/platform/api/quic_arraysize.h12
-rw-r--r--chromium/net/quic/platform/api/quic_bug_tracker.h2
-rw-r--r--chromium/net/quic/platform/api/quic_flags.h5
-rw-r--r--chromium/net/quic/platform/api/quic_hostname_utils.cc6
-rw-r--r--chromium/net/quic/platform/api/quic_hostname_utils.h6
-rw-r--r--chromium/net/quic/platform/api/quic_hostname_utils_test.cc3
-rw-r--r--chromium/net/quic/platform/api/quic_mem_slice_span_test.cc6
-rw-r--r--chromium/net/quic/platform/api/quic_prefetch.h39
-rw-r--r--chromium/net/quic/platform/api/quic_reference_counted.h4
-rw-r--r--chromium/net/quic/platform/impl/quic_aligned_impl.h3
-rw-r--r--chromium/net/quic/platform/impl/quic_arraysize_impl.h10
-rw-r--r--chromium/net/quic/platform/impl/quic_bug_tracker_impl.h2
-rw-r--r--chromium/net/quic/platform/impl/quic_flags_impl.h13
-rw-r--r--chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc13
-rw-r--r--chromium/net/quic/platform/impl/quic_hostname_utils_impl.h5
-rw-r--r--chromium/net/quic/platform/impl/quic_prefetch_impl.h24
-rw-r--r--chromium/net/quic/platform/impl/quic_text_utils_impl.h2
-rw-r--r--chromium/net/quic/quartc/quartc_factory.cc9
-rw-r--r--chromium/net/quic/quartc/quartc_packet_writer.cc8
-rw-r--r--chromium/net/quic/quartc/quartc_packet_writer.h10
-rw-r--r--chromium/net/quic/quartc/quartc_session.cc10
-rw-r--r--chromium/net/quic/quartc/quartc_session_interface.h5
-rw-r--r--chromium/net/quic/quartc/quartc_session_test.cc19
-rw-r--r--chromium/net/quic/quartc/quartc_stream_test.cc2
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils.cc52
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils.h4
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils_test.cc4
-rw-r--r--chromium/net/quic/test_tools/mock_decrypter.cc8
-rw-r--r--chromium/net/quic/test_tools/mock_decrypter.h2
-rw-r--r--chromium/net/quic/test_tools/mock_encrypter.cc4
-rw-r--r--chromium/net/quic/test_tools/mock_encrypter.h1
-rw-r--r--chromium/net/quic/test_tools/quic_spdy_session_peer.cc3
-rw-r--r--chromium/net/quic/test_tools/quic_spdy_session_peer.h2
-rw-r--r--chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc8
-rw-r--r--chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h3
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc40
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h8
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc7
-rw-r--r--chromium/net/quic/test_tools/quic_stream_sequencer_peer.h3
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.cc105
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.h79
-rw-r--r--chromium/net/quic/test_tools/quic_time_wait_list_manager_peer.cc3
-rw-r--r--chromium/net/quic/test_tools/simple_data_producer.cc18
-rw-r--r--chromium/net/quic/test_tools/simple_data_producer.h10
-rw-r--r--chromium/net/quic/test_tools/simple_quic_framer.cc8
-rw-r--r--chromium/net/quic/test_tools/simple_quic_framer.h10
-rw-r--r--chromium/net/quic/test_tools/simulator/quic_endpoint.cc2
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover.cc2
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover.h2
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover_unittest.cc119
-rw-r--r--chromium/net/reporting/reporting_cache.cc150
-rw-r--r--chromium/net/reporting/reporting_cache.h13
-rw-r--r--chromium/net/reporting/reporting_cache_unittest.cc115
-rw-r--r--chromium/net/reporting/reporting_client.cc16
-rw-r--r--chromium/net/reporting/reporting_client.h19
-rw-r--r--chromium/net/reporting/reporting_context.cc23
-rw-r--r--chromium/net/reporting/reporting_context.h20
-rw-r--r--chromium/net/reporting/reporting_delegate.cc4
-rw-r--r--chromium/net/reporting/reporting_delivery_agent.cc14
-rw-r--r--chromium/net/reporting/reporting_delivery_agent_unittest.cc48
-rw-r--r--chromium/net/reporting/reporting_endpoint_manager.cc55
-rw-r--r--chromium/net/reporting/reporting_endpoint_manager.h4
-rw-r--r--chromium/net/reporting/reporting_endpoint_manager_unittest.cc107
-rw-r--r--chromium/net/reporting/reporting_garbage_collector.cc9
-rw-r--r--chromium/net/reporting/reporting_header_parser.cc78
-rw-r--r--chromium/net/reporting/reporting_header_parser_fuzzer.cc6
-rw-r--r--chromium/net/reporting/reporting_header_parser_unittest.cc78
-rw-r--r--chromium/net/reporting/reporting_network_change_observer.cc2
-rw-r--r--chromium/net/reporting/reporting_network_change_observer_unittest.cc23
-rw-r--r--chromium/net/reporting/reporting_observer.cc4
-rw-r--r--chromium/net/reporting/reporting_persister.cc321
-rw-r--r--chromium/net/reporting/reporting_persister.h29
-rw-r--r--chromium/net/reporting/reporting_persister_unittest.cc84
-rw-r--r--chromium/net/reporting/reporting_policy.cc17
-rw-r--r--chromium/net/reporting/reporting_service.cc21
-rw-r--r--chromium/net/reporting/reporting_service.h7
-rw-r--r--chromium/net/reporting/reporting_service_unittest.cc6
-rw-r--r--chromium/net/reporting/reporting_test_util.cc76
-rw-r--r--chromium/net/reporting/reporting_test_util.h35
-rw-r--r--chromium/net/reporting/reporting_uploader.cc27
-rw-r--r--chromium/net/reporting/reporting_uploader.h8
-rw-r--r--chromium/net/reporting/reporting_uploader_unittest.cc47
-rw-r--r--chromium/net/server/http_server_unittest.cc11
-rw-r--r--chromium/net/socket/client_socket_handle.h9
-rw-r--r--chromium/net/socket/client_socket_pool.h1
-rw-r--r--chromium/net/socket/client_socket_pool_base.cc29
-rw-r--r--chromium/net/socket/client_socket_pool_base.h22
-rw-r--r--chromium/net/socket/client_socket_pool_base_unittest.cc288
-rw-r--r--chromium/net/socket/client_socket_pool_manager.cc52
-rw-r--r--chromium/net/socket/client_socket_pool_manager.h1
-rw-r--r--chromium/net/socket/datagram_client_socket.h3
-rw-r--r--chromium/net/socket/fuzzed_datagram_client_socket.cc11
-rw-r--r--chromium/net/socket/fuzzed_datagram_client_socket.h5
-rw-r--r--chromium/net/socket/fuzzed_socket.cc11
-rw-r--r--chromium/net/socket/fuzzed_socket.h5
-rw-r--r--chromium/net/socket/fuzzed_socket_factory.cc6
-rw-r--r--chromium/net/socket/sequenced_socket_data_unittest.cc7
-rw-r--r--chromium/net/socket/socket.h11
-rw-r--r--chromium/net/socket/socket_posix.cc9
-rw-r--r--chromium/net/socket/socket_posix.h6
-rw-r--r--chromium/net/socket/socket_tag_unittest.cc63
-rw-r--r--chromium/net/socket/socket_test_util.cc261
-rw-r--r--chromium/net/socket/socket_test_util.h141
-rw-r--r--chromium/net/socket/socks5_client_socket.cc29
-rw-r--r--chromium/net/socket/socks5_client_socket.h11
-rw-r--r--chromium/net/socket/socks5_client_socket_fuzzer.cc4
-rw-r--r--chromium/net/socket/socks5_client_socket_unittest.cc33
-rw-r--r--chromium/net/socket/socks_client_socket.cc27
-rw-r--r--chromium/net/socket/socks_client_socket.h11
-rw-r--r--chromium/net/socket/socks_client_socket_fuzzer.cc5
-rw-r--r--chromium/net/socket/socks_client_socket_pool.cc30
-rw-r--r--chromium/net/socket/socks_client_socket_pool.h13
-rw-r--r--chromium/net/socket/socks_client_socket_pool_unittest.cc107
-rw-r--r--chromium/net/socket/socks_client_socket_unittest.cc77
-rw-r--r--chromium/net/socket/ssl_client_socket_impl.cc160
-rw-r--r--chromium/net/socket/ssl_client_socket_impl.h9
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.cc55
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.h2
-rw-r--r--chromium/net/socket/ssl_client_socket_pool_unittest.cc344
-rw-r--r--chromium/net/socket/ssl_client_socket_unittest.cc247
-rw-r--r--chromium/net/socket/ssl_server_socket.h6
-rw-r--r--chromium/net/socket/ssl_server_socket_impl.cc252
-rw-r--r--chromium/net/socket/ssl_server_socket_impl.h7
-rw-r--r--chromium/net/socket/ssl_server_socket_unittest.cc114
-rw-r--r--chromium/net/socket/stream_socket.h13
-rw-r--r--chromium/net/socket/tcp_client_socket.cc15
-rw-r--r--chromium/net/socket/tcp_client_socket.h14
-rw-r--r--chromium/net/socket/tcp_client_socket_unittest.cc105
-rw-r--r--chromium/net/socket/tcp_socket_posix.cc128
-rw-r--r--chromium/net/socket/tcp_socket_posix.h15
-rw-r--r--chromium/net/socket/tcp_socket_unittest.cc115
-rw-r--r--chromium/net/socket/tcp_socket_win.cc15
-rw-r--r--chromium/net/socket/tcp_socket_win.h10
-rw-r--r--chromium/net/socket/transport_client_socket_pool.cc14
-rw-r--r--chromium/net/socket/transport_client_socket_pool.h3
-rw-r--r--chromium/net/socket/transport_client_socket_pool_test_util.cc13
-rw-r--r--chromium/net/socket/transport_client_socket_pool_unittest.cc242
-rw-r--r--chromium/net/socket/udp_client_socket.cc15
-rw-r--r--chromium/net/socket/udp_client_socket.h5
-rw-r--r--chromium/net/socket/udp_socket_perftest.cc4
-rw-r--r--chromium/net/socket/udp_socket_posix.cc29
-rw-r--r--chromium/net/socket/udp_socket_posix.h15
-rw-r--r--chromium/net/socket/udp_socket_unittest.cc97
-rw-r--r--chromium/net/socket/udp_socket_win.cc20
-rw-r--r--chromium/net/socket/udp_socket_win.h10
-rw-r--r--chromium/net/socket/unix_domain_client_socket_posix.cc14
-rw-r--r--chromium/net/socket/unix_domain_client_socket_posix.h5
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc6
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.cc15
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.h1
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc119
-rw-r--r--chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc2
-rw-r--r--chromium/net/spdy/chromium/buffered_spdy_framer.cc11
-rw-r--r--chromium/net/spdy/chromium/buffered_spdy_framer.h1
-rw-r--r--chromium/net/spdy/chromium/http2_priority_dependencies.cc14
-rw-r--r--chromium/net/spdy/chromium/http2_push_promise_index.cc174
-rw-r--r--chromium/net/spdy/chromium/http2_push_promise_index.h131
-rw-r--r--chromium/net/spdy/chromium/http2_push_promise_index_test.cc552
-rw-r--r--chromium/net/spdy/chromium/multiplexed_http_stream.cc2
-rw-r--r--chromium/net/spdy/chromium/multiplexed_session.cc2
-rw-r--r--chromium/net/spdy/chromium/spdy_buffer_producer.cc6
-rw-r--r--chromium/net/spdy/chromium/spdy_flags.cc3
-rw-r--r--chromium/net/spdy/chromium/spdy_flags.h3
-rw-r--r--chromium/net/spdy/chromium/spdy_http_stream.cc12
-rw-r--r--chromium/net/spdy/chromium/spdy_http_stream.h8
-rw-r--r--chromium/net/spdy/chromium/spdy_http_stream_unittest.cc115
-rw-r--r--chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc558
-rw-r--r--chromium/net/spdy/chromium/spdy_proxy_client_socket.cc13
-rw-r--r--chromium/net/spdy/chromium/spdy_proxy_client_socket.h5
-rw-r--r--chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc36
-rw-r--r--chromium/net/spdy/chromium/spdy_session.cc217
-rw-r--r--chromium/net/spdy/chromium/spdy_session.h169
-rw-r--r--chromium/net/spdy/chromium/spdy_session_key.cc16
-rw-r--r--chromium/net/spdy/chromium/spdy_session_key.h10
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool.cc36
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool.h9
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool_unittest.cc117
-rw-r--r--chromium/net/spdy/chromium/spdy_session_unittest.cc972
-rw-r--r--chromium/net/spdy/chromium/spdy_stream.cc8
-rw-r--r--chromium/net/spdy/chromium/spdy_stream.h3
-rw-r--r--chromium/net/spdy/chromium/spdy_stream_test_util.cc17
-rw-r--r--chromium/net/spdy/chromium/spdy_stream_unittest.cc48
-rw-r--r--chromium/net/spdy/chromium/spdy_test_util_common.cc46
-rw-r--r--chromium/net/spdy/chromium/spdy_test_util_common.h13
-rw-r--r--chromium/net/spdy/chromium/spdy_write_queue.cc4
-rw-r--r--chromium/net/spdy/core/fuzzing/hpack_fuzz_util.cc10
-rw-r--r--chromium/net/spdy/core/hpack/hpack_decoder_adapter.cc4
-rw-r--r--chromium/net/spdy/core/hpack/hpack_decoder_adapter_test.cc6
-rw-r--r--chromium/net/spdy/core/hpack/hpack_encoder.cc2
-rw-r--r--chromium/net/spdy/core/hpack/hpack_encoder_test.cc4
-rw-r--r--chromium/net/spdy/core/hpack/hpack_entry.cc2
-rw-r--r--chromium/net/spdy/core/hpack/hpack_header_table.cc12
-rw-r--r--chromium/net/spdy/core/hpack/hpack_header_table_test.cc12
-rw-r--r--chromium/net/spdy/core/hpack/hpack_huffman_table.cc2
-rw-r--r--chromium/net/spdy/core/hpack/hpack_output_stream.cc2
-rw-r--r--chromium/net/spdy/core/hpack/hpack_static_table.cc4
-rw-r--r--chromium/net/spdy/core/http2_frame_decoder_adapter.cc16
-rw-r--r--chromium/net/spdy/core/http2_frame_decoder_adapter.h12
-rw-r--r--chromium/net/spdy/core/mock_spdy_framer_visitor.cc2
-rw-r--r--chromium/net/spdy/core/mock_spdy_framer_visitor.h1
-rw-r--r--chromium/net/spdy/core/spdy_alt_svc_wire_format.cc4
-rw-r--r--chromium/net/spdy/core/spdy_deframer_visitor.cc28
-rw-r--r--chromium/net/spdy/core/spdy_frame_builder.cc4
-rw-r--r--chromium/net/spdy/core/spdy_frame_builder.h2
-rw-r--r--chromium/net/spdy/core/spdy_framer.cc57
-rw-r--r--chromium/net/spdy/core/spdy_framer.h8
-rw-r--r--chromium/net/spdy/core/spdy_framer_test.cc159
-rw-r--r--chromium/net/spdy/core/spdy_header_block.cc60
-rw-r--r--chromium/net/spdy/core/spdy_header_block.h18
-rw-r--r--chromium/net/spdy/core/spdy_header_block_test.cc44
-rw-r--r--chromium/net/spdy/core/spdy_no_op_visitor.cc2
-rw-r--r--chromium/net/spdy/core/spdy_pinnable_buffer_piece.cc2
-rw-r--r--chromium/net/spdy/core/spdy_protocol.cc115
-rw-r--r--chromium/net/spdy/core/spdy_protocol.h40
-rw-r--r--chromium/net/spdy/core/spdy_test_utils.cc4
-rw-r--r--chromium/net/ssl/client_cert_identity.cc16
-rw-r--r--chromium/net/ssl/client_cert_identity.h3
-rw-r--r--chromium/net/ssl/client_cert_store_mac.cc128
-rw-r--r--chromium/net/ssl/client_cert_store_nss.cc7
-rw-r--r--chromium/net/ssl/client_cert_store_nss_unittest.cc20
-rw-r--r--chromium/net/ssl/client_cert_store_unittest-inl.h2
-rw-r--r--chromium/net/ssl/client_cert_store_win.cc13
-rw-r--r--chromium/net/ssl/openssl_ssl_util.cc9
-rw-r--r--chromium/net/ssl/ssl_client_session_cache.cc7
-rw-r--r--chromium/net/ssl/ssl_client_session_cache.h4
-rw-r--r--chromium/net/ssl/ssl_client_session_cache_unittest.cc12
-rw-r--r--chromium/net/ssl/ssl_config.cc6
-rw-r--r--chromium/net/ssl/ssl_config.h10
-rw-r--r--chromium/net/ssl/ssl_config_unittest.cc58
-rw-r--r--chromium/net/ssl/ssl_info.cc1
-rw-r--r--chromium/net/ssl/ssl_info.h4
-rw-r--r--chromium/net/ssl/ssl_platform_key_util.cc8
-rw-r--r--chromium/net/test/cert_test_util.cc11
-rw-r--r--chromium/net/test/embedded_test_server/default_handlers.cc43
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.cc4
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.h7
-rw-r--r--chromium/net/test/net_test_suite.cc12
-rw-r--r--chromium/net/test/net_test_suite.h4
-rw-r--r--chromium/net/test/python_utils.cc47
-rw-r--r--chromium/net/test/run_all_unittests.cc6
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.cc9
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.h5
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server.cc9
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.cc42
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.h1
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server_proxy.cc44
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server_proxy.h7
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc4
-rw-r--r--chromium/net/third_party/nss/ssl/cmpcert.cc4
-rw-r--r--chromium/net/tools/cachetool/cachetool.cc2
-rw-r--r--chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc23
-rw-r--r--chromium/net/tools/ct_log_list/PRESUBMIT.py11
-rw-r--r--chromium/net/tools/quic/chlo_extractor.cc7
-rw-r--r--chromium/net/tools/quic/chlo_extractor.h2
-rw-r--r--chromium/net/tools/quic/chlo_extractor_test.cc28
-rw-r--r--chromium/net/tools/quic/end_to_end_test.cc106
-rw-r--r--chromium/net/tools/quic/quic_client.cc6
-rw-r--r--chromium/net/tools/quic/quic_client.h6
-rw-r--r--chromium/net/tools/quic/quic_client_base.cc10
-rw-r--r--chromium/net/tools/quic/quic_client_base.h21
-rw-r--r--chromium/net/tools/quic/quic_client_bin.cc10
-rw-r--r--chromium/net/tools/quic/quic_client_test.cc2
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.cc65
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.h9
-rw-r--r--chromium/net/tools/quic/quic_dispatcher_test.cc141
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache.cc6
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache.h2
-rw-r--r--chromium/net/tools/quic/quic_packet_printer_bin.cc13
-rw-r--r--chromium/net/tools/quic/quic_server.cc8
-rw-r--r--chromium/net/tools/quic/quic_server.h2
-rw-r--r--chromium/net/tools/quic/quic_server_bin.cc2
-rw-r--r--chromium/net/tools/quic/quic_server_test.cc13
-rw-r--r--chromium/net/tools/quic/quic_simple_client.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_client.h2
-rw-r--r--chromium/net/tools/quic/quic_simple_client_bin.cc10
-rw-r--r--chromium/net/tools/quic/quic_simple_client_test.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_dispatcher.cc9
-rw-r--r--chromium/net/tools/quic/quic_simple_server.cc9
-rw-r--r--chromium/net/tools/quic/quic_simple_server.h2
-rw-r--r--chromium/net/tools/quic/quic_simple_server_bin.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_server_packet_writer.cc4
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.cc3
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_test.cc28
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream_test.cc34
-rw-r--r--chromium/net/tools/quic/quic_simple_server_test.cc6
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_base.cc4
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_base.h2
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_session_test.cc17
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream_test.cc4
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.cc8
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.h12
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager_test.cc17
-rw-r--r--chromium/net/tools/quic/stateless_rejector.cc4
-rw-r--r--chromium/net/tools/quic/stateless_rejector_test.cc14
-rw-r--r--chromium/net/tools/quic/test_tools/bad_packet_writer.cc36
-rw-r--r--chromium/net/tools/quic/test_tools/bad_packet_writer.h36
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h6
-rw-r--r--chromium/net/tools/quic/test_tools/packet_reordering_writer.cc2
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.cc25
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.h19
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.cc4
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_server.h2
-rw-r--r--chromium/net/tools/testserver/minica.py43
-rwxr-xr-xchromium/net/tools/testserver/testserver.py45
-rw-r--r--chromium/net/traffic_annotation/network_traffic_annotation.h6
-rw-r--r--chromium/net/url_request/network_error_logging_delegate.h7
-rw-r--r--chromium/net/url_request/url_request.cc19
-rw-r--r--chromium/net/url_request/url_request.h12
-rw-r--r--chromium/net/url_request/url_request_context.cc32
-rw-r--r--chromium/net/url_request/url_request_context.h14
-rw-r--r--chromium/net/url_request/url_request_context_builder.cc6
-rw-r--r--chromium/net/url_request/url_request_ftp_job.cc23
-rw-r--r--chromium/net/url_request/url_request_ftp_job.h2
-rw-r--r--chromium/net/url_request/url_request_http_job.cc4
-rw-r--r--chromium/net/url_request/url_request_http_job_unittest.cc1
-rw-r--r--chromium/net/url_request/url_request_quic_perftest.cc7
-rw-r--r--chromium/net/url_request/url_request_quic_unittest.cc120
-rw-r--r--chromium/net/url_request/url_request_test_util.cc4
-rw-r--r--chromium/net/url_request/url_request_throttler_manager.cc6
-rw-r--r--chromium/net/url_request/url_request_unittest.cc139
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.cc14
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.h1
-rw-r--r--chromium/net/websockets/websocket_basic_stream_test.cc3
-rw-r--r--chromium/net/websockets/websocket_end_to_end_test.cc13
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc5
-rw-r--r--chromium/net/websockets/websocket_stream.cc13
865 files changed, 25093 insertions, 13721 deletions
diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn
index cda37cb455f..7676ff4cbf8 100644
--- a/chromium/net/BUILD.gn
+++ b/chromium/net/BUILD.gn
@@ -82,15 +82,9 @@ net_configs = [
":net_internal_config",
"//build/config:precompiled_headers",
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- "//build/config/compiler:no_size_t_to_int_warning",
"//build/config/compiler:wexit_time_destructors",
]
-if (use_glib && use_gconf && !is_chromeos) {
- net_configs += [ "//build/config/linux/gconf" ]
-}
-
if (is_linux) {
net_configs += [ "//build/config/linux:libresolv" ]
}
@@ -1051,6 +1045,7 @@ component("net") {
"proxy/multi_threaded_proxy_resolver.h",
"proxy/network_delegate_error_observer.cc",
"proxy/network_delegate_error_observer.h",
+ "proxy/pac_js_library.h",
"proxy/polling_proxy_config_service.cc",
"proxy/polling_proxy_config_service.h",
"proxy/proxy_bypass_rules.cc",
@@ -1082,7 +1077,6 @@ component("net") {
"proxy/proxy_resolver_factory.h",
"proxy/proxy_resolver_mac.cc",
"proxy/proxy_resolver_mac.h",
- "proxy/proxy_resolver_script.h",
"proxy/proxy_resolver_script_data.cc",
"proxy/proxy_resolver_script_data.h",
"proxy/proxy_resolver_winhttp.cc",
@@ -1148,8 +1142,6 @@ component("net") {
"quic/core/congestion_control/bandwidth_sampler.h",
"quic/core/congestion_control/bbr_sender.cc",
"quic/core/congestion_control/bbr_sender.h",
- "quic/core/congestion_control/cubic.cc",
- "quic/core/congestion_control/cubic.h",
"quic/core/congestion_control/cubic_bytes.cc",
"quic/core/congestion_control/cubic_bytes.h",
"quic/core/congestion_control/general_loss_algorithm.cc",
@@ -1165,8 +1157,6 @@ component("net") {
"quic/core/congestion_control/rtt_stats.h",
"quic/core/congestion_control/send_algorithm_interface.cc",
"quic/core/congestion_control/send_algorithm_interface.h",
- "quic/core/congestion_control/tcp_cubic_sender_base.cc",
- "quic/core/congestion_control/tcp_cubic_sender_base.h",
"quic/core/congestion_control/tcp_cubic_sender_bytes.cc",
"quic/core/congestion_control/tcp_cubic_sender_bytes.h",
"quic/core/congestion_control/windowed_filter.h",
@@ -1436,6 +1426,7 @@ component("net") {
"quic/http/quic_http_structures.cc",
"quic/http/quic_http_structures.h",
"quic/platform/api/quic_aligned.h",
+ "quic/platform/api/quic_arraysize.h",
"quic/platform/api/quic_bug_tracker.h",
"quic/platform/api/quic_clock.cc",
"quic/platform/api/quic_clock.h",
@@ -1459,6 +1450,7 @@ component("net") {
"quic/platform/api/quic_mutex.h",
"quic/platform/api/quic_optional.h",
"quic/platform/api/quic_pcc_sender.h",
+ "quic/platform/api/quic_prefetch.h",
"quic/platform/api/quic_ptr_util.h",
"quic/platform/api/quic_reconstruct_object.h",
"quic/platform/api/quic_reference_counted.h",
@@ -1474,6 +1466,7 @@ component("net") {
"quic/platform/api/quic_url_utils.cc",
"quic/platform/api/quic_url_utils.h",
"quic/platform/impl/quic_aligned_impl.h",
+ "quic/platform/impl/quic_arraysize_impl.h",
"quic/platform/impl/quic_bug_tracker_impl.h",
"quic/platform/impl/quic_chromium_clock.cc",
"quic/platform/impl/quic_chromium_clock.h",
@@ -1499,6 +1492,7 @@ component("net") {
"quic/platform/impl/quic_mutex_impl.h",
"quic/platform/impl/quic_optional_impl.h",
"quic/platform/impl/quic_pcc_sender_impl.h",
+ "quic/platform/impl/quic_prefetch_impl.h",
"quic/platform/impl/quic_ptr_util_impl.h",
"quic/platform/impl/quic_reconstruct_object_impl.h",
"quic/platform/impl/quic_reference_counted_impl.h",
@@ -1833,8 +1827,6 @@ component("net") {
"reporting/reporting_network_change_observer.h",
"reporting/reporting_observer.cc",
"reporting/reporting_observer.h",
- "reporting/reporting_persister.cc",
- "reporting/reporting_persister.h",
"reporting/reporting_policy.cc",
"reporting/reporting_policy.h",
"reporting/reporting_report.cc",
@@ -1908,7 +1900,7 @@ component("net") {
}
if (use_gio) {
- deps += [ "//build/linux/libgio" ]
+ configs += [ "//build/linux:gio_config" ]
}
if (!use_nss_certs) {
@@ -2308,10 +2300,7 @@ static_library("http_server") {
"server/web_socket_encoder.cc",
"server/web_socket_encoder.h",
]
- configs += [
- "//build/config/compiler:no_size_t_to_int_warning",
- "//build/config/compiler:wexit_time_destructors",
- ]
+ configs += [ "//build/config/compiler:wexit_time_destructors" ]
deps = [
":net",
"//base",
@@ -2327,9 +2316,6 @@ if (!is_ios) {
"tools/dump_cache/dump_files.h",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
deps = [
":net",
":test_support",
@@ -2407,10 +2393,14 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/client_6.pk8",
"data/ssl/certificates/client_6_ca.pem",
"data/ssl/certificates/client_root_ca.pem",
+ "data/ssl/certificates/common_name_only.pem",
"data/ssl/certificates/crit-codeSigning-chain.pem",
"data/ssl/certificates/crlset_by_intermediate_serial.raw",
"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_subject.raw",
+ "data/ssl/certificates/crlset_by_root_subject_no_spki.raw",
"data/ssl/certificates/cross-signed-leaf.pem",
"data/ssl/certificates/cross-signed-root-md5.pem",
"data/ssl/certificates/cross-signed-root-sha256.pem",
@@ -2418,6 +2408,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/ct-test-embedded-with-intermediate-chain.pem",
"data/ssl/certificates/ct-test-embedded-with-intermediate-preca-chain.pem",
"data/ssl/certificates/ct-test-embedded-with-preca-chain.pem",
+ "data/ssl/certificates/dec_2017.pem",
"data/ssl/certificates/diginotar_cyber_ca.pem",
"data/ssl/certificates/diginotar_pkioverheid.pem",
"data/ssl/certificates/diginotar_pkioverheid_g2.pem",
@@ -2487,19 +2478,11 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/prime256v1-ecdsa-ee-by-prime256v1-ecdsa-intermediate.pem",
"data/ssl/certificates/prime256v1-ecdsa-intermediate.pem",
"data/ssl/certificates/punycodetest.pem",
- "data/ssl/certificates/quic_chain.crt",
- "data/ssl/certificates/quic_intermediate.crt",
- "data/ssl/certificates/quic_intermediate.key",
- "data/ssl/certificates/quic_root.crt",
- "data/ssl/certificates/quic_root.key",
- "data/ssl/certificates/quic_test.example.com.crt",
- "data/ssl/certificates/quic_test.example.com.key",
- "data/ssl/certificates/quic_test.example.com.key.pkcs8",
- "data/ssl/certificates/quic_test.example.com.key.pkcs8.pem",
- "data/ssl/certificates/quic_test.example.com.key.sct",
- "data/ssl/certificates/quic_test_ecc.example.com.crt",
- "data/ssl/certificates/quic_test_ecc.example.com.key",
- "data/ssl/certificates/quic_test_ecc.example.com.sct",
+ "data/ssl/certificates/quic-chain.pem",
+ "data/ssl/certificates/quic-leaf-cert.key",
+ "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/redundant-server-chain.pem",
"data/ssl/certificates/redundant-validated-chain-root.pem",
"data/ssl/certificates/redundant-validated-chain.pem",
@@ -2511,6 +2494,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/sha1_2016.pem",
"data/ssl/certificates/sha1_dec_2015.pem",
"data/ssl/certificates/sha1_jan_2016.pem",
+ "data/ssl/certificates/sha1_leaf.pem",
"data/ssl/certificates/spdy_pooling.pem",
"data/ssl/certificates/start_after_expiry.pem",
"data/ssl/certificates/subjectAltName_sanity_check.pem",
@@ -2665,12 +2649,7 @@ static_library("test_support") {
"url_request/url_request_test_util.h",
]
- configs += [
- "//build/config:precompiled_headers",
-
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- "//build/config/compiler:no_size_t_to_int_warning",
- ]
+ configs += [ "//build/config:precompiled_headers" ]
public_deps = [
":traffic_annotation",
@@ -2776,7 +2755,6 @@ if (use_v8_in_net) {
defines = [ "NET_IMPLEMENTATION" ]
configs += [
- "//build/config/compiler:no_size_t_to_int_warning",
"//build/config/compiler:wexit_time_destructors",
"//v8:external_startup_data",
]
@@ -2841,8 +2819,6 @@ if (!is_ios && !is_android) {
"tools/cert_verify_tool/verify_using_path_builder.h",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
":test_support",
@@ -2862,8 +2838,6 @@ if (!is_ios && !is_android) {
"tools/crash_cache/crash_cache.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
":test_support",
@@ -2879,8 +2853,6 @@ if (!is_ios && !is_android) {
"tools/crl_set_dump/crl_set_dump.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
"//base",
@@ -2895,8 +2867,6 @@ if (!is_ios && !is_android) {
"tools/dns_fuzz_stub/dns_fuzz_stub.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
"//base",
@@ -2926,8 +2896,6 @@ if (!is_ios && !is_android) {
"tools/get_server_time/get_server_time.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
"//base",
@@ -2944,8 +2912,6 @@ if (!is_ios && !is_android) {
"spdy/core/fuzzing/hpack_example_generator.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
"//base",
@@ -2991,8 +2957,6 @@ if (!is_ios && !is_android) {
"tools/stress_cache/stress_cache.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":net",
":test_support",
@@ -3007,8 +2971,6 @@ if (!is_ios && !is_android) {
"tools/tld_cleanup/tld_cleanup.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
"//base",
"//base:i18n",
@@ -3290,6 +3252,8 @@ source_set("quic_test_tools") {
if (is_linux) {
sources += [
+ "tools/quic/test_tools/bad_packet_writer.cc",
+ "tools/quic/test_tools/bad_packet_writer.h",
"tools/quic/test_tools/limited_mtu_test_writer.cc",
"tools/quic/test_tools/limited_mtu_test_writer.h",
"tools/quic/test_tools/mock_epoll_server.cc",
@@ -4036,6 +4000,7 @@ bundle_data("net_unittests_bundle_data") {
"data/verify_name_match_unittest/names/ascii-UTF8-unmangled.pem",
"data/verify_name_match_unittest/names/ascii-mixed-rdn_dupetype_sorting_1.pem",
"data/verify_name_match_unittest/names/ascii-mixed-rdn_dupetype_sorting_2.pem",
+ "data/verify_name_match_unittest/names/custom-custom-normalized.pem",
"data/verify_name_match_unittest/names/invalid-AttributeTypeAndValue-badAttributeType.pem",
"data/verify_name_match_unittest/names/invalid-AttributeTypeAndValue-empty.pem",
"data/verify_name_match_unittest/names/invalid-AttributeTypeAndValue-extradata.pem",
@@ -4887,6 +4852,7 @@ test("net_unittests") {
"http/http_network_transaction_ssl_unittest.cc",
"http/http_network_transaction_unittest.cc",
"http/http_proxy_client_socket_pool_unittest.cc",
+ "http/http_proxy_client_socket_unittest.cc",
"http/http_proxy_client_socket_wrapper_unittest.cc",
"http/http_request_headers_unittest.cc",
"http/http_response_body_drainer_unittest.cc",
@@ -5059,7 +5025,6 @@ test("net_unittests") {
"quic/core/congestion_control/bandwidth_sampler_test.cc",
"quic/core/congestion_control/bbr_sender_test.cc",
"quic/core/congestion_control/cubic_bytes_test.cc",
- "quic/core/congestion_control/cubic_test.cc",
"quic/core/congestion_control/general_loss_algorithm_test.cc",
"quic/core/congestion_control/hybrid_slow_start_test.cc",
"quic/core/congestion_control/pacing_sender_test.cc",
@@ -5332,12 +5297,7 @@ test("net_unittests") {
]
net_unfiltered_sources = []
- configs += [
- "//build/config:precompiled_headers",
-
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- "//build/config/compiler:no_size_t_to_int_warning",
- ]
+ configs += [ "//build/config:precompiled_headers" ]
defines = []
deps = [
@@ -5364,6 +5324,7 @@ test("net_unittests") {
if (enable_reporting) {
sources += [
+ "network_error_logging/network_error_logging_end_to_end_test.cc",
"network_error_logging/network_error_logging_service_unittest.cc",
"reporting/reporting_browsing_data_remover_unittest.cc",
"reporting/reporting_cache_unittest.cc",
@@ -5372,7 +5333,6 @@ test("net_unittests") {
"reporting/reporting_garbage_collector_unittest.cc",
"reporting/reporting_header_parser_unittest.cc",
"reporting/reporting_network_change_observer_unittest.cc",
- "reporting/reporting_persister_unittest.cc",
"reporting/reporting_service_unittest.cc",
"reporting/reporting_test_util.cc",
"reporting/reporting_test_util.h",
@@ -5768,8 +5728,6 @@ if (!is_ios && !is_proto_quic) {
"url_request/url_request_quic_perftest.cc",
]
- # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":extras",
":net",
diff --git a/chromium/net/android/network_library.cc b/chromium/net/android/network_library.cc
index e2cadfdc39a..494288fc696 100644
--- a/chromium/net/android/network_library.cc
+++ b/chromium/net/android/network_library.cc
@@ -62,22 +62,6 @@ void ClearTestRootCertificates() {
Java_AndroidNetworkLibrary_clearTestRootCertificates(env);
}
-bool StoreKeyPair(const uint8_t* public_key,
- size_t public_len,
- const uint8_t* private_key,
- size_t private_len) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jbyteArray> public_array =
- ToJavaByteArray(env, public_key, public_len);
- ScopedJavaLocalRef<jbyteArray> private_array =
- ToJavaByteArray(env, private_key, private_len);
- jboolean ret =
- Java_AndroidNetworkLibrary_storeKeyPair(env, public_array, private_array);
- LOG_IF(WARNING, !ret) <<
- "Call to Java_AndroidNetworkLibrary_storeKeyPair failed";
- return ret;
-}
-
bool IsCleartextPermitted(const std::string& host) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> host_string = ConvertUTF8ToJavaString(env, host);
diff --git a/chromium/net/base/fuzzer_test_support.cc b/chromium/net/base/fuzzer_test_support.cc
index 8e10957bfc5..f2a54d51686 100644
--- a/chromium/net/base/fuzzer_test_support.cc
+++ b/chromium/net/base/fuzzer_test_support.cc
@@ -6,7 +6,6 @@
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
-#include "base/metrics/statistics_recorder.h"
#include "base/test/scoped_task_environment.h"
namespace {
@@ -26,10 +25,6 @@ struct InitGlobals {
// asserting when handling non-ASCII urls.
CHECK(base::i18n::InitializeICU());
- // Prevent every call to get a Histogram* from leaking memory. Instead, only
- // the fist call to get each Histogram* leaks memory.
- base::StatisticsRecorder::Initialize();
-
// Disable noisy logging as per "libFuzzer in Chrome" documentation:
// testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
logging::SetMinLogLevel(logging::LOG_FATAL);
diff --git a/chromium/net/base/hash_value.cc b/chromium/net/base/hash_value.cc
index 7a2dbd4c7ec..80d8eecdda6 100644
--- a/chromium/net/base/hash_value.cc
+++ b/chromium/net/base/hash_value.cc
@@ -22,12 +22,12 @@ namespace {
// SHA256HashValues.
struct SHA256ToHashValueComparator {
bool operator()(const SHA256HashValue& lhs, const HashValue& rhs) const {
- DCHECK_EQ(HASH_VALUE_SHA256, rhs.tag);
+ DCHECK_EQ(HASH_VALUE_SHA256, rhs.tag());
return memcmp(lhs.data, rhs.data(), rhs.size()) < 0;
}
bool operator()(const HashValue& lhs, const SHA256HashValue& rhs) const {
- DCHECK_EQ(HASH_VALUE_SHA256, lhs.tag);
+ DCHECK_EQ(HASH_VALUE_SHA256, lhs.tag());
return memcmp(lhs.data(), rhs.data, lhs.size()) < 0;
}
};
@@ -43,7 +43,7 @@ HashValue::HashValue(const SHA256HashValue& hash)
bool HashValue::FromString(const base::StringPiece value) {
base::StringPiece base64_str;
if (value.starts_with("sha256/")) {
- tag = HASH_VALUE_SHA256;
+ tag_ = HASH_VALUE_SHA256;
base64_str = value.substr(7);
} else {
return false;
@@ -61,26 +61,26 @@ std::string HashValue::ToString() const {
std::string base64_str;
base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>(data()),
size()), &base64_str);
- switch (tag) {
- case HASH_VALUE_SHA256:
- return std::string("sha256/") + base64_str;
- default:
- NOTREACHED() << "Unknown HashValueTag " << tag;
- return std::string("unknown/" + base64_str);
+ switch (tag_) {
+ case HASH_VALUE_SHA256:
+ return std::string("sha256/") + base64_str;
}
+
+ NOTREACHED() << "Unknown HashValueTag " << tag_;
+ return std::string("unknown/" + base64_str);
}
size_t HashValue::size() const {
- switch (tag) {
+ switch (tag_) {
case HASH_VALUE_SHA256:
return sizeof(fingerprint.sha256.data);
- default:
- NOTREACHED() << "Unknown HashValueTag " << tag;
- // While an invalid tag should not happen, return a non-zero length
- // to avoid compiler warnings when the result of size() is
- // used with functions like memset.
- return sizeof(fingerprint.sha256.data);
}
+
+ NOTREACHED() << "Unknown HashValueTag " << tag_;
+ // While an invalid tag should not happen, return a non-zero length
+ // to avoid compiler warnings when the result of size() is
+ // used with functions like memset.
+ return sizeof(fingerprint.sha256.data);
}
unsigned char* HashValue::data() {
@@ -88,13 +88,55 @@ unsigned char* HashValue::data() {
}
const unsigned char* HashValue::data() const {
- switch (tag) {
+ switch (tag_) {
case HASH_VALUE_SHA256:
return fingerprint.sha256.data;
- default:
- NOTREACHED() << "Unknown HashValueTag " << tag;
- return NULL;
}
+
+ NOTREACHED() << "Unknown HashValueTag " << tag_;
+ return nullptr;
+}
+
+bool operator==(const HashValue& lhs, const HashValue& rhs) {
+ if (lhs.tag_ != rhs.tag_)
+ return false;
+
+ switch (lhs.tag_) {
+ case HASH_VALUE_SHA256:
+ return lhs.fingerprint.sha256 == rhs.fingerprint.sha256;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+bool operator!=(const HashValue& lhs, const HashValue& rhs) {
+ return !(lhs == rhs);
+}
+
+bool operator<(const HashValue& lhs, const HashValue& rhs) {
+ if (lhs.tag_ != rhs.tag_)
+ return lhs.tag_ < rhs.tag_;
+
+ switch (lhs.tag_) {
+ case HASH_VALUE_SHA256:
+ return lhs.fingerprint.sha256 < rhs.fingerprint.sha256;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+bool operator>(const HashValue& lhs, const HashValue& rhs) {
+ return rhs < lhs;
+}
+
+bool operator<=(const HashValue& lhs, const HashValue& rhs) {
+ return !(lhs > rhs);
+}
+
+bool operator>=(const HashValue& lhs, const HashValue& rhs) {
+ return !(lhs < rhs);
}
bool IsSHA256HashInSortedArray(const HashValue& hash,
@@ -108,7 +150,7 @@ bool IsAnySHA256HashInSortedArray(const HashValueVector& hashes,
const SHA256HashValue* list,
size_t list_length) {
for (const auto& hash : hashes) {
- if (hash.tag != HASH_VALUE_SHA256)
+ if (hash.tag() != HASH_VALUE_SHA256)
continue;
if (IsSHA256HashInSortedArray(hash, list, list_length))
diff --git a/chromium/net/base/hash_value.h b/chromium/net/base/hash_value.h
index 52732ebd5d7..f01181d1cba 100644
--- a/chromium/net/base/hash_value.h
+++ b/chromium/net/base/hash_value.h
@@ -27,7 +27,23 @@ inline bool operator==(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
}
inline bool operator!=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
- return !(lhs == rhs);
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) != 0;
+}
+
+inline bool operator<(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
+}
+
+inline bool operator>(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) > 0;
+}
+
+inline bool operator<=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) <= 0;
+}
+
+inline bool operator>=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) {
+ return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) >= 0;
}
enum HashValueTag {
@@ -37,8 +53,8 @@ enum HashValueTag {
class NET_EXPORT HashValue {
public:
explicit HashValue(const SHA256HashValue& hash);
- explicit HashValue(HashValueTag tag) : tag(tag) {}
- HashValue() : tag(HASH_VALUE_SHA256) {}
+ explicit HashValue(HashValueTag tag) : tag_(tag) {}
+ HashValue() : tag_(HASH_VALUE_SHA256) {}
// Serializes/Deserializes hashes in the form of
// <hash-name>"/"<base64-hash-value>
@@ -63,33 +79,26 @@ class NET_EXPORT HashValue {
unsigned char* data();
const unsigned char* data() const;
- HashValueTag tag;
+ HashValueTag tag() const { return tag_; }
+
+ NET_EXPORT friend bool operator==(const HashValue& lhs, const HashValue& rhs);
+ NET_EXPORT friend bool operator!=(const HashValue& lhs, const HashValue& rhs);
+ NET_EXPORT friend bool operator<(const HashValue& lhs, const HashValue& rhs);
+ NET_EXPORT friend bool operator>(const HashValue& lhs, const HashValue& rhs);
+ NET_EXPORT friend bool operator<=(const HashValue& lhs, const HashValue& rhs);
+ NET_EXPORT friend bool operator>=(const HashValue& lhs, const HashValue& rhs);
private:
+ HashValueTag tag_;
+
union {
SHA256HashValue sha256;
} fingerprint;
};
-inline bool operator==(const HashValue& lhs, const HashValue& rhs) {
- return lhs.tag == rhs.tag && memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
-}
-
-inline bool operator!=(const HashValue& lhs, const HashValue& rhs) {
- return !(lhs == rhs);
-}
-
typedef std::vector<HashValue> HashValueVector;
-class SHA256HashValueLessThan {
- public:
- bool operator()(const SHA256HashValue& lhs,
- const SHA256HashValue& rhs) const {
- return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
- }
-};
-
// IsSHA256HashInSortedArray returns true iff |hash| is in |array|, a sorted
// array of SHA256 hashes.
bool IsSHA256HashInSortedArray(const HashValue& hash,
diff --git a/chromium/net/base/hex_utils.cc b/chromium/net/base/hex_utils.cc
index 62cdb637255..f6efcbefe16 100644
--- a/chromium/net/base/hex_utils.cc
+++ b/chromium/net/base/hex_utils.cc
@@ -16,7 +16,7 @@ namespace net {
std::string HexDecode(base::StringPiece input) {
std::vector<uint8_t> output;
std::string result;
- if (base::HexStringToBytes(input.as_string(), &output))
+ if (base::HexStringToBytes(input, &output))
result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
return result;
}
diff --git a/chromium/net/base/mime_sniffer_fuzzer.cc b/chromium/net/base/mime_sniffer_fuzzer.cc
index fec7feaf677..66bb264f0b2 100644
--- a/chromium/net/base/mime_sniffer_fuzzer.cc
+++ b/chromium/net/base/mime_sniffer_fuzzer.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <algorithm>
#include <string>
#include "base/strings/string_piece.h"
@@ -37,14 +38,28 @@ std::string GetNextArgument(base::StringPiece* input) {
// own line, and content is everything after them. Since neither URLs nor
// content-encoding headers can have line breaks, this doesn't reduce coverage.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- base::StringPiece input(reinterpret_cast<const char*>(data), size);
- GURL url(GetNextArgument(&input));
+ // net::SniffMimeType DCHECKs if passed an input buffer that's too large,
+ // since it's meant to be used only on the first chunk of a file that's bing
+ // fed into a stream. Set a max size of the input to avoid running into that
+ // DCHECK. Use 64k because that's twice the size of a typical read attempt.
+ constexpr size_t kMaxSniffLength = 64 * 1024;
+ static_assert(kMaxSniffLength >= net::kMaxBytesToSniff,
+ "kMaxSniffLength is too small.");
+ base::StringPiece input(reinterpret_cast<const char*>(data), size);
+ // Divide up the input. It's important not to pass |url_string| to the GURL
+ // constructor until after the length check, to prevent the fuzzer from
+ // exploring GURL space with invalid inputs.
+ std::string url_string = GetNextArgument(&input);
std::string mime_type_hint = GetNextArgument(&input);
+ // Do nothing if input is too long.
+ if (input.length() > kMaxSniffLength)
+ return 0;
+
std::string result;
- net::SniffMimeType(input.data(), input.length(), url, mime_type_hint,
- &result);
+ net::SniffMimeType(input.data(), input.length(), GURL(url_string),
+ mime_type_hint, &result);
net::SniffMimeTypeFromLocalData(input.data(), input.length(), &result);
diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h
index 8b7e5b4b9e3..d1857c25feb 100644
--- a/chromium/net/base/net_error_list.h
+++ b/chromium/net/base/net_error_list.h
@@ -729,6 +729,13 @@ NET_ERROR(CONTENT_DECODING_INIT_FAILED, -371)
// SpdyStream layer.
NET_ERROR(SPDY_RST_STREAM_NO_ERROR_RECEIVED, -372)
+// The pushed stream claimed by the request is no longer available.
+NET_ERROR(SPDY_PUSHED_STREAM_NOT_AVAILABLE, -373)
+
+// A pushed stream was claimed and later reset by the server. When this happens,
+// the request should be retried.
+NET_ERROR(SPDY_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER, -374)
+
// The cache does not have the requested entry.
NET_ERROR(CACHE_MISS, -400)
diff --git a/chromium/net/base/network_change_notifier.cc b/chromium/net/base/network_change_notifier.cc
index 190b420f9f1..573ec3a23db 100644
--- a/chromium/net/base/network_change_notifier.cc
+++ b/chromium/net/base/network_change_notifier.cc
@@ -21,7 +21,7 @@
#include "url/gurl.h"
#if defined(OS_ANDROID)
-#include "base/metrics/sparse_histogram.h"
+#include "base/metrics/histogram_functions.h"
#include "base/strings/string_number_conversions.h"
#include "net/android/network_library.h"
#endif
@@ -296,8 +296,7 @@ class NetworkChangeNotifier::HistogramWatcher : public ConnectionTypeObserver,
// from the network thread.
void NotifyDataReceived(const URLRequest& request, int bytes_read) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (IsLocalhost(request.url().host()) ||
- !request.url().SchemeIsHTTPOrHTTPS()) {
+ if (IsLocalhost(request.url()) || !request.url().SchemeIsHTTPOrHTTPS()) {
return;
}
@@ -500,6 +499,11 @@ NetworkChangeNotifier::~NetworkChangeNotifier() {
}
// static
+NetworkChangeNotifierFactory* NetworkChangeNotifier::GetFactory() {
+ return g_network_change_notifier_factory;
+}
+
+// static
void NetworkChangeNotifier::SetFactory(
NetworkChangeNotifierFactory* factory) {
CHECK(!g_network_change_notifier_factory);
@@ -760,7 +764,7 @@ void NetworkChangeNotifier::LogOperatorCodeHistogram(ConnectionType type) {
mcc_mnc = 0;
}
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("NCN.NetworkOperatorMCCMNC", mcc_mnc);
+ base::UmaHistogramSparse("NCN.NetworkOperatorMCCMNC", mcc_mnc);
#endif
}
diff --git a/chromium/net/base/network_change_notifier.h b/chromium/net/base/network_change_notifier.h
index 3fa2d360c6d..62d064b55cf 100644
--- a/chromium/net/base/network_change_notifier.h
+++ b/chromium/net/base/network_change_notifier.h
@@ -253,6 +253,9 @@ class NET_EXPORT NetworkChangeNotifier {
virtual ~NetworkChangeNotifier();
+ // Returns the factory or nullptr if it is not set.
+ static NetworkChangeNotifierFactory* GetFactory();
+
// Replaces the default class factory instance of NetworkChangeNotifier class.
// The method will take over the ownership of |factory| object.
static void SetFactory(NetworkChangeNotifierFactory* factory);
diff --git a/chromium/net/base/network_throttle_manager_impl.cc b/chromium/net/base/network_throttle_manager_impl.cc
index 4c96573b02d..52e1fcffc58 100644
--- a/chromium/net/base/network_throttle_manager_impl.cc
+++ b/chromium/net/base/network_throttle_manager_impl.cc
@@ -156,7 +156,7 @@ NetworkThrottleManagerImpl::NetworkThrottleManagerImpl()
outstanding_recomputation_timer_(
std::make_unique<base::Timer>(false /* retain_user_task */,
false /* is_repeating */)),
- tick_clock_(new base::DefaultTickClock()),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
weak_ptr_factory_(this) {}
NetworkThrottleManagerImpl::~NetworkThrottleManagerImpl() = default;
@@ -188,12 +188,11 @@ NetworkThrottleManagerImpl::CreateThrottle(
}
void NetworkThrottleManagerImpl::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
- tick_clock_ = std::move(tick_clock);
+ base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
DCHECK(!outstanding_recomputation_timer_->IsRunning());
outstanding_recomputation_timer_ = std::make_unique<base::Timer>(
- false /* retain_user_task */, false /* is_repeating */,
- tick_clock_.get());
+ false /* retain_user_task */, false /* is_repeating */, tick_clock_);
}
bool NetworkThrottleManagerImpl::ConditionallyTriggerTimerForTesting() {
diff --git a/chromium/net/base/network_throttle_manager_impl.h b/chromium/net/base/network_throttle_manager_impl.h
index a388032d90c..620da459931 100644
--- a/chromium/net/base/network_throttle_manager_impl.h
+++ b/chromium/net/base/network_throttle_manager_impl.h
@@ -71,7 +71,7 @@ class NET_EXPORT NetworkThrottleManagerImpl : public NetworkThrottleManager {
RequestPriority priority,
bool ignore_limits) override;
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ void SetTickClockForTesting(base::TickClock* tick_clock);
// If the |NowTicks()| value of |tick_clock_| is greater than the
// time the outstanding_recomputation_timer_ has set to go off, Stop()
@@ -140,7 +140,7 @@ class NET_EXPORT NetworkThrottleManagerImpl : public NetworkThrottleManager {
ThrottleList blocked_throttles_;
// For testing.
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
base::WeakPtrFactory<NetworkThrottleManagerImpl> weak_ptr_factory_;
diff --git a/chromium/net/base/network_throttle_manager_impl_unittest.cc b/chromium/net/base/network_throttle_manager_impl_unittest.cc
index 16ad54ceb3a..713b2680d13 100644
--- a/chromium/net/base/network_throttle_manager_impl_unittest.cc
+++ b/chromium/net/base/network_throttle_manager_impl_unittest.cc
@@ -47,14 +47,12 @@ class NetworkThrottleManagerTest : public testing::Test,
NetworkThrottleManager::ThrottleDelegate {
public:
NetworkThrottleManagerTest()
- : clock_(new base::SimpleTestTickClock),
- now_(base::TimeTicks::Now()),
+ : now_(base::TimeTicks::Now()),
throttle_state_change_count_(0),
last_throttle_to_change_state_(nullptr),
throttle_manager_(new NetworkThrottleManagerImpl) {
- clock_->SetNowTicks(now_);
- throttle_manager_->SetTickClockForTesting(
- std::unique_ptr<base::TickClock>(clock_));
+ clock_.SetNowTicks(now_);
+ throttle_manager_->SetTickClockForTesting(&clock_);
}
protected:
@@ -67,7 +65,7 @@ class NetworkThrottleManagerTest : public testing::Test,
// Set the offset of the test clock from now_.
void SetClockDelta(base::TimeDelta time_delta) {
- clock_->SetNowTicks(now_ + time_delta);
+ clock_.SetNowTicks(now_ + time_delta);
}
// Throttle creation
@@ -108,7 +106,7 @@ class NetworkThrottleManagerTest : public testing::Test,
base::ResetAndReturn(&throttle_state_changed_callback_).Run();
}
- base::SimpleTestTickClock* clock_;
+ base::SimpleTestTickClock clock_;
base::TimeTicks now_;
int throttle_state_change_count_;
NetworkThrottleManager::Throttle* last_throttle_to_change_state_;
diff --git a/chromium/net/base/platform_mime_util_win.cc b/chromium/net/base/platform_mime_util_win.cc
index d68aa8cba8b..89b36ececbd 100644
--- a/chromium/net/base/platform_mime_util_win.cc
+++ b/chromium/net/base/platform_mime_util_win.cc
@@ -9,6 +9,8 @@
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
+#include <windows.h>
+
namespace net {
bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
diff --git a/chromium/net/base/port_util.cc b/chromium/net/base/port_util.cc
index 543d9db9435..83c98213988 100644
--- a/chromium/net/base/port_util.cc
+++ b/chromium/net/base/port_util.cc
@@ -90,10 +90,9 @@ const int kRestrictedPorts[] = {
// KURL::port())
};
-// FTP overrides the following restricted ports.
+// FTP overrides the following restricted port.
const int kAllowedFtpPorts[] = {
21, // ftp data
- 22, // ssh
};
base::LazyInstance<std::multiset<int>>::Leaky g_explicitly_allowed_ports =
diff --git a/chromium/net/base/prioritized_dispatcher_unittest.cc b/chromium/net/base/prioritized_dispatcher_unittest.cc
index 7d0b90ea58f..3970ff4d5dc 100644
--- a/chromium/net/base/prioritized_dispatcher_unittest.cc
+++ b/chromium/net/base/prioritized_dispatcher_unittest.cc
@@ -177,7 +177,8 @@ TEST_F(PrioritizedDispatcherTest, GetLimits) {
// Get current limits, make sure the original limits are returned.
PrioritizedDispatcher::Limits retrieved_limits = dispatcher_->GetLimits();
ASSERT_EQ(original_limits.total_jobs, retrieved_limits.total_jobs);
- ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size());
+ ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
+ retrieved_limits.reserved_slots.size());
for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
++priority) {
EXPECT_EQ(original_limits.reserved_slots[priority],
@@ -193,7 +194,8 @@ TEST_F(PrioritizedDispatcherTest, GetLimits) {
// Get current limits, make sure the new limits are returned.
retrieved_limits = dispatcher_->GetLimits();
ASSERT_EQ(new_limits.total_jobs, retrieved_limits.total_jobs);
- ASSERT_EQ(NUM_PRIORITIES, retrieved_limits.reserved_slots.size());
+ ASSERT_EQ(static_cast<size_t>(NUM_PRIORITIES),
+ retrieved_limits.reserved_slots.size());
for (size_t priority = MINIMUM_PRIORITY; priority <= MAXIMUM_PRIORITY;
++priority) {
EXPECT_EQ(new_limits.reserved_slots[priority],
diff --git a/chromium/net/base/proxy_delegate.h b/chromium/net/base/proxy_delegate.h
index efcc347ffd4..356717b30b2 100644
--- a/chromium/net/base/proxy_delegate.h
+++ b/chromium/net/base/proxy_delegate.h
@@ -15,12 +15,8 @@ class GURL;
namespace net {
-class HttpRequestHeaders;
-class HttpResponseHeaders;
-class HostPortPair;
class ProxyInfo;
class ProxyServer;
-class ProxyService;
// Delegate for setting up a connection.
class NET_EXPORT ProxyDelegate {
@@ -48,36 +44,9 @@ class NET_EXPORT ProxyDelegate {
virtual void OnFallback(const ProxyServer& bad_proxy,
int net_error) = 0;
- // Called immediately before a proxy tunnel request is sent.
- // Provides the embedder an opportunity to add extra request headers.
- virtual void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) = 0;
-
- // Called when the connect attempt to a CONNECT proxy has completed.
- virtual void OnTunnelConnectCompleted(const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) = 0;
-
- // Called after the response headers for the tunnel request are received.
- virtual void OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) = 0;
-
// Returns true if |proxy_server| is a trusted SPDY/HTTP2 proxy that is
// allowed to push cross-origin resources.
- virtual bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) = 0;
-
- // Called after the proxy is resolved but before the connection is
- // established. |resolved_proxy_server| is the proxy server resolved by the
- // proxy service for fetching |url|. Sets |alternative_proxy_server| to an
- // alternative proxy server, if one is available to fetch |url|.
- // |alternative_proxy_server| is owned by the caller, and is guaranteed to be
- // non-null.
- virtual void GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const = 0;
+ virtual bool IsTrustedSpdyProxy(const ProxyServer& proxy_server) = 0;
// Notifies the ProxyDelegate that |alternative_proxy_server| is broken.
virtual void OnAlternativeProxyBroken(
diff --git a/chromium/net/base/test_proxy_delegate.cc b/chromium/net/base/test_proxy_delegate.cc
index 35d7f6438b7..66e98cb0d1d 100644
--- a/chromium/net/base/test_proxy_delegate.cc
+++ b/chromium/net/base/test_proxy_delegate.cc
@@ -4,93 +4,30 @@
#include "net/base/test_proxy_delegate.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
+#include "net/proxy/proxy_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
-TestProxyDelegate::TestProxyDelegate()
- : on_before_tunnel_request_called_(false),
- on_tunnel_request_completed_called_(false),
- on_tunnel_headers_received_called_(false),
- get_alternative_proxy_invocations_(0) {}
+TestProxyDelegate::TestProxyDelegate() = default;
TestProxyDelegate::~TestProxyDelegate() = default;
-void TestProxyDelegate::VerifyOnTunnelRequestCompleted(
- const std::string& endpoint,
- const std::string& proxy_server) const {
- EXPECT_TRUE(on_tunnel_request_completed_called_);
- EXPECT_TRUE(HostPortPair::FromString(endpoint).Equals(
- on_tunnel_request_completed_endpoint_));
- EXPECT_TRUE(HostPortPair::FromString(proxy_server)
- .Equals(on_tunnel_request_completed_proxy_server_));
-}
-
-void TestProxyDelegate::VerifyOnTunnelHeadersReceived(
- const std::string& origin,
- const std::string& proxy_server,
- const std::string& status_line) const {
- EXPECT_TRUE(on_tunnel_headers_received_called_);
- EXPECT_TRUE(HostPortPair::FromString(origin).Equals(
- on_tunnel_headers_received_origin_));
- EXPECT_TRUE(HostPortPair::FromString(proxy_server)
- .Equals(on_tunnel_headers_received_proxy_server_));
- EXPECT_EQ(status_line, on_tunnel_headers_received_status_line_);
-}
-
void TestProxyDelegate::OnResolveProxy(
const GURL& url,
const std::string& method,
const ProxyRetryInfoMap& proxy_retry_info,
- ProxyInfo* result) {}
-
-void TestProxyDelegate::OnTunnelConnectCompleted(
- const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) {
- on_tunnel_request_completed_called_ = true;
- on_tunnel_request_completed_endpoint_ = endpoint;
- on_tunnel_request_completed_proxy_server_ = proxy_server;
+ ProxyInfo* result) {
+ result->SetAlternativeProxy(alternative_proxy_server_);
}
void TestProxyDelegate::OnFallback(const ProxyServer& bad_proxy,
int net_error) {}
-void TestProxyDelegate::OnBeforeTunnelRequest(
- const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) {
- on_before_tunnel_request_called_ = true;
- if (extra_headers)
- extra_headers->SetHeader("Foo", proxy_server.ToString());
-}
-
-void TestProxyDelegate::OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) {
- on_tunnel_headers_received_called_ = true;
- on_tunnel_headers_received_origin_ = origin;
- on_tunnel_headers_received_proxy_server_ = proxy_server;
- on_tunnel_headers_received_status_line_ = response_headers.GetStatusLine();
-}
-
-bool TestProxyDelegate::IsTrustedSpdyProxy(
- const net::ProxyServer& proxy_server) {
+bool TestProxyDelegate::IsTrustedSpdyProxy(const ProxyServer& proxy_server) {
return proxy_server.is_valid() && trusted_spdy_proxy_ == proxy_server;
}
-void TestProxyDelegate::GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const {
- EXPECT_TRUE(resolved_proxy_server.is_valid());
- EXPECT_FALSE(alternative_proxy_server->is_valid());
- *alternative_proxy_server = alternative_proxy_server_;
- get_alternative_proxy_invocations_++;
-}
-
void TestProxyDelegate::OnAlternativeProxyBroken(
const ProxyServer& alternative_proxy_server) {
EXPECT_TRUE(alternative_proxy_server.is_valid());
diff --git a/chromium/net/base/test_proxy_delegate.h b/chromium/net/base/test_proxy_delegate.h
index 08c2caa1eb4..073e4da6f8d 100644
--- a/chromium/net/base/test_proxy_delegate.h
+++ b/chromium/net/base/test_proxy_delegate.h
@@ -7,7 +7,6 @@
#include <string>
-#include "net/base/host_port_pair.h"
#include "net/base/proxy_delegate.h"
#include "net/proxy/proxy_server.h"
@@ -15,8 +14,6 @@ class GURL;
namespace net {
-class HttpRequestHeaders;
-class HttpResponseHeaders;
class ProxyInfo;
class TestProxyDelegate : public ProxyDelegate {
@@ -24,49 +21,17 @@ class TestProxyDelegate : public ProxyDelegate {
TestProxyDelegate();
~TestProxyDelegate() override;
- bool on_before_tunnel_request_called() const {
- return on_before_tunnel_request_called_;
- }
-
- bool on_tunnel_request_completed_called() const {
- return on_tunnel_request_completed_called_;
- }
-
- bool on_tunnel_headers_received_called() const {
- return on_tunnel_headers_received_called_;
- }
-
- void set_trusted_spdy_proxy(const net::ProxyServer& proxy_server) {
+ void set_trusted_spdy_proxy(const ProxyServer& proxy_server) {
trusted_spdy_proxy_ = proxy_server;
}
- void VerifyOnTunnelRequestCompleted(const std::string& endpoint,
- const std::string& proxy_server) const;
-
- void VerifyOnTunnelHeadersReceived(const std::string& origin,
- const std::string& proxy_server,
- const std::string& status_line) const;
-
// ProxyDelegate implementation:
void OnResolveProxy(const GURL& url,
const std::string& method,
const ProxyRetryInfoMap& proxy_retry_info,
ProxyInfo* result) override;
- void OnTunnelConnectCompleted(const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) override;
void OnFallback(const ProxyServer& bad_proxy, int net_error) override;
- void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) override;
- void OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) override;
- bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override;
- void GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const override;
+ bool IsTrustedSpdyProxy(const ProxyServer& proxy_server) override;
void OnAlternativeProxyBroken(
const ProxyServer& alternative_proxy_server) override;
@@ -78,24 +43,9 @@ class TestProxyDelegate : public ProxyDelegate {
return alternative_proxy_server_;
}
- int get_alternative_proxy_invocations() const {
- return get_alternative_proxy_invocations_;
- }
-
private:
- bool on_before_tunnel_request_called_;
- bool on_tunnel_request_completed_called_;
- bool on_tunnel_headers_received_called_;
- net::ProxyServer trusted_spdy_proxy_;
- HostPortPair on_tunnel_request_completed_endpoint_;
- HostPortPair on_tunnel_request_completed_proxy_server_;
- HostPortPair on_tunnel_headers_received_origin_;
- HostPortPair on_tunnel_headers_received_proxy_server_;
- std::string on_tunnel_headers_received_status_line_;
+ ProxyServer trusted_spdy_proxy_;
ProxyServer alternative_proxy_server_;
-
- // Number of times GetAlternativeProxy() method has been called.
- mutable int get_alternative_proxy_invocations_;
};
} // namespace net
diff --git a/chromium/net/base/upload_element_reader.h b/chromium/net/base/upload_element_reader.h
index 08353f48089..32751dae03f 100644
--- a/chromium/net/base/upload_element_reader.h
+++ b/chromium/net/base/upload_element_reader.h
@@ -33,8 +33,9 @@ class NET_EXPORT UploadElementReader {
// This function must be called before calling any other method. It is not
// valid to call any method (other than the destructor) if Init() fails.
- // This method can be called multiple times. Calling this method after an
- // Init() success results in resetting the state (i.e. the stream is rewound).
+ // This method can be called multiple times. Calling this results in resetting
+ // the state (i.e. the stream is rewound), and any previously pending Init()
+ // or Read() calls are aborted.
//
// Initializes the instance synchronously when possible, otherwise does
// initialization aynschronously, returns ERR_IO_PENDING and runs callback.
diff --git a/chromium/net/base/url_util.cc b/chromium/net/base/url_util.cc
index 565788b3b13..3bd93aa4006 100644
--- a/chromium/net/base/url_util.cc
+++ b/chromium/net/base/url_util.cc
@@ -346,7 +346,11 @@ bool IsHostnameNonUnique(const std::string& hostname) {
registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
}
-bool IsLocalhost(base::StringPiece host) {
+bool IsLocalhost(const GURL& url) {
+ return HostStringIsLocalhost(url.HostNoBracketsPiece());
+}
+
+bool HostStringIsLocalhost(base::StringPiece host) {
if (IsLocalHostname(host, nullptr))
return true;
diff --git a/chromium/net/base/url_util.h b/chromium/net/base/url_util.h
index 2eb6d384112..97e7724cfd3 100644
--- a/chromium/net/base/url_util.h
+++ b/chromium/net/base/url_util.h
@@ -142,13 +142,19 @@ NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host);
// that falls in an IANA-reserved range.
NET_EXPORT bool IsHostnameNonUnique(const std::string& hostname);
+// Returns true if the host part of |url| is a local host name according to
+// HostStringIsLocalhost.
+NET_EXPORT bool IsLocalhost(const GURL& url);
+
// Returns true if |host| is one of the local hostnames
// (e.g. "localhost") or IP addresses (IPv4 127.0.0.0/8 or IPv6 ::1).
+// "[::1]" is not detected as a local hostname. Do not use this method to check
+// whether the host part of a URL is a local host name; use IsLocalhost instead.
//
// Note that this function does not check for IP addresses other than
// the above, although other IP addresses may point to the local
// machine.
-NET_EXPORT bool IsLocalhost(base::StringPiece host);
+NET_EXPORT bool HostStringIsLocalhost(base::StringPiece host);
// Strip the portions of |url| that aren't core to the network request.
// - user name / password
diff --git a/chromium/net/base/url_util_unittest.cc b/chromium/net/base/url_util_unittest.cc
index cee4bb22d71..67acfd2381b 100644
--- a/chromium/net/base/url_util_unittest.cc
+++ b/chromium/net/base/url_util_unittest.cc
@@ -388,47 +388,51 @@ INSTANTIATE_TEST_CASE_P(, UrlUtilNonUniqueNameTest,
testing::ValuesIn(kNonUniqueNameTestData));
TEST(UrlUtilTest, IsLocalhost) {
- EXPECT_TRUE(IsLocalhost("localhost"));
- EXPECT_TRUE(IsLocalhost("localHosT"));
- EXPECT_TRUE(IsLocalhost("localhost."));
- EXPECT_TRUE(IsLocalhost("localHost."));
- EXPECT_TRUE(IsLocalhost("localhost.localdomain"));
- EXPECT_TRUE(IsLocalhost("localhost.localDOMain"));
- EXPECT_TRUE(IsLocalhost("localhost.localdomain."));
- EXPECT_TRUE(IsLocalhost("localhost6"));
- EXPECT_TRUE(IsLocalhost("localhost6."));
- EXPECT_TRUE(IsLocalhost("localhost6.localdomain6"));
- EXPECT_TRUE(IsLocalhost("localhost6.localdomain6."));
- EXPECT_TRUE(IsLocalhost("127.0.0.1"));
- EXPECT_TRUE(IsLocalhost("127.0.1.0"));
- EXPECT_TRUE(IsLocalhost("127.1.0.0"));
- EXPECT_TRUE(IsLocalhost("127.0.0.255"));
- EXPECT_TRUE(IsLocalhost("127.0.255.0"));
- EXPECT_TRUE(IsLocalhost("127.255.0.0"));
- EXPECT_TRUE(IsLocalhost("::1"));
- EXPECT_TRUE(IsLocalhost("0:0:0:0:0:0:0:1"));
- EXPECT_TRUE(IsLocalhost("foo.localhost"));
- EXPECT_TRUE(IsLocalhost("foo.localhost."));
- EXPECT_TRUE(IsLocalhost("foo.localhoST"));
- EXPECT_TRUE(IsLocalhost("foo.localhoST."));
-
- EXPECT_FALSE(IsLocalhost("localhostx"));
- EXPECT_FALSE(IsLocalhost("localhost.x"));
- EXPECT_FALSE(IsLocalhost("foo.localdomain"));
- EXPECT_FALSE(IsLocalhost("foo.localdomain.x"));
- EXPECT_FALSE(IsLocalhost("localhost6x"));
- EXPECT_FALSE(IsLocalhost("localhost.localdomain6"));
- EXPECT_FALSE(IsLocalhost("localhost6.localdomain"));
- EXPECT_FALSE(IsLocalhost("127.0.0.1.1"));
- EXPECT_FALSE(IsLocalhost(".127.0.0.255"));
- EXPECT_FALSE(IsLocalhost("::2"));
- EXPECT_FALSE(IsLocalhost("::1:1"));
- EXPECT_FALSE(IsLocalhost("0:0:0:0:1:0:0:1"));
- EXPECT_FALSE(IsLocalhost("::1:1"));
- EXPECT_FALSE(IsLocalhost("0:0:0:0:0:0:0:0:1"));
- EXPECT_FALSE(IsLocalhost("foo.localhost.com"));
- EXPECT_FALSE(IsLocalhost("foo.localhoste"));
- EXPECT_FALSE(IsLocalhost("foo.localhos"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost"));
+ EXPECT_TRUE(HostStringIsLocalhost("localHosT"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost."));
+ EXPECT_TRUE(HostStringIsLocalhost("localHost."));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost.localdomain"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost.localDOMain"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost.localdomain."));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost6"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost6."));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost6.localdomain6"));
+ EXPECT_TRUE(HostStringIsLocalhost("localhost6.localdomain6."));
+ EXPECT_TRUE(HostStringIsLocalhost("127.0.0.1"));
+ EXPECT_TRUE(HostStringIsLocalhost("127.0.1.0"));
+ EXPECT_TRUE(HostStringIsLocalhost("127.1.0.0"));
+ EXPECT_TRUE(HostStringIsLocalhost("127.0.0.255"));
+ EXPECT_TRUE(HostStringIsLocalhost("127.0.255.0"));
+ EXPECT_TRUE(HostStringIsLocalhost("127.255.0.0"));
+ EXPECT_TRUE(HostStringIsLocalhost("::1"));
+ EXPECT_TRUE(HostStringIsLocalhost("0:0:0:0:0:0:0:1"));
+ EXPECT_TRUE(HostStringIsLocalhost("foo.localhost"));
+ EXPECT_TRUE(HostStringIsLocalhost("foo.localhost."));
+ EXPECT_TRUE(HostStringIsLocalhost("foo.localhoST"));
+ EXPECT_TRUE(HostStringIsLocalhost("foo.localhoST."));
+
+ EXPECT_FALSE(HostStringIsLocalhost("localhostx"));
+ EXPECT_FALSE(HostStringIsLocalhost("localhost.x"));
+ EXPECT_FALSE(HostStringIsLocalhost("foo.localdomain"));
+ EXPECT_FALSE(HostStringIsLocalhost("foo.localdomain.x"));
+ EXPECT_FALSE(HostStringIsLocalhost("localhost6x"));
+ EXPECT_FALSE(HostStringIsLocalhost("localhost.localdomain6"));
+ EXPECT_FALSE(HostStringIsLocalhost("localhost6.localdomain"));
+ EXPECT_FALSE(HostStringIsLocalhost("127.0.0.1.1"));
+ EXPECT_FALSE(HostStringIsLocalhost(".127.0.0.255"));
+ EXPECT_FALSE(HostStringIsLocalhost("::2"));
+ EXPECT_FALSE(HostStringIsLocalhost("::1:1"));
+ EXPECT_FALSE(HostStringIsLocalhost("0:0:0:0:1:0:0:1"));
+ EXPECT_FALSE(HostStringIsLocalhost("::1:1"));
+ EXPECT_FALSE(HostStringIsLocalhost("0:0:0:0:0:0:0:0:1"));
+ EXPECT_FALSE(HostStringIsLocalhost("foo.localhost.com"));
+ EXPECT_FALSE(HostStringIsLocalhost("foo.localhoste"));
+ EXPECT_FALSE(HostStringIsLocalhost("foo.localhos"));
+ EXPECT_FALSE(HostStringIsLocalhost("[::1]"));
+
+ GURL localhost6("http://[::1]/");
+ EXPECT_TRUE(IsLocalhost(localhost6));
}
TEST(UrlUtilTest, SimplifyUrlForRequest) {
diff --git a/chromium/net/cert/asn1_util.cc b/chromium/net/cert/asn1_util.cc
index 6b45f1651f1..abba2d55559 100644
--- a/chromium/net/cert/asn1_util.cc
+++ b/chromium/net/cert/asn1_util.cc
@@ -15,10 +15,10 @@ namespace asn1 {
namespace {
// Parses input |in| which should point to the beginning of a Certificate, and
-// sets |*tbs_certificate| ready to parse the SubjectPublicKeyInfo. If parsing
+// sets |*tbs_certificate| ready to parse the Subject. If parsing
// fails, this function returns false and |*tbs_certificate| is left in an
// undefined state.
-bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
+bool SeekToSubject(der::Input in, der::Parser* tbs_certificate) {
// From RFC 5280, section 4.1
// Certificate ::= SEQUENCE {
// tbsCertificate TBSCertificate,
@@ -65,12 +65,19 @@ bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
// validity
if (!tbs_certificate->SkipTag(der::kSequence))
return false;
- // subject
- if (!tbs_certificate->SkipTag(der::kSequence))
- return false;
return true;
}
+// Parses input |in| which should point to the beginning of a Certificate, and
+// sets |*tbs_certificate| ready to parse the SubjectPublicKeyInfo. If parsing
+// fails, this function returns false and |*tbs_certificate| is left in an
+// undefined state.
+bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
+ return SeekToSubject(in, tbs_certificate) &&
+ // Skip over Subject.
+ tbs_certificate->SkipTag(der::kSequence);
+}
+
// Parses input |in| which should point to the beginning of a
// Certificate. If parsing fails, this function returns false, with
// |*extensions_present| and |*extensions_parser| left in an undefined
@@ -142,6 +149,18 @@ bool SeekToExtensions(der::Input in,
} // namespace
+bool ExtractSubjectFromDERCert(base::StringPiece cert,
+ base::StringPiece* subject_out) {
+ der::Parser parser;
+ if (!SeekToSubject(der::Input(cert), &parser))
+ return false;
+ der::Input subject;
+ if (!parser.ReadRawTLV(&subject))
+ return false;
+ *subject_out = subject.AsStringPiece();
+ return true;
+}
+
bool ExtractSPKIFromDERCert(base::StringPiece cert,
base::StringPiece* spki_out) {
der::Parser parser;
diff --git a/chromium/net/cert/asn1_util.h b/chromium/net/cert/asn1_util.h
index 30ccc766333..96f3d2ab663 100644
--- a/chromium/net/cert/asn1_util.h
+++ b/chromium/net/cert/asn1_util.h
@@ -14,6 +14,13 @@ namespace net {
namespace asn1 {
+// ExtractSubjectFromDERCert parses the DER encoded certificate in |cert| and
+// extracts the bytes of the X.501 Subject. On successful return, |subject_out|
+// is set to contain the Subject, pointing into |cert|.
+NET_EXPORT_PRIVATE bool ExtractSubjectFromDERCert(
+ base::StringPiece cert,
+ base::StringPiece* subject_out);
+
// ExtractSPKIFromDERCert parses the DER encoded certificate in |cert| and
// extracts the bytes of the SubjectPublicKeyInfo. On successful return,
// |spki_out| is set to contain the SPKI, pointing into |cert|.
diff --git a/chromium/net/cert/caching_cert_verifier_unittest.cc b/chromium/net/cert/caching_cert_verifier_unittest.cc
index 354059f17e2..11e0917fe2d 100644
--- a/chromium/net/cert/caching_cert_verifier_unittest.cc
+++ b/chromium/net/cert/caching_cert_verifier_unittest.cc
@@ -12,6 +12,7 @@
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/log/net_log_with_source.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
@@ -234,18 +235,22 @@ TEST_F(CachingCertVerifierTest, DifferentCACerts) {
ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
ASSERT_TRUE(intermediate_cert2);
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate_cert1->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert1->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain1 =
- X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain1);
intermediates.clear();
- intermediates.push_back(intermediate_cert2->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert2->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain2 =
- X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain2);
int error;
diff --git a/chromium/net/cert/cert_verifier.cc b/chromium/net/cert/cert_verifier.cc
index 5742ee16d25..f8e6a7f9711 100644
--- a/chromium/net/cert/cert_verifier.cc
+++ b/chromium/net/cert/cert_verifier.cc
@@ -9,6 +9,7 @@
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "net/cert/cert_verify_proc.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
#if defined(OS_NACL)
@@ -37,19 +38,18 @@ CertVerifier::RequestParams::RequestParams(
// sake.
SHA256_CTX ctx;
SHA256_Init(&ctx);
- std::string cert_der;
- X509Certificate::GetDEREncoded(certificate_->os_cert_handle(), &cert_der);
- SHA256_Update(&ctx, cert_der.data(), cert_der.size());
- for (auto* cert_handle : certificate_->GetIntermediateCertificates()) {
- X509Certificate::GetDEREncoded(cert_handle, &cert_der);
- SHA256_Update(&ctx, cert_der.data(), cert_der.size());
+ SHA256_Update(&ctx, CRYPTO_BUFFER_data(certificate_->cert_buffer()),
+ CRYPTO_BUFFER_len(certificate_->cert_buffer()));
+ for (const auto& cert_handle : certificate_->intermediate_buffers()) {
+ SHA256_Update(&ctx, CRYPTO_BUFFER_data(cert_handle.get()),
+ CRYPTO_BUFFER_len(cert_handle.get()));
}
SHA256_Update(&ctx, hostname_.data(), hostname.size());
SHA256_Update(&ctx, &flags, sizeof(flags));
SHA256_Update(&ctx, ocsp_response.data(), ocsp_response.size());
for (const auto& trust_anchor : additional_trust_anchors_) {
- X509Certificate::GetDEREncoded(trust_anchor->os_cert_handle(), &cert_der);
- SHA256_Update(&ctx, cert_der.data(), cert_der.size());
+ SHA256_Update(&ctx, CRYPTO_BUFFER_data(trust_anchor->cert_buffer()),
+ CRYPTO_BUFFER_len(trust_anchor->cert_buffer()));
}
SHA256_Final(reinterpret_cast<uint8_t*>(
base::WriteInto(&key_, SHA256_DIGEST_LENGTH + 1)),
diff --git a/chromium/net/cert/cert_verifier.h b/chromium/net/cert/cert_verifier.h
index 50cc8334902..2745942ed6f 100644
--- a/chromium/net/cert/cert_verifier.h
+++ b/chromium/net/cert/cert_verifier.h
@@ -84,6 +84,10 @@ class NET_EXPORT CertVerifier {
// match against the commonName of the certificate, but only if they are
// issued by non-public trust anchors.
VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS = 1 << 6,
+
+ // If set, disables the policy enforcement described at
+ // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+ VERIFY_DISABLE_SYMANTEC_ENFORCEMENT = 1 << 7,
};
// Parameters to verify |certificate| against the supplied
diff --git a/chromium/net/cert/cert_verifier_unittest.cc b/chromium/net/cert/cert_verifier_unittest.cc
index 73e7c9f8c88..b54f00fa3ab 100644
--- a/chromium/net/cert/cert_verifier_unittest.cc
+++ b/chromium/net/cert/cert_verifier_unittest.cc
@@ -7,6 +7,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -28,10 +29,11 @@ TEST(CertVerifierTest, RequestParamsComparators) {
// Create a certificate that contains both a leaf and an
// intermediate/root.
- X509Certificate::OSCertHandles chain;
- chain.push_back(root_cert->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> chain;
+ chain.push_back(x509_util::DupCryptoBuffer(root_cert->cert_buffer()));
const scoped_refptr<X509Certificate> combined_cert =
- X509Certificate::CreateFromHandle(ok_cert->os_cert_handle(), chain);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ok_cert->cert_buffer()), std::move(chain));
ASSERT_TRUE(combined_cert.get());
const CertificateList empty_list;
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index 47562afd75d..181590b6606 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
@@ -29,7 +30,9 @@
#include "net/cert/internal/signature_algorithm.h"
#include "net/cert/known_roots.h"
#include "net/cert/ocsp_revocation_status.h"
+#include "net/cert/symantec_certs.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/der/encode_values.h"
#include "url/url_canon.h"
@@ -152,7 +155,7 @@ bool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert,
cert->valid_start() >= kBaselineEffectiveDate &&
cert->valid_expiry() >= kBaselineKeysizeEffectiveDate;
- X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &size_bits, &type);
+ X509Certificate::GetPublicKeyInfo(cert->cert_buffer(), &size_bits, &type);
if (should_histogram) {
RecordPublicKeyHistogram(kLeafCert, baseline_keysize_applies, size_bits,
type);
@@ -160,10 +163,11 @@ bool ExaminePublicKeys(const scoped_refptr<X509Certificate>& cert,
if (IsWeakKey(type, size_bits))
weak_key = true;
- const X509Certificate::OSCertHandles& intermediates =
- cert->GetIntermediateCertificates();
+ const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& intermediates =
+ cert->intermediate_buffers();
for (size_t i = 0; i < intermediates.size(); ++i) {
- X509Certificate::GetPublicKeyInfo(intermediates[i], &size_bits, &type);
+ X509Certificate::GetPublicKeyInfo(intermediates[i].get(), &size_bits,
+ &type);
if (should_histogram) {
RecordPublicKeyHistogram(
(i < intermediates.size() - 1) ? kIntermediateCert : kRootCert,
@@ -190,6 +194,23 @@ bool IsPastSHA1DeprecationDate(const X509Certificate& cert) {
return start >= kSHA1DeprecationDate;
}
+// See
+// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+// for more details.
+bool IsUntrustedSymantecCert(const X509Certificate& cert) {
+ const base::Time& start = cert.valid_start();
+ if (start.is_max() || start.is_null())
+ return true;
+ // Certificates issued on/after 2017-12-01 00:00:00 UTC are no longer
+ // trusted.
+ const base::Time kSymantecDeprecationDate =
+ base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1512086400);
+ if (start >= kSymantecDeprecationDate)
+ return true;
+
+ return false;
+}
+
void BestEffortCheckOCSP(const std::string& raw_response,
const X509Certificate& certificate,
OCSPVerifyResult* verify_result) {
@@ -199,31 +220,24 @@ void BestEffortCheckOCSP(const std::string& raw_response,
return;
}
- std::string cert_der;
- if (!X509Certificate::GetDEREncoded(certificate.os_cert_handle(),
- &cert_der)) {
- *verify_result = OCSPVerifyResult();
- return;
- }
+ base::StringPiece cert_der =
+ x509_util::CryptoBufferAsStringPiece(certificate.cert_buffer());
// Try to get the certificate that signed |certificate|. This will run into
// problems if the CertVerifyProc implementation doesn't return the ordered
// certificates. If that happens the OCSP verification may be incorrect.
- std::string issuer_der;
- const X509Certificate::OSCertHandles& intermediates =
- certificate.GetIntermediateCertificates();
- if (intermediates.empty()) {
- if (X509Certificate::IsSelfSigned(certificate.os_cert_handle())) {
+ base::StringPiece issuer_der;
+ if (certificate.intermediate_buffers().empty()) {
+ if (X509Certificate::IsSelfSigned(certificate.cert_buffer())) {
issuer_der = cert_der;
} else {
// A valid cert chain wasn't provided.
*verify_result = OCSPVerifyResult();
return;
}
- } else if (!X509Certificate::GetDEREncoded(intermediates.front(),
- &issuer_der)) {
- *verify_result = OCSPVerifyResult();
- return;
+ } else {
+ issuer_der = x509_util::CryptoBufferAsStringPiece(
+ certificate.intermediate_buffers().front().get());
}
verify_result->revocation_status =
@@ -238,16 +252,13 @@ void BestEffortCheckOCSP(const std::string& raw_response,
void RecordTLSFeatureExtensionWithPrivateRoot(
X509Certificate* cert,
const OCSPVerifyResult& ocsp_result) {
- std::string cert_der;
- if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &cert_der))
- return;
-
// This checks only for the presence of the TLS Feature Extension, but
// does not check the feature list, and in particular does not verify that
// its value is 'status_request' or 'status_request2'. In practice the
// only use of the TLS feature extension is for OCSP stapling, so
// don't bother to check the value.
- bool has_extension = asn1::HasTLSFeatureExtension(cert_der);
+ bool has_extension = asn1::HasTLSFeatureExtension(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
UMA_HISTOGRAM_BOOLEAN("Net.Certificate.TLSFeatureExtensionWithPrivateRoot",
has_extension);
@@ -279,7 +290,7 @@ void RecordTrustAnchorHistogram(const HashValueVector& spki_hashes) {
if (id != 0)
break;
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.Certificate.TrustAnchor.Verify", id);
+ base::UmaHistogramSparse("Net.Certificate.TrustAnchor.Verify", id);
}
// Comparison functor used for binary searching whether a given HashValue,
@@ -345,16 +356,15 @@ void MapAlgorithmToBool(DigestAlgorithm hash, CertVerifyResult* verify_result) {
//
// Returns false if the signature algorithm was unknown or mismatched.
WARN_UNUSED_RESULT bool InspectSignatureAlgorithmForCert(
- X509Certificate::OSCertHandle cert,
+ const CRYPTO_BUFFER* cert,
CertVerifyResult* verify_result) {
- std::string cert_der;
base::StringPiece cert_algorithm_sequence;
base::StringPiece tbs_algorithm_sequence;
// Extract the AlgorithmIdentifier SEQUENCEs
- if (!X509Certificate::GetDEREncoded(cert, &cert_der) ||
- !asn1::ExtractSignatureAlgorithmsFromDERCert(
- cert_der, &cert_algorithm_sequence, &tbs_algorithm_sequence)) {
+ if (!asn1::ExtractSignatureAlgorithmsFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(cert), &cert_algorithm_sequence,
+ &tbs_algorithm_sequence)) {
return false;
}
@@ -412,8 +422,8 @@ WARN_UNUSED_RESULT bool InspectSignatureAlgorithmForCert(
// in order to prevent such confusion.
WARN_UNUSED_RESULT bool InspectSignatureAlgorithmsInChain(
CertVerifyResult* verify_result) {
- const X509Certificate::OSCertHandles& intermediates =
- verify_result->verified_cert->GetIntermediateCertificates();
+ const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& intermediates =
+ verify_result->verified_cert->intermediate_buffers();
// If there are no intermediates, then the leaf is trusted or verification
// failed.
@@ -424,7 +434,7 @@ WARN_UNUSED_RESULT bool InspectSignatureAlgorithmsInChain(
// Fill in hash algorithms for the leaf certificate.
if (!InspectSignatureAlgorithmForCert(
- verify_result->verified_cert->os_cert_handle(), verify_result)) {
+ verify_result->verified_cert->cert_buffer(), verify_result)) {
return false;
}
@@ -434,7 +444,8 @@ WARN_UNUSED_RESULT bool InspectSignatureAlgorithmsInChain(
// final one (which is presumably the trust anchor; may be incorrect for
// partial chains).
for (size_t i = 0; i + 1 < intermediates.size(); ++i) {
- if (!InspectSignatureAlgorithmForCert(intermediates[i], verify_result))
+ if (!InspectSignatureAlgorithmForCert(intermediates[i].get(),
+ verify_result))
return false;
}
@@ -589,6 +600,17 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
+ // Distrust Symantec-issued certificates, as described at
+ // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+ if (!(flags & CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT) &&
+ IsLegacySymantecCert(verify_result->public_key_hashes)) {
+ if (IsUntrustedSymantecCert(*verify_result->verified_cert)) {
+ verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
+ if (rv == OK || IsCertificateError(rv))
+ rv = MapCertStatusToNetError(verify_result->cert_status);
+ }
+ }
+
// Flag certificates from publicly-trusted CAs that are issued to intranet
// hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit
// these to be issued until 1 November 2015, they represent a real risk for
@@ -649,7 +671,7 @@ bool CertVerifyProc::IsPublicKeyBlacklisted(
// Defines kBlacklistedSPKIs.
#include "net/cert/cert_verify_proc_blacklist.inc"
for (const auto& hash : public_key_hashes) {
- if (hash.tag != HASH_VALUE_SHA256)
+ if (hash.tag() != HASH_VALUE_SHA256)
continue;
if (std::binary_search(std::begin(kBlacklistedSPKIs),
std::end(kBlacklistedSPKIs), hash,
@@ -806,7 +828,7 @@ bool CertVerifyProc::HasNameConstraintsViolation(
for (unsigned i = 0; i < arraysize(kLimits); ++i) {
for (HashValueVector::const_iterator j = public_key_hashes.begin();
j != public_key_hashes.end(); ++j) {
- if (j->tag == HASH_VALUE_SHA256 &&
+ if (j->tag() == HASH_VALUE_SHA256 &&
memcmp(j->data(), kLimits[i].public_key, crypto::kSHA256Length) ==
0) {
if (dns_names.empty() && ip_addrs.empty()) {
diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc
index cdf87d3d829..e9c62318dee 100644
--- a/chromium/net/cert/cert_verify_proc_android.cc
+++ b/chromium/net/cert/cert_verify_proc_android.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
#include "base/strings/string_piece.h"
@@ -103,8 +104,8 @@ bool PerformAIAFetchAndAddResultToVector(scoped_refptr<CertNetFetcher> fetcher,
Error error;
std::vector<uint8_t> aia_fetch_bytes;
request->WaitForResult(&error, &aia_fetch_bytes);
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.Certificate.AndroidAIAFetchError",
- std::abs(error));
+ base::UmaHistogramSparse("Net.Certificate.AndroidAIAFetchError",
+ std::abs(error));
if (error != OK)
return false;
CertErrors errors;
@@ -317,12 +318,12 @@ bool VerifyFromAndroidTrustManager(
void GetChainDEREncodedBytes(X509Certificate* cert,
std::vector<std::string>* chain_bytes) {
- chain_bytes->reserve(1 + cert->GetIntermediateCertificates().size());
+ chain_bytes->reserve(1 + cert->intermediate_buffers().size());
chain_bytes->emplace_back(
- net::x509_util::CryptoBufferAsStringPiece(cert->os_cert_handle()));
- for (auto* handle : cert->GetIntermediateCertificates()) {
+ net::x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
+ for (const auto& handle : cert->intermediate_buffers()) {
chain_bytes->emplace_back(
- net::x509_util::CryptoBufferAsStringPiece(handle));
+ net::x509_util::CryptoBufferAsStringPiece(handle.get()));
}
}
diff --git a/chromium/net/cert/cert_verify_proc_android_unittest.cc b/chromium/net/cert/cert_verify_proc_android_unittest.cc
index 4f8c42431eb..cc5e0ec4069 100644
--- a/chromium/net/cert/cert_verify_proc_android_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_android_unittest.cc
@@ -13,6 +13,7 @@
#include "net/cert/internal/test_helpers.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_certificate_data.h"
#include "net/test/test_data_directory.h"
@@ -64,8 +65,8 @@ class MockCertNetFetcher : public CertNetFetcher {
std::unique_ptr<CertNetFetcher::Request> CreateMockRequestFromX509Certificate(
Error error,
const scoped_refptr<X509Certificate>& cert) {
- std::string der;
- EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der));
+ base::StringPiece der =
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer());
return std::make_unique<TestCertNetFetcherRequest>(
error, std::vector<uint8_t>(der.data(), der.data() + der.length()));
}
@@ -121,18 +122,18 @@ CreateMockRequestWithInvalidCertificate() {
::testing::AssertionResult r = ReadTestCert(files[0], &leaf);
if (!r)
return r;
- CertificateList intermediates;
- X509Certificate::OSCertHandles intermediate_os_cert_handles;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_buffers;
for (size_t i = 1; i < files.size(); i++) {
scoped_refptr<X509Certificate> intermediate;
r = ReadTestCert(files[i], &intermediate);
if (!r)
return r;
- intermediates.push_back(intermediate);
- intermediate_os_cert_handles.push_back(intermediate->os_cert_handle());
+ intermediate_buffers.push_back(
+ x509_util::DupCryptoBuffer(intermediate->cert_buffer()));
}
- *result = X509Certificate::CreateFromHandle(leaf->os_cert_handle(),
- intermediate_os_cert_handles);
+ *result = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(leaf->cert_buffer()),
+ std::move(intermediate_buffers));
return ::testing::AssertionSuccess();
}
diff --git a/chromium/net/cert/cert_verify_proc_builtin.cc b/chromium/net/cert/cert_verify_proc_builtin.cc
index a8220270333..dc565ea73b5 100644
--- a/chromium/net/cert/cert_verify_proc_builtin.cc
+++ b/chromium/net/cert/cert_verify_proc_builtin.cc
@@ -293,25 +293,20 @@ bool CertVerifyProcBuiltin::SupportsOCSPStapling() const {
return true;
}
-scoped_refptr<ParsedCertificate> ParseCertificateFromOSHandle(
- X509Certificate::OSCertHandle cert_handle,
+scoped_refptr<ParsedCertificate> ParseCertificateFromBuffer(
+ CRYPTO_BUFFER* cert_handle,
CertErrors* errors) {
- std::string cert_bytes;
- if (!X509Certificate::GetDEREncoded(cert_handle, &cert_bytes))
- return nullptr;
- return ParsedCertificate::Create(x509_util::CreateCryptoBuffer(cert_bytes),
+ return ParsedCertificate::Create(x509_util::DupCryptoBuffer(cert_handle),
x509_util::DefaultParseCertificateOptions(),
errors);
}
void AddIntermediatesToIssuerSource(X509Certificate* x509_cert,
CertIssuerSourceStatic* intermediates) {
- const X509Certificate::OSCertHandles& cert_handles =
- x509_cert->GetIntermediateCertificates();
CertErrors errors;
- for (auto it = cert_handles.begin(); it != cert_handles.end(); ++it) {
+ for (const auto& intermediate : x509_cert->intermediate_buffers()) {
scoped_refptr<ParsedCertificate> cert =
- ParseCertificateFromOSHandle(*it, &errors);
+ ParseCertificateFromBuffer(intermediate.get(), &errors);
if (cert)
intermediates->AddCert(std::move(cert));
// TODO(crbug.com/634443): Surface these parsing errors?
@@ -371,9 +366,9 @@ void MapPathBuilderErrorsToCertStatus(const CertPathErrors& errors,
*cert_status |= CERT_STATUS_INVALID;
}
-X509Certificate::OSCertHandle CreateOSCertHandle(
+bssl::UniquePtr<CRYPTO_BUFFER> CreateCertBuffers(
const scoped_refptr<ParsedCertificate>& certificate) {
- return X509Certificate::CreateOSCertHandleFromBytes(
+ return X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(certificate->der_cert().UnsafeData()),
certificate->der_cert().Length());
}
@@ -386,20 +381,18 @@ X509Certificate::OSCertHandle CreateOSCertHandle(
scoped_refptr<X509Certificate> CreateVerifiedCertChain(
X509Certificate* target_cert,
const CertPathBuilderResultPath& path) {
- X509Certificate::OSCertHandles intermediates;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
// Skip the first certificate in the path as that is the target certificate
for (size_t i = 1; i < path.certs.size(); ++i)
- intermediates.push_back(CreateOSCertHandle(path.certs[i]));
+ intermediates.push_back(CreateCertBuffers(path.certs[i]));
- scoped_refptr<X509Certificate> result = X509Certificate::CreateFromHandle(
- target_cert->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> result = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(target_cert->cert_buffer()),
+ std::move(intermediates));
// |target_cert| was already successfully parsed, so this should never fail.
DCHECK(result);
- for (const X509Certificate::OSCertHandle handle : intermediates)
- X509Certificate::FreeOSCertHandle(handle);
-
return result;
}
@@ -534,8 +527,8 @@ int CertVerifyProcBuiltin::VerifyInternal(
base::Time verification_time = base::Time::Now();
// Parse the target certificate.
- scoped_refptr<ParsedCertificate> target = ParseCertificateFromOSHandle(
- input_cert->os_cert_handle(), &parsing_errors);
+ scoped_refptr<ParsedCertificate> target =
+ ParseCertificateFromBuffer(input_cert->cert_buffer(), &parsing_errors);
if (!target) {
// TODO(crbug.com/634443): Surface these parsing errors?
verify_result->cert_status |= CERT_STATUS_INVALID;
@@ -551,8 +544,8 @@ int CertVerifyProcBuiltin::VerifyInternal(
CreateSslSystemTrustStore();
for (const auto& x509_cert : additional_trust_anchors) {
- scoped_refptr<ParsedCertificate> cert = ParseCertificateFromOSHandle(
- x509_cert->os_cert_handle(), &parsing_errors);
+ scoped_refptr<ParsedCertificate> cert =
+ ParseCertificateFromBuffer(x509_cert->cert_buffer(), &parsing_errors);
if (cert)
ssl_trust_store->AddTrustAnchor(cert);
// TODO(eroman): Surface parsing errors of additional trust anchor.
diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc
index 539d27e0f47..4dd8715c686 100644
--- a/chromium/net/cert/cert_verify_proc_mac.cc
+++ b/chromium/net/cert/cert_verify_proc_mac.cc
@@ -309,14 +309,8 @@ void GetCandidateEVPolicy(const X509Certificate* cert_input,
std::string* ev_policy_oid) {
ev_policy_oid->clear();
- std::string der_cert;
- if (!X509Certificate::GetDEREncoded(cert_input->os_cert_handle(),
- &der_cert)) {
- return;
- }
-
scoped_refptr<ParsedCertificate> cert(ParsedCertificate::Create(
- x509_util::CreateCryptoBuffer(der_cert), {}, nullptr));
+ x509_util::DupCryptoBuffer(cert_input->cert_buffer()), {}, nullptr));
if (!cert)
return;
@@ -342,27 +336,24 @@ void GetCandidateEVPolicy(const X509Certificate* cert_input,
bool CheckCertChainEV(const X509Certificate* cert,
const std::string& ev_policy_oid_string) {
der::Input ev_policy_oid(&ev_policy_oid_string);
- X509Certificate::OSCertHandles os_cert_chain =
- cert->GetIntermediateCertificates();
+ const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& cert_chain =
+ cert->intermediate_buffers();
// Root should have matching policy in EVRootCAMetadata.
- if (os_cert_chain.empty())
+ if (cert_chain.empty())
return false;
SHA256HashValue fingerprint =
- X509Certificate::CalculateFingerprint256(os_cert_chain.back());
+ X509Certificate::CalculateFingerprint256(cert_chain.back().get());
EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
if (!metadata->HasEVPolicyOID(fingerprint, ev_policy_oid))
return false;
// Intermediates should have Certificate Policies extension with the EV policy
// or AnyPolicy.
- for (size_t i = 0; i < os_cert_chain.size() - 1; ++i) {
- std::string der_cert;
- if (!X509Certificate::GetDEREncoded(os_cert_chain[i], &der_cert))
- return false;
+ for (size_t i = 0; i < cert_chain.size() - 1; ++i) {
scoped_refptr<ParsedCertificate> intermediate_cert(
- ParsedCertificate::Create(x509_util::CreateCryptoBuffer(der_cert), {},
- nullptr));
+ ParsedCertificate::Create(
+ x509_util::DupCryptoBuffer(cert_chain[i].get()), {}, nullptr));
if (!intermediate_cert)
return false;
if (!HasPolicyOrAnyPolicy(intermediate_cert.get(), ev_policy_oid))
@@ -440,8 +431,9 @@ CRLSetResult CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) {
}
base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data),
cert_data.Length);
- base::StringPiece spki;
- if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) {
+ base::StringPiece spki, subject;
+ if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki) ||
+ !asn1::ExtractSubjectFromDERCert(der_bytes, &subject)) {
NOTREACHED();
error = true;
continue;
@@ -468,6 +460,8 @@ CRLSetResult CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) {
CRLSet::Result result = crl_set->CheckSPKI(spki_hash);
+ if (result != CRLSet::REVOKED)
+ result = crl_set->CheckSubject(subject, spki_hash);
if (result != CRLSet::REVOKED && !issuer_spki_hash.empty())
result = crl_set->CheckSerial(serial, issuer_spki_hash);
diff --git a/chromium/net/cert/cert_verify_proc_mac_unittest.cc b/chromium/net/cert/cert_verify_proc_mac_unittest.cc
index 71200c0b37d..24ced3f3b42 100644
--- a/chromium/net/cert/cert_verify_proc_mac_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_mac_unittest.cc
@@ -19,6 +19,7 @@
#include "net/cert/test_keychain_search_list_mac.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
@@ -69,11 +70,14 @@ TEST(CertVerifyProcMacTest, MacCRLIntermediate) {
// Add E as trust anchor.
ScopedTestRoot test_root_E(path_3_certs[3].get()); // E-by-E
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(path_2_certs[1]->os_cert_handle()); // B-by-C
- intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E
- scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
- path_3_certs[0]->os_cert_handle(), intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_2_certs[1]->cert_buffer())); // B-by-C
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_2_certs[2]->cert_buffer())); // C-by-E
+ scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(path_3_certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert);
std::unique_ptr<TestKeychainSearchList> test_keychain_search_list(
@@ -113,13 +117,13 @@ TEST(CertVerifyProcMacTest, MacCRLIntermediate) {
ASSERT_EQ(0U, verify_result.cert_status);
ASSERT_TRUE(verify_result.verified_cert.get());
- const X509Certificate::OSCertHandles& verified_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ const auto& verified_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(3U, verified_intermediates.size());
scoped_refptr<X509Certificate> intermediate =
- X509Certificate::CreateFromHandle(verified_intermediates[1],
- X509Certificate::OSCertHandles());
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(verified_intermediates[1].get()), {});
ASSERT_TRUE(intermediate);
scoped_refptr<X509Certificate> expected_intermediate = path_3_certs[2];
@@ -171,8 +175,8 @@ TEST(CertVerifyProcMacTest, MacKeychainReordering) {
EXPECT_FALSE(verify_result.has_sha1);
ASSERT_TRUE(verify_result.verified_cert.get());
- const X509Certificate::OSCertHandles& verified_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ const auto& verified_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(2U, verified_intermediates.size());
}
diff --git a/chromium/net/cert/cert_verify_proc_nss.cc b/chromium/net/cert/cert_verify_proc_nss.cc
index dc9a449083c..a137d5eaa72 100644
--- a/chromium/net/cert/cert_verify_proc_nss.cc
+++ b/chromium/net/cert/cert_verify_proc_nss.cc
@@ -17,6 +17,8 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/protected_memory.h"
+#include "base/memory/protected_memory_cfi.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
@@ -38,6 +40,28 @@ namespace net {
namespace {
+using CacheOCSPResponseFunction = SECStatus (*)(CERTCertDBHandle* handle,
+ CERTCertificate* cert,
+ PRTime time,
+ const SECItem* encodedResponse,
+ void* pwArg);
+
+static PROTECTED_MEMORY_SECTION base::ProtectedMemory<CacheOCSPResponseFunction>
+ g_cache_ocsp_response;
+
+// The function pointer for CERT_CacheOCSPResponseFromSideChannel is saved to
+// read-only memory after being dynamically resolved as a security mitigation to
+// prevent the pointer from being tampered with. See crbug.com/771365 for
+// details.
+const base::ProtectedMemory<CacheOCSPResponseFunction>&
+ResolveCacheOCSPResponse() {
+ static base::ProtectedMemory<CacheOCSPResponseFunction>::Initializer init(
+ &g_cache_ocsp_response,
+ reinterpret_cast<CacheOCSPResponseFunction>(
+ dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel")));
+ return g_cache_ocsp_response;
+}
+
typedef std::unique_ptr<
CERTCertificatePolicies,
crypto::NSSDestroyer<CERTCertificatePolicies,
@@ -270,8 +294,9 @@ CRLSetResult CheckRevocationWithCRLSet(const CERTCertList* cert_list,
base::StringPiece der(reinterpret_cast<char*>(cert->derCert.data),
cert->derCert.len);
- base::StringPiece spki;
- if (!asn1::ExtractSPKIFromDERCert(der, &spki)) {
+ base::StringPiece spki, subject;
+ if (!asn1::ExtractSPKIFromDERCert(der, &spki) ||
+ !asn1::ExtractSubjectFromDERCert(der, &subject)) {
NOTREACHED();
error = true;
continue;
@@ -284,6 +309,8 @@ CRLSetResult CheckRevocationWithCRLSet(const CERTCertList* cert_list,
CRLSet::Result result = crl_set->CheckSPKI(spki_hash);
+ if (result != CRLSet::REVOKED)
+ result = crl_set->CheckSubject(subject, spki_hash);
if (result != CRLSet::REVOKED && !issuer_spki_hash.empty())
result = crl_set->CheckSerial(serial_number, issuer_spki_hash);
@@ -754,12 +781,7 @@ ScopedCERTCertList CertificateListToCERTCertListIgnoringErrors(
} // namespace
-CertVerifyProcNSS::CertVerifyProcNSS()
- : cache_ocsp_response_from_side_channel_(
- reinterpret_cast<CacheOCSPResponseFromSideChannelFunction>(
- dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel")))
-{
-}
+CertVerifyProcNSS::CertVerifyProcNSS() = default;
CertVerifyProcNSS::~CertVerifyProcNSS() = default;
@@ -768,7 +790,7 @@ bool CertVerifyProcNSS::SupportsAdditionalTrustAnchors() const {
}
bool CertVerifyProcNSS::SupportsOCSPStapling() const {
- return cache_ocsp_response_from_side_channel_;
+ return *ResolveCacheOCSPResponse() != nullptr;
}
int CertVerifyProcNSS::VerifyInternalImpl(
@@ -793,7 +815,7 @@ int CertVerifyProcNSS::VerifyInternalImpl(
}
CERTCertificate* cert_handle = input_chain[0].get();
- if (!ocsp_response.empty() && cache_ocsp_response_from_side_channel_) {
+ if (!ocsp_response.empty() && SupportsOCSPStapling()) {
// Note: NSS uses a thread-safe global hash table, so this call will
// affect any concurrent verification operations on |cert| or copies of
// the same certificate. This is an unavoidable limitation of NSS's OCSP
@@ -802,9 +824,9 @@ int CertVerifyProcNSS::VerifyInternalImpl(
ocsp_response_item.data = reinterpret_cast<unsigned char*>(
const_cast<char*>(ocsp_response.data()));
ocsp_response_item.len = ocsp_response.size();
- cache_ocsp_response_from_side_channel_(CERT_GetDefaultCertDB(), cert_handle,
- PR_Now(), &ocsp_response_item,
- nullptr);
+ UnsanitizedCfiCall(ResolveCacheOCSPResponse())(
+ CERT_GetDefaultCertDB(), cert_handle, PR_Now(), &ocsp_response_item,
+ nullptr);
}
// Setup a callback to call into CheckChainRevocationWithCRLSet with the
diff --git a/chromium/net/cert/cert_verify_proc_nss.h b/chromium/net/cert/cert_verify_proc_nss.h
index c7b90b72b7a..bd18e03c119 100644
--- a/chromium/net/cert/cert_verify_proc_nss.h
+++ b/chromium/net/cert/cert_verify_proc_nss.h
@@ -43,15 +43,6 @@ class NET_EXPORT_PRIVATE CertVerifyProcNSS : public CertVerifyProc {
CRLSet* crl_set,
const CertificateList& additional_trust_anchors,
CertVerifyResult* verify_result) override;
-
- using CacheOCSPResponseFromSideChannelFunction =
- SECStatus (*)(CERTCertDBHandle* handle,
- CERTCertificate* cert,
- PRTime time,
- const SECItem* encodedResponse,
- void* pwArg);
- const CacheOCSPResponseFromSideChannelFunction
- cache_ocsp_response_from_side_channel_;
};
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index e7a8a9cc174..9199b892f36 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -333,15 +333,16 @@ TEST_P(CertVerifyProcInternalTest, EVVerificationMultipleOID) {
//
// This way CRLSet coverage will be sufficient for EV revocation checking,
// so this test does not depend on online revocation checking.
- ASSERT_EQ(1u, chain->GetIntermediateCertificates().size());
- std::string der_bytes;
- ASSERT_TRUE(X509Certificate::GetDEREncoded(
- chain->GetIntermediateCertificates()[0], &der_bytes));
+ ASSERT_EQ(1u, chain->intermediate_buffers().size());
base::StringPiece spki;
- ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
+ ASSERT_TRUE(
+ asn1::ExtractSPKIFromDERCert(x509_util::CryptoBufferAsStringPiece(
+ chain->intermediate_buffers()[0].get()),
+ &spki));
SHA256HashValue spki_sha256;
crypto::SHA256HashString(spki, spki_sha256.data, sizeof(spki_sha256.data));
- scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, &spki_sha256, ""));
+ scoped_refptr<CRLSet> crl_set(
+ CRLSet::ForTesting(false, &spki_sha256, "", "", {}));
CertVerifyResult verify_result;
int flags = CertVerifier::VERIFY_EV_CERT;
@@ -375,8 +376,7 @@ TEST_P(CertVerifyProcInternalTest, TrustedTargetCertWithEVPolicy) {
} else if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
EXPECT_THAT(error, IsOk());
ASSERT_TRUE(verify_result.verified_cert);
- EXPECT_TRUE(
- verify_result.verified_cert->GetIntermediateCertificates().empty());
+ EXPECT_TRUE(verify_result.verified_cert->intermediate_buffers().empty());
} else {
EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
}
@@ -416,8 +416,7 @@ TEST_P(CertVerifyProcInternalTest,
} else if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
EXPECT_THAT(error, IsOk());
ASSERT_TRUE(verify_result.verified_cert);
- EXPECT_TRUE(
- verify_result.verified_cert->GetIntermediateCertificates().empty());
+ EXPECT_TRUE(verify_result.verified_cert->intermediate_buffers().empty());
} else {
EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
}
@@ -442,7 +441,7 @@ TEST_P(CertVerifyProcInternalTest, DISABLED_PaypalNullCertParsing) {
ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert.get());
EXPECT_EQ(paypal_null_fingerprint, X509Certificate::CalculateFingerprint256(
- paypal_null_cert->os_cert_handle()));
+ paypal_null_cert->cert_buffer()));
int flags = 0;
CertVerifyResult verify_result;
@@ -488,11 +487,14 @@ TEST_P(CertVerifyProcInternalTest, InvalidTarget) {
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
ASSERT_TRUE(ok_cert);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(ok_cert->cert_buffer()));
scoped_refptr<X509Certificate> cert_with_bad_target(
- X509Certificate::CreateFromHandle(bad_cert->os_cert_handle(),
- {ok_cert->os_cert_handle()}));
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(bad_cert->cert_buffer()),
+ std::move(intermediates)));
ASSERT_TRUE(cert_with_bad_target);
- EXPECT_EQ(1U, cert_with_bad_target->GetIntermediateCertificates().size());
+ EXPECT_EQ(1U, cert_with_bad_target->intermediate_buffers().size());
int flags = 0;
CertVerifyResult verify_result;
@@ -521,12 +523,14 @@ TEST_P(CertVerifyProcInternalTest, UnnecessaryInvalidIntermediate) {
ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
ASSERT_TRUE(ok_cert);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(std::move(bad_cert));
scoped_refptr<X509Certificate> cert_with_bad_intermediate(
- X509Certificate::CreateFromHandle(ok_cert->os_cert_handle(),
- {bad_cert.get()}));
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ok_cert->cert_buffer()),
+ std::move(intermediates)));
ASSERT_TRUE(cert_with_bad_intermediate);
- EXPECT_EQ(1U,
- cert_with_bad_intermediate->GetIntermediateCertificates().size());
+ EXPECT_EQ(1U, cert_with_bad_intermediate->intermediate_buffers().size());
int flags = 0;
CertVerifyResult verify_result;
@@ -552,11 +556,12 @@ TEST_P(CertVerifyProcInternalTest, IntermediateCARequireExplicitPolicy) {
certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
ASSERT_EQ(3U, certs.size());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(certs[1]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
- scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
- certs[0]->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert.get());
ScopedTestRoot scoped_root(certs[2].get());
@@ -579,7 +584,7 @@ TEST_P(CertVerifyProcInternalTest, RejectExpiredCert) {
scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
certs_dir, "expired_cert.pem", X509Certificate::FORMAT_AUTO);
ASSERT_TRUE(cert);
- ASSERT_EQ(0U, cert->GetIntermediateCertificates().size());
+ ASSERT_EQ(0U, cert->intermediate_buffers().size());
int flags = 0;
CertVerifyResult verify_result;
@@ -642,11 +647,13 @@ TEST_P(CertVerifyProcInternalTest, RejectWeakKeys) {
ImportCertFromFile(certs_dir, basename);
ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate.get());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain =
- X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ee_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
CertVerifyResult verify_result;
@@ -699,10 +706,12 @@ TEST_P(CertVerifyProcInternalTest, ExtraneousMD5RootCert) {
ScopedTestRoot scoped_root(root_cert.get());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(extra_cert->os_cert_handle());
- scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
- server_cert->os_cert_handle(), intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(extra_cert->cert_buffer()));
+ scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
CertVerifyResult verify_result;
@@ -713,11 +722,10 @@ TEST_P(CertVerifyProcInternalTest, ExtraneousMD5RootCert) {
// The extra MD5 root should be discarded
ASSERT_TRUE(verify_result.verified_cert.get());
- ASSERT_EQ(1u,
- verify_result.verified_cert->GetIntermediateCertificates().size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- verify_result.verified_cert->GetIntermediateCertificates().front(),
- root_cert->os_cert_handle()));
+ ASSERT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size());
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(
+ verify_result.verified_cert->intermediate_buffers().front().get(),
+ root_cert->cert_buffer()));
EXPECT_FALSE(verify_result.has_md5);
}
@@ -734,10 +742,12 @@ TEST_P(CertVerifyProcInternalTest, GoogleDigiNotarTest) {
ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert.get());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate_cert->os_cert_handle());
- scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
- server_cert->os_cert_handle(), intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util ::DupCryptoBuffer(intermediate_cert->cert_buffer()));
+ scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
CertVerifyResult verify_result;
@@ -778,12 +788,10 @@ TEST(CertVerifyProcTest, DigiNotarCerts) {
for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
scoped_refptr<X509Certificate> diginotar_cert =
ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
- std::string der_bytes;
- ASSERT_TRUE(X509Certificate::GetDEREncoded(diginotar_cert->os_cert_handle(),
- &der_bytes));
-
base::StringPiece spki;
- ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
+ ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(diginotar_cert->cert_buffer()),
+ &spki));
std::string spki_sha256 = crypto::SHA256HashString(spki);
@@ -809,7 +817,7 @@ TEST_P(CertVerifyProcInternalTest, NameConstraintsOk) {
GetTestCertsDirectory(), "name_constraint_good.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_TRUE(leaf);
- ASSERT_EQ(0U, leaf->GetIntermediateCertificates().size());
+ ASSERT_EQ(0U, leaf->intermediate_buffers().size());
int flags = 0;
CertVerifyResult verify_result;
@@ -1004,13 +1012,10 @@ class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test {
return nullptr;
}
- // Start with the DER bytes of a valid certificate. This will be the basis
- // for building a modified certificate.
- std::string cert_der;
- if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), &cert_der)) {
- ADD_FAILURE() << "Failed getting DER bytes";
- return nullptr;
- }
+ // Start with the DER bytes of a valid certificate. The der data is copied
+ // to a new std::string as it will modified to create a new certificate.
+ std::string cert_der(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
// Parse the certificate and identify the locations of interest within
// |cert_der|.
@@ -1061,12 +1066,14 @@ class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test {
return nullptr;
}
- X509Certificate::OSCertHandles intermediates;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
for (size_t i = 1; i < certs.size(); ++i)
- intermediates.push_back(certs[i]->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(certs[i]->cert_buffer()));
- return X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
- intermediates);
+ return X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
}
};
@@ -1205,9 +1212,8 @@ TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) {
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, cert_list.size());
- X509Certificate::OSCertHandles intermediates;
- scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
- cert_list[0]->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(cert_list[0]->cert_buffer()), {});
ASSERT_TRUE(leaf);
int flags = 0;
@@ -1261,11 +1267,12 @@ TEST_P(CertVerifyProcInternalTest, DISABLED_TestKnownRoot) {
certs_dir, "twitter-chain.pem", X509Certificate::FORMAT_AUTO);
ASSERT_EQ(3U, certs.size());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(certs[1]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
- scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
- certs[0]->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
int flags = 0;
@@ -1292,15 +1299,16 @@ TEST_P(CertVerifyProcInternalTest, PublicKeyHashes) {
certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
ASSERT_EQ(3U, certs.size());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(certs[1]->os_cert_handle());
- intermediates.push_back(certs[2]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
ScopedTestRoot scoped_root(certs[2].get());
- scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
- certs[0]->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
- ASSERT_EQ(2U, cert_chain->GetIntermediateCertificates().size());
+ ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
int flags = 0;
CertVerifyResult verify_result;
@@ -1384,17 +1392,18 @@ TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) {
certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
ASSERT_EQ(3U, certs.size());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(certs[1]->os_cert_handle());
- intermediates.push_back(certs[2]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
ScopedTestRoot scoped_root(certs[2].get());
scoped_refptr<X509Certificate> google_full_chain =
- X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
- ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
+ ASSERT_EQ(2U, google_full_chain->intermediate_buffers().size());
CertVerifyResult verify_result;
EXPECT_EQ(static_cast<X509Certificate*>(NULL),
@@ -1406,16 +1415,16 @@ TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) {
verify_result.verified_cert.get());
EXPECT_NE(google_full_chain, verify_result.verified_cert);
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- google_full_chain->os_cert_handle(),
- verify_result.verified_cert->os_cert_handle()));
- const X509Certificate::OSCertHandles& return_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ EXPECT_TRUE(
+ x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
+ verify_result.verified_cert->cert_buffer()));
+ const auto& return_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(2U, return_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
- certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
- certs[2]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
+ certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
+ certs[2]->cert_buffer()));
}
// Test that certificates issued for 'intranet' names (that is, containing no
@@ -1452,6 +1461,63 @@ TEST(CertVerifyProcTest, IntranetHostsRejected) {
EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
}
+// Tests that certificates issued by Symantec's legacy infrastructure
+// are rejected according to the policies outlined in
+// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+// unless the caller has explicitly disabled that enforcement.
+TEST(CertVerifyProcTest, SymantecCertsRejected) {
+ constexpr SHA256HashValue kSymantecHashValue = {
+ {0xb2, 0xde, 0xf5, 0x36, 0x2a, 0xd3, 0xfa, 0xcd, 0x04, 0xbd, 0x29,
+ 0x04, 0x7a, 0x43, 0x84, 0x4f, 0x76, 0x70, 0x34, 0xea, 0x48, 0x92,
+ 0xf8, 0x0e, 0x56, 0xbe, 0xe6, 0x90, 0x24, 0x3e, 0x25, 0x02}};
+ constexpr SHA256HashValue kGoogleHashValue = {
+ {0xec, 0x72, 0x29, 0x69, 0xcb, 0x64, 0x20, 0x0a, 0xb6, 0x63, 0x8f,
+ 0x68, 0xac, 0x53, 0x8e, 0x40, 0xab, 0xab, 0x5b, 0x19, 0xa6, 0x48,
+ 0x56, 0x61, 0x04, 0x2a, 0x10, 0x61, 0xc4, 0x61, 0x27, 0x76}};
+
+ scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
+ GetTestCertsDirectory(), "dec_2017.pem", X509Certificate::FORMAT_AUTO);
+ ASSERT_TRUE(cert);
+
+ scoped_refptr<CertVerifyProc> verify_proc;
+ int error = 0;
+
+ // Test that a Symantec certificate is rejected if issued after 2017-12-01.
+ CertVerifyResult symantec_result;
+ symantec_result.verified_cert = cert;
+ symantec_result.public_key_hashes.push_back(HashValue(kSymantecHashValue));
+ symantec_result.is_issued_by_known_root = true;
+ verify_proc = base::MakeRefCounted<MockCertVerifyProc>(symantec_result);
+
+ CertVerifyResult test_result_1;
+ error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0,
+ nullptr, CertificateList(), &test_result_1);
+ EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
+ EXPECT_TRUE(test_result_1.cert_status & CERT_STATUS_AUTHORITY_INVALID);
+
+ // ... Unless the Symantec cert chains through a whitelisted intermediate.
+ CertVerifyResult whitelisted_result;
+ whitelisted_result.verified_cert = cert;
+ whitelisted_result.public_key_hashes.push_back(HashValue(kSymantecHashValue));
+ whitelisted_result.public_key_hashes.push_back(HashValue(kGoogleHashValue));
+ whitelisted_result.is_issued_by_known_root = true;
+ verify_proc = base::MakeRefCounted<MockCertVerifyProc>(whitelisted_result);
+
+ CertVerifyResult test_result_2;
+ error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0,
+ nullptr, CertificateList(), &test_result_2);
+ EXPECT_THAT(error, IsOk());
+ EXPECT_FALSE(test_result_2.cert_status & CERT_STATUS_AUTHORITY_INVALID);
+
+ // ... Or the caller disabled enforcement of Symantec policies.
+ CertVerifyResult test_result_3;
+ error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(),
+ CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT,
+ nullptr, CertificateList(), &test_result_3);
+ EXPECT_THAT(error, IsOk());
+ EXPECT_FALSE(test_result_3.cert_status & CERT_STATUS_AUTHORITY_INVALID);
+}
+
// While all SHA-1 certificates should be rejected, in the event that there
// emerges some unexpected bug, test that the 'legacy' behaviour works
// correctly - rejecting all SHA-1 certificates from publicly trusted CAs
@@ -1554,38 +1620,37 @@ TEST_P(CertVerifyProcInternalTest, VerifyReturnChainProperlyOrdered) {
ASSERT_EQ(3U, certs.size());
// Construct the chain out of order.
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(certs[2]->os_cert_handle());
- intermediates.push_back(certs[1]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
ScopedTestRoot scoped_root(certs[2].get());
scoped_refptr<X509Certificate> google_full_chain =
- X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
- intermediates);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
- ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
+ ASSERT_TRUE(google_full_chain);
+ ASSERT_EQ(2U, google_full_chain->intermediate_buffers().size());
CertVerifyResult verify_result;
- EXPECT_EQ(static_cast<X509Certificate*>(NULL),
- verify_result.verified_cert.get());
+ EXPECT_FALSE(verify_result.verified_cert);
int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL,
CertificateList(), &verify_result);
EXPECT_THAT(error, IsOk());
- ASSERT_NE(static_cast<X509Certificate*>(NULL),
- verify_result.verified_cert.get());
+ ASSERT_TRUE(verify_result.verified_cert);
EXPECT_NE(google_full_chain, verify_result.verified_cert);
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- google_full_chain->os_cert_handle(),
- verify_result.verified_cert->os_cert_handle()));
- const X509Certificate::OSCertHandles& return_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ EXPECT_TRUE(
+ x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
+ verify_result.verified_cert->cert_buffer()));
+ const auto& return_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(2U, return_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
- certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
- certs[2]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
+ certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
+ certs[2]->cert_buffer()));
}
// Test that Verify() filters out certificates which are not related to
@@ -1610,38 +1675,39 @@ TEST_P(CertVerifyProcInternalTest, VerifyReturnChainFiltersUnrelatedCerts) {
ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2.get());
// Interject unrelated certificates into the list of intermediates.
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(unrelated_certificate->os_cert_handle());
- intermediates.push_back(certs[1]->os_cert_handle());
- intermediates.push_back(unrelated_certificate2->os_cert_handle());
- intermediates.push_back(certs[2]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(unrelated_certificate->cert_buffer()));
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(unrelated_certificate2->cert_buffer()));
+ intermediates.push_back(x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
scoped_refptr<X509Certificate> google_full_chain =
- X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
- intermediates);
- ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
- ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates));
+ ASSERT_TRUE(google_full_chain);
+ ASSERT_EQ(4U, google_full_chain->intermediate_buffers().size());
CertVerifyResult verify_result;
- EXPECT_EQ(static_cast<X509Certificate*>(NULL),
- verify_result.verified_cert.get());
+ EXPECT_FALSE(verify_result.verified_cert);
int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL,
CertificateList(), &verify_result);
EXPECT_THAT(error, IsOk());
- ASSERT_NE(static_cast<X509Certificate*>(NULL),
- verify_result.verified_cert.get());
+ ASSERT_TRUE(verify_result.verified_cert);
EXPECT_NE(google_full_chain, verify_result.verified_cert);
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- google_full_chain->os_cert_handle(),
- verify_result.verified_cert->os_cert_handle()));
- const X509Certificate::OSCertHandles& return_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ EXPECT_TRUE(
+ x509_util::CryptoBufferEqual(google_full_chain->cert_buffer(),
+ verify_result.verified_cert->cert_buffer()));
+ const auto& return_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(2U, return_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
- certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
- certs[2]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[0].get(),
+ certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(return_intermediates[1].get(),
+ certs[2]->cert_buffer()));
}
TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchors) {
@@ -1780,16 +1846,18 @@ TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) {
GetTestCertsDirectory(), "intermediate_ca_cert.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, intermediate_cert_list.size());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert_list[0]->cert_buffer()));
CertificateList cert_list = CreateCertificateListFromFile(
GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, cert_list.size());
- scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
- cert_list[0]->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(cert_list[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(leaf);
int flags = 0;
@@ -1811,6 +1879,67 @@ TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) {
EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
}
+// Tests that CertVerifyProc implementations apply CRLSet revocations by
+// subject.
+TEST_P(CertVerifyProcInternalTest, CRLSetRevokedBySubject) {
+ if (!SupportsCRLSet()) {
+ LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
+ return;
+ }
+
+ scoped_refptr<X509Certificate> root(
+ ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
+ ASSERT_TRUE(root);
+
+ scoped_refptr<X509Certificate> leaf(
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
+ ASSERT_TRUE(leaf);
+
+ ScopedTestRoot scoped_root(root.get());
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+
+ // Confirm that verifying the certificate chain with an empty CRLSet succeeds.
+ scoped_refptr<CRLSet> crl_set = CRLSet::EmptyCRLSetForTesting();
+ int error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
+ CertificateList(), &verify_result);
+ EXPECT_THAT(error, IsOk());
+
+ std::string crl_set_bytes;
+
+ // Revoke the leaf by subject. Verification should now fail.
+ ASSERT_TRUE(base::ReadFileToString(
+ GetTestCertsDirectory().AppendASCII("crlset_by_leaf_subject_no_spki.raw"),
+ &crl_set_bytes));
+ ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
+
+ error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
+ CertificateList(), &verify_result);
+ EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
+
+ // Revoke the root by subject. Verification should now fail.
+ ASSERT_TRUE(base::ReadFileToString(
+ GetTestCertsDirectory().AppendASCII("crlset_by_root_subject_no_spki.raw"),
+ &crl_set_bytes));
+ ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
+
+ error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
+ CertificateList(), &verify_result);
+ EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
+
+ // Revoke the leaf by subject, but only if the SPKI doesn't match the given
+ // one. Verification should pass when using the certificate's actual SPKI.
+ ASSERT_TRUE(base::ReadFileToString(
+ GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
+ &crl_set_bytes));
+ ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
+
+ error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
+ CertificateList(), &verify_result);
+ EXPECT_THAT(error, IsOk());
+}
+
// Tests that CRLSets participate in path building functions, and that as
// long as a valid path exists within the verification graph, verification
// succeeds.
@@ -1859,14 +1988,20 @@ TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) {
// that they're ignored if not necessary.
// This is to avoid relying on AIA or internal object caches when
// interacting with the underlying library.
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(path_1_certs[1]->os_cert_handle()); // B-by-C
- intermediates.push_back(path_1_certs[2]->os_cert_handle()); // C-by-D
- intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E
- intermediates.push_back(path_3_certs[1]->os_cert_handle()); // B-by-F
- intermediates.push_back(path_3_certs[2]->os_cert_handle()); // F-by-E
- scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
- path_1_certs[0]->os_cert_handle(), intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_1_certs[1]->cert_buffer())); // B-by-C
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_1_certs[2]->cert_buffer())); // C-by-D
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_2_certs[2]->cert_buffer())); // C-by-E
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_3_certs[1]->cert_buffer())); // B-by-F
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(path_3_certs[2]->cert_buffer())); // F-by-E
+ scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(path_1_certs[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert);
struct TestPermutations {
@@ -1906,13 +2041,13 @@ TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) {
if (!testcase.expected_intermediate)
continue;
- const X509Certificate::OSCertHandles& verified_intermediates =
- verify_result.verified_cert->GetIntermediateCertificates();
+ const auto& verified_intermediates =
+ verify_result.verified_cert->intermediate_buffers();
ASSERT_EQ(3U, verified_intermediates.size());
scoped_refptr<X509Certificate> intermediate =
- X509Certificate::CreateFromHandle(verified_intermediates[1],
- X509Certificate::OSCertHandles());
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(verified_intermediates[1].get()), {});
ASSERT_TRUE(intermediate);
EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get()))
@@ -2112,31 +2247,32 @@ TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
WeakDigestTestData data = GetParam();
base::FilePath certs_dir = GetTestCertsDirectory();
- scoped_refptr<X509Certificate> intermediate_cert;
- scoped_refptr<X509Certificate> root_cert;
-
// Build |intermediates| as the full chain (including trust anchor).
- X509Certificate::OSCertHandles intermediates;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
if (data.intermediate_cert_filename) {
- intermediate_cert =
+ scoped_refptr<X509Certificate> intermediate_cert =
ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
ASSERT_TRUE(intermediate_cert);
- intermediates.push_back(intermediate_cert->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert->cert_buffer()));
}
if (data.root_cert_filename) {
- root_cert = ImportCertFromFile(certs_dir, data.root_cert_filename);
+ scoped_refptr<X509Certificate> root_cert =
+ ImportCertFromFile(certs_dir, data.root_cert_filename);
ASSERT_TRUE(root_cert);
- intermediates.push_back(root_cert->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(root_cert->cert_buffer()));
}
scoped_refptr<X509Certificate> ee_cert =
ImportCertFromFile(certs_dir, data.ee_cert_filename);
ASSERT_TRUE(ee_cert);
- scoped_refptr<X509Certificate> ee_chain = X509Certificate::CreateFromHandle(
- ee_cert->os_cert_handle(), intermediates);
+ scoped_refptr<X509Certificate> ee_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ee_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(ee_chain);
int flags = 0;
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index 8318f8c90aa..a606da9dc32 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -375,6 +375,12 @@ bool HashSPKI(PCCERT_CONTEXT cert, std::string* hash) {
return true;
}
+bool GetSubject(PCCERT_CONTEXT cert, base::StringPiece* out_subject) {
+ base::StringPiece der_bytes(
+ reinterpret_cast<const char*>(cert->pbCertEncoded), cert->cbCertEncoded);
+ return asn1::ExtractSubjectFromDERCert(der_bytes, out_subject);
+}
+
enum CRLSetResult {
// Indicates an error happened while attempting to determine CRLSet status.
// For example, if the certificate's SPKI could not be extracted.
@@ -422,18 +428,20 @@ CRLSetResult CheckRevocationWithCRLSet(CRLSet* crl_set,
DCHECK(crl_set);
DCHECK(subject_cert);
- // Check to see if |subject_cert|'s SPKI is revoked. The actual revocation
- // is handled by the SHA-256 hash of the SPKI, so compute that.
+ // Check to see if |subject_cert|'s SPKI or Subject is revoked.
std::string subject_hash;
- if (!HashSPKI(subject_cert, &subject_hash)) {
+ base::StringPiece subject_name;
+ if (!HashSPKI(subject_cert, &subject_hash) ||
+ !GetSubject(subject_cert, &subject_name)) {
NOTREACHED(); // Indicates Windows accepted something irrecoverably bad.
previous_hash->clear();
return kCRLSetError;
}
- CRLSet::Result result = crl_set->CheckSPKI(subject_hash);
- if (result == CRLSet::REVOKED)
+ if (crl_set->CheckSPKI(subject_hash) == CRLSet::REVOKED ||
+ crl_set->CheckSubject(subject_name, subject_hash) == CRLSet::REVOKED) {
return kCRLSetRevoked;
+ }
// If no issuer cert is provided, nor a hash of the issuer's SPKI, no
// further checks can be done.
@@ -468,7 +476,7 @@ CRLSetResult CheckRevocationWithCRLSet(CRLSet* crl_set,
}
// Look up by serial & issuer SPKI.
- result = crl_set->CheckSerial(serial, *issuer_hash);
+ const CRLSet::Result result = crl_set->CheckSerial(serial, *issuer_hash);
if (result == CRLSet::REVOKED)
return kCRLSetRevoked;
diff --git a/chromium/net/cert/cert_verify_result.h b/chromium/net/cert/cert_verify_result.h
index 5077e2fd349..43c88b9c203 100644
--- a/chromium/net/cert/cert_verify_result.h
+++ b/chromium/net/cert/cert_verify_result.h
@@ -31,7 +31,7 @@ class NET_EXPORT CertVerifyResult {
// The certificate chain that was constructed during verification.
//
// Note: Although |verified_cert| will match the originally supplied
- // certificate to be validated, the results of GetIntermediateCertificates()
+ // certificate to be validated, the results of intermediate_buffers()
// may be substantially different, both in order and in content, then the
// originally supplied intermediates.
//
@@ -40,9 +40,9 @@ class NET_EXPORT CertVerifyResult {
// the implementation.
//
// In the event of validation success, the trust anchor will be
- // |verified_cert->GetIntermediateCertificates().back()| if
+ // |verified_cert->intermediate_buffers().back()| if
// there was a certificate chain to the trust anchor, and will
- // be |verified_cert->os_cert_handle()| if the certificate was
+ // be |verified_cert->cert_buffer()| if the certificate was
// the trust anchor.
scoped_refptr<X509Certificate> verified_cert;
diff --git a/chromium/net/cert/crl_set.cc b/chromium/net/cert/crl_set.cc
index a6f3e0ed2b2..da71f4bca40 100644
--- a/chromium/net/cert/crl_set.cc
+++ b/chromium/net/cert/crl_set.cc
@@ -6,6 +6,9 @@
#include "base/logging.h"
#include "base/time/time.h"
+#include "crypto/sha2.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
namespace net {
@@ -28,6 +31,23 @@ CRLSet::Result CRLSet::CheckSPKI(const base::StringPiece& spki_hash) const {
return GOOD;
}
+CRLSet::Result CRLSet::CheckSubject(const base::StringPiece& encoded_subject,
+ const base::StringPiece& spki_hash) const {
+ const std::string digest(crypto::SHA256HashString(encoded_subject));
+ const auto i = limited_subjects_.find(digest);
+ if (i == limited_subjects_.end()) {
+ return GOOD;
+ }
+
+ for (const auto& j : i->second) {
+ if (spki_hash == j) {
+ return GOOD;
+ }
+ }
+
+ return REVOKED;
+}
+
CRLSet::Result CRLSet::CheckSerial(
const base::StringPiece& serial_number,
const base::StringPiece& issuer_spki_hash) const {
@@ -75,21 +95,54 @@ const CRLSet::CRLList& CRLSet::crls() const {
}
// static
-CRLSet* CRLSet::EmptyCRLSetForTesting() {
- return ForTesting(false, NULL, "");
+scoped_refptr<CRLSet> CRLSet::EmptyCRLSetForTesting() {
+ return ForTesting(false, NULL, "", "", {});
}
-CRLSet* CRLSet::ExpiredCRLSetForTesting() {
- return ForTesting(true, NULL, "");
+scoped_refptr<CRLSet> CRLSet::ExpiredCRLSetForTesting() {
+ return ForTesting(true, NULL, "", "", {});
}
// static
-CRLSet* CRLSet::ForTesting(bool is_expired,
- const SHA256HashValue* issuer_spki,
- const std::string& serial_number) {
- CRLSet* crl_set = new CRLSet;
+scoped_refptr<CRLSet> CRLSet::ForTesting(
+ bool is_expired,
+ const SHA256HashValue* issuer_spki,
+ const std::string& serial_number,
+ const std::string common_name,
+ const std::vector<std::string> acceptable_spki_hashes_for_cn) {
+ std::string subject_hash;
+ if (!common_name.empty()) {
+ CBB cbb, top_level, set, inner_seq, oid, cn;
+ uint8_t* x501_data;
+ size_t x501_len;
+ static const uint8_t kCommonNameOID[] = {0x55, 0x04, 0x03}; // 2.5.4.3
+
+ CBB_zero(&cbb);
+
+ if (!CBB_init(&cbb, 32) ||
+ !CBB_add_asn1(&cbb, &top_level, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&top_level, &set, CBS_ASN1_SET) ||
+ !CBB_add_asn1(&set, &inner_seq, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1(&inner_seq, &oid, CBS_ASN1_OBJECT) ||
+ !CBB_add_bytes(&oid, kCommonNameOID, sizeof(kCommonNameOID)) ||
+ !CBB_add_asn1(&inner_seq, &cn, CBS_ASN1_PRINTABLESTRING) ||
+ !CBB_add_bytes(&cn,
+ reinterpret_cast<const uint8_t*>(common_name.data()),
+ common_name.size()) ||
+ !CBB_finish(&cbb, &x501_data, &x501_len)) {
+ CBB_cleanup(&cbb);
+ return nullptr;
+ }
+
+ subject_hash.assign(crypto::SHA256HashString(
+ base::StringPiece(reinterpret_cast<char*>(x501_data), x501_len)));
+ OPENSSL_free(x501_data);
+ }
+
+ scoped_refptr<CRLSet> crl_set(new CRLSet);
if (is_expired)
crl_set->not_after_ = 1;
+
if (issuer_spki != NULL) {
const std::string spki(reinterpret_cast<const char*>(issuer_spki->data),
sizeof(issuer_spki->data));
@@ -100,6 +153,9 @@ CRLSet* CRLSet::ForTesting(bool is_expired,
if (!serial_number.empty())
crl_set->crls_[0].second.push_back(serial_number);
+ if (!subject_hash.empty())
+ crl_set->limited_subjects_[subject_hash] = acceptable_spki_hashes_for_cn;
+
return crl_set;
}
diff --git a/chromium/net/cert/crl_set.h b/chromium/net/cert/crl_set.h
index d32faed654c..8cb293fbcd9 100644
--- a/chromium/net/cert/crl_set.h
+++ b/chromium/net/cert/crl_set.h
@@ -45,6 +45,12 @@ class NET_EXPORT CRLSet : public base::RefCountedThreadSafe<CRLSet> {
const base::StringPiece& serial_number,
const base::StringPiece& issuer_spki_hash) const;
+ // CheckSubject returns the information contained in the set for a given,
+ // encoded subject name and SPKI hash. The subject name is encoded as a DER
+ // X.501 Name (see https://tools.ietf.org/html/rfc5280#section-4.1.2.4).
+ Result CheckSubject(const base::StringPiece& asn1_subject,
+ const base::StringPiece& spki_hash) const;
+
// IsExpired returns true iff the current time is past the NotAfter time
// specified in the CRLSet.
bool IsExpired() const;
@@ -64,19 +70,25 @@ class NET_EXPORT CRLSet : public base::RefCountedThreadSafe<CRLSet> {
const CRLList& crls() const;
// EmptyCRLSetForTesting returns a valid, but empty, CRLSet for unit tests.
- static CRLSet* EmptyCRLSetForTesting();
+ static scoped_refptr<CRLSet> EmptyCRLSetForTesting();
// ExpiredCRLSetForTesting returns a expired, empty CRLSet for unit tests.
- static CRLSet* ExpiredCRLSetForTesting();
+ static scoped_refptr<CRLSet> ExpiredCRLSetForTesting();
// ForTesting returns a CRLSet for testing. If |is_expired| is true, calling
// IsExpired on the result will return true. If |issuer_spki| is not NULL,
// the CRLSet will cover certificates issued by that SPKI. If |serial_number|
// is not empty, then that big-endian serial number will be considered to
- // have been revoked by |issuer_spki|.
- static CRLSet* ForTesting(bool is_expired,
- const SHA256HashValue* issuer_spki,
- const std::string& serial_number);
+ // have been revoked by |issuer_spki|. If |common_name| is not empty then the
+ // CRLSet will consider certificates with a subject consisting only of that
+ // common name to be revoked unless they match an SPKI hash from
+ // |acceptable_spki_hashes_for_cn|.
+ static scoped_refptr<CRLSet> ForTesting(
+ bool is_expired,
+ const SHA256HashValue* issuer_spki,
+ const std::string& serial_number,
+ const std::string common_name,
+ const std::vector<std::string> acceptable_spki_hashes_for_cn);
private:
CRLSet();
@@ -98,6 +110,13 @@ class NET_EXPORT CRLSet : public base::RefCountedThreadSafe<CRLSet> {
// blocked_spkis_ contains the SHA256 hashes of SPKIs which are to be blocked
// no matter where in a certificate chain they might appear.
std::vector<std::string> blocked_spkis_;
+ // limited_subjects_ is a map from the SHA256 hash of an X.501 subject name
+ // to a list of allowed SPKI hashes for certificates with that subject name.
+ std::unordered_map<std::string, std::vector<std::string>> limited_subjects_;
+ // limited_subjects_ordered_ contains the keys of |limited_subjects_|,
+ // ordered in the same order as they were found when parsing. This allows
+ // exact reserialisation.
+ std::vector<std::string> limited_subjects_ordered_;
};
} // namespace net
diff --git a/chromium/net/cert/crl_set_storage.cc b/chromium/net/cert/crl_set_storage.cc
index 007cf3c1f47..0ca26779fde 100644
--- a/chromium/net/cert/crl_set_storage.cc
+++ b/chromium/net/cert/crl_set_storage.cc
@@ -133,7 +133,7 @@ static base::DictionaryValue* ReadHeader(base::StringPiece* data) {
if (header.get() == NULL)
return NULL;
- if (!header->IsType(base::Value::Type::DICTIONARY))
+ if (!header->is_dict())
return NULL;
return static_cast<base::DictionaryValue*>(header.release());
}
@@ -179,31 +179,32 @@ static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash,
return true;
}
-// static
-bool CRLSetStorage::CopyBlockedSPKIsFromHeader(
- CRLSet* crl_set,
- base::DictionaryValue* header_dict) {
- base::ListValue* blocked_spkis_list = NULL;
- if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) {
- // BlockedSPKIs is optional, so it's fine if we don't find it.
+// CopyHashListFromHeader parses a list of base64-encoded, SHA-256 hashes from
+// the given |key| in |header_dict| and sets |*out| to the decoded values. It's
+// not an error if |key| is not found in |header_dict|.
+static bool CopyHashListFromHeader(base::DictionaryValue* header_dict,
+ const char* key,
+ std::vector<std::string>* out) {
+ base::ListValue* list = nullptr;
+ if (!header_dict->GetList(key, &list)) {
+ // Hash lists are optional so it's not an error if not present.
return true;
}
- crl_set->blocked_spkis_.clear();
- crl_set->blocked_spkis_.reserve(blocked_spkis_list->GetSize());
+ out->clear();
+ out->reserve(list->GetSize());
- std::string spki_sha256_base64;
+ std::string sha256_base64;
- for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) {
- spki_sha256_base64.clear();
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ sha256_base64.clear();
- if (!blocked_spkis_list->GetString(i, &spki_sha256_base64))
+ if (!list->GetString(i, &sha256_base64))
return false;
- crl_set->blocked_spkis_.push_back(std::string());
- if (!base::Base64Decode(spki_sha256_base64,
- &crl_set->blocked_spkis_.back())) {
- crl_set->blocked_spkis_.pop_back();
+ out->push_back(std::string());
+ if (!base::Base64Decode(sha256_base64, &out->back())) {
+ out->pop_back();
return false;
}
}
@@ -211,6 +212,51 @@ bool CRLSetStorage::CopyBlockedSPKIsFromHeader(
return true;
}
+// CopyHashToHashesMapFromHeader parse a map from base64-encoded, SHA-256
+// hashes to lists of the same, from the given |key| in |header_dict|. It
+// copies the map data into |out| (after base64-decoding) and writes the order
+// of map keys into |out_key_order|.
+static bool CopyHashToHashesMapFromHeader(
+ base::DictionaryValue* header_dict,
+ const char* key,
+ std::unordered_map<std::string, std::vector<std::string>>* out,
+ std::vector<std::string>* out_key_order) {
+ out->clear();
+ out_key_order->clear();
+
+ base::Value* const dict =
+ header_dict->FindKeyOfType(key, base::Value::Type::DICTIONARY);
+ if (dict == nullptr) {
+ // Maps are optional so it's not an error if not present.
+ return true;
+ }
+
+ for (const auto& i : dict->DictItems()) {
+ if (!i.second.is_list()) {
+ return false;
+ }
+
+ std::vector<std::string> allowed_spkis;
+ for (const auto& j : i.second.GetList()) {
+ allowed_spkis.push_back(std::string());
+ if (!j.is_string() ||
+ !base::Base64Decode(j.GetString(), &allowed_spkis.back())) {
+ return false;
+ }
+ }
+
+ std::string subject_hash;
+ if (!base::Base64Decode(i.first, &subject_hash)) {
+ return false;
+ }
+
+ out_key_order->push_back(subject_hash);
+ (*out)[subject_hash] = allowed_spkis;
+ }
+
+ return true;
+}
+
// kMaxUncompressedChangesLength is the largest changes array that we'll
// accept. This bounds the number of CRLs in the CRLSet as well as the number
// of serial numbers in a given CRL.
@@ -356,8 +402,13 @@ bool CRLSetStorage::Parse(base::StringPiece data,
crl_set->crls_index_by_issuer_[back_pair->first] = crl_index;
}
- if (!CopyBlockedSPKIsFromHeader(crl_set.get(), header_dict.get()))
+ if (!CopyHashListFromHeader(header_dict.get(), "BlockedSPKIs",
+ &crl_set->blocked_spkis_) ||
+ !CopyHashToHashesMapFromHeader(header_dict.get(), "LimitedSubjects",
+ &crl_set->limited_subjects_,
+ &crl_set->limited_subjects_ordered_)) {
return false;
+ }
*out_crl_set = crl_set;
return true;
@@ -403,8 +454,13 @@ bool CRLSetStorage::ApplyDelta(const CRLSet* in_crl_set,
crl_set->sequence_ = static_cast<uint32_t>(sequence);
crl_set->not_after_ = static_cast<uint64_t>(not_after);
- if (!CopyBlockedSPKIsFromHeader(crl_set.get(), header_dict.get()))
+ if (!CopyHashListFromHeader(header_dict.get(), "BlockedSPKIs",
+ &crl_set->blocked_spkis_) ||
+ !CopyHashToHashesMapFromHeader(header_dict.get(), "LimitedSubjects",
+ &crl_set->limited_subjects_,
+ &crl_set->limited_subjects_ordered_)) {
return false;
+ }
std::vector<uint8_t> crl_changes;
@@ -505,9 +561,41 @@ std::string CRLSetStorage::Serialize(const CRLSet* crl_set) {
header += ",";
header += "\"" + spki_hash_base64 + "\"";
}
+
header += "]";
if (crl_set->not_after_ != 0)
header += base::StringPrintf(",\"NotAfter\":%" PRIu64, crl_set->not_after_);
+
+ if (!crl_set->limited_subjects_ordered_.empty()) {
+ header += ",LimitedSubjects:{";
+ bool first = true;
+
+ for (const auto& i : crl_set->limited_subjects_ordered_) {
+ if (!first)
+ header += ",";
+ first = false;
+
+ std::string subject_hash_base64;
+ base::Base64Encode(i, &subject_hash_base64);
+ header += "\"" + subject_hash_base64 + "\":[";
+
+ bool first_hash = true;
+ for (const auto& j : crl_set->limited_subjects_.find(i)->second) {
+ if (!first_hash)
+ header += ",";
+ first_hash = false;
+
+ std::string spki_hash_base64;
+ base::Base64Encode(j, &spki_hash_base64);
+ header += "\"" + spki_hash_base64 + "\"";
+ }
+
+ header += "]";
+ }
+
+ header += "}";
+ }
+
header += "}";
size_t len = 2 /* header len */ + header.size();
diff --git a/chromium/net/cert/crl_set_storage.h b/chromium/net/cert/crl_set_storage.h
index dd15796aa5b..92659931420 100644
--- a/chromium/net/cert/crl_set_storage.h
+++ b/chromium/net/cert/crl_set_storage.h
@@ -13,10 +13,6 @@
#include "net/base/net_export.h"
#include "net/cert/crl_set.h"
-namespace base {
-class DictionaryValue;
-}
-
namespace net {
// Static helpers to save and load CRLSet.
@@ -42,12 +38,6 @@ class NET_EXPORT CRLSetStorage {
// and serializing a CRLSet is a lossless operation - the resulting bytes
// will be equal.
static std::string Serialize(const CRLSet* crl_set);
-
- private:
- // CopyBlockedSPKIsFromHeader sets |blocked_spkis_| to the list of values
- // from "BlockedSPKIs" in |header_dict|.
- static bool CopyBlockedSPKIsFromHeader(CRLSet* crl_set,
- base::DictionaryValue* header_dict);
};
} // namespace net
diff --git a/chromium/net/cert/crl_set_unittest.cc b/chromium/net/cert/crl_set_unittest.cc
index 6e154d3e5ce..88c072038fa 100644
--- a/chromium/net/cert/crl_set_unittest.cc
+++ b/chromium/net/cert/crl_set_unittest.cc
@@ -3,7 +3,15 @@
// found in the LICENSE file.
#include "net/cert/crl_set.h"
+
+#include "base/files/file_util.h"
+#include "crypto/sha2.h"
+#include "net/cert/asn1_util.h"
#include "net/cert/crl_set_storage.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
+#include "net/test/cert_test_util.h"
+#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -202,9 +210,8 @@ TEST(CRLSetTest, Parse) {
EXPECT_EQ(std::string("\x64\x63\x49\xD2\x00\x03\x00\x00\x1D\x77", 10),
serials[kExpectedNumSerials - 1]);
- const std::string gia_spki_hash(
- reinterpret_cast<const char*>(kGIASPKISHA256),
- sizeof(kGIASPKISHA256));
+ const std::string gia_spki_hash(reinterpret_cast<const char*>(kGIASPKISHA256),
+ sizeof(kGIASPKISHA256));
EXPECT_EQ(CRLSet::REVOKED,
set->CheckSerial(
std::string("\x16\x7D\x75\x9D\x00\x03\x00\x00\x14\x55", 10),
@@ -318,6 +325,48 @@ TEST(CRLSetTest, BlockedSPKIs) {
set->CheckSPKI(reinterpret_cast<const char*>(spki_hash)));
}
+TEST(CRLSetTest, BlockedSubjects) {
+ std::string crl_set_bytes;
+ EXPECT_TRUE(base::ReadFileToString(
+ GetTestCertsDirectory().AppendASCII("crlset_by_root_subject.raw"),
+ &crl_set_bytes));
+ scoped_refptr<CRLSet> set;
+ EXPECT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &set));
+ ASSERT_TRUE(set.get() != NULL);
+
+ scoped_refptr<X509Certificate> root = CreateCertificateChainFromFile(
+ GetTestCertsDirectory(), "root_ca_cert.pem",
+ X509Certificate::FORMAT_AUTO);
+ base::StringPiece root_der =
+ net::x509_util::CryptoBufferAsStringPiece(root->cert_buffer());
+
+ base::StringPiece spki;
+ ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(root_der, &spki));
+ SHA256HashValue spki_sha256;
+ crypto::SHA256HashString(spki, spki_sha256.data, sizeof(spki_sha256.data));
+
+ base::StringPiece subject;
+ ASSERT_TRUE(asn1::ExtractSubjectFromDERCert(root_der, &subject));
+
+ // Unrelated subjects are unaffected.
+ EXPECT_EQ(CRLSet::GOOD, set->CheckSubject("abcdef", ""));
+
+ // The subject in question is considered revoked if used with an unknown SPKI
+ // hash.
+ EXPECT_EQ(CRLSet::REVOKED,
+ set->CheckSubject(
+ subject,
+ base::StringPiece(reinterpret_cast<const char*>(kGIASPKISHA256),
+ sizeof(kGIASPKISHA256))));
+
+ // When used with the correct hash, that subject should be accepted.
+ EXPECT_EQ(CRLSet::GOOD,
+ set->CheckSubject(
+ subject, base::StringPiece(
+ reinterpret_cast<const char*>(spki_sha256.data),
+ sizeof(spki_sha256.data))));
+}
+
TEST(CRLSetTest, Expired) {
// This CRLSet has an expiry value set to one second past midnight, 1st Jan,
// 1970.
diff --git a/chromium/net/cert/ct_log_response_parser.cc b/chromium/net/cert/ct_log_response_parser.cc
index b6067d14f38..81e0f0a8015 100644
--- a/chromium/net/cert/ct_log_response_parser.cc
+++ b/chromium/net/cert/ct_log_response_parser.cc
@@ -33,7 +33,7 @@ struct JsonSignedTreeHead {
base::JSONValueConverter<JsonSignedTreeHead>* converted);
};
-bool ConvertSHA256RootHash(const base::StringPiece& s, std::string* result) {
+bool ConvertSHA256RootHash(base::StringPiece s, std::string* result) {
if (!base::Base64Decode(s, result)) {
DVLOG(1) << "Failed decoding sha256_root_hash";
return false;
@@ -48,8 +48,7 @@ bool ConvertSHA256RootHash(const base::StringPiece& s, std::string* result) {
return true;
}
-bool ConvertTreeHeadSignature(const base::StringPiece& s,
- DigitallySigned* result) {
+bool ConvertTreeHeadSignature(base::StringPiece s, DigitallySigned* result) {
std::string tree_head_signature;
if (!base::Base64Decode(s, &tree_head_signature)) {
DVLOG(1) << "Failed decoding tree_head_signature";
diff --git a/chromium/net/cert/ct_objects_extractor.cc b/chromium/net/cert/ct_objects_extractor.cc
index 25c8219fb5e..055fbdb1728 100644
--- a/chromium/net/cert/ct_objects_extractor.cc
+++ b/chromium/net/cert/ct_objects_extractor.cc
@@ -12,6 +12,7 @@
#include "crypto/sha2.h"
#include "net/cert/asn1_util.h"
#include "net/cert/signed_certificate_timestamp.h"
+#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
@@ -174,15 +175,12 @@ bool ParseSCTListFromExtensions(const CBS& extensions,
// |*out_single_response| to the body of the SingleResponse starting at the
// |certStatus| field.
bool FindMatchingSingleResponse(CBS* responses,
- X509Certificate::OSCertHandle issuer,
+ const CRYPTO_BUFFER* issuer,
const std::string& cert_serial_number,
CBS* out_single_response) {
- std::string issuer_der;
- if (!X509Certificate::GetDEREncoded(issuer, &issuer_der))
- return false;
-
base::StringPiece issuer_spki;
- if (!asn1::ExtractSPKIFromDERCert(issuer_der, &issuer_spki))
+ if (!asn1::ExtractSPKIFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(issuer), &issuer_spki))
return false;
// In OCSP, only the key itself is under hash.
@@ -245,13 +243,9 @@ bool FindMatchingSingleResponse(CBS* responses,
} // namespace
-bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert,
- std::string* sct_list) {
- std::string der;
- if (!X509Certificate::GetDEREncoded(cert, &der))
- return false;
+bool ExtractEmbeddedSCTList(const CRYPTO_BUFFER* cert, std::string* sct_list) {
CBS cert_cbs;
- CBS_init(&cert_cbs, reinterpret_cast<const uint8_t*>(der.data()), der.size());
+ CBS_init(&cert_cbs, CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert));
CBS cert_body, tbs_cert, extensions_wrap, extensions;
if (!CBS_get_asn1(&cert_cbs, &cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&cert_cbs) != 0 ||
@@ -269,19 +263,14 @@ bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert,
sizeof(kEmbeddedSCTOid), sct_list);
}
-bool GetPrecertSignedEntry(X509Certificate::OSCertHandle leaf,
- X509Certificate::OSCertHandle issuer,
+bool GetPrecertSignedEntry(const CRYPTO_BUFFER* leaf,
+ const CRYPTO_BUFFER* issuer,
SignedEntryData* result) {
result->Reset();
- std::string leaf_der;
- if (!X509Certificate::GetDEREncoded(leaf, &leaf_der))
- return false;
-
// Parse the TBSCertificate.
CBS cert_cbs;
- CBS_init(&cert_cbs, reinterpret_cast<const uint8_t*>(leaf_der.data()),
- leaf_der.size());
+ CBS_init(&cert_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf));
CBS cert_body, tbs_cert;
if (!CBS_get_asn1(&cert_cbs, &cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&cert_cbs) != 0 ||
@@ -336,10 +325,9 @@ bool GetPrecertSignedEntry(X509Certificate::OSCertHandle leaf,
bssl::UniquePtr<uint8_t> scoped_new_tbs_cert_der(new_tbs_cert_der);
// Extract the issuer's public key.
- std::string issuer_der;
base::StringPiece issuer_key;
- if (!X509Certificate::GetDEREncoded(issuer, &issuer_der) ||
- !asn1::ExtractSPKIFromDERCert(issuer_der, &issuer_key)) {
+ if (!asn1::ExtractSPKIFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(issuer), &issuer_key)) {
return false;
}
@@ -353,21 +341,17 @@ bool GetPrecertSignedEntry(X509Certificate::OSCertHandle leaf,
return true;
}
-bool GetX509SignedEntry(X509Certificate::OSCertHandle leaf,
- SignedEntryData* result) {
+bool GetX509SignedEntry(const CRYPTO_BUFFER* leaf, SignedEntryData* result) {
DCHECK(leaf);
- std::string encoded;
- if (!X509Certificate::GetDEREncoded(leaf, &encoded))
- return false;
-
result->Reset();
result->type = ct::SignedEntryData::LOG_ENTRY_TYPE_X509;
- result->leaf_certificate.swap(encoded);
+ result->leaf_certificate =
+ std::string(x509_util::CryptoBufferAsStringPiece(leaf));
return true;
}
-bool ExtractSCTListFromOCSPResponse(X509Certificate::OSCertHandle issuer,
+bool ExtractSCTListFromOCSPResponse(const CRYPTO_BUFFER* issuer,
const std::string& cert_serial_number,
base::StringPiece ocsp_response,
std::string* sct_list) {
diff --git a/chromium/net/cert/ct_objects_extractor.h b/chromium/net/cert/ct_objects_extractor.h
index 469e315dadd..e18a84a5ac5 100644
--- a/chromium/net/cert/ct_objects_extractor.h
+++ b/chromium/net/cert/ct_objects_extractor.h
@@ -22,9 +22,8 @@ struct SignedEntryData;
// If the extension is present, returns true, updating |*sct_list| to contain
// the encoded list, minus the DER encoding necessary for the extension.
// |*sct_list| can then be further decoded with ct::DecodeSCTList
-NET_EXPORT_PRIVATE bool ExtractEmbeddedSCTList(
- X509Certificate::OSCertHandle cert,
- std::string* sct_list);
+NET_EXPORT_PRIVATE bool ExtractEmbeddedSCTList(const CRYPTO_BUFFER* cert,
+ std::string* sct_list);
// Obtains a PrecertChain log entry for |leaf|, an X.509v3 certificate that
// contains an X.509v3 extension with the OID 1.3.6.1.4.1.11129.2.4.2. On
@@ -33,10 +32,9 @@ NET_EXPORT_PRIVATE bool ExtractEmbeddedSCTList(
// The filled |*result| should be verified using ct::CTLogVerifier::Verify
// Note: If |leaf| does not contain the required extension, it is treated as
// a failure.
-NET_EXPORT_PRIVATE bool GetPrecertSignedEntry(
- X509Certificate::OSCertHandle leaf,
- X509Certificate::OSCertHandle issuer,
- SignedEntryData* result);
+NET_EXPORT_PRIVATE bool GetPrecertSignedEntry(const CRYPTO_BUFFER* leaf,
+ const CRYPTO_BUFFER* issuer,
+ SignedEntryData* result);
// Obtains an X509Chain log entry for |leaf|, an X.509v3 certificate that
// is not expected to contain an X.509v3 extension with the OID
@@ -44,7 +42,7 @@ NET_EXPORT_PRIVATE bool GetPrecertSignedEntry(
// On success, fills |result| with the data for an X509Chain log entry and
// returns true.
// The filled |*result| should be verified using ct::CTLogVerifier::Verify
-NET_EXPORT_PRIVATE bool GetX509SignedEntry(X509Certificate::OSCertHandle leaf,
+NET_EXPORT_PRIVATE bool GetX509SignedEntry(const CRYPTO_BUFFER* leaf,
SignedEntryData* result);
// Extracts a SignedCertificateTimestampList that has been embedded within
@@ -54,7 +52,7 @@ NET_EXPORT_PRIVATE bool GetX509SignedEntry(X509Certificate::OSCertHandle leaf,
// the encoded list, minus the DER encoding necessary for the extension.
// |*sct_list| can then be further decoded with ct::DecodeSCTList.
NET_EXPORT_PRIVATE bool ExtractSCTListFromOCSPResponse(
- X509Certificate::OSCertHandle issuer,
+ const CRYPTO_BUFFER* issuer,
const std::string& cert_serial_number,
base::StringPiece ocsp_response,
std::string* sct_list);
diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc
index 846dd62cf20..8152d023191 100644
--- a/chromium/net/cert/ct_objects_extractor_unittest.cc
+++ b/chromium/net/cert/ct_objects_extractor_unittest.cc
@@ -40,7 +40,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
void ExtractEmbeddedSCT(scoped_refptr<X509Certificate> cert,
scoped_refptr<SignedCertificateTimestamp>* sct) {
std::string sct_list;
- ASSERT_TRUE(ExtractEmbeddedSCTList(cert->os_cert_handle(), &sct_list));
+ ASSERT_TRUE(ExtractEmbeddedSCTList(cert->cert_buffer(), &sct_list));
std::vector<base::StringPiece> parsed_scts;
// Make sure the SCT list can be decoded properly
@@ -73,9 +73,8 @@ TEST_F(CTObjectsExtractorTest, ExtractEmbeddedSCT) {
TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
SignedEntryData entry;
- ASSERT_TRUE(GetPrecertSignedEntry(precert_chain_[0]->os_cert_handle(),
- precert_chain_[1]->os_cert_handle(),
- &entry));
+ ASSERT_TRUE(GetPrecertSignedEntry(precert_chain_[0]->cert_buffer(),
+ precert_chain_[1]->cert_buffer(), &entry));
ASSERT_EQ(ct::SignedEntryData::LOG_ENTRY_TYPE_PRECERT, entry.type);
// Should have empty leaf cert for this log entry type.
@@ -88,7 +87,7 @@ TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
TEST_F(CTObjectsExtractorTest, ExtractOrdinaryX509Cert) {
SignedEntryData entry;
- ASSERT_TRUE(GetX509SignedEntry(test_cert_->os_cert_handle(), &entry));
+ ASSERT_TRUE(GetX509SignedEntry(test_cert_->cert_buffer(), &entry));
ASSERT_EQ(ct::SignedEntryData::LOG_ENTRY_TYPE_X509, entry.type);
// Should have empty tbs_certificate for this log entry type.
@@ -104,9 +103,8 @@ TEST_F(CTObjectsExtractorTest, ExtractedSCTVerifies) {
ExtractEmbeddedSCT(precert_chain_[0], &sct);
SignedEntryData entry;
- ASSERT_TRUE(GetPrecertSignedEntry(precert_chain_[0]->os_cert_handle(),
- precert_chain_[1]->os_cert_handle(),
- &entry));
+ ASSERT_TRUE(GetPrecertSignedEntry(precert_chain_[0]->cert_buffer(),
+ precert_chain_[1]->cert_buffer(), &entry));
EXPECT_TRUE(log_->Verify(entry, *sct.get()));
}
@@ -119,7 +117,7 @@ TEST_F(CTObjectsExtractorTest, ComplementarySCTVerifies) {
GetX509CertSCT(&sct);
SignedEntryData entry;
- ASSERT_TRUE(GetX509SignedEntry(test_cert_->os_cert_handle(), &entry));
+ ASSERT_TRUE(GetX509SignedEntry(test_cert_->cert_buffer(), &entry));
EXPECT_TRUE(log_->Verify(entry, *sct.get()));
}
@@ -143,8 +141,8 @@ TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponse) {
std::string extracted_sct_list;
EXPECT_TRUE(ct::ExtractSCTListFromOCSPResponse(
- issuer_cert->os_cert_handle(), subject_cert->serial_number(),
- ocsp_response, &extracted_sct_list));
+ issuer_cert->cert_buffer(), subject_cert->serial_number(), ocsp_response,
+ &extracted_sct_list));
EXPECT_EQ(extracted_sct_list, fake_sct_list);
}
@@ -160,8 +158,8 @@ TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesSerial) {
std::string extracted_sct_list;
EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
- issuer_cert->os_cert_handle(), test_cert_->serial_number(),
- ocsp_response, &extracted_sct_list));
+ issuer_cert->cert_buffer(), test_cert_->serial_number(), ocsp_response,
+ &extracted_sct_list));
}
// Test that the extractor honours issuer ID.
@@ -177,8 +175,8 @@ TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesIssuer) {
std::string extracted_sct_list;
// Use test_cert_ for issuer - it is not the correct issuer of |subject_cert|.
EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
- test_cert_->os_cert_handle(), subject_cert->serial_number(),
- ocsp_response, &extracted_sct_list));
+ test_cert_->cert_buffer(), subject_cert->serial_number(), ocsp_response,
+ &extracted_sct_list));
}
} // namespace ct
diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h
index b5b1c79045f..0368044f4fd 100644
--- a/chromium/net/cert/ct_verifier.h
+++ b/chromium/net/cert/ct_verifier.h
@@ -21,12 +21,14 @@ class NET_EXPORT CTVerifier {
public:
// Called for each Signed Certificate Timestamp from a known log that vas
// verified successfully (i.e. the signature verifies). |sct| is the
- // Signed Certificate Timestamp, |cert| is the certificate it applies to.
- // The certificate is needed to calculate the hash of the log entry,
- // necessary for checking inclusion in the log.
+ // Signed Certificate Timestamp, |cert| is the certificate it applies to and
+ // |hostname| is the server that presented the certificate (DNS name or IP
+ // address literal). The certificate is needed to calculate the hash of the
+ // log entry, necessary for checking inclusion in the log.
// Note: The observer (whose implementation is expected to exist outside
// net/) may store the observed |cert| and |sct|.
- virtual void OnSCTVerified(X509Certificate* cert,
+ virtual void OnSCTVerified(base::StringPiece hostname,
+ X509Certificate* cert,
const ct::SignedCertificateTimestamp* sct) = 0;
protected:
@@ -45,7 +47,11 @@ class NET_EXPORT CTVerifier {
// TLS extension was negotiated, |sct_list_from_tls_extension| should be an
// empty string. |output_scts| will be cleared and filled with the SCTs
// present, if any, along with their verification results.
- virtual void Verify(X509Certificate* cert,
+ // The |hostname| (or IP address literal) of the server that presented |cert|
+ // must be provided so that inclusion checks for |cert| are able to avoid
+ // leaking information about which servers have been visited.
+ virtual void Verify(base::StringPiece hostname,
+ X509Certificate* cert,
base::StringPiece stapled_ocsp_response,
base::StringPiece sct_list_from_tls_extension,
SignedCertificateTimestampAndStatusList* output_scts,
@@ -56,6 +62,10 @@ class NET_EXPORT CTVerifier {
// URLRequests which have to be cancelled before this object is destroyed.
// Setting |observer| to nullptr has the effect of stopping all notifications.
virtual void SetObserver(Observer* observer) = 0;
+
+ // Gets the Observer, if any, that is currently receiving notifications of
+ // validated SCTs.
+ virtual Observer* GetObserver() const = 0;
};
} // namespace net
diff --git a/chromium/net/cert/do_nothing_ct_verifier.cc b/chromium/net/cert/do_nothing_ct_verifier.cc
index 0429d86e765..63b9c0ae306 100644
--- a/chromium/net/cert/do_nothing_ct_verifier.cc
+++ b/chromium/net/cert/do_nothing_ct_verifier.cc
@@ -12,6 +12,7 @@ DoNothingCTVerifier::DoNothingCTVerifier() = default;
DoNothingCTVerifier::~DoNothingCTVerifier() = default;
void DoNothingCTVerifier::Verify(
+ base::StringPiece hostname,
X509Certificate* cert,
base::StringPiece stapled_ocsp_response,
base::StringPiece sct_list_from_tls_extension,
@@ -22,4 +23,8 @@ void DoNothingCTVerifier::Verify(
void DoNothingCTVerifier::SetObserver(Observer* observer) {}
+CTVerifier::Observer* DoNothingCTVerifier::GetObserver() const {
+ return nullptr;
+}
+
} // namespace net
diff --git a/chromium/net/cert/do_nothing_ct_verifier.h b/chromium/net/cert/do_nothing_ct_verifier.h
index 025ffd11be8..1aad260088a 100644
--- a/chromium/net/cert/do_nothing_ct_verifier.h
+++ b/chromium/net/cert/do_nothing_ct_verifier.h
@@ -50,13 +50,15 @@ class NET_EXPORT DoNothingCTVerifier : public CTVerifier {
DoNothingCTVerifier();
~DoNothingCTVerifier() override;
- void Verify(X509Certificate* cert,
+ void Verify(base::StringPiece hostname,
+ X509Certificate* cert,
base::StringPiece stapled_ocsp_response,
base::StringPiece sct_list_from_tls_extension,
SignedCertificateTimestampAndStatusList* output_scts,
const NetLogWithSource& net_log) override;
void SetObserver(Observer* observer) override;
+ Observer* GetObserver() const override;
private:
DISALLOW_COPY_AND_ASSIGN(DoNothingCTVerifier);
diff --git a/chromium/net/cert/ev_root_ca_metadata.cc b/chromium/net/cert/ev_root_ca_metadata.cc
index 85c84e1a52d..8880c1c3ea5 100644
--- a/chromium/net/cert/ev_root_ca_metadata.cc
+++ b/chromium/net/cert/ev_root_ca_metadata.cc
@@ -18,9 +18,9 @@
#include "net/der/input.h"
#if defined(USE_NSS_CERTS)
#include "crypto/nss_util.h"
-#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
-#include "third_party/boringssl/src/include/openssl/asn1.h"
-#include "third_party/boringssl/src/include/openssl/obj.h"
+#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA) || defined(OS_WIN)
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
#endif
namespace net {
@@ -836,20 +836,13 @@ namespace {
bool ConvertBytesToDottedString(const der::Input& policy_oid,
std::string* dotted) {
- ASN1_OBJECT obj;
- memset(&obj, 0, sizeof(obj));
- obj.data = policy_oid.UnsafeData();
- obj.length = policy_oid.Length();
-
- // Determine the length of the dotted string.
- int len = OBJ_obj2txt(nullptr, 0, &obj, 1 /* dont_search_names */);
- if (len == -1)
+ CBS cbs;
+ CBS_init(&cbs, policy_oid.UnsafeData(), policy_oid.Length());
+ bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
+ if (!text)
return false;
-
- // Write the dotted string into |*dotted|.
- dotted->resize(len + 1);
- return len == OBJ_obj2txt(&(*dotted)[0], static_cast<int>(dotted->size()),
- &obj, 1 /* dont_search_names */);
+ dotted->assign(text.get());
+ return true;
}
} // namespace
@@ -938,12 +931,16 @@ bool EVRootCAMetadata::RemoveEVCA(const SHA256HashValue& fingerprint) {
namespace {
std::string OIDStringToDER(const char* policy) {
- bssl::UniquePtr<ASN1_OBJECT> obj(
- OBJ_txt2obj(policy, 1 /* dont_search_names */));
- if (!obj)
+ uint8_t* der;
+ size_t len;
+ bssl::ScopedCBB cbb;
+ if (!CBB_init(cbb.get(), 32) ||
+ !CBB_add_asn1_oid_from_text(cbb.get(), policy, strlen(policy)) ||
+ !CBB_finish(cbb.get(), &der, &len)) {
return std::string();
-
- return std::string(reinterpret_cast<const char*>(obj->data), obj->length);
+ }
+ bssl::UniquePtr<uint8_t> delete_der(der);
+ return std::string(reinterpret_cast<const char*>(der), len);
}
} // namespace
diff --git a/chromium/net/cert/ev_root_ca_metadata.h b/chromium/net/cert/ev_root_ca_metadata.h
index e69dbd7979d..42daddbd8bd 100644
--- a/chromium/net/cert/ev_root_ca_metadata.h
+++ b/chromium/net/cert/ev_root_ca_metadata.h
@@ -91,8 +91,7 @@ class NET_EXPORT_PRIVATE EVRootCAMetadata {
~EVRootCAMetadata();
#if defined(USE_NSS_CERTS)
- using PolicyOIDMap = std::
- map<SHA256HashValue, std::vector<PolicyOID>, SHA256HashValueLessThan>;
+ 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.
@@ -101,14 +100,12 @@ class NET_EXPORT_PRIVATE EVRootCAMetadata {
PolicyOIDMap ev_policy_;
std::set<PolicyOID> policy_oids_;
#elif defined(OS_WIN)
- using ExtraEVCAMap =
- std::map<SHA256HashValue, std::string, SHA256HashValueLessThan>;
+ using ExtraEVCAMap = std::map<SHA256HashValue, std::string>;
// extra_cas_ contains any EV CA metadata that was added at runtime.
ExtraEVCAMap extra_cas_;
#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
- using PolicyOIDMap = std::
- map<SHA256HashValue, std::vector<std::string>, SHA256HashValueLessThan>;
+ using PolicyOIDMap = std::map<SHA256HashValue, std::vector<std::string>>;
PolicyOIDMap ev_policy_;
std::set<std::string> policy_oids_;
diff --git a/chromium/net/cert/internal/revocation_checker.cc b/chromium/net/cert/internal/revocation_checker.cc
index a8333e24781..e33f8e9fd9a 100644
--- a/chromium/net/cert/internal/revocation_checker.cc
+++ b/chromium/net/cert/internal/revocation_checker.cc
@@ -242,6 +242,12 @@ CRLSet::Result CheckChainRevocationUsingCRLSet(
crypto::SHA256HashString(cert->tbs().spki_tlv.AsStringPiece());
CRLSet::Result result = crl_set->CheckSPKI(spki_hash);
+ // Check for revocation using the certificate's Subject.
+ if (result != CRLSet::REVOKED) {
+ result = crl_set->CheckSubject(cert->tbs().subject_tlv.AsStringPiece(),
+ spki_hash);
+ }
+
// Check for revocation using the certificate's serial number and issuer's
// SPKI.
if (result != CRLSet::REVOKED && !is_root) {
diff --git a/chromium/net/cert/internal/system_trust_store.cc b/chromium/net/cert/internal/system_trust_store.cc
index 5f0c724f7a0..f5c2b5fae3a 100644
--- a/chromium/net/cert/internal/system_trust_store.cc
+++ b/chromium/net/cert/internal/system_trust_store.cc
@@ -175,8 +175,7 @@ class FuchsiaSystemCerts {
for (const auto& cert : certs) {
CertErrors errors;
auto parsed = ParsedCertificate::Create(
- bssl::UniquePtr<CRYPTO_BUFFER>(
- X509Certificate::DupOSCertHandle(cert->os_cert_handle())),
+ x509_util::DupCryptoBuffer(cert->cert_buffer()),
x509_util::DefaultParseCertificateOptions(), &errors);
CHECK(parsed) << errors.ToDebugString();
system_trust_store_.AddTrustAnchor(parsed);
diff --git a/chromium/net/cert/internal/trust_store_mac.cc b/chromium/net/cert/internal/trust_store_mac.cc
index 0d78dd0b7ad..01b505d259d 100644
--- a/chromium/net/cert/internal/trust_store_mac.cc
+++ b/chromium/net/cert/internal/trust_store_mac.cc
@@ -347,7 +347,7 @@ base::ScopedCFTypeRef<CFDataRef> TrustStoreMac::GetMacNormalizedIssuer(
x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(),
cert->der_cert().Length()));
if (!cert_handle) {
- LOG(ERROR) << "CreateOSCertHandleFromBytes";
+ LOG(ERROR) << "CreateCertBufferFromBytes";
return name_data;
}
{
diff --git a/chromium/net/cert/internal/trust_store_mac_unittest.cc b/chromium/net/cert/internal/trust_store_mac_unittest.cc
index 70a3775ae66..04b3fbbc960 100644
--- a/chromium/net/cert/internal/trust_store_mac_unittest.cc
+++ b/chromium/net/cert/internal/trust_store_mac_unittest.cc
@@ -273,7 +273,7 @@ TEST(TrustStoreMacTest, SystemCerts) {
x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(),
cert->der_cert().Length()));
if (!cert_handle) {
- ADD_FAILURE() << "CreateOSCertHandleFromBytes " << hash_text;
+ ADD_FAILURE() << "CreateCertBufferFromBytes " << hash_text;
continue;
}
base::ScopedCFTypeRef<SecTrustRef> trust;
diff --git a/chromium/net/cert/internal/verify_name_match_unittest.cc b/chromium/net/cert/internal/verify_name_match_unittest.cc
index 25bdd1ab7b8..e706d9c488c 100644
--- a/chromium/net/cert/internal/verify_name_match_unittest.cc
+++ b/chromium/net/cert/internal/verify_name_match_unittest.cc
@@ -597,4 +597,16 @@ TEST(NameNormalizationTest, TestEverything) {
EXPECT_EQ(normalized_der, renormalized_der);
}
+// Unknown AttributeValue types normalize as-is, even non-primitive tags.
+TEST(NameNormalizationTest, NormalizeCustom) {
+ std::string raw_der;
+ ASSERT_TRUE(LoadTestData("custom", "custom", "normalized", &raw_der));
+
+ std::string normalized_der;
+ CertErrors errors;
+ ASSERT_TRUE(NormalizeName(SequenceValueFromString(&raw_der), &normalized_der,
+ &errors));
+ EXPECT_EQ(SequenceValueFromString(&raw_der), der::Input(&normalized_der));
+}
+
} // namespace net
diff --git a/chromium/net/cert/known_roots.cc b/chromium/net/cert/known_roots.cc
index 191923c8929..1a59ec5dde5 100644
--- a/chromium/net/cert/known_roots.cc
+++ b/chromium/net/cert/known_roots.cc
@@ -19,12 +19,12 @@ namespace {
// RootCertData to a HashValue
struct HashValueToRootCertDataComp {
bool operator()(const HashValue& hash, const RootCertData& root_cert) {
- DCHECK_EQ(HASH_VALUE_SHA256, hash.tag);
+ DCHECK_EQ(HASH_VALUE_SHA256, hash.tag());
return memcmp(hash.data(), root_cert.sha256_spki_hash, 32) < 0;
}
bool operator()(const RootCertData& root_cert, const HashValue& hash) {
- DCHECK_EQ(HASH_VALUE_SHA256, hash.tag);
+ DCHECK_EQ(HASH_VALUE_SHA256, hash.tag());
return memcmp(root_cert.sha256_spki_hash, hash.data(), 32) < 0;
}
};
@@ -32,7 +32,7 @@ struct HashValueToRootCertDataComp {
} // namespace
int32_t GetNetTrustAnchorHistogramIdForSPKI(const HashValue& spki_hash) {
- if (spki_hash.tag != HASH_VALUE_SHA256)
+ if (spki_hash.tag() != HASH_VALUE_SHA256)
return 0;
auto* it = std::lower_bound(std::begin(kRootCerts), std::end(kRootCerts),
diff --git a/chromium/net/cert/known_roots_mac.cc b/chromium/net/cert/known_roots_mac.cc
index 475dda6e9cf..c4c7c64575f 100644
--- a/chromium/net/cert/known_roots_mac.cc
+++ b/chromium/net/cert/known_roots_mac.cc
@@ -60,7 +60,7 @@ class OSXKnownRootHelper {
~OSXKnownRootHelper() {}
- std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
+ std::set<SHA256HashValue> known_roots_;
};
base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
diff --git a/chromium/net/cert/known_roots_nss.cc b/chromium/net/cert/known_roots_nss.cc
index 34f3896d183..1e4b45ae1e7 100644
--- a/chromium/net/cert/known_roots_nss.cc
+++ b/chromium/net/cert/known_roots_nss.cc
@@ -5,18 +5,87 @@
#include "net/cert/known_roots_nss.h"
#include <cert.h>
+#include <dlfcn.h>
#include <pk11pub.h>
+#include <secmod.h>
#include <memory>
+#include "base/memory/protected_memory.h"
+#include "base/memory/protected_memory_cfi.h"
+#include "crypto/nss_util_internal.h"
+#include "net/base/hash_value.h"
+#include "net/cert/x509_util_nss.h"
+
namespace net {
+namespace {
+
+// This can be removed once the minimum NSS version to build is >= 3.30.
+#if !defined(CKA_NSS_MOZILLA_CA_POLICY)
+#define CKA_NSS_MOZILLA_CA_POLICY (CKA_NSS + 34)
+#endif
+
+using PK11HasAttributeSetFunction = CK_BBOOL (*)(PK11SlotInfo* slot,
+ CK_OBJECT_HANDLE id,
+ CK_ATTRIBUTE_TYPE type,
+ PRBool haslock);
+static PROTECTED_MEMORY_SECTION
+ base::ProtectedMemory<PK11HasAttributeSetFunction>
+ g_pk11_has_attribute_set;
+
+// The function pointer for PK11_HasAttributeSet is saved to read-only memory
+// after being dynamically resolved as a security mitigation to prevent the
+// pointer from being tampered with. See https://crbug.com/771365 for details.
+const base::ProtectedMemory<PK11HasAttributeSetFunction>&
+ResolvePK11HasAttributeSet() {
+ static base::ProtectedMemory<PK11HasAttributeSetFunction>::Initializer init(
+ &g_pk11_has_attribute_set,
+ reinterpret_cast<PK11HasAttributeSetFunction>(
+ dlsym(RTLD_DEFAULT, "PK11_HasAttributeSet")));
+ return g_pk11_has_attribute_set;
+}
+
+} // namespace
+
// IsKnownRoot returns true if the given certificate is one that we believe
// is a standard (as opposed to user-installed) root.
bool IsKnownRoot(CERTCertificate* root) {
if (!root || !root->slot)
return false;
+ if (*ResolvePK11HasAttributeSet() != nullptr) {
+ // Historically, the set of root certs was determined based on whether or
+ // not it was part of nssckbi.[so,dll], the read-only PKCS#11 module that
+ // exported the certs with trust settings. However, some distributions,
+ // notably those in the Red Hat family, replace nssckbi with a redirect to
+ // their own store, such as from p11-kit, which can support more robust
+ // trust settings, like per-system trust, admin-defined, and user-defined
+ // trust.
+ //
+ // As a given certificate may exist in multiple modules and slots, scan
+ // through all of the available modules, all of the (connected) slots on
+ // those modules, and check to see if it has the CKA_NSS_MOZILLA_CA_POLICY
+ // attribute set. This attribute indicates it's from the upstream Mozilla
+ // trust store, and these distributions preserve the attribute as a flag.
+ crypto::AutoSECMODListReadLock lock_id;
+ for (const SECMODModuleList* item = SECMOD_GetDefaultModuleList();
+ item != nullptr; item = item->next) {
+ for (int i = 0; i < item->module->slotCount; ++i) {
+ PK11SlotInfo* slot = item->module->slots[i];
+ if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) {
+ CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, root, nullptr);
+ if (handle != CK_INVALID_HANDLE &&
+ UnsanitizedCfiCall(ResolvePK11HasAttributeSet())(
+ root->slot, handle, CKA_NSS_MOZILLA_CA_POLICY, PR_FALSE) ==
+ CK_TRUE) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
// This magic name is taken from
// http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw/builtins/constants.c&rev=1.13&mark=86,89#79
return 0 == strcmp(PK11_GetSlotName(root->slot), "NSS Builtin Objects");
diff --git a/chromium/net/cert/merkle_tree_leaf.cc b/chromium/net/cert/merkle_tree_leaf.cc
index 07cd4692da4..1030213ac25 100644
--- a/chromium/net/cert/merkle_tree_leaf.cc
+++ b/chromium/net/cert/merkle_tree_leaf.cc
@@ -35,14 +35,14 @@ bool GetMerkleTreeLeaf(const X509Certificate* cert,
const SignedCertificateTimestamp* sct,
MerkleTreeLeaf* merkle_tree_leaf) {
if (sct->origin == SignedCertificateTimestamp::SCT_EMBEDDED) {
- if (cert->GetIntermediateCertificates().empty() ||
- !GetPrecertSignedEntry(cert->os_cert_handle(),
- cert->GetIntermediateCertificates().front(),
+ if (cert->intermediate_buffers().empty() ||
+ !GetPrecertSignedEntry(cert->cert_buffer(),
+ cert->intermediate_buffers().front().get(),
&merkle_tree_leaf->signed_entry)) {
return false;
}
} else {
- if (!GetX509SignedEntry(cert->os_cert_handle(),
+ if (!GetX509SignedEntry(cert->cert_buffer(),
&merkle_tree_leaf->signed_entry)) {
return false;
}
diff --git a/chromium/net/cert/merkle_tree_leaf_unittest.cc b/chromium/net/cert/merkle_tree_leaf_unittest.cc
index 59ac7dceb6e..691c1102e5e 100644
--- a/chromium/net/cert/merkle_tree_leaf_unittest.cc
+++ b/chromium/net/cert/merkle_tree_leaf_unittest.cc
@@ -59,7 +59,7 @@ class MerkleTreeLeafTest : public ::testing::Test {
GetTestCertsDirectory(), "ct-test-embedded-cert.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_TRUE(test_precert_);
- ASSERT_EQ(1u, test_precert_->GetIntermediateCertificates().size());
+ ASSERT_EQ(1u, test_precert_->intermediate_buffers().size());
GetPrecertSCT(&precert_sct_);
precert_sct_->origin = SignedCertificateTimestamp::SCT_EMBEDDED;
}
diff --git a/chromium/net/cert/multi_log_ct_verifier.cc b/chromium/net/cert/multi_log_ct_verifier.cc
index 784924a55d2..791ddca2102 100644
--- a/chromium/net/cert/multi_log_ct_verifier.cc
+++ b/chromium/net/cert/multi_log_ct_verifier.cc
@@ -81,7 +81,12 @@ void MultiLogCTVerifier::SetObserver(Observer* observer) {
observer_ = observer;
}
+CTVerifier::Observer* MultiLogCTVerifier::GetObserver() const {
+ return observer_;
+}
+
void MultiLogCTVerifier::Verify(
+ base::StringPiece hostname,
X509Certificate* cert,
base::StringPiece stapled_ocsp_response,
base::StringPiece sct_list_from_tls_extension,
@@ -93,26 +98,23 @@ void MultiLogCTVerifier::Verify(
output_scts->clear();
std::string embedded_scts;
- if (!cert->GetIntermediateCertificates().empty() &&
- ct::ExtractEmbeddedSCTList(
- cert->os_cert_handle(),
- &embedded_scts)) {
+ if (!cert->intermediate_buffers().empty() &&
+ ct::ExtractEmbeddedSCTList(cert->cert_buffer(), &embedded_scts)) {
ct::SignedEntryData precert_entry;
- if (ct::GetPrecertSignedEntry(cert->os_cert_handle(),
- cert->GetIntermediateCertificates().front(),
+ if (ct::GetPrecertSignedEntry(cert->cert_buffer(),
+ cert->intermediate_buffers().front().get(),
&precert_entry)) {
- VerifySCTs(embedded_scts, precert_entry,
+ VerifySCTs(hostname, embedded_scts, precert_entry,
ct::SignedCertificateTimestamp::SCT_EMBEDDED, cert,
output_scts);
}
}
std::string sct_list_from_ocsp;
- if (!stapled_ocsp_response.empty() &&
- !cert->GetIntermediateCertificates().empty()) {
+ if (!stapled_ocsp_response.empty() && !cert->intermediate_buffers().empty()) {
ct::ExtractSCTListFromOCSPResponse(
- cert->GetIntermediateCertificates().front(), cert->serial_number(),
+ cert->intermediate_buffers().front().get(), cert->serial_number(),
stapled_ocsp_response, &sct_list_from_ocsp);
}
@@ -126,12 +128,12 @@ void MultiLogCTVerifier::Verify(
net_log_callback);
ct::SignedEntryData x509_entry;
- if (ct::GetX509SignedEntry(cert->os_cert_handle(), &x509_entry)) {
- VerifySCTs(sct_list_from_ocsp, x509_entry,
+ if (ct::GetX509SignedEntry(cert->cert_buffer(), &x509_entry)) {
+ VerifySCTs(hostname, sct_list_from_ocsp, x509_entry,
ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, cert,
output_scts);
- VerifySCTs(sct_list_from_tls_extension, x509_entry,
+ VerifySCTs(hostname, sct_list_from_tls_extension, x509_entry,
ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, cert,
output_scts);
}
@@ -146,6 +148,7 @@ void MultiLogCTVerifier::Verify(
}
void MultiLogCTVerifier::VerifySCTs(
+ base::StringPiece hostname,
base::StringPiece encoded_sct_list,
const ct::SignedEntryData& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
@@ -171,11 +174,12 @@ void MultiLogCTVerifier::VerifySCTs(
}
decoded_sct->origin = origin;
- VerifySingleSCT(decoded_sct, expected_entry, cert, output_scts);
+ VerifySingleSCT(hostname, decoded_sct, expected_entry, cert, output_scts);
}
}
bool MultiLogCTVerifier::VerifySingleSCT(
+ base::StringPiece hostname,
scoped_refptr<ct::SignedCertificateTimestamp> sct,
const ct::SignedEntryData& expected_entry,
X509Certificate* cert,
@@ -205,7 +209,7 @@ bool MultiLogCTVerifier::VerifySingleSCT(
AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, output_scts);
if (observer_)
- observer_->OnSCTVerified(cert, sct.get());
+ observer_->OnSCTVerified(hostname, cert, sct.get());
return true;
}
diff --git a/chromium/net/cert/multi_log_ct_verifier.h b/chromium/net/cert/multi_log_ct_verifier.h
index 3a69b5e22a3..af389d6f4cc 100644
--- a/chromium/net/cert/multi_log_ct_verifier.h
+++ b/chromium/net/cert/multi_log_ct_verifier.h
@@ -35,26 +35,30 @@ class NET_EXPORT MultiLogCTVerifier : public CTVerifier {
const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers);
// CTVerifier implementation:
- void Verify(X509Certificate* cert,
+ void Verify(base::StringPiece hostname,
+ X509Certificate* cert,
base::StringPiece stapled_ocsp_response,
base::StringPiece sct_list_from_tls_extension,
SignedCertificateTimestampAndStatusList* output_scts,
const NetLogWithSource& net_log) override;
void SetObserver(Observer* observer) override;
+ Observer* GetObserver() const override;
private:
// Verify a list of SCTs from |encoded_sct_list| over |expected_entry|,
// placing the verification results in |output_scts|. The SCTs in the list
// come from |origin| (as will be indicated in the origin field of each SCT).
- void VerifySCTs(base::StringPiece encoded_sct_list,
+ void VerifySCTs(base::StringPiece hostname,
+ base::StringPiece encoded_sct_list,
const ct::SignedEntryData& expected_entry,
ct::SignedCertificateTimestamp::Origin origin,
X509Certificate* cert,
SignedCertificateTimestampAndStatusList* output_scts);
// Verifies a single, parsed SCT against all logs.
- bool VerifySingleSCT(scoped_refptr<ct::SignedCertificateTimestamp> sct,
+ bool VerifySingleSCT(base::StringPiece hostname,
+ scoped_refptr<ct::SignedCertificateTimestamp> sct,
const ct::SignedEntryData& expected_entry,
X509Certificate* cert,
SignedCertificateTimestampAndStatusList* output_scts);
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index fa4a894e653..e12a567d314 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -38,14 +38,16 @@ namespace net {
namespace {
+const char kHostname[] = "example.com";
const char kLogDescription[] = "somelog";
const char kSCTCountHistogram[] =
"Net.CertificateTransparency.SCTsPerConnection";
class MockSCTObserver : public CTVerifier::Observer {
public:
- MOCK_METHOD2(OnSCTVerified,
- void(X509Certificate* cert,
+ MOCK_METHOD3(OnSCTVerified,
+ void(base::StringPiece hostname,
+ X509Certificate* cert,
const ct::SignedCertificateTimestamp* sct));
};
@@ -111,12 +113,12 @@ class MultiLogCTVerifierTest : public ::testing::Test {
return true;
}
- // Returns true is |chain| is a certificate with embedded SCTs that can be
+ // Returns true if |chain| is a certificate with embedded SCTs that can be
// successfully extracted.
bool VerifySinglePrecertificateChain(scoped_refptr<X509Certificate> chain) {
SignedCertificateTimestampAndStatusList scts;
- verifier_->Verify(chain.get(), base::StringPiece(), base::StringPiece(),
- &scts, NetLogWithSource());
+ verifier_->Verify(kHostname, chain.get(), base::StringPiece(),
+ base::StringPiece(), &scts, NetLogWithSource());
return !scts.empty();
}
@@ -128,8 +130,8 @@ class MultiLogCTVerifierTest : public ::testing::Test {
TestNetLog test_net_log;
NetLogWithSource net_log = NetLogWithSource::Make(
&test_net_log, NetLogSourceType::SSL_CONNECT_JOB);
- verifier_->Verify(chain.get(), base::StringPiece(), base::StringPiece(),
- &scts, net_log);
+ verifier_->Verify(kHostname, chain.get(), base::StringPiece(),
+ base::StringPiece(), &scts, net_log);
return ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription) &&
ct::CheckForSCTOrigin(
scts, ct::SignedCertificateTimestamp::SCT_EMBEDDED) &&
@@ -207,8 +209,8 @@ TEST_F(MultiLogCTVerifierTest, VerifiesSCTOverX509Cert) {
std::string sct_list = ct::GetSCTListForTesting();
SignedCertificateTimestampAndStatusList scts;
- verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
- NetLogWithSource());
+ verifier_->Verify(kHostname, chain_.get(), base::StringPiece(), sct_list,
+ &scts, NetLogWithSource());
ASSERT_TRUE(ct::CheckForSingleVerifiedSCTInResult(scts, kLogDescription));
ASSERT_TRUE(ct::CheckForSCTOrigin(
scts, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
@@ -218,8 +220,8 @@ TEST_F(MultiLogCTVerifierTest, IdentifiesSCTFromUnknownLog) {
std::string sct_list = ct::GetSCTListWithInvalidSCT();
SignedCertificateTimestampAndStatusList scts;
- verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
- NetLogWithSource());
+ verifier_->Verify(kHostname, chain_.get(), base::StringPiece(), sct_list,
+ &scts, NetLogWithSource());
EXPECT_EQ(1U, scts.size());
EXPECT_EQ("", scts[0].sct->log_description);
EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, scts[0].status);
@@ -241,8 +243,8 @@ TEST_F(MultiLogCTVerifierTest, CountsInvalidSCTsInStatusHistogram) {
int num_invalid_scts = GetValueFromHistogram(
"Net.CertificateTransparency.SCTStatus", ct::SCT_STATUS_LOG_UNKNOWN);
- verifier_->Verify(chain_.get(), base::StringPiece(), sct_list, &scts,
- NetLogWithSource());
+ verifier_->Verify(kHostname, chain_.get(), base::StringPiece(), sct_list,
+ &scts, NetLogWithSource());
ASSERT_EQ(num_valid_scts, NumValidSCTsInStatusHistogram());
ASSERT_EQ(num_invalid_scts + 1,
@@ -273,7 +275,8 @@ TEST_F(MultiLogCTVerifierTest, NotifiesOfValidSCT) {
MockSCTObserver observer;
verifier_->SetObserver(&observer);
- EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _));
+ EXPECT_CALL(observer, OnSCTVerified(base::StringPiece(kHostname),
+ embedded_sct_chain_.get(), _));
ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_));
}
@@ -281,11 +284,15 @@ TEST_F(MultiLogCTVerifierTest, StopsNotifyingCorrectly) {
MockSCTObserver observer;
verifier_->SetObserver(&observer);
- EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(1);
+ EXPECT_CALL(observer, OnSCTVerified(base::StringPiece(kHostname),
+ embedded_sct_chain_.get(), _))
+ .Times(1);
ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_));
Mock::VerifyAndClearExpectations(&observer);
- EXPECT_CALL(observer, OnSCTVerified(embedded_sct_chain_.get(), _)).Times(0);
+ EXPECT_CALL(observer, OnSCTVerified(base::StringPiece(kHostname),
+ embedded_sct_chain_.get(), _))
+ .Times(0);
verifier_->SetObserver(nullptr);
ASSERT_TRUE(VerifySinglePrecertificateChain(embedded_sct_chain_));
}
diff --git a/chromium/net/cert/nss_cert_database_unittest.cc b/chromium/net/cert/nss_cert_database_unittest.cc
index d1753aefb3b..7781ea4fd5f 100644
--- a/chromium/net/cert/nss_cert_database_unittest.cc
+++ b/chromium/net/cert/nss_cert_database_unittest.cc
@@ -117,9 +117,8 @@ class CertDatabaseNSSTest : public testing::Test {
std::sort(
result.begin(), result.end(),
[](const ScopedCERTCertificate& lhs, const ScopedCERTCertificate& rhs) {
- return SHA256HashValueLessThan()(
- x509_util::CalculateFingerprint256(lhs.get()),
- x509_util::CalculateFingerprint256(rhs.get()));
+ return x509_util::CalculateFingerprint256(lhs.get()) <
+ x509_util::CalculateFingerprint256(rhs.get());
});
return result;
}
@@ -383,7 +382,7 @@ TEST_F(CertDatabaseNSSTest, ImportCA_NotCACert) {
ASSERT_EQ(1U, failed.size());
// Note: this compares pointers directly. It's okay in this case because
// ImportCACerts returns the same pointers that were passed in. In the
- // general case IsSameOSCert should be used.
+ // general case x509_util::CryptoBufferEqual should be used.
EXPECT_EQ(certs[0], failed[0].certificate);
EXPECT_THAT(failed[0].net_error, IsError(ERR_IMPORT_CA_CERT_NOT_CA));
diff --git a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
index 33019166744..4c2cdef83d6 100644
--- a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
+++ b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc
@@ -55,9 +55,8 @@ ScopedCERTCertificateList ListCertsInSlot(PK11SlotInfo* slot) {
std::sort(
result.begin(), result.end(),
[](const ScopedCERTCertificate& lhs, const ScopedCERTCertificate& rhs) {
- return SHA256HashValueLessThan()(
- x509_util::CalculateFingerprint256(lhs.get()),
- x509_util::CalculateFingerprint256(rhs.get()));
+ return x509_util::CalculateFingerprint256(lhs.get()) <
+ x509_util::CalculateFingerprint256(rhs.get());
});
return result;
}
diff --git a/chromium/net/cert/symantec_certs.cc b/chromium/net/cert/symantec_certs.cc
index 3a1d3886a84..fdaafdf338b 100644
--- a/chromium/net/cert/symantec_certs.cc
+++ b/chromium/net/cert/symantec_certs.cc
@@ -193,9 +193,15 @@ const SHA256HashValue kSymantecExceptions[] = {
{{0x72, 0x89, 0xc0, 0x6d, 0xed, 0xd1, 0x6b, 0x71, 0xa7, 0xdc, 0xca,
0x66, 0x57, 0x85, 0x72, 0xe2, 0xe1, 0x09, 0xb1, 0x1d, 0x70, 0xad,
0x04, 0xc2, 0x60, 0x1b, 0x67, 0x43, 0xbc, 0x66, 0xd0, 0x7b}},
+ {{0x8b, 0xb5, 0x93, 0xa9, 0x3b, 0xe1, 0xd0, 0xe8, 0xa8, 0x22, 0xbb,
+ 0x88, 0x7c, 0x54, 0x78, 0x90, 0xc3, 0xe7, 0x06, 0xaa, 0xd2, 0xda,
+ 0xb7, 0x62, 0x54, 0xf9, 0x7f, 0xb3, 0x6b, 0x82, 0xfc, 0x26}},
{{0xb5, 0xcf, 0x82, 0xd4, 0x7e, 0xf9, 0x82, 0x3f, 0x9a, 0xa7, 0x8f,
0x12, 0x31, 0x86, 0xc5, 0x2e, 0x88, 0x79, 0xea, 0x84, 0xb0, 0xf8,
0x22, 0xc9, 0x1d, 0x83, 0xe0, 0x42, 0x79, 0xb7, 0x8f, 0xd5}},
+ {{0xb9, 0x4c, 0x19, 0x83, 0x00, 0xce, 0xc5, 0xc0, 0x57, 0xad, 0x07,
+ 0x27, 0xb7, 0x0b, 0xbe, 0x91, 0x81, 0x69, 0x92, 0x25, 0x64, 0x39,
+ 0xa7, 0xb3, 0x2f, 0x45, 0x98, 0x11, 0x9d, 0xda, 0x9c, 0x97}},
{{0xc0, 0x55, 0x4b, 0xde, 0x87, 0xa0, 0x75, 0xec, 0x13, 0xa6, 0x1f,
0x27, 0x59, 0x83, 0xae, 0x02, 0x39, 0x57, 0x29, 0x4b, 0x45, 0x4c,
0xaf, 0x0a, 0x97, 0x24, 0xe3, 0xb2, 0x1b, 0x79, 0x35, 0xbc}},
@@ -212,11 +218,24 @@ const SHA256HashValue kSymantecExceptions[] = {
const size_t kSymantecExceptionsLength = arraysize(kSymantecExceptions);
+const SHA256HashValue kSymantecManagedCAs[] = {
+ {{0x7c, 0xac, 0x9a, 0x0f, 0xf3, 0x15, 0x38, 0x77, 0x50, 0xba, 0x8b,
+ 0xaf, 0xdb, 0x1c, 0x2b, 0xc2, 0x9b, 0x3f, 0x0b, 0xba, 0x16, 0x36,
+ 0x2c, 0xa9, 0x3a, 0x90, 0xf8, 0x4d, 0xa2, 0xdf, 0x5f, 0x3e}},
+ {{0xac, 0x50, 0xb5, 0xfb, 0x73, 0x8a, 0xed, 0x6c, 0xb7, 0x81, 0xcc,
+ 0x35, 0xfb, 0xff, 0xf7, 0x78, 0x6f, 0x77, 0x10, 0x9a, 0xda, 0x7c,
+ 0x08, 0x86, 0x7c, 0x04, 0xa5, 0x73, 0xfd, 0x5c, 0xf9, 0xee}},
+};
+
+const size_t kSymantecManagedCAsLength = arraysize(kSymantecManagedCAs);
+
bool IsLegacySymantecCert(const HashValueVector& public_key_hashes) {
return IsAnySHA256HashInSortedArray(public_key_hashes, kSymantecRoots,
kSymantecRootsLength) &&
- !IsAnySHA256HashInSortedArray(public_key_hashes, kSymantecExceptions,
- kSymantecExceptionsLength);
+ !(IsAnySHA256HashInSortedArray(public_key_hashes, kSymantecExceptions,
+ kSymantecExceptionsLength) ||
+ IsAnySHA256HashInSortedArray(public_key_hashes, kSymantecManagedCAs,
+ kSymantecManagedCAsLength));
}
} // namespace net
diff --git a/chromium/net/cert/symantec_certs.h b/chromium/net/cert/symantec_certs.h
index 88e4532aeb1..cf4ad4a8555 100644
--- a/chromium/net/cert/symantec_certs.h
+++ b/chromium/net/cert/symantec_certs.h
@@ -17,12 +17,17 @@ namespace net {
// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
// for details about why.
//
-// Independently operated sub-CAs are exempt from these policies, and are
-// listed in |kSymantecExceptions|.
-extern const SHA256HashValue kSymantecRoots[];
-extern const size_t kSymantecRootsLength;
-extern const SHA256HashValue kSymantecExceptions[];
-extern const size_t kSymantecExceptionsLength;
+// Pre-existing, independently operated sub-CAs are exempt from these
+// policies, and are listed in |kSymantecExceptions|.
+//
+// The Managed Partner CAs are required to disclose via Certificate
+// Transparency, and are listed in |kSymantecManagedCAs|.
+NET_EXPORT_PRIVATE extern const SHA256HashValue kSymantecRoots[];
+NET_EXPORT_PRIVATE extern const size_t kSymantecRootsLength;
+NET_EXPORT_PRIVATE extern const SHA256HashValue kSymantecExceptions[];
+NET_EXPORT_PRIVATE extern const size_t kSymantecExceptionsLength;
+NET_EXPORT_PRIVATE extern const SHA256HashValue kSymantecManagedCAs[];
+NET_EXPORT_PRIVATE extern const size_t kSymantecManagedCAsLength;
// Returns true if |public_key_hashes| contains a certificate issued from
// Symantec's "legacy" PKI. This constraint excludes certificates that were
diff --git a/chromium/net/cert/symantec_certs_unittest.cc b/chromium/net/cert/symantec_certs_unittest.cc
index dcb94ab4037..6a1fff6cb31 100644
--- a/chromium/net/cert/symantec_certs_unittest.cc
+++ b/chromium/net/cert/symantec_certs_unittest.cc
@@ -4,6 +4,9 @@
#include "net/cert/symantec_certs.h"
+#include <algorithm>
+
+#include "net/base/hash_value.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -38,4 +41,13 @@ TEST(SymantecCertsTest, IsLegacySymantecCert) {
EXPECT_FALSE(IsLegacySymantecCert(hashes));
}
+TEST(SymantecCertsTest, AreSortedArrays) {
+ ASSERT_TRUE(
+ std::is_sorted(kSymantecRoots, kSymantecRoots + kSymantecRootsLength));
+ ASSERT_TRUE(std::is_sorted(kSymantecExceptions,
+ kSymantecExceptions + kSymantecExceptionsLength));
+ ASSERT_TRUE(std::is_sorted(kSymantecManagedCAs,
+ kSymantecManagedCAs + kSymantecManagedCAsLength));
+}
+
} // namespace net
diff --git a/chromium/net/cert/test_root_certs_android.cc b/chromium/net/cert/test_root_certs_android.cc
index 44cd1f9d674..6160fa379c6 100644
--- a/chromium/net/cert/test_root_certs_android.cc
+++ b/chromium/net/cert/test_root_certs_android.cc
@@ -8,16 +8,14 @@
#include "base/logging.h"
#include "net/android/network_library.h"
#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
bool TestRootCerts::Add(X509Certificate* certificate) {
- std::string cert_bytes;
- if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(),
- &cert_bytes))
- return false;
android::AddTestRootCertificate(
- reinterpret_cast<const uint8_t*>(cert_bytes.data()), cert_bytes.size());
+ CRYPTO_BUFFER_data(certificate->cert_buffer()),
+ CRYPTO_BUFFER_len(certificate->cert_buffer()));
empty_ = false;
return true;
}
diff --git a/chromium/net/cert/test_root_certs_fuchsia.cc b/chromium/net/cert/test_root_certs_fuchsia.cc
index b0bd830f309..cd909be2198 100644
--- a/chromium/net/cert/test_root_certs_fuchsia.cc
+++ b/chromium/net/cert/test_root_certs_fuchsia.cc
@@ -9,6 +9,7 @@
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
@@ -16,8 +17,7 @@ namespace net {
bool TestRootCerts::Add(X509Certificate* certificate) {
CertErrors errors;
auto parsed = ParsedCertificate::Create(
- bssl::UniquePtr<CRYPTO_BUFFER>(
- X509Certificate::DupOSCertHandle(certificate->os_cert_handle())),
+ x509_util::DupCryptoBuffer(certificate->cert_buffer()),
ParseCertificateOptions(), &errors);
if (!parsed) {
LOG(ERROR) << "Failed to parse DER certificate: " << errors.ToDebugString();
diff --git a/chromium/net/cert/test_root_certs_mac.cc b/chromium/net/cert/test_root_certs_mac.cc
index 876395fc976..9e0206a3c71 100644
--- a/chromium/net/cert/test_root_certs_mac.cc
+++ b/chromium/net/cert/test_root_certs_mac.cc
@@ -33,12 +33,8 @@ bool TestRootCerts::Add(X509Certificate* certificate) {
// Add the certificate to the parallel |test_trust_store_|.
CertErrors errors;
- std::string cert_bytes;
- if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(),
- &cert_bytes))
- return false;
scoped_refptr<ParsedCertificate> parsed = ParsedCertificate::Create(
- x509_util::CreateCryptoBuffer(cert_bytes),
+ x509_util::DupCryptoBuffer(certificate->cert_buffer()),
x509_util::DefaultParseCertificateOptions(), &errors);
if (!parsed)
return false;
diff --git a/chromium/net/cert/test_root_certs_win.cc b/chromium/net/cert/test_root_certs_win.cc
index 3c900ca346d..8bf74cdabd8 100644
--- a/chromium/net/cert/test_root_certs_win.cc
+++ b/chromium/net/cert/test_root_certs_win.cc
@@ -11,6 +11,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/win/win_util.h"
#include "net/cert/x509_certificate.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
@@ -143,12 +144,12 @@ bool TestRootCerts::Add(X509Certificate* certificate) {
// happen.
g_capi_injector.Get();
- std::string der_cert;
- X509Certificate::GetDEREncoded(certificate->os_cert_handle(), &der_cert);
BOOL ok = CertAddEncodedCertificateToStore(
temporary_roots_, X509_ASN_ENCODING,
- reinterpret_cast<const BYTE*>(der_cert.data()),
- base::checked_cast<DWORD>(der_cert.size()), CERT_STORE_ADD_NEW, NULL);
+ reinterpret_cast<const BYTE*>(
+ CRYPTO_BUFFER_data(certificate->cert_buffer())),
+ base::checked_cast<DWORD>(CRYPTO_BUFFER_len(certificate->cert_buffer())),
+ CERT_STORE_ADD_NEW, NULL);
if (!ok) {
// If the certificate is already added, return successfully.
return GetLastError() == static_cast<DWORD>(CRYPT_E_EXISTS);
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index 370d4abbe40..ffc90d02cee 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -145,10 +145,10 @@ bool GetNormalizedCertIssuer(CRYPTO_BUFFER* cert,
// Parses certificates from a PKCS#7 SignedData structure, appending them to
// |handles|.
-void CreateOSCertHandlesFromPKCS7Bytes(
+void CreateCertBuffersFromPKCS7Bytes(
const char* data,
size_t length,
- X509Certificate::OSCertHandles* handles) {
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>* handles) {
crypto::EnsureOpenSSLInit();
crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
@@ -159,7 +159,8 @@ void CreateOSCertHandlesFromPKCS7Bytes(
if (PKCS7_get_raw_certificates(certs, &der_data,
x509_util::GetBufferPool())) {
for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(certs); ++i) {
- handles->push_back(sk_CRYPTO_BUFFER_value(certs, i));
+ handles->push_back(
+ bssl::UniquePtr<CRYPTO_BUFFER>(sk_CRYPTO_BUFFER_value(certs, i)));
}
}
// |handles| took ownership of the individual buffers, so only free the list
@@ -170,26 +171,26 @@ void CreateOSCertHandlesFromPKCS7Bytes(
} // namespace
// static
-scoped_refptr<X509Certificate> X509Certificate::CreateFromHandle(
- OSCertHandle cert_handle,
- const OSCertHandles& intermediates) {
- DCHECK(cert_handle);
+scoped_refptr<X509Certificate> X509Certificate::CreateFromBuffer(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) {
+ DCHECK(cert_buffer);
scoped_refptr<X509Certificate> cert(
- new X509Certificate(cert_handle, intermediates));
- if (!cert->os_cert_handle())
+ new X509Certificate(std::move(cert_buffer), std::move(intermediates)));
+ if (!cert->cert_buffer())
return nullptr; // Initialize() failed.
return cert;
}
// static
-scoped_refptr<X509Certificate> X509Certificate::CreateFromHandleUnsafeOptions(
- OSCertHandle cert_handle,
- const OSCertHandles& intermediates,
+scoped_refptr<X509Certificate> X509Certificate::CreateFromBufferUnsafeOptions(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
UnsafeCreateOptions options) {
- DCHECK(cert_handle);
- scoped_refptr<X509Certificate> cert(
- new X509Certificate(cert_handle, intermediates, options));
- if (!cert->os_cert_handle())
+ DCHECK(cert_buffer);
+ scoped_refptr<X509Certificate> cert(new X509Certificate(
+ std::move(cert_buffer), std::move(intermediates), options));
+ if (!cert->cert_buffer())
return nullptr; // Initialize() failed.
return cert;
}
@@ -197,36 +198,39 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromHandleUnsafeOptions(
// static
scoped_refptr<X509Certificate> X509Certificate::CreateFromDERCertChain(
const std::vector<base::StringPiece>& der_certs) {
+ return CreateFromDERCertChainUnsafeOptions(der_certs, {});
+}
+
+// static
+scoped_refptr<X509Certificate>
+X509Certificate::CreateFromDERCertChainUnsafeOptions(
+ const std::vector<base::StringPiece>& der_certs,
+ UnsafeCreateOptions options) {
TRACE_EVENT0("io", "X509Certificate::CreateFromDERCertChain");
if (der_certs.empty())
- return NULL;
+ return nullptr;
- X509Certificate::OSCertHandles intermediate_ca_certs;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_ca_certs;
+ intermediate_ca_certs.reserve(der_certs.size() - 1);
for (size_t i = 1; i < der_certs.size(); i++) {
- OSCertHandle handle = CreateOSCertHandleFromBytes(
+ bssl::UniquePtr<CRYPTO_BUFFER> handle = CreateCertBufferFromBytes(
const_cast<char*>(der_certs[i].data()), der_certs[i].size());
if (!handle)
break;
- intermediate_ca_certs.push_back(handle);
+ intermediate_ca_certs.push_back(std::move(handle));
}
- OSCertHandle handle = NULL;
// Return NULL if we failed to parse any of the certs.
- if (der_certs.size() - 1 == intermediate_ca_certs.size()) {
- handle = CreateOSCertHandleFromBytes(
- const_cast<char*>(der_certs[0].data()), der_certs[0].size());
- }
-
- scoped_refptr<X509Certificate> cert = nullptr;
- if (handle) {
- cert = CreateFromHandle(handle, intermediate_ca_certs);
- FreeOSCertHandle(handle);
- }
+ if (der_certs.size() - 1 != intermediate_ca_certs.size())
+ return nullptr;
- for (size_t i = 0; i < intermediate_ca_certs.size(); i++)
- FreeOSCertHandle(intermediate_ca_certs[i]);
+ bssl::UniquePtr<CRYPTO_BUFFER> handle = CreateCertBufferFromBytes(
+ const_cast<char*>(der_certs[0].data()), der_certs[0].size());
+ if (!handle)
+ return nullptr;
- return cert;
+ return CreateFromBufferUnsafeOptions(
+ std::move(handle), std::move(intermediate_ca_certs), options);
}
// static
@@ -241,19 +245,26 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromBytesUnsafeOptions(
const char* data,
size_t length,
UnsafeCreateOptions options) {
- OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length);
- if (!cert_handle)
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer =
+ CreateCertBufferFromBytes(data, length);
+ if (!cert_buffer)
return NULL;
scoped_refptr<X509Certificate> cert =
- CreateFromHandleUnsafeOptions(cert_handle, {}, options);
- FreeOSCertHandle(cert_handle);
+ CreateFromBufferUnsafeOptions(std::move(cert_buffer), {}, options);
return cert;
}
// static
scoped_refptr<X509Certificate> X509Certificate::CreateFromPickle(
base::PickleIterator* pickle_iter) {
+ return CreateFromPickleUnsafeOptions(pickle_iter, {});
+}
+
+// static
+scoped_refptr<X509Certificate> X509Certificate::CreateFromPickleUnsafeOptions(
+ base::PickleIterator* pickle_iter,
+ UnsafeCreateOptions options) {
int chain_length = 0;
if (!pickle_iter->ReadLength(&chain_length))
return nullptr;
@@ -266,7 +277,7 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromPickle(
return nullptr;
cert_chain.push_back(base::StringPiece(data, data_length));
}
- return CreateFromDERCertChain(cert_chain);
+ return CreateFromDERCertChainUnsafeOptions(cert_chain, options);
}
// static
@@ -274,7 +285,7 @@ CertificateList X509Certificate::CreateCertificateListFromBytes(
const char* data,
size_t length,
int format) {
- OSCertHandles certificates;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certificates;
// Check to see if it is in a PEM-encoded form. This check is performed
// first, as both OS X and NSS will both try to convert if they detect
@@ -292,14 +303,14 @@ CertificateList X509Certificate::CreateCertificateListFromBytes(
while (pem_tokenizer.GetNext()) {
std::string decoded(pem_tokenizer.data());
- OSCertHandle handle = NULL;
+ bssl::UniquePtr<CRYPTO_BUFFER> handle;
if (format & FORMAT_PEM_CERT_SEQUENCE)
- handle = CreateOSCertHandleFromBytes(decoded.c_str(), decoded.size());
- if (handle != NULL) {
+ handle = CreateCertBufferFromBytes(decoded.c_str(), decoded.size());
+ if (handle) {
// Parsed a DER encoded certificate. All PEM blocks that follow must
// also be DER encoded certificates wrapped inside of PEM blocks.
format = FORMAT_PEM_CERT_SEQUENCE;
- certificates.push_back(handle);
+ certificates.push_back(std::move(handle));
continue;
}
@@ -310,8 +321,8 @@ CertificateList X509Certificate::CreateCertificateListFromBytes(
for (size_t i = 0; certificates.empty() &&
i < arraysize(kFormatDecodePriority); ++i) {
if (format & kFormatDecodePriority[i]) {
- certificates = CreateOSCertHandlesFromBytes(decoded.c_str(),
- decoded.size(), kFormatDecodePriority[i]);
+ certificates = CreateCertBuffersFromBytes(
+ decoded.c_str(), decoded.size(), kFormatDecodePriority[i]);
}
}
}
@@ -329,8 +340,8 @@ CertificateList X509Certificate::CreateCertificateListFromBytes(
for (size_t i = 0; certificates.empty() &&
i < arraysize(kFormatDecodePriority); ++i) {
if (format & kFormatDecodePriority[i])
- certificates = CreateOSCertHandlesFromBytes(data, length,
- kFormatDecodePriority[i]);
+ certificates =
+ CreateCertBuffersFromBytes(data, length, kFormatDecodePriority[i]);
}
CertificateList results;
@@ -338,29 +349,28 @@ CertificateList X509Certificate::CreateCertificateListFromBytes(
if (certificates.empty())
return results;
- for (OSCertHandles::iterator it = certificates.begin();
- it != certificates.end(); ++it) {
- scoped_refptr<X509Certificate> cert =
- CreateFromHandle(*it, OSCertHandles());
+ for (auto& it : certificates) {
+ scoped_refptr<X509Certificate> cert = CreateFromBuffer(std::move(it), {});
if (cert)
results.push_back(std::move(cert));
- FreeOSCertHandle(*it);
}
return results;
}
void X509Certificate::Persist(base::Pickle* pickle) {
- DCHECK(cert_handle_);
+ DCHECK(cert_buffer_);
// This would be an absolutely insane number of intermediates.
if (intermediate_ca_certs_.size() > static_cast<size_t>(INT_MAX) - 1) {
NOTREACHED();
return;
}
pickle->WriteInt(static_cast<int>(intermediate_ca_certs_.size() + 1));
- pickle->WriteString(x509_util::CryptoBufferAsStringPiece(cert_handle_));
- for (auto* intermediate : intermediate_ca_certs_)
- pickle->WriteString(x509_util::CryptoBufferAsStringPiece(intermediate));
+ pickle->WriteString(x509_util::CryptoBufferAsStringPiece(cert_buffer_.get()));
+ for (const auto& intermediate : intermediate_ca_certs_) {
+ pickle->WriteString(
+ x509_util::CryptoBufferAsStringPiece(intermediate.get()));
+ }
}
void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
@@ -380,8 +390,8 @@ bool X509Certificate::GetSubjectAltName(
der::Input tbs_certificate_tlv;
der::Input signature_algorithm_tlv;
der::BitString signature_value;
- if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle_),
- CRYPTO_BUFFER_len(cert_handle_)),
+ if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_buffer_.get()),
+ CRYPTO_BUFFER_len(cert_buffer_.get())),
&tbs_certificate_tlv, &signature_algorithm_tlv,
&signature_value, nullptr)) {
return false;
@@ -432,7 +442,8 @@ bool X509Certificate::HasExpired() const {
}
bool X509Certificate::Equals(const X509Certificate* other) const {
- return IsSameOSCert(cert_handle_, other->cert_handle_);
+ return x509_util::CryptoBufferEqual(cert_buffer_.get(),
+ other->cert_buffer_.get());
}
bool X509Certificate::IsIssuedByEncoded(
@@ -450,13 +461,13 @@ bool X509Certificate::IsIssuedByEncoded(
}
std::string normalized_cert_issuer;
- if (!GetNormalizedCertIssuer(cert_handle_, &normalized_cert_issuer))
+ if (!GetNormalizedCertIssuer(cert_buffer_.get(), &normalized_cert_issuer))
return false;
if (base::ContainsValue(normalized_issuers, normalized_cert_issuer))
return true;
- for (CRYPTO_BUFFER* intermediate : intermediate_ca_certs_) {
- if (!GetNormalizedCertIssuer(intermediate, &normalized_cert_issuer))
+ for (const auto& intermediate : intermediate_ca_certs_) {
+ if (!GetNormalizedCertIssuer(intermediate.get(), &normalized_cert_issuer))
return false;
if (base::ContainsValue(normalized_issuers, normalized_cert_issuer))
return true;
@@ -616,18 +627,7 @@ bool X509Certificate::VerifyNameMatch(const std::string& hostname,
}
// static
-bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
- std::string* encoded) {
- if (!cert_handle)
- return false;
- encoded->assign(
- reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)),
- CRYPTO_BUFFER_len(cert_handle));
- return true;
-}
-
-// static
-bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded,
+bool X509Certificate::GetPEMEncodedFromDER(base::StringPiece der_encoded,
std::string* pem_encoded) {
if (der_encoded.empty())
return false;
@@ -649,23 +649,21 @@ bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded,
}
// static
-bool X509Certificate::GetPEMEncoded(OSCertHandle cert_handle,
+bool X509Certificate::GetPEMEncoded(const CRYPTO_BUFFER* cert_buffer,
std::string* pem_encoded) {
- std::string der_encoded;
- if (!GetDEREncoded(cert_handle, &der_encoded))
- return false;
- return GetPEMEncodedFromDER(der_encoded, pem_encoded);
+ return GetPEMEncodedFromDER(x509_util::CryptoBufferAsStringPiece(cert_buffer),
+ pem_encoded);
}
bool X509Certificate::GetPEMEncodedChain(
std::vector<std::string>* pem_encoded) const {
std::vector<std::string> encoded_chain;
std::string pem_data;
- if (!GetPEMEncoded(os_cert_handle(), &pem_data))
+ if (!GetPEMEncoded(cert_buffer(), &pem_data))
return false;
encoded_chain.push_back(pem_data);
for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
- if (!GetPEMEncoded(intermediate_ca_certs_[i], &pem_data))
+ if (!GetPEMEncoded(intermediate_ca_certs_[i].get(), &pem_data))
return false;
encoded_chain.push_back(pem_data);
}
@@ -674,7 +672,7 @@ bool X509Certificate::GetPEMEncodedChain(
}
// static
-void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
+void X509Certificate::GetPublicKeyInfo(const CRYPTO_BUFFER* cert_buffer,
size_t* size_bits,
PublicKeyType* type) {
*type = kPublicKeyTypeUnknown;
@@ -683,8 +681,8 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
base::StringPiece spki;
if (!asn1::ExtractSPKIFromDERCert(
base::StringPiece(
- reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)),
- CRYPTO_BUFFER_len(cert_handle)),
+ reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_buffer)),
+ CRYPTO_BUFFER_len(cert_buffer)),
&spki)) {
return;
}
@@ -715,18 +713,7 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
}
// static
-bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
- X509Certificate::OSCertHandle b) {
- DCHECK(a && b);
- if (a == b)
- return true;
- return CRYPTO_BUFFER_len(a) == CRYPTO_BUFFER_len(b) &&
- memcmp(CRYPTO_BUFFER_data(a), CRYPTO_BUFFER_data(b),
- CRYPTO_BUFFER_len(a)) == 0;
-}
-
-// static
-X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
+bssl::UniquePtr<CRYPTO_BUFFER> X509Certificate::CreateCertBufferFromBytes(
const char* data,
size_t length) {
der::Input tbs_certificate_tlv;
@@ -742,26 +729,27 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
return nullptr;
}
- return CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(data), length,
- x509_util::GetBufferPool());
+ return x509_util::CreateCryptoBuffer(reinterpret_cast<const uint8_t*>(data),
+ length);
}
// static
-X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
- const char* data,
- size_t length,
- Format format) {
- OSCertHandles results;
+std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>
+X509Certificate::CreateCertBuffersFromBytes(const char* data,
+ size_t length,
+ Format format) {
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> results;
switch (format) {
case FORMAT_SINGLE_CERTIFICATE: {
- OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
+ bssl::UniquePtr<CRYPTO_BUFFER> handle =
+ CreateCertBufferFromBytes(data, length);
if (handle)
- results.push_back(handle);
+ results.push_back(std::move(handle));
break;
}
case FORMAT_PKCS7: {
- CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
+ CreateCertBuffersFromPKCS7Bytes(data, length, &results);
break;
}
default: {
@@ -774,19 +762,8 @@ X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
}
// static
-X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
- OSCertHandle cert_handle) {
- CRYPTO_BUFFER_up_ref(cert_handle);
- return cert_handle;
-}
-
-// static
-void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
- CRYPTO_BUFFER_free(cert_handle);
-}
-
-// static
-SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+SHA256HashValue X509Certificate::CalculateFingerprint256(
+ const CRYPTO_BUFFER* cert) {
SHA256HashValue sha256;
SHA256(CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert), sha256.data);
@@ -799,11 +776,11 @@ SHA256HashValue X509Certificate::CalculateChainFingerprint256() const {
SHA256_CTX sha256_ctx;
SHA256_Init(&sha256_ctx);
- SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert_handle_),
- CRYPTO_BUFFER_len(cert_handle_));
- for (CRYPTO_BUFFER* cert : intermediate_ca_certs_) {
- SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert),
- CRYPTO_BUFFER_len(cert));
+ SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert_buffer_.get()),
+ CRYPTO_BUFFER_len(cert_buffer_.get()));
+ for (const auto& cert : intermediate_ca_certs_) {
+ SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert.get()),
+ CRYPTO_BUFFER_len(cert.get()));
}
SHA256_Final(sha256.data, &sha256_ctx);
@@ -811,12 +788,12 @@ SHA256HashValue X509Certificate::CalculateChainFingerprint256() const {
}
// static
-bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
+bool X509Certificate::IsSelfSigned(const CRYPTO_BUFFER* cert_buffer) {
der::Input tbs_certificate_tlv;
der::Input signature_algorithm_tlv;
der::BitString signature_value;
- if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle),
- CRYPTO_BUFFER_len(cert_handle)),
+ if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_buffer),
+ CRYPTO_BUFFER_len(cert_buffer)),
&tbs_certificate_tlv, &signature_algorithm_tlv,
&signature_value, nullptr)) {
return false;
@@ -856,41 +833,33 @@ bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
signature_value, tbs.spki_tlv);
}
-X509Certificate::X509Certificate(OSCertHandle cert_handle,
- const OSCertHandles& intermediates)
- : X509Certificate(cert_handle, intermediates, {}) {}
+X509Certificate::X509Certificate(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates)
+ : X509Certificate(std::move(cert_buffer), std::move(intermediates), {}) {}
-X509Certificate::X509Certificate(OSCertHandle cert_handle,
- const OSCertHandles& intermediates,
- UnsafeCreateOptions options)
- : cert_handle_(DupOSCertHandle(cert_handle)) {
- for (size_t i = 0; i < intermediates.size(); ++i) {
- // Duplicate the incoming certificate, as the caller retains ownership
- // of |intermediates|.
- intermediate_ca_certs_.push_back(DupOSCertHandle(intermediates[i]));
- }
+X509Certificate::X509Certificate(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
+ UnsafeCreateOptions options)
+ : cert_buffer_(std::move(cert_buffer)),
+ intermediate_ca_certs_(std::move(intermediates)) {
// Platform-specific initialization.
- if (!Initialize(options) && cert_handle_) {
- // Signal initialization failure by clearing cert_handle_.
- FreeOSCertHandle(cert_handle_);
- cert_handle_ = nullptr;
+ if (!Initialize(options) && cert_buffer_) {
+ // Signal initialization failure by clearing cert_buffer_.
+ cert_buffer_.reset();
}
}
-X509Certificate::~X509Certificate() {
- if (cert_handle_)
- FreeOSCertHandle(cert_handle_);
- for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
- FreeOSCertHandle(intermediate_ca_certs_[i]);
-}
+X509Certificate::~X509Certificate() = default;
bool X509Certificate::Initialize(UnsafeCreateOptions options) {
der::Input tbs_certificate_tlv;
der::Input signature_algorithm_tlv;
der::BitString signature_value;
- if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle_),
- CRYPTO_BUFFER_len(cert_handle_)),
+ if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_buffer_.get()),
+ CRYPTO_BUFFER_len(cert_buffer_.get())),
&tbs_certificate_tlv, &signature_algorithm_tlv,
&signature_value, nullptr)) {
return false;
diff --git a/chromium/net/cert/x509_certificate.h b/chromium/net/cert/x509_certificate.h
index 70cc20c122a..9d3af4866e6 100644
--- a/chromium/net/cert/x509_certificate.h
+++ b/chromium/net/cert/x509_certificate.h
@@ -38,15 +38,6 @@ typedef std::vector<scoped_refptr<X509Certificate> > CertificateList;
class NET_EXPORT X509Certificate
: public base::RefCountedThreadSafe<X509Certificate> {
public:
- // An OSCertHandle is a handle to a certificate object in the underlying
- // crypto library. We assume that OSCertHandle is a pointer type on all
- // platforms and that NULL represents an invalid OSCertHandle.
- // TODO(mattm): Remove OSCertHandle type and clean up the interfaces once all
- // platforms use the CRYPTO_BUFFER version.
- typedef CRYPTO_BUFFER* OSCertHandle;
-
- typedef std::vector<OSCertHandle> OSCertHandles;
-
enum PublicKeyType {
kPublicKeyTypeUnknown,
kPublicKeyTypeRSA,
@@ -78,15 +69,15 @@ class NET_EXPORT X509Certificate
FORMAT_PKCS7,
};
- // Create an X509Certificate from a handle to the certificate object in the
- // underlying crypto library. Returns NULL on failure to parse or extract
- // data from the the certificate. Note that this does not guarantee the
- // certificate is fully parsed and validated, only that the members of this
- // class, such as subject, issuer, expiry times, and serial number, could be
- // successfully initialized from the certificate.
- static scoped_refptr<X509Certificate> CreateFromHandle(
- OSCertHandle cert_handle,
- const OSCertHandles& intermediates);
+ // Create an X509Certificate from a CRYPTO_BUFFER containing the DER-encoded
+ // representation. Returns NULL on failure to parse or extract data from the
+ // the certificate. Note that this does not guarantee the certificate is
+ // fully parsed and validated, only that the members of this class, such as
+ // subject, issuer, expiry times, and serial number, could be successfully
+ // initialized from the certificate.
+ static scoped_refptr<X509Certificate> CreateFromBuffer(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
// Options for configuring certificate parsing.
// Do not use without consulting //net owners.
@@ -95,9 +86,9 @@ class NET_EXPORT X509Certificate
};
// Create an X509Certificate with non-standard parsing options.
// Do not use without consulting //net owners.
- static scoped_refptr<X509Certificate> CreateFromHandleUnsafeOptions(
- OSCertHandle cert_handle,
- const OSCertHandles& intermediates,
+ static scoped_refptr<X509Certificate> CreateFromBufferUnsafeOptions(
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
UnsafeCreateOptions options);
// Create an X509Certificate from a chain of DER encoded certificates. The
@@ -107,6 +98,13 @@ class NET_EXPORT X509Certificate
static scoped_refptr<X509Certificate> CreateFromDERCertChain(
const std::vector<base::StringPiece>& der_certs);
+ // Create an X509Certificate from a chain of DER encoded certificates with
+ // non-standard parsing options.
+ // Do not use without consulting //net owners.
+ static scoped_refptr<X509Certificate> CreateFromDERCertChainUnsafeOptions(
+ const std::vector<base::StringPiece>& der_certs,
+ UnsafeCreateOptions options);
+
// Create an X509Certificate from the DER-encoded representation.
// Returns NULL on failure.
static scoped_refptr<X509Certificate> CreateFromBytes(const char* data,
@@ -126,6 +124,13 @@ class NET_EXPORT X509Certificate
static scoped_refptr<X509Certificate> CreateFromPickle(
base::PickleIterator* pickle_iter);
+ // Create an X509Certificate from the representation stored in the given
+ // pickle with non-standard parsing options.
+ // Do not use without consulting //net owners.
+ static scoped_refptr<X509Certificate> CreateFromPickleUnsafeOptions(
+ base::PickleIterator* pickle_iter,
+ UnsafeCreateOptions options);
+
// Parses all of the certificates possible from |data|. |format| is a
// bit-wise OR of Format, indicating the possible formats the
// certificates may have been serialized as. If an error occurs, an empty
@@ -187,14 +192,6 @@ class NET_EXPORT X509Certificate
// Does not consider any associated intermediates.
bool Equals(const X509Certificate* other) const;
- // Returns the associated intermediate certificates that were specified
- // during creation of this object, if any.
- // Ownership follows the "get" rule: it is the caller's responsibility to
- // retain the elements of the result.
- const OSCertHandles& GetIntermediateCertificates() const {
- return intermediate_ca_certs_;
- }
-
// Do any of the given issuer names appear in this cert's chain of trust?
// |valid_issuers| is a list of DER-encoded X.509 DistinguishedNames.
bool IsIssuedByEncoded(const std::vector<std::string>& valid_issuers);
@@ -208,20 +205,15 @@ class NET_EXPORT X509Certificate
bool VerifyNameMatch(const std::string& hostname,
bool allow_common_name_fallback) const;
- // Obtains the DER encoded certificate data for |cert_handle|. On success,
- // returns true and writes the DER encoded certificate to |*der_encoded|.
- static bool GetDEREncoded(OSCertHandle cert_handle,
- std::string* der_encoded);
-
// Returns the PEM encoded data from a DER encoded certificate. If the return
// value is true, then the PEM encoded certificate is written to
// |pem_encoded|.
- static bool GetPEMEncodedFromDER(const std::string& der_encoded,
+ static bool GetPEMEncodedFromDER(base::StringPiece der_encoded,
std::string* pem_encoded);
- // Returns the PEM encoded data from an OSCertHandle. If the return value is
+ // Returns the PEM encoded data from a CRYPTO_BUFFER. If the return value is
// true, then the PEM encoded certificate is written to |pem_encoded|.
- static bool GetPEMEncoded(OSCertHandle cert_handle,
+ static bool GetPEMEncoded(const CRYPTO_BUFFER* cert_buffer,
std::string* pem_encoded);
// Encodes the entire certificate chain (this certificate and any
@@ -234,40 +226,42 @@ class NET_EXPORT X509Certificate
// Sets |*size_bits| to be the length of the public key in bits, and sets
// |*type| to one of the |PublicKeyType| values. In case of
// |kPublicKeyTypeUnknown|, |*size_bits| will be set to 0.
- static void GetPublicKeyInfo(OSCertHandle cert_handle,
+ static void GetPublicKeyInfo(const CRYPTO_BUFFER* cert_buffer,
size_t* size_bits,
PublicKeyType* type);
- // Returns the OSCertHandle of this object. Because of caching, this may
- // differ from the OSCertHandle originally supplied during initialization.
- // Note: On Windows, CryptoAPI may return unexpected results if this handle
- // is used across multiple threads. For more details, see
- // CreateOSCertChainForCert().
- OSCertHandle os_cert_handle() const { return cert_handle_; }
+ // Returns the CRYPTO_BUFFER holding this certificate's DER encoded data. The
+ // data is not guaranteed to be valid DER or to encode a valid Certificate
+ // object.
+ CRYPTO_BUFFER* cert_buffer() const { return cert_buffer_.get(); }
- // Returns true if two OSCertHandles refer to identical certificates.
- static bool IsSameOSCert(OSCertHandle a, OSCertHandle b);
+ // Returns the associated intermediate certificates that were specified
+ // during creation of this object, if any. The intermediates are not
+ // guaranteed to be valid DER or to encode valid Certificate objects.
+ // Ownership follows the "get" rule: it is the caller's responsibility to
+ // retain the elements of the result.
+ const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& intermediate_buffers()
+ const {
+ return intermediate_ca_certs_;
+ }
- // Creates an OS certificate handle from the DER-encoded representation.
+ // Creates a CRYPTO_BUFFER from the DER-encoded representation. Unlike
+ // creating a CRYPTO_BUFFER directly, this function does some minimal
+ // checking to reject obviously invalid inputs.
// Returns NULL on failure.
- static OSCertHandle CreateOSCertHandleFromBytes(const char* data,
- size_t length);
-
- // Creates all possible OS certificate handles from |data| encoded in a
- // specific |format|. Returns an empty collection on failure.
- static OSCertHandles CreateOSCertHandlesFromBytes(const char* data,
- size_t length,
- Format format);
-
- // Duplicates (or adds a reference to) an OS certificate handle.
- static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle);
+ static bssl::UniquePtr<CRYPTO_BUFFER> CreateCertBufferFromBytes(
+ const char* data,
+ size_t length);
- // Frees (or releases a reference to) an OS certificate handle.
- static void FreeOSCertHandle(OSCertHandle cert_handle);
+ // Creates all possible CRYPTO_BUFFERs from |data| encoded in a specific
+ // |format|. Returns an empty collection on failure.
+ static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>
+ CreateCertBuffersFromBytes(const char* data, size_t length, Format format);
// Calculates the SHA-256 fingerprint of the certificate. Returns an empty
// (all zero) fingerprint on failure.
- static SHA256HashValue CalculateFingerprint256(OSCertHandle cert_handle);
+ static SHA256HashValue CalculateFingerprint256(
+ const CRYPTO_BUFFER* cert_buffer);
// Calculates the SHA-256 fingerprint for the complete chain, including the
// leaf certificate and all intermediate CA certificates. Returns an empty
@@ -275,7 +269,7 @@ class NET_EXPORT X509Certificate
SHA256HashValue CalculateChainFingerprint256() const;
// Returns true if the certificate is self-signed.
- static bool IsSelfSigned(OSCertHandle cert_handle);
+ static bool IsSelfSigned(const CRYPTO_BUFFER* cert_buffer);
private:
friend class base::RefCountedThreadSafe<X509Certificate>;
@@ -284,12 +278,12 @@ class NET_EXPORT X509Certificate
FRIEND_TEST_ALL_PREFIXES(X509CertificateNameVerifyTest, VerifyHostname);
FRIEND_TEST_ALL_PREFIXES(X509CertificateTest, SerialNumbers);
- // Construct an X509Certificate from a handle to the certificate object
- // in the underlying crypto library.
- X509Certificate(OSCertHandle cert_handle,
- const OSCertHandles& intermediates);
- X509Certificate(OSCertHandle cert_handle,
- const OSCertHandles& intermediates,
+ // Construct an X509Certificate from a CRYPTO_BUFFER containing the
+ // DER-encoded representation.
+ X509Certificate(bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
+ X509Certificate(bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer,
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates,
UnsafeCreateOptions options);
~X509Certificate();
@@ -330,12 +324,12 @@ class NET_EXPORT X509Certificate
// The serial number of this certificate, DER encoded.
std::string serial_number_;
- // A handle to the certificate object in the underlying crypto library.
- OSCertHandle cert_handle_;
+ // A handle to the DER encoded certificate data.
+ bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer_;
// Untrusted intermediate certificates associated with this certificate
// that may be needed for chain building.
- OSCertHandles intermediate_ca_certs_;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_ca_certs_;
DISALLOW_COPY_AND_ASSIGN(X509Certificate);
};
diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc
index a9cee29077d..76ba8500fdf 100644
--- a/chromium/net/cert/x509_certificate_unittest.cc
+++ b/chromium/net/cert/x509_certificate_unittest.cc
@@ -103,7 +103,7 @@ void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert,
EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
EXPECT_EQ(expected_fingerprint, X509Certificate::CalculateFingerprint256(
- google_cert->os_cert_handle()));
+ google_cert->cert_buffer()));
std::vector<std::string> dns_names;
google_cert->GetDNSNames(&dns_names);
@@ -284,13 +284,14 @@ TEST(X509CertificateTest, InvalidPrintableStringIsUtf8) {
x509_util::CreateCryptoBuffer(cert_der);
ASSERT_TRUE(cert_handle);
- EXPECT_FALSE(X509Certificate::CreateFromHandle(cert_handle.get(), {}));
+ EXPECT_FALSE(X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(cert_handle.get()), {}));
X509Certificate::UnsafeCreateOptions options;
options.printable_string_is_utf8 = true;
scoped_refptr<X509Certificate> cert =
- X509Certificate::CreateFromHandleUnsafeOptions(cert_handle.get(), {},
- options);
+ X509Certificate::CreateFromBufferUnsafeOptions(
+ x509_util::DupCryptoBuffer(cert_handle.get()), {}, options);
const CertPrincipal& subject = cert->subject();
EXPECT_EQ("Foo@#_ Clïênt Cërt", subject.common_name);
@@ -456,7 +457,7 @@ TEST(X509CertificateTest, SHA256FingerprintsCorrectly) {
0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38}};
EXPECT_EQ(google_sha256_fingerprint, X509Certificate::CalculateFingerprint256(
- google_cert->os_cert_handle()));
+ google_cert->cert_buffer()));
}
TEST(X509CertificateTest, CAFingerprints) {
@@ -474,25 +475,30 @@ TEST(X509CertificateTest, CAFingerprints) {
ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2.get());
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(intermediate_cert1->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert1->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain1 =
- X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain1);
intermediates.clear();
- intermediates.push_back(intermediate_cert2->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(intermediate_cert2->cert_buffer()));
scoped_refptr<X509Certificate> cert_chain2 =
- X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain2);
// No intermediate CA certicates.
intermediates.clear();
scoped_refptr<X509Certificate> cert_chain3 =
- X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
- intermediates);
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(server_cert->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain3);
SHA256HashValue cert_chain1_chain_fingerprint_256 = {
@@ -576,12 +582,9 @@ TEST(X509CertificateTest, ExtractSPKIFromDERCert) {
ImportCertFromFile(certs_dir, "nist.der");
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
- std::string derBytes;
- EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
- &derBytes));
-
base::StringPiece spkiBytes;
- EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
+ EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()), &spkiBytes));
uint8_t hash[base::kSHA1Length];
base::SHA1HashBytes(reinterpret_cast<const uint8_t*>(spkiBytes.data()),
@@ -596,11 +599,8 @@ TEST(X509CertificateTest, HasTLSFeatureExtension) {
ImportCertFromFile(certs_dir, "tls_feature_extension.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
- std::string derBytes;
- EXPECT_TRUE(
- X509Certificate::GetDEREncoded(cert->os_cert_handle(), &derBytes));
-
- EXPECT_TRUE(asn1::HasTLSFeatureExtension(derBytes));
+ EXPECT_TRUE(asn1::HasTLSFeatureExtension(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
}
TEST(X509CertificateTest, DoesNotHaveTLSFeatureExtension) {
@@ -609,83 +609,79 @@ TEST(X509CertificateTest, DoesNotHaveTLSFeatureExtension) {
ImportCertFromFile(certs_dir, "ok_cert.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
- std::string derBytes;
- EXPECT_TRUE(
- X509Certificate::GetDEREncoded(cert->os_cert_handle(), &derBytes));
-
- EXPECT_FALSE(asn1::HasTLSFeatureExtension(derBytes));
+ EXPECT_FALSE(asn1::HasTLSFeatureExtension(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
}
-// Tests OSCertHandle deduping via X509Certificate::CreateFromHandle. We
-// call X509Certificate::CreateFromHandle several times and observe whether
-// it returns a cached or new OSCertHandle.
+// Tests CRYPTO_BUFFER deduping via X509Certificate::CreateFromBuffer. We
+// call X509Certificate::CreateFromBuffer several times and observe whether
+// it returns a cached or new CRYPTO_BUFFER.
TEST(X509CertificateTest, Cache) {
- X509Certificate::OSCertHandle google_cert_handle;
- X509Certificate::OSCertHandle thawte_cert_handle;
+ bssl::UniquePtr<CRYPTO_BUFFER> google_cert_handle;
+ bssl::UniquePtr<CRYPTO_BUFFER> thawte_cert_handle;
// Add a single certificate to the certificate cache.
- google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
+ google_cert_handle = X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
- scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle(
- google_cert_handle, X509Certificate::OSCertHandles()));
- X509Certificate::FreeOSCertHandle(google_cert_handle);
+ ASSERT_TRUE(google_cert_handle);
+ scoped_refptr<X509Certificate> cert1(
+ X509Certificate::CreateFromBuffer(std::move(google_cert_handle), {}));
ASSERT_TRUE(cert1);
// Add the same certificate, but as a new handle.
- google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
+ google_cert_handle = X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
- scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle(
- google_cert_handle, X509Certificate::OSCertHandles()));
- X509Certificate::FreeOSCertHandle(google_cert_handle);
+ ASSERT_TRUE(google_cert_handle);
+ scoped_refptr<X509Certificate> cert2(
+ X509Certificate::CreateFromBuffer(std::move(google_cert_handle), {}));
ASSERT_TRUE(cert2);
// A new X509Certificate should be returned.
EXPECT_NE(cert1.get(), cert2.get());
// But both instances should share the underlying OS certificate handle.
- EXPECT_EQ(cert1->os_cert_handle(), cert2->os_cert_handle());
- EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
- EXPECT_EQ(0u, cert2->GetIntermediateCertificates().size());
+ EXPECT_EQ(cert1->cert_buffer(), cert2->cert_buffer());
+ EXPECT_EQ(0u, cert1->intermediate_buffers().size());
+ EXPECT_EQ(0u, cert2->intermediate_buffers().size());
// Add the same certificate, but this time with an intermediate. This
// should result in the intermediate being cached. Note that this is not
// a legitimate chain, but is suitable for testing.
- google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
+ google_cert_handle = X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
- thawte_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
+ thawte_cert_handle = X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(thawte_cert_handle);
- scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle(
- google_cert_handle, intermediates));
- X509Certificate::FreeOSCertHandle(google_cert_handle);
- X509Certificate::FreeOSCertHandle(thawte_cert_handle);
+ ASSERT_TRUE(google_cert_handle);
+ ASSERT_TRUE(thawte_cert_handle);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(std::move(thawte_cert_handle));
+ scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromBuffer(
+ std::move(google_cert_handle), std::move(intermediates)));
ASSERT_TRUE(cert3);
// Test that the new certificate, even with intermediates, results in the
// same underlying handle being used.
- EXPECT_EQ(cert1->os_cert_handle(), cert3->os_cert_handle());
+ EXPECT_EQ(cert1->cert_buffer(), cert3->cert_buffer());
// Though they use the same OS handle, the intermediates should be different.
- EXPECT_NE(cert1->GetIntermediateCertificates().size(),
- cert3->GetIntermediateCertificates().size());
+ EXPECT_NE(cert1->intermediate_buffers().size(),
+ cert3->intermediate_buffers().size());
}
TEST(X509CertificateTest, Pickle) {
- X509Certificate::OSCertHandle google_cert_handle =
- X509Certificate::CreateOSCertHandleFromBytes(
+ bssl::UniquePtr<CRYPTO_BUFFER> google_cert_handle =
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
- X509Certificate::OSCertHandle thawte_cert_handle =
- X509Certificate::CreateOSCertHandleFromBytes(
+ ASSERT_TRUE(google_cert_handle);
+ bssl::UniquePtr<CRYPTO_BUFFER> thawte_cert_handle =
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
+ ASSERT_TRUE(thawte_cert_handle);
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(thawte_cert_handle);
- scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
- google_cert_handle, intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(std::move(thawte_cert_handle));
+ scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromBuffer(
+ std::move(google_cert_handle), std::move(intermediates));
ASSERT_TRUE(cert);
- X509Certificate::FreeOSCertHandle(google_cert_handle);
- X509Certificate::FreeOSCertHandle(thawte_cert_handle);
-
base::Pickle pickle;
cert->Persist(&pickle);
@@ -693,16 +689,14 @@ TEST(X509CertificateTest, Pickle) {
scoped_refptr<X509Certificate> cert_from_pickle =
X509Certificate::CreateFromPickle(&iter);
ASSERT_TRUE(cert_from_pickle);
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- cert->os_cert_handle(), cert_from_pickle->os_cert_handle()));
- const X509Certificate::OSCertHandles& cert_intermediates =
- cert->GetIntermediateCertificates();
- const X509Certificate::OSCertHandles& pickle_intermediates =
- cert_from_pickle->GetIntermediateCertificates();
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(cert->cert_buffer(),
+ cert_from_pickle->cert_buffer()));
+ const auto& cert_intermediates = cert->intermediate_buffers();
+ const auto& pickle_intermediates = cert_from_pickle->intermediate_buffers();
ASSERT_EQ(cert_intermediates.size(), pickle_intermediates.size());
for (size_t i = 0; i < cert_intermediates.size(); ++i) {
- EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates[i],
- pickle_intermediates[i]));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(cert_intermediates[i].get(),
+ pickle_intermediates[i].get()));
}
}
@@ -717,35 +711,34 @@ TEST(X509CertificateTest, IntermediateCertificates) {
reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
ASSERT_TRUE(thawte_cert);
- X509Certificate::OSCertHandle google_handle;
+ bssl::UniquePtr<CRYPTO_BUFFER> google_handle;
// Create object with no intermediates:
- google_handle = X509Certificate::CreateOSCertHandleFromBytes(
+ google_handle = X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
- X509Certificate::OSCertHandles intermediates1;
scoped_refptr<X509Certificate> cert1;
- cert1 = X509Certificate::CreateFromHandle(google_handle, intermediates1);
+ cert1 = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(google_handle.get()), {});
ASSERT_TRUE(cert1);
- EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
+ EXPECT_EQ(0u, cert1->intermediate_buffers().size());
// Create object with 2 intermediates:
- X509Certificate::OSCertHandles intermediates2;
- intermediates2.push_back(webkit_cert->os_cert_handle());
- intermediates2.push_back(thawte_cert->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates2;
+ intermediates2.push_back(
+ x509_util::DupCryptoBuffer(webkit_cert->cert_buffer()));
+ intermediates2.push_back(
+ x509_util::DupCryptoBuffer(thawte_cert->cert_buffer()));
scoped_refptr<X509Certificate> cert2;
- cert2 = X509Certificate::CreateFromHandle(google_handle, intermediates2);
+ cert2 = X509Certificate::CreateFromBuffer(std::move(google_handle),
+ std::move(intermediates2));
ASSERT_TRUE(cert2);
// Verify it has all the intermediates:
- const X509Certificate::OSCertHandles& cert2_intermediates =
- cert2->GetIntermediateCertificates();
+ const auto& cert2_intermediates = cert2->intermediate_buffers();
ASSERT_EQ(2u, cert2_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[0],
- webkit_cert->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[1],
- thawte_cert->os_cert_handle()));
-
- // Cleanup
- X509Certificate::FreeOSCertHandle(google_handle);
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(cert2_intermediates[0].get(),
+ webkit_cert->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(cert2_intermediates[1].get(),
+ thawte_cert->cert_buffer()));
}
TEST(X509CertificateTest, IsIssuedByEncoded) {
@@ -796,22 +789,22 @@ TEST(X509CertificateTest, IsSelfSigned) {
scoped_refptr<X509Certificate> cert(
ImportCertFromFile(certs_dir, "mit.davidben.der"));
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
- EXPECT_FALSE(X509Certificate::IsSelfSigned(cert->os_cert_handle()));
+ EXPECT_FALSE(X509Certificate::IsSelfSigned(cert->cert_buffer()));
scoped_refptr<X509Certificate> self_signed(
ImportCertFromFile(certs_dir, "aia-root.pem"));
ASSERT_NE(static_cast<X509Certificate*>(NULL), self_signed.get());
- EXPECT_TRUE(X509Certificate::IsSelfSigned(self_signed->os_cert_handle()));
+ EXPECT_TRUE(X509Certificate::IsSelfSigned(self_signed->cert_buffer()));
scoped_refptr<X509Certificate> bad_name(
ImportCertFromFile(certs_dir, "self-signed-invalid-name.pem"));
ASSERT_NE(static_cast<X509Certificate*>(NULL), bad_name.get());
- EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_name->os_cert_handle()));
+ EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_name->cert_buffer()));
scoped_refptr<X509Certificate> bad_sig(
ImportCertFromFile(certs_dir, "self-signed-invalid-sig.pem"));
ASSERT_NE(static_cast<X509Certificate*>(NULL), bad_sig.get());
- EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_sig->os_cert_handle()));
+ EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_sig->cert_buffer()));
}
TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
@@ -841,11 +834,12 @@ TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
std::string policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN),
sizeof(kPolicyRootDN));
- X509Certificate::OSCertHandles intermediates;
- intermediates.push_back(policy_chain[1]->os_cert_handle());
- scoped_refptr<X509Certificate> cert_chain =
- X509Certificate::CreateFromHandle(policy_chain[0]->os_cert_handle(),
- intermediates);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(policy_chain[1]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(policy_chain[0]->cert_buffer()),
+ std::move(intermediates));
ASSERT_TRUE(cert_chain);
std::vector<std::string> issuers;
@@ -878,11 +872,6 @@ TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
}
-// Tests that FreeOSCertHandle ignores NULL on each OS.
-TEST(X509CertificateTest, FreeNullHandle) {
- X509Certificate::FreeOSCertHandle(NULL);
-}
-
const struct CertificateFormatTestData {
const char* file_name;
X509Certificate::Format format;
@@ -1005,7 +994,7 @@ TEST_P(X509CertificateParseTest, CanParseFormat) {
// comparing fingerprints.
EXPECT_EQ(
*test_data_.chain_fingerprints[i],
- X509Certificate::CalculateFingerprint256(certs[i]->os_cert_handle()));
+ X509Certificate::CalculateFingerprint256(certs[i]->cert_buffer()));
}
}
@@ -1281,7 +1270,7 @@ TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
X509Certificate::PublicKeyType actual_type =
X509Certificate::kPublicKeyTypeUnknown;
- X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &actual_bits,
+ X509Certificate::GetPublicKeyInfo(cert->cert_buffer(), &actual_bits,
&actual_type);
EXPECT_EQ(data.expected_bits, actual_bits);
diff --git a/chromium/net/cert/x509_util.cc b/chromium/net/cert/x509_util.cc
index 9f39287f6a6..b0558744c57 100644
--- a/chromium/net/cert/x509_util.cc
+++ b/chromium/net/cert/x509_util.cc
@@ -4,6 +4,7 @@
#include "net/cert/x509_util.h"
+#include <string.h>
#include <memory>
#include "base/lazy_instance.h"
@@ -113,33 +114,6 @@ bool AddTime(CBB* cbb, base::Time time) {
der::EncodeGeneralizedTime(generalized_time, out) && CBB_flush(cbb);
}
-bool GetCommonName(const der::Input& tlv, std::string* common_name) {
- RDNSequence rdn_sequence;
- if (!ParseName(tlv, &rdn_sequence))
- return false;
-
- for (const auto& rdn : rdn_sequence) {
- for (const auto& atv : rdn) {
- if (atv.type == TypeCommonNameOid()) {
- return atv.ValueAsString(common_name);
- }
- }
- }
- return true;
-}
-
-bool DecodeTime(const der::GeneralizedTime& generalized_time,
- base::Time* time) {
- base::Time::Exploded exploded = {0};
- exploded.year = generalized_time.year;
- exploded.month = generalized_time.month;
- exploded.day_of_month = generalized_time.day;
- exploded.hour = generalized_time.hours;
- exploded.minute = generalized_time.minutes;
- exploded.second = generalized_time.seconds;
- return base::Time::FromUTCExploded(exploded, time);
-}
-
class BufferPoolSingleton {
public:
BufferPoolSingleton() : pool_(CRYPTO_BUFFER_POOL_new()) {}
@@ -159,15 +133,13 @@ bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate,
std::string* token) {
static const char kChannelBindingPrefix[] = "tls-server-end-point:";
- std::string der_encoded_certificate;
- if (!X509Certificate::GetDEREncoded(certificate.os_cert_handle(),
- &der_encoded_certificate))
- return false;
+ base::StringPiece der_encoded_certificate =
+ x509_util::CryptoBufferAsStringPiece(certificate.cert_buffer());
der::Input tbs_certificate_tlv;
der::Input signature_algorithm_tlv;
der::BitString signature_value;
- if (!ParseCertificate(der::Input(&der_encoded_certificate),
+ if (!ParseCertificate(der::Input(der_encoded_certificate),
&tbs_certificate_tlv, &signature_algorithm_tlv,
&signature_value, nullptr))
return false;
@@ -321,61 +293,6 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
return true;
}
-bool ParseCertificateSandboxed(const base::StringPiece& certificate,
- std::string* subject,
- std::string* issuer,
- base::Time* not_before,
- base::Time* not_after,
- std::vector<std::string>* dns_names,
- std::vector<std::string>* ip_addresses) {
- der::Input cert_data(certificate);
- der::Input tbs_cert, signature_alg;
- der::BitString signature_value;
- if (!ParseCertificate(cert_data, &tbs_cert, &signature_alg, &signature_value,
- nullptr))
- return false;
-
- ParsedTbsCertificate parsed_tbs_cert;
- if (!ParseTbsCertificate(tbs_cert, DefaultParseCertificateOptions(),
- &parsed_tbs_cert, nullptr))
- return false;
-
- if (!GetCommonName(parsed_tbs_cert.subject_tlv, subject))
- return false;
-
- if (!GetCommonName(parsed_tbs_cert.issuer_tlv, issuer))
- return false;
-
- if (!DecodeTime(parsed_tbs_cert.validity_not_before, not_before))
- return false;
-
- if (!DecodeTime(parsed_tbs_cert.validity_not_after, not_after))
- return false;
-
- if (!parsed_tbs_cert.has_extensions)
- return true;
-
- std::map<der::Input, ParsedExtension> extensions;
- if (!ParseExtensions(parsed_tbs_cert.extensions_tlv, &extensions))
- return false;
-
- CertErrors unused_errors;
- std::vector<std::string> san;
- auto iter = extensions.find(SubjectAltNameOid());
- if (iter != extensions.end()) {
- std::unique_ptr<GeneralNames> subject_alt_names =
- GeneralNames::Create(iter->second.value, &unused_errors);
- if (subject_alt_names) {
- for (const auto& dns_name : subject_alt_names->dns_names)
- dns_names->push_back(dns_name.as_string());
- for (const auto& ip : subject_alt_names->ip_addresses)
- ip_addresses->push_back(ip.ToString());
- }
- }
-
- return true;
-}
-
CRYPTO_BUFFER_POOL* GetBufferPool() {
return g_buffer_pool_singleton.Get().pool();
}
@@ -393,6 +310,20 @@ bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
data.size(), GetBufferPool()));
}
+bssl::UniquePtr<CRYPTO_BUFFER> DupCryptoBuffer(CRYPTO_BUFFER* buffer) {
+ CRYPTO_BUFFER_up_ref(buffer);
+ return bssl::UniquePtr<CRYPTO_BUFFER>(buffer);
+}
+
+bool CryptoBufferEqual(const CRYPTO_BUFFER* a, const CRYPTO_BUFFER* b) {
+ DCHECK(a && b);
+ if (a == b)
+ return true;
+ return CRYPTO_BUFFER_len(a) == CRYPTO_BUFFER_len(b) &&
+ memcmp(CRYPTO_BUFFER_data(a), CRYPTO_BUFFER_data(b),
+ CRYPTO_BUFFER_len(a)) == 0;
+}
+
base::StringPiece CryptoBufferAsStringPiece(const CRYPTO_BUFFER* buffer) {
return base::StringPiece(
reinterpret_cast<const char*>(CRYPTO_BUFFER_data(buffer)),
@@ -406,11 +337,14 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromBuffers(
return nullptr;
}
- std::vector<CRYPTO_BUFFER*> intermediate_chain;
- for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(buffers); ++i)
- intermediate_chain.push_back(sk_CRYPTO_BUFFER_value(buffers, i));
- return X509Certificate::CreateFromHandle(sk_CRYPTO_BUFFER_value(buffers, 0),
- intermediate_chain);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_chain;
+ for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(buffers); ++i) {
+ intermediate_chain.push_back(
+ DupCryptoBuffer(sk_CRYPTO_BUFFER_value(buffers, i)));
+ }
+ return X509Certificate::CreateFromBuffer(
+ DupCryptoBuffer(sk_CRYPTO_BUFFER_value(buffers, 0)),
+ std::move(intermediate_chain));
}
ParseCertificateOptions DefaultParseCertificateOptions() {
diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h
index c75059ad5d2..6f0b8b215b0 100644
--- a/chromium/net/cert/x509_util.h
+++ b/chromium/net/cert/x509_util.h
@@ -74,17 +74,6 @@ NET_EXPORT bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
base::Time not_valid_after,
std::string* der_cert);
-// Provides a method to parse a DER-encoded X509 certificate without calling any
-// OS primitives. This is useful in sandboxed processes.
-NET_EXPORT bool ParseCertificateSandboxed(
- const base::StringPiece& certificate,
- std::string* subject,
- std::string* issuer,
- base::Time* not_before,
- base::Time* not_after,
- std::vector<std::string>* dns_names,
- std::vector<std::string>* ip_addresses);
-
// Returns a CRYPTO_BUFFER_POOL for deduplicating certificates.
NET_EXPORT CRYPTO_BUFFER_POOL* GetBufferPool();
@@ -102,6 +91,15 @@ NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
const char* invalid_data);
+// Increments the reference count of |buffer| and returns a UniquePtr owning
+// that reference.
+NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> DupCryptoBuffer(
+ CRYPTO_BUFFER* buffer);
+
+// Compares two CRYPTO_BUFFERs and returns true if they have the same contents.
+NET_EXPORT bool CryptoBufferEqual(const CRYPTO_BUFFER* a,
+ const CRYPTO_BUFFER* b);
+
// Returns a StringPiece pointing to the data in |buffer|.
NET_EXPORT base::StringPiece CryptoBufferAsStringPiece(
const CRYPTO_BUFFER* buffer);
diff --git a/chromium/net/cert/x509_util_android.cc b/chromium/net/cert/x509_util_android.cc
index 8da297b03c7..8ee18742066 100644
--- a/chromium/net/cert/x509_util_android.cc
+++ b/chromium/net/cert/x509_util_android.cc
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/android/build_info.h"
-#include "base/metrics/histogram_macros.h"
#include "jni/X509Util_jni.h"
#include "net/cert/cert_database.h"
@@ -16,16 +14,4 @@ void JNI_X509Util_NotifyKeyChainChanged(JNIEnv* env,
CertDatabase::GetInstance()->OnAndroidKeyChainChanged();
}
-void JNI_X509Util_RecordCertVerifyCapabilitiesHistogram(
- JNIEnv* env,
- const JavaParamRef<jclass>& clazz,
- jboolean found_system_trust_roots) {
- // Only record the histogram for 4.2 and up. Before 4.2, the platform doesn't
- // return the certificate chain anyway.
- if (base::android::BuildInfo::GetInstance()->sdk_int() >= 17) {
- UMA_HISTOGRAM_BOOLEAN("Net.FoundSystemTrustRootsAndroid",
- found_system_trust_roots);
- }
-}
-
} // namespace net
diff --git a/chromium/net/cert/x509_util_ios.cc b/chromium/net/cert/x509_util_ios.cc
index 26c4354d166..0ae1e779f28 100644
--- a/chromium/net/cert/x509_util_ios.cc
+++ b/chromium/net/cert/x509_util_ios.cc
@@ -26,9 +26,8 @@ base::ScopedCFTypeRef<SecCertificateRef> CreateSecCertificateFromBytes(
base::ScopedCFTypeRef<SecCertificateRef>
CreateSecCertificateFromX509Certificate(const X509Certificate* cert) {
- return CreateSecCertificateFromBytes(
- CRYPTO_BUFFER_data(cert->os_cert_handle()),
- CRYPTO_BUFFER_len(cert->os_cert_handle()));
+ return CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
+ CRYPTO_BUFFER_len(cert->cert_buffer()));
}
scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
@@ -40,13 +39,12 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
if (!der_data)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)),
CFDataGetLength(der_data)));
if (!cert_handle)
return nullptr;
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
- X509Certificate::OSCertHandles intermediates_raw;
for (const SecCertificateRef& sec_intermediate : sec_chain) {
if (!sec_intermediate)
return nullptr;
@@ -54,16 +52,15 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
if (!der_data)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)),
CFDataGetLength(der_data)));
if (!intermediate_cert_handle)
return nullptr;
- intermediates_raw.push_back(intermediate_cert_handle.get());
intermediates.push_back(std::move(intermediate_cert_handle));
}
- scoped_refptr<X509Certificate> result(
- X509Certificate::CreateFromHandle(cert_handle.get(), intermediates_raw));
+ scoped_refptr<X509Certificate> result(X509Certificate::CreateFromBuffer(
+ std::move(cert_handle), std::move(intermediates)));
return result;
}
diff --git a/chromium/net/cert/x509_util_ios_and_mac.cc b/chromium/net/cert/x509_util_ios_and_mac.cc
index 0659e43871d..8e41cd87cd0 100644
--- a/chromium/net/cert/x509_util_ios_and_mac.cc
+++ b/chromium/net/cert/x509_util_ios_and_mac.cc
@@ -32,16 +32,15 @@ CreateSecCertificateArrayForX509Certificate(
return base::ScopedCFTypeRef<CFMutableArrayRef>();
std::string bytes;
base::ScopedCFTypeRef<SecCertificateRef> sec_cert(
- CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->os_cert_handle()),
- CRYPTO_BUFFER_len(cert->os_cert_handle())));
+ CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
+ CRYPTO_BUFFER_len(cert->cert_buffer())));
if (!sec_cert)
return base::ScopedCFTypeRef<CFMutableArrayRef>();
CFArrayAppendValue(cert_list, sec_cert);
- for (X509Certificate::OSCertHandle intermediate :
- cert->GetIntermediateCertificates()) {
+ for (const auto& intermediate : cert->intermediate_buffers()) {
base::ScopedCFTypeRef<SecCertificateRef> sec_cert(
- CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(intermediate),
- CRYPTO_BUFFER_len(intermediate)));
+ CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(intermediate.get()),
+ CRYPTO_BUFFER_len(intermediate.get())));
if (!sec_cert) {
if (invalid_intermediate_behavior == InvalidIntermediateBehavior::kFail)
return base::ScopedCFTypeRef<CFMutableArrayRef>();
diff --git a/chromium/net/cert/x509_util_ios_and_mac_unittest.cc b/chromium/net/cert/x509_util_ios_and_mac_unittest.cc
index 5b2eae18c34..d2e6883b1c6 100644
--- a/chromium/net/cert/x509_util_ios_and_mac_unittest.cc
+++ b/chromium/net/cert/x509_util_ios_and_mac_unittest.cc
@@ -39,17 +39,6 @@ std::string BytesForSecCert(const void* sec_cert) {
reinterpret_cast<SecCertificateRef>(const_cast<void*>(sec_cert)));
}
-std::string BytesForX509CertHandle(X509Certificate::OSCertHandle handle) {
- std::string result;
- if (!X509Certificate::GetDEREncoded(handle, &result))
- ADD_FAILURE();
- return result;
-}
-
-std::string BytesForX509Cert(X509Certificate* cert) {
- return BytesForX509CertHandle(cert->os_cert_handle());
-}
-
} // namespace
TEST(X509UtilTest, CreateSecCertificateArrayForX509Certificate) {
@@ -57,7 +46,7 @@ TEST(X509UtilTest, CreateSecCertificateArrayForX509Certificate) {
GetTestCertsDirectory(), "multi-root-chain1.pem",
X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
ASSERT_TRUE(cert);
- EXPECT_EQ(3U, cert->GetIntermediateCertificates().size());
+ EXPECT_EQ(3U, cert->intermediate_buffers().size());
base::ScopedCFTypeRef<CFMutableArrayRef> sec_certs(
CreateSecCertificateArrayForX509Certificate(cert.get()));
@@ -66,13 +55,16 @@ TEST(X509UtilTest, CreateSecCertificateArrayForX509Certificate) {
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(CFArrayGetValueAtIndex(sec_certs.get(), i));
- EXPECT_EQ(BytesForX509Cert(cert.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 0)));
- EXPECT_EQ(BytesForX509CertHandle(cert->GetIntermediateCertificates()[0]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ cert->intermediate_buffers()[0].get()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 1)));
- EXPECT_EQ(BytesForX509CertHandle(cert->GetIntermediateCertificates()[1]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ cert->intermediate_buffers()[1].get()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 2)));
- EXPECT_EQ(BytesForX509CertHandle(cert->GetIntermediateCertificates()[2]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ cert->intermediate_buffers()[2].get()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 3)));
}
@@ -89,12 +81,15 @@ TEST(X509UtilTest, CreateSecCertificateArrayForX509CertificateErrors) {
ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
ASSERT_TRUE(ok_cert);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(std::move(bad_cert));
+ intermediates.push_back(x509_util::DupCryptoBuffer(ok_cert2->cert_buffer()));
scoped_refptr<X509Certificate> cert_with_intermediates(
- X509Certificate::CreateFromHandle(
- ok_cert->os_cert_handle(),
- {bad_cert.get(), ok_cert2->os_cert_handle()}));
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ok_cert->cert_buffer()),
+ std::move(intermediates)));
ASSERT_TRUE(cert_with_intermediates);
- EXPECT_EQ(2U, cert_with_intermediates->GetIntermediateCertificates().size());
+ EXPECT_EQ(2U, cert_with_intermediates->intermediate_buffers().size());
// Normal CreateSecCertificateArrayForX509Certificate fails with invalid
// certs in chain.
@@ -111,9 +106,9 @@ TEST(X509UtilTest, CreateSecCertificateArrayForX509CertificateErrors) {
for (int i = 0; i < 2; ++i)
ASSERT_TRUE(CFArrayGetValueAtIndex(sec_certs.get(), i));
- EXPECT_EQ(BytesForX509Cert(ok_cert.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert->cert_buffer()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 0)));
- EXPECT_EQ(BytesForX509Cert(ok_cert2.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert2->cert_buffer()),
BytesForSecCert(CFArrayGetValueAtIndex(sec_certs.get(), 1)));
}
@@ -124,10 +119,14 @@ TEST(X509UtilTest,
X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
ASSERT_EQ(4u, certs.size());
- std::string bytes_cert0 = BytesForX509CertHandle(certs[0]->os_cert_handle());
- std::string bytes_cert1 = BytesForX509CertHandle(certs[1]->os_cert_handle());
- std::string bytes_cert2 = BytesForX509CertHandle(certs[2]->os_cert_handle());
- std::string bytes_cert3 = BytesForX509CertHandle(certs[3]->os_cert_handle());
+ std::string bytes_cert0(
+ x509_util::CryptoBufferAsStringPiece(certs[0]->cert_buffer()));
+ std::string bytes_cert1(
+ x509_util::CryptoBufferAsStringPiece(certs[1]->cert_buffer()));
+ std::string bytes_cert2(
+ x509_util::CryptoBufferAsStringPiece(certs[2]->cert_buffer()));
+ std::string bytes_cert3(
+ x509_util::CryptoBufferAsStringPiece(certs[3]->cert_buffer()));
base::ScopedCFTypeRef<SecCertificateRef> sec_cert0(
CreateSecCertificateFromBytes(
@@ -156,37 +155,34 @@ TEST(X509UtilTest,
scoped_refptr<X509Certificate> x509_cert_no_intermediates =
CreateX509CertificateFromSecCertificate(sec_cert0.get(), {});
ASSERT_TRUE(x509_cert_no_intermediates);
- EXPECT_EQ(0U,
- x509_cert_no_intermediates->GetIntermediateCertificates().size());
- EXPECT_EQ(bytes_cert0, BytesForX509CertHandle(
- x509_cert_no_intermediates->os_cert_handle()));
+ EXPECT_EQ(0U, x509_cert_no_intermediates->intermediate_buffers().size());
+ EXPECT_EQ(bytes_cert0, x509_util::CryptoBufferAsStringPiece(
+ x509_cert_no_intermediates->cert_buffer()));
scoped_refptr<X509Certificate> x509_cert_one_intermediate =
CreateX509CertificateFromSecCertificate(sec_cert0.get(),
{sec_cert1.get()});
ASSERT_TRUE(x509_cert_one_intermediate);
- EXPECT_EQ(bytes_cert0, BytesForX509CertHandle(
- x509_cert_one_intermediate->os_cert_handle()));
- ASSERT_EQ(1U,
- x509_cert_one_intermediate->GetIntermediateCertificates().size());
+ EXPECT_EQ(bytes_cert0, x509_util::CryptoBufferAsStringPiece(
+ x509_cert_one_intermediate->cert_buffer()));
+ ASSERT_EQ(1U, x509_cert_one_intermediate->intermediate_buffers().size());
EXPECT_EQ(bytes_cert1,
- BytesForX509CertHandle(
- x509_cert_one_intermediate->GetIntermediateCertificates()[0]));
+ x509_util::CryptoBufferAsStringPiece(
+ x509_cert_one_intermediate->intermediate_buffers()[0].get()));
scoped_refptr<X509Certificate> x509_cert_two_intermediates =
CreateX509CertificateFromSecCertificate(
sec_cert0.get(), {sec_cert1.get(), sec_cert2.get()});
ASSERT_TRUE(x509_cert_two_intermediates);
- EXPECT_EQ(bytes_cert0, BytesForX509CertHandle(
- x509_cert_two_intermediates->os_cert_handle()));
- ASSERT_EQ(2U,
- x509_cert_two_intermediates->GetIntermediateCertificates().size());
+ EXPECT_EQ(bytes_cert0, x509_util::CryptoBufferAsStringPiece(
+ x509_cert_two_intermediates->cert_buffer()));
+ ASSERT_EQ(2U, x509_cert_two_intermediates->intermediate_buffers().size());
EXPECT_EQ(bytes_cert1,
- BytesForX509CertHandle(
- x509_cert_two_intermediates->GetIntermediateCertificates()[0]));
+ x509_util::CryptoBufferAsStringPiece(
+ x509_cert_two_intermediates->intermediate_buffers()[0].get()));
EXPECT_EQ(bytes_cert2,
- BytesForX509CertHandle(
- x509_cert_two_intermediates->GetIntermediateCertificates()[1]));
+ x509_util::CryptoBufferAsStringPiece(
+ x509_cert_two_intermediates->intermediate_buffers()[1].get()));
}
} // namespace x509_util
diff --git a/chromium/net/cert/x509_util_mac.cc b/chromium/net/cert/x509_util_mac.cc
index 51c5a19d2d8..5285c4bcd4a 100644
--- a/chromium/net/cert/x509_util_mac.cc
+++ b/chromium/net/cert/x509_util_mac.cc
@@ -80,9 +80,8 @@ base::ScopedCFTypeRef<SecCertificateRef> CreateSecCertificateFromBytes(
base::ScopedCFTypeRef<SecCertificateRef>
CreateSecCertificateFromX509Certificate(const X509Certificate* cert) {
- return CreateSecCertificateFromBytes(
- CRYPTO_BUFFER_data(cert->os_cert_handle()),
- CRYPTO_BUFFER_len(cert->os_cert_handle()));
+ return CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
+ CRYPTO_BUFFER_len(cert->cert_buffer()));
}
scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
@@ -99,28 +98,26 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
if (!sec_cert || SecCertificateGetData(sec_cert, &der_data) != noErr)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(der_data.Data), der_data.Length));
if (!cert_handle)
return nullptr;
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
- X509Certificate::OSCertHandles intermediates_raw;
for (const SecCertificateRef& sec_intermediate : sec_chain) {
if (!sec_intermediate ||
SecCertificateGetData(sec_intermediate, &der_data) != noErr) {
return nullptr;
}
bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(der_data.Data), der_data.Length));
if (!intermediate_cert_handle)
return nullptr;
- intermediates_raw.push_back(intermediate_cert_handle.get());
intermediates.push_back(std::move(intermediate_cert_handle));
}
scoped_refptr<X509Certificate> result(
- X509Certificate::CreateFromHandleUnsafeOptions(
- cert_handle.get(), intermediates_raw, options));
+ X509Certificate::CreateFromBufferUnsafeOptions(
+ std::move(cert_handle), std::move(intermediates), options));
return result;
}
diff --git a/chromium/net/cert/x509_util_nss.cc b/chromium/net/cert/x509_util_nss.cc
index 33f39d2a461..9ba26e3b967 100644
--- a/chromium/net/cert/x509_util_nss.cc
+++ b/chromium/net/cert/x509_util_nss.cc
@@ -142,8 +142,8 @@ bool IsSameCertificate(CERTCertificate* a, CERTCertificate* b) {
}
bool IsSameCertificate(CERTCertificate* a, const X509Certificate* b) {
- return a->derCert.len == CRYPTO_BUFFER_len(b->os_cert_handle()) &&
- memcmp(a->derCert.data, CRYPTO_BUFFER_data(b->os_cert_handle()),
+ return a->derCert.len == CRYPTO_BUFFER_len(b->cert_buffer()) &&
+ memcmp(a->derCert.data, CRYPTO_BUFFER_data(b->cert_buffer()),
a->derCert.len) == 0;
}
bool IsSameCertificate(const X509Certificate* a, CERTCertificate* b) {
@@ -170,9 +170,8 @@ ScopedCERTCertificate CreateCERTCertificateFromBytes(const uint8_t* data,
ScopedCERTCertificate CreateCERTCertificateFromX509Certificate(
const X509Certificate* cert) {
- return CreateCERTCertificateFromBytes(
- CRYPTO_BUFFER_data(cert->os_cert_handle()),
- CRYPTO_BUFFER_len(cert->os_cert_handle()));
+ return CreateCERTCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
+ CRYPTO_BUFFER_len(cert->cert_buffer()));
}
ScopedCERTCertificateList CreateCERTCertificateListFromX509Certificate(
@@ -185,16 +184,16 @@ ScopedCERTCertificateList CreateCERTCertificateListFromX509Certificate(
const X509Certificate* cert,
InvalidIntermediateBehavior invalid_intermediate_behavior) {
ScopedCERTCertificateList nss_chain;
- nss_chain.reserve(1 + cert->GetIntermediateCertificates().size());
+ nss_chain.reserve(1 + cert->intermediate_buffers().size());
ScopedCERTCertificate nss_cert =
CreateCERTCertificateFromX509Certificate(cert);
if (!nss_cert)
return {};
nss_chain.push_back(std::move(nss_cert));
- for (net::X509Certificate::OSCertHandle intermediate :
- cert->GetIntermediateCertificates()) {
- ScopedCERTCertificate nss_intermediate = CreateCERTCertificateFromBytes(
- CRYPTO_BUFFER_data(intermediate), CRYPTO_BUFFER_len(intermediate));
+ for (const auto& intermediate : cert->intermediate_buffers()) {
+ ScopedCERTCertificate nss_intermediate =
+ CreateCERTCertificateFromBytes(CRYPTO_BUFFER_data(intermediate.get()),
+ CRYPTO_BUFFER_len(intermediate.get()));
if (!nss_intermediate) {
if (invalid_intermediate_behavior == InvalidIntermediateBehavior::kFail)
return {};
@@ -249,7 +248,7 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromCERTCertificate(
if (!nss_cert || !nss_cert->derCert.len)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(nss_cert->derCert.data),
nss_cert->derCert.len));
if (!cert_handle)
@@ -257,23 +256,20 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromCERTCertificate(
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
intermediates.reserve(nss_chain.size());
- X509Certificate::OSCertHandles intermediates_raw;
- intermediates_raw.reserve(nss_chain.size());
for (const CERTCertificate* nss_intermediate : nss_chain) {
if (!nss_intermediate || !nss_intermediate->derCert.len)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(nss_intermediate->derCert.data),
nss_intermediate->derCert.len));
if (!intermediate_cert_handle)
return nullptr;
- intermediates_raw.push_back(intermediate_cert_handle.get());
intermediates.push_back(std::move(intermediate_cert_handle));
}
scoped_refptr<X509Certificate> result(
- X509Certificate::CreateFromHandleUnsafeOptions(
- cert_handle.get(), intermediates_raw, options));
+ X509Certificate::CreateFromBufferUnsafeOptions(
+ std::move(cert_handle), std::move(intermediates), options));
return result;
}
diff --git a/chromium/net/cert/x509_util_nss_unittest.cc b/chromium/net/cert/x509_util_nss_unittest.cc
index d9b9a70072b..fb671259a38 100644
--- a/chromium/net/cert/x509_util_nss_unittest.cc
+++ b/chromium/net/cert/x509_util_nss_unittest.cc
@@ -25,17 +25,6 @@ std::string BytesForNSSCert(CERTCertificate* cert) {
return der_encoded;
}
-std::string BytesForX509CertHandle(X509Certificate::OSCertHandle handle) {
- std::string result;
- if (!X509Certificate::GetDEREncoded(handle, &result))
- ADD_FAILURE();
- return result;
-}
-
-std::string BytesForX509Cert(X509Certificate* cert) {
- return BytesForX509CertHandle(cert->os_cert_handle());
-}
-
} // namespace
TEST(X509UtilNSSTest, IsSameCertificate) {
@@ -121,7 +110,7 @@ TEST(X509UtilNSSTest, CreateCERTCertificateListFromX509Certificate) {
GetTestCertsDirectory(), "multi-root-chain1.pem",
X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
ASSERT_TRUE(x509_cert);
- EXPECT_EQ(3U, x509_cert->GetIntermediateCertificates().size());
+ EXPECT_EQ(3U, x509_cert->intermediate_buffers().size());
ScopedCERTCertificateList nss_certs =
x509_util::CreateCERTCertificateListFromX509Certificate(x509_cert.get());
@@ -129,13 +118,16 @@ TEST(X509UtilNSSTest, CreateCERTCertificateListFromX509Certificate) {
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(nss_certs[i]);
- EXPECT_EQ(BytesForX509Cert(x509_cert.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer()),
BytesForNSSCert(nss_certs[0].get()));
- EXPECT_EQ(BytesForX509CertHandle(x509_cert->GetIntermediateCertificates()[0]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ x509_cert->intermediate_buffers()[0].get()),
BytesForNSSCert(nss_certs[1].get()));
- EXPECT_EQ(BytesForX509CertHandle(x509_cert->GetIntermediateCertificates()[1]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ x509_cert->intermediate_buffers()[1].get()),
BytesForNSSCert(nss_certs[2].get()));
- EXPECT_EQ(BytesForX509CertHandle(x509_cert->GetIntermediateCertificates()[2]),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ x509_cert->intermediate_buffers()[2].get()),
BytesForNSSCert(nss_certs[3].get()));
}
@@ -152,12 +144,15 @@ TEST(X509UtilTest, CreateCERTCertificateListFromX509CertificateErrors) {
ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"));
ASSERT_TRUE(ok_cert);
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+ intermediates.push_back(std::move(bad_cert));
+ intermediates.push_back(x509_util::DupCryptoBuffer(ok_cert2->cert_buffer()));
scoped_refptr<X509Certificate> cert_with_intermediates(
- X509Certificate::CreateFromHandle(
- ok_cert->os_cert_handle(),
- {bad_cert.get(), ok_cert2->os_cert_handle()}));
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(ok_cert->cert_buffer()),
+ std::move(intermediates)));
ASSERT_TRUE(cert_with_intermediates);
- EXPECT_EQ(2U, cert_with_intermediates->GetIntermediateCertificates().size());
+ EXPECT_EQ(2U, cert_with_intermediates->intermediate_buffers().size());
// Normal CreateCERTCertificateListFromX509Certificate fails with invalid
// certs in chain.
@@ -175,9 +170,9 @@ TEST(X509UtilTest, CreateCERTCertificateListFromX509CertificateErrors) {
for (const auto& nss_cert : nss_certs)
ASSERT_TRUE(nss_cert.get());
- EXPECT_EQ(BytesForX509Cert(ok_cert.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert->cert_buffer()),
BytesForNSSCert(nss_certs[0].get()));
- EXPECT_EQ(BytesForX509Cert(ok_cert2.get()),
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert2->cert_buffer()),
BytesForNSSCert(nss_certs[1].get()));
}
@@ -254,8 +249,9 @@ TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_NoChain) {
ASSERT_TRUE(nss_cert);
scoped_refptr<X509Certificate> x509_cert =
x509_util::CreateX509CertificateFromCERTCertificate(nss_cert.get());
- EXPECT_EQ(BytesForNSSCert(nss_cert.get()), BytesForX509Cert(x509_cert.get()));
- EXPECT_TRUE(x509_cert->GetIntermediateCertificates().empty());
+ EXPECT_EQ(BytesForNSSCert(nss_cert.get()),
+ x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer()));
+ EXPECT_TRUE(x509_cert->intermediate_buffers().empty());
}
TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_EmptyChain) {
@@ -265,8 +261,9 @@ TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_EmptyChain) {
scoped_refptr<X509Certificate> x509_cert =
x509_util::CreateX509CertificateFromCERTCertificate(
nss_cert.get(), std::vector<CERTCertificate*>());
- EXPECT_EQ(BytesForNSSCert(nss_cert.get()), BytesForX509Cert(x509_cert.get()));
- EXPECT_TRUE(x509_cert->GetIntermediateCertificates().empty());
+ EXPECT_EQ(BytesForNSSCert(nss_cert.get()),
+ x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer()));
+ EXPECT_TRUE(x509_cert->intermediate_buffers().empty());
}
TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_WithChain) {
@@ -283,9 +280,11 @@ TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_WithChain) {
scoped_refptr<X509Certificate> x509_cert =
x509_util::CreateX509CertificateFromCERTCertificate(nss_cert.get(),
chain);
- EXPECT_EQ(BytesForNSSCert(nss_cert.get()), BytesForX509Cert(x509_cert.get()));
- ASSERT_EQ(1U, x509_cert->GetIntermediateCertificates().size());
- EXPECT_EQ(BytesForX509CertHandle(x509_cert->GetIntermediateCertificates()[0]),
+ EXPECT_EQ(BytesForNSSCert(nss_cert.get()),
+ x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer()));
+ ASSERT_EQ(1U, x509_cert->intermediate_buffers().size());
+ EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(
+ x509_cert->intermediate_buffers()[0].get()),
BytesForNSSCert(nss_cert2.get()));
}
@@ -305,9 +304,9 @@ TEST(X509UtilNSSTest, CreateX509CertificateListFromCERTCertificates) {
ASSERT_EQ(2U, x509_certs.size());
EXPECT_EQ(BytesForNSSCert(nss_certs[0].get()),
- BytesForX509Cert(x509_certs[0].get()));
+ x509_util::CryptoBufferAsStringPiece(x509_certs[0]->cert_buffer()));
EXPECT_EQ(BytesForNSSCert(nss_certs[1].get()),
- BytesForX509Cert(x509_certs[1].get()));
+ x509_util::CryptoBufferAsStringPiece(x509_certs[1]->cert_buffer()));
}
TEST(X509UtilNSSTest, CreateX509CertificateListFromCERTCertificates_EmptyList) {
diff --git a/chromium/net/cert/x509_util_win.cc b/chromium/net/cert/x509_util_win.cc
index 09d94576cb5..9def51f963a 100644
--- a/chromium/net/cert/x509_util_win.cc
+++ b/chromium/net/cert/x509_util_win.cc
@@ -35,29 +35,27 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromCertContexts(
if (!os_cert || !os_cert->pbCertEncoded || !os_cert->cbCertEncoded)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(os_cert->pbCertEncoded),
os_cert->cbCertEncoded));
if (!cert_handle)
return nullptr;
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
- X509Certificate::OSCertHandles intermediates_raw;
for (PCCERT_CONTEXT os_intermediate : os_chain) {
if (!os_intermediate || !os_intermediate->pbCertEncoded ||
!os_intermediate->cbCertEncoded)
return nullptr;
bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(os_intermediate->pbCertEncoded),
os_intermediate->cbCertEncoded));
if (!intermediate_cert_handle)
return nullptr;
- intermediates_raw.push_back(intermediate_cert_handle.get());
intermediates.push_back(std::move(intermediate_cert_handle));
}
scoped_refptr<X509Certificate> result(
- X509Certificate::CreateFromHandleUnsafeOptions(
- cert_handle.get(), intermediates_raw, options));
+ X509Certificate::CreateFromBufferUnsafeOptions(
+ std::move(cert_handle), std::move(intermediates), options));
return result;
}
@@ -80,19 +78,17 @@ ScopedPCCERT_CONTEXT CreateCertContextWithChain(
PCCERT_CONTEXT primary_cert = nullptr;
BOOL ok = CertAddEncodedCertificateToStore(
- store.get(), X509_ASN_ENCODING,
- CRYPTO_BUFFER_data(cert->os_cert_handle()),
- base::checked_cast<DWORD>(CRYPTO_BUFFER_len(cert->os_cert_handle())),
+ store.get(), X509_ASN_ENCODING, CRYPTO_BUFFER_data(cert->cert_buffer()),
+ base::checked_cast<DWORD>(CRYPTO_BUFFER_len(cert->cert_buffer())),
CERT_STORE_ADD_ALWAYS, &primary_cert);
if (!ok || !primary_cert)
return nullptr;
ScopedPCCERT_CONTEXT scoped_primary_cert(primary_cert);
- for (X509Certificate::OSCertHandle intermediate :
- cert->GetIntermediateCertificates()) {
+ for (const auto& intermediate : cert->intermediate_buffers()) {
ok = CertAddEncodedCertificateToStore(
- store.get(), X509_ASN_ENCODING, CRYPTO_BUFFER_data(intermediate),
- base::checked_cast<DWORD>(CRYPTO_BUFFER_len(intermediate)),
+ store.get(), X509_ASN_ENCODING, CRYPTO_BUFFER_data(intermediate.get()),
+ base::checked_cast<DWORD>(CRYPTO_BUFFER_len(intermediate.get())),
CERT_STORE_ADD_ALWAYS, NULL);
if (!ok) {
if (invalid_intermediate_behavior == InvalidIntermediateBehavior::kFail)
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index da851febcf5..5d45b3014b2 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -1988,7 +1988,6 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
base::Time current(base::Time::Now());
scoped_refptr<MockSimplePersistentCookieStore> store(
new MockSimplePersistentCookieStore);
- base::Time new_access_time;
base::Time expires(base::Time::Now() + base::TimeDelta::FromSeconds(100));
const CookiesInputInfo input_info[] = {
diff --git a/chromium/net/data/gencerts/__init__.py b/chromium/net/data/gencerts/__init__.py
new file mode 100755
index 00000000000..a7e82b57760
--- /dev/null
+++ b/chromium/net/data/gencerts/__init__.py
@@ -0,0 +1,525 @@
+#!/usr/bin/python
+# Copyright (c) 2015 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.
+
+"""Set of helpers to generate signed X.509v3 certificates.
+
+This works by shelling out calls to the 'openssl req' and 'openssl ca'
+commands, and passing the appropriate command line flags and configuration file
+(.cnf).
+"""
+
+import base64
+import os
+import shutil
+import subprocess
+import sys
+
+import openssl_conf
+
+# Enum for the "type" of certificate that is to be created. This is used to
+# select sane defaults for the .cnf file and command line flags, but they can
+# all be overridden.
+TYPE_CA = 2
+TYPE_END_ENTITY = 3
+
+# March 1st, 2015 12:00 UTC
+MARCH_1_2015_UTC = '150301120000Z'
+
+# March 2nd, 2015 12:00 UTC
+MARCH_2_2015_UTC = '150302120000Z'
+
+# January 1st, 2015 12:00 UTC
+JANUARY_1_2015_UTC = '150101120000Z'
+
+# September 1st, 2015 12:00 UTC
+SEPTEMBER_1_2015_UTC = '150901120000Z'
+
+# January 1st, 2016 12:00 UTC
+JANUARY_1_2016_UTC = '160101120000Z'
+
+# January 1st, 2021 12:00 UTC
+JANUARY_1_2021_UTC = '210101120000Z'
+
+# The default time tests should use when verifying.
+DEFAULT_TIME = MARCH_2_2015_UTC
+
+KEY_PURPOSE_ANY = 'anyExtendedKeyUsage'
+KEY_PURPOSE_SERVER_AUTH = 'serverAuth'
+KEY_PURPOSE_CLIENT_AUTH = 'clientAuth'
+
+DEFAULT_KEY_PURPOSE = KEY_PURPOSE_SERVER_AUTH
+
+# Counters used to generate unique (but readable) path names.
+g_cur_path_id = {}
+
+# Output paths used:
+# - g_tmp_dir: where any temporary files (cert req, signing db etc) are
+# saved to.
+
+# See init() for how these are assigned.
+g_tmp_dir = None
+
+# The default validity range of generated certificates. Can be modified with
+# set_default_validity_range().
+g_default_start_date = JANUARY_1_2015_UTC
+g_default_end_date = JANUARY_1_2016_UTC
+
+
+def set_default_validity_range(start_date, end_date):
+ """Sets the validity range that will be used for certificates created with
+ Certificate"""
+ global g_default_start_date
+ global g_default_end_date
+ g_default_start_date = start_date
+ g_default_end_date = end_date
+
+
+def get_unique_path_id(name):
+ """Returns a base filename that contains 'name', but is unique to the output
+ directory"""
+ # Use case-insensitive matching for counting duplicates, since some
+ # filesystems are case insensitive, but case preserving.
+ lowercase_name = name.lower()
+ path_id = g_cur_path_id.get(lowercase_name, 0)
+ g_cur_path_id[lowercase_name] = path_id + 1
+
+ # Use a short and clean name for the first use of this name.
+ if path_id == 0:
+ return name
+
+ # Otherwise append the count to make it unique.
+ return '%s_%d' % (name, path_id)
+
+
+def get_path_in_tmp_dir(name, suffix):
+ return os.path.join(g_tmp_dir, '%s%s' % (name, suffix))
+
+
+class Key(object):
+ """Describes a public + private key pair. It is a dumb wrapper around an
+ on-disk key."""
+
+ def __init__(self, path):
+ self.path = path
+
+
+ def get_path(self):
+ """Returns the path to a file that contains the key contents."""
+ return self.path
+
+
+def get_or_generate_key(generation_arguments, path):
+ """Helper function to either retrieve a key from an existing file |path|, or
+ generate a new one using the command line |generation_arguments|."""
+
+ generation_arguments_str = ' '.join(generation_arguments)
+
+ # If the file doesn't already exist, generate a new key using the generation
+ # parameters.
+ if not os.path.isfile(path):
+ key_contents = subprocess.check_output(generation_arguments)
+
+ # Prepend the generation parameters to the key file.
+ write_string_to_file(generation_arguments_str + '\n' + key_contents,
+ path)
+ else:
+ # If the path already exists, confirm that it is for the expected key type.
+ first_line = read_file_to_string(path).splitlines()[0]
+ if first_line != generation_arguments_str:
+ sys.stderr.write(('\nERROR: The existing key file:\n %s\nis not '
+ 'compatible with the requested parameters:\n "%s" vs "%s".\n'
+ 'Delete the file if you want to re-generate it with the new '
+ 'parameters, otherwise pick a new filename\n') % (
+ path, first_line, generation_arguments_str))
+ sys.exit(1)
+
+ return Key(path)
+
+
+def get_or_generate_rsa_key(size_bits, path):
+ """Retrieves an existing key from a file if the path exists. Otherwise
+ generates an RSA key with the specified bit size and saves it to the path."""
+ return get_or_generate_key(['openssl', 'genrsa', str(size_bits)], path)
+
+
+def get_or_generate_ec_key(named_curve, path):
+ """Retrieves an existing key from a file if the path exists. Otherwise
+ generates an EC key with the specified named curve and saves it to the
+ path."""
+ return get_or_generate_key(['openssl', 'ecparam', '-name', named_curve,
+ '-genkey'], path)
+
+
+def create_key_path(base_name):
+ """Generates a name that contains |base_name| in it, and is relative to the
+ "keys/" directory. If create_key_path(xxx) is called more than once during
+ the script run, a suffix will be added."""
+
+ # Save keys to CWD/keys/*.key
+ keys_dir = 'keys'
+
+ # Create the keys directory if it doesn't exist
+ if not os.path.exists(keys_dir):
+ os.makedirs(keys_dir)
+
+ return get_unique_path_id(os.path.join(keys_dir, base_name)) + '.key'
+
+
+class Certificate(object):
+ """Helper for building an X.509 certificate."""
+
+ def __init__(self, name, cert_type, issuer):
+ # The name will be used for the subject's CN, and also as a component of
+ # the temporary filenames to help with debugging.
+ self.name = name
+ self.path_id = get_unique_path_id(name)
+
+ # Allow the caller to override the key later. If no key was set will
+ # auto-generate one.
+ self.key = None
+
+ # The issuer is also a Certificate object. Passing |None| means it is a
+ # self-signed certificate.
+ self.issuer = issuer
+ if issuer is None:
+ self.issuer = self
+
+ # The config contains all the OpenSSL options that will be passed via a
+ # .cnf file. Set up defaults.
+ self.config = openssl_conf.Config()
+ self.init_config()
+
+ # Some settings need to be passed as flags rather than in the .cnf file.
+ # Technically these can be set though a .cnf, however doing so makes it
+ # sticky to the issuing certificate, rather than selecting it per
+ # subordinate certificate.
+ self.validity_flags = []
+ self.md_flags = []
+
+ # By default OpenSSL will use the current time for the start time. Instead
+ # default to using a fixed timestamp for more predictable results each time
+ # the certificates are re-generated.
+ self.set_validity_range(g_default_start_date, g_default_end_date)
+
+ # Use SHA-256 when THIS certificate is signed (setting it in the
+ # configuration would instead set the hash to use when signing other
+ # certificates with this one).
+ self.set_signature_hash('sha256')
+
+ # Set appropriate key usages and basic constraints. For flexibility in
+ # testing (since want to generate some flawed certificates) these are set
+ # on a per-certificate basis rather than automatically when signing.
+ if cert_type == TYPE_END_ENTITY:
+ self.get_extensions().set_property('keyUsage',
+ 'critical,digitalSignature,keyEncipherment')
+ self.get_extensions().set_property('extendedKeyUsage',
+ 'serverAuth,clientAuth')
+ else:
+ self.get_extensions().set_property('keyUsage',
+ 'critical,keyCertSign,cRLSign')
+ self.get_extensions().set_property('basicConstraints', 'critical,CA:true')
+
+ # Tracks whether the PEM file for this certificate has been written (since
+ # generation is done lazily).
+ self.finalized = False
+
+ # Initialize any files that will be needed if this certificate is used to
+ # sign other certificates. Starts off serial numbers at 1, and will
+ # increment them for each signed certificate.
+ if not os.path.exists(self.get_serial_path()):
+ write_string_to_file('01\n', self.get_serial_path())
+ if not os.path.exists(self.get_database_path()):
+ write_string_to_file('', self.get_database_path())
+
+
+ def set_validity_range(self, start_date, end_date):
+ """Sets the Validity notBefore and notAfter properties for the
+ certificate"""
+ self.validity_flags = ['-startdate', start_date, '-enddate', end_date]
+
+
+ def set_signature_hash(self, md):
+ """Sets the hash function that will be used when signing this certificate.
+ Can be sha1, sha256, sha512, md5, etc."""
+ self.md_flags = ['-md', md]
+
+
+ def get_extensions(self):
+ return self.config.get_section('req_ext')
+
+
+ def get_path(self, suffix):
+ """Forms a path to an output file for this certificate, containing the
+ indicated suffix. The certificate's name will be used as its basis."""
+ return os.path.join(g_tmp_dir, '%s%s' % (self.path_id, suffix))
+
+
+ def get_name_path(self, suffix):
+ """Forms a path to an output file for this CA, containing the indicated
+ suffix. If multiple certificates have the same name, they will use the same
+ path."""
+ return get_path_in_tmp_dir(self.name, suffix)
+
+
+ def set_key(self, key):
+ assert self.finalized is False
+ self.set_key_internal(key)
+
+
+ def set_key_internal(self, key):
+ self.key = key
+
+ # Associate the private key with the certificate.
+ section = self.config.get_section('root_ca')
+ section.set_property('private_key', self.key.get_path())
+
+
+ def get_key(self):
+ if self.key is None:
+ self.set_key_internal(
+ get_or_generate_rsa_key(2048, create_key_path(self.name)))
+ return self.key
+
+
+ def get_cert_path(self):
+ return self.get_path('.pem')
+
+
+ def get_serial_path(self):
+ return self.get_name_path('.serial')
+
+
+ def get_csr_path(self):
+ return self.get_path('.csr')
+
+
+ def get_database_path(self):
+ return self.get_name_path('.db')
+
+
+ def get_config_path(self):
+ return self.get_path('.cnf')
+
+
+ def get_cert_pem(self):
+ # Finish generating a .pem file for the certificate.
+ self.finalize()
+
+ # Read the certificate data.
+ return read_file_to_string(self.get_cert_path())
+
+
+ def finalize(self):
+ """Finishes the certificate creation process. This generates any needed
+ key, creates and signs the CSR. On completion the resulting PEM file can be
+ found at self.get_cert_path()"""
+
+ if self.finalized:
+ return # Already finalized, no work needed.
+
+ self.finalized = True
+
+ # Ensure that the issuer has been "finalized", since its outputs need to be
+ # accessible. Note that self.issuer could be the same as self.
+ self.issuer.finalize()
+
+ # Ensure the certificate has a key (gets lazily created by this call if
+ # missing).
+ self.get_key()
+
+ # Serialize the config to a file.
+ self.config.write_to_file(self.get_config_path())
+
+ # Create a CSR.
+ subprocess.check_call(
+ ['openssl', 'req', '-new',
+ '-key', self.key.get_path(),
+ '-out', self.get_csr_path(),
+ '-config', self.get_config_path()])
+
+ cmd = ['openssl', 'ca', '-batch', '-in',
+ self.get_csr_path(), '-out', self.get_cert_path(), '-config',
+ self.issuer.get_config_path()]
+
+ if self.issuer == self:
+ cmd.append('-selfsign')
+
+ # Add in any extra flags.
+ cmd.extend(self.validity_flags)
+ cmd.extend(self.md_flags)
+
+ # Run the 'openssl ca' command.
+ subprocess.check_call(cmd)
+
+
+ def init_config(self):
+ """Initializes default properties in the certificate .cnf file that are
+ generic enough to work for all certificates (but can be overridden later).
+ """
+
+ # --------------------------------------
+ # 'req' section
+ # --------------------------------------
+
+ section = self.config.get_section('req')
+
+ section.set_property('encrypt_key', 'no')
+ section.set_property('utf8', 'yes')
+ section.set_property('string_mask', 'utf8only')
+ section.set_property('prompt', 'no')
+ section.set_property('distinguished_name', 'req_dn')
+ section.set_property('req_extensions', 'req_ext')
+
+ # --------------------------------------
+ # 'req_dn' section
+ # --------------------------------------
+
+ # This section describes the certificate subject's distinguished name.
+
+ section = self.config.get_section('req_dn')
+ section.set_property('commonName', '"%s"' % (self.name))
+
+ # --------------------------------------
+ # 'req_ext' section
+ # --------------------------------------
+
+ # This section describes the certificate's extensions.
+
+ section = self.config.get_section('req_ext')
+ section.set_property('subjectKeyIdentifier', 'hash')
+
+ # --------------------------------------
+ # SECTIONS FOR CAs
+ # --------------------------------------
+
+ # The following sections are used by the 'openssl ca' and relate to the
+ # signing operation. They are not needed for end-entity certificate
+ # configurations, but only if this certifiate will be used to sign other
+ # certificates.
+
+ # --------------------------------------
+ # 'ca' section
+ # --------------------------------------
+
+ section = self.config.get_section('ca')
+ section.set_property('default_ca', 'root_ca')
+
+ section = self.config.get_section('root_ca')
+ section.set_property('certificate', self.get_cert_path())
+ section.set_property('new_certs_dir', g_tmp_dir)
+ section.set_property('serial', self.get_serial_path())
+ section.set_property('database', self.get_database_path())
+ section.set_property('unique_subject', 'no')
+
+ # These will get overridden via command line flags.
+ section.set_property('default_days', '365')
+ section.set_property('default_md', 'sha256')
+
+ section.set_property('policy', 'policy_anything')
+ section.set_property('email_in_dn', 'no')
+ section.set_property('preserve', 'yes')
+ section.set_property('name_opt', 'multiline,-esc_msb,utf8')
+ section.set_property('cert_opt', 'ca_default')
+ section.set_property('copy_extensions', 'copy')
+ section.set_property('x509_extensions', 'signing_ca_ext')
+ section.set_property('default_crl_days', '30')
+ section.set_property('crl_extensions', 'crl_ext')
+
+ section = self.config.get_section('policy_anything')
+ section.set_property('domainComponent', 'optional')
+ section.set_property('countryName', 'optional')
+ section.set_property('stateOrProvinceName', 'optional')
+ section.set_property('localityName', 'optional')
+ section.set_property('organizationName', 'optional')
+ section.set_property('organizationalUnitName', 'optional')
+ section.set_property('commonName', 'optional')
+ section.set_property('emailAddress', 'optional')
+
+ section = self.config.get_section('signing_ca_ext')
+ section.set_property('subjectKeyIdentifier', 'hash')
+ section.set_property('authorityKeyIdentifier', 'keyid:always')
+ section.set_property('authorityInfoAccess', '@issuer_info')
+ section.set_property('crlDistributionPoints', '@crl_info')
+
+ section = self.config.get_section('issuer_info')
+ section.set_property('caIssuers;URI.0',
+ 'http://url-for-aia/%s.cer' % (self.name))
+
+ section = self.config.get_section('crl_info')
+ section.set_property('URI.0', 'http://url-for-crl/%s.crl' % (self.name))
+
+ section = self.config.get_section('crl_ext')
+ section.set_property('authorityKeyIdentifier', 'keyid:always')
+ section.set_property('authorityInfoAccess', '@issuer_info')
+
+
+def text_data_to_pem(block_header, text_data):
+ return '%s\n-----BEGIN %s-----\n%s\n-----END %s-----\n' % (text_data,
+ block_header, base64.b64encode(text_data), block_header)
+
+
+def write_chain(description, chain, out_pem):
+ """Writes the chain to a .pem file as a series of CERTIFICATE blocks"""
+
+ # Prepend the script name that generated the file to the description.
+ test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], description)
+
+ # Write the certificate chain to the output file.
+ for cert in chain:
+ test_data += '\n' + cert.get_cert_pem()
+
+ write_string_to_file(test_data, out_pem)
+
+
+def write_string_to_file(data, path):
+ with open(path, 'w') as f:
+ f.write(data)
+
+
+def read_file_to_string(path):
+ with open(path, 'r') as f:
+ return f.read()
+
+
+def init(invoking_script_path):
+ """Creates an output directory to contain all the temporary files that may be
+ created, as well as determining the path for the final output. These paths
+ are all based off of the name of the calling script.
+ """
+
+ global g_tmp_dir
+
+ # The scripts assume to be run from within their containing directory (paths
+ # to things like "keys/" are written relative).
+ expected_cwd = os.path.realpath(os.path.dirname(invoking_script_path))
+ actual_cwd = os.path.realpath(os.getcwd())
+ if actual_cwd != expected_cwd:
+ sys.stderr.write(
+ ('Your current working directory must be that containing the python '
+ 'scripts:\n%s\nas the script may reference paths relative to this\n')
+ % (expected_cwd))
+ sys.exit(1)
+
+ # Use an output directory with the same name as the invoking script.
+ g_tmp_dir = 'out'
+
+ # Ensure the output directory exists and is empty.
+ sys.stdout.write('Creating output directory: %s\n' % (g_tmp_dir))
+ shutil.rmtree(g_tmp_dir, True)
+ os.makedirs(g_tmp_dir)
+
+
+def create_self_signed_root_certificate(name):
+ return Certificate(name, TYPE_CA, None)
+
+
+def create_intermediate_certificate(name, issuer):
+ return Certificate(name, TYPE_CA, issuer)
+
+
+def create_end_entity_certificate(name, issuer):
+ return Certificate(name, TYPE_END_ENTITY, issuer)
+
+init(sys.argv[0])
diff --git a/chromium/net/data/gencerts/openssl_conf.py b/chromium/net/data/gencerts/openssl_conf.py
new file mode 100755
index 00000000000..fe1838d6638
--- /dev/null
+++ b/chromium/net/data/gencerts/openssl_conf.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# Copyright (c) 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This file contains helpers for representing, manipulating, and writing
+OpenSSL configuration files [1]
+
+Configuration files are simply a collection of name=value "properties", which
+are grouped into "sections".
+
+[1] https://www.openssl.org/docs/manmaster/apps/config.html
+"""
+
+class Property(object):
+ """Represents a key/value pair in OpenSSL .cnf files.
+
+ Names and values are not quoted in any way, so callers need to pass the text
+ exactly as it should be written to the file (leading and trailing whitespace
+ doesn't matter).
+
+ For instance:
+ baseConstraints = critical, CA:false
+
+ Could be represented by a Property where:
+ name = 'baseConstraints'
+ value = 'critical, CA:false'
+ """
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+
+ def write_to(self, out):
+ """Outputs this property to .cnf file."""
+ out.write('%s = %s\n' % (self.name, self.value))
+
+
+class Section(object):
+ """Represents a section in OpenSSL. For instance:
+ [CA_root]
+ preserve = true
+
+ Could be represented by a Section where:
+ name = 'CA_root'
+ properties = [Property('preserve', 'true')]
+ """
+ def __init__(self, name):
+ self.name = name
+ self.properties = []
+
+
+ def ensure_property_name_not_duplicated(self, name):
+ """Raises an exception of there is more than 1 property named |name|."""
+ count = 0
+ for prop in self.properties:
+ if prop.name == name:
+ count += 1
+ if count > 1:
+ raise Exception('Duplicate property: %s' % (name))
+
+
+ def set_property(self, name, value):
+ """Replaces, adds, or removes a Property from the Section:
+
+ - If |value| is None, then this is equivalent to calling
+ remove_property(name)
+ - If there is an existing property matching |name| then its value is
+ replaced with |value|
+ - If there are no properties matching |name| then a new one is added at
+ the end of the section
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+
+ if value is None:
+ self.remove_property(name)
+ return
+
+ self.ensure_property_name_not_duplicated(name)
+
+ for prop in self.properties:
+ if prop.name == name:
+ prop.value = value
+ return
+
+ self.add_property(name, value)
+
+
+ def add_property(self, name, value):
+ """Adds a property (allows duplicates)"""
+ self.properties.append(Property(name, value))
+
+
+ def remove_property(self, name):
+ """Removes the property with the indicated name, if it exists.
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+ self.ensure_property_name_not_duplicated(name)
+
+ for i in range(len(self.properties)):
+ if self.properties[i].name == name:
+ self.properties.pop(i)
+ return
+
+
+ def write_to(self, out):
+ """Outputs the section in the format used by .cnf files"""
+ out.write('[%s]\n' % (self.name))
+ for prop in self.properties:
+ prop.write_to(out)
+ out.write('\n')
+
+
+class Config(object):
+ """Represents a .cnf (configuration) file in OpenSSL"""
+ def __init__(self):
+ self.sections = []
+
+
+ def get_section(self, name):
+ """Gets or creates a section with the given name."""
+ for section in self.sections:
+ if section.name == name:
+ return section
+ new_section = Section(name)
+ self.sections.append(new_section)
+ return new_section
+
+
+ def write_to_file(self, path):
+ """Outputs the Config to a .cnf files."""
+ with open(path, 'w') as out:
+ for section in self.sections:
+ section.write_to(out)
diff --git a/chromium/net/data/ssl/certificates/README b/chromium/net/data/ssl/certificates/README
index e70316247ec..3c0f4ac7cc6 100644
--- a/chromium/net/data/ssl/certificates/README
+++ b/chromium/net/data/ssl/certificates/README
@@ -114,11 +114,16 @@ unit tests.
NSS certificate nickname for a user certificate. This certificate's Subject
field doesn't have a common name.
-- quic_intermediate.crt
-- quic_test_ecc.example.com.crt
-- quic_test.example.com.crt
-- quic_root.crt
- These certificates are used by the ProofVerifier's unit tests of QUIC.
+===== From net/data/ssl/scripts/generate-quic-chain.sh
+- quic-chain.pem
+- quic-leaf-cert.key
+- quic-leaf-cert.key.pkcs8.pem
+- quic-root.pem
+ These certificates are used by integration tests that use QUIC.
+
+- quic-leaf-cert.key.sct
+ This isn't generated and just contains a simple text file (the contents
+ don't actually matter, just the presence of the file).
===== From net/data/ssl/scripts/generate-test-certs.sh
- expired_cert.pem
@@ -180,11 +185,11 @@ unit tests.
- pre_june_2016.pem
- post_june_2016.pem
+- dec_2017.pem
Certs to test that policies related to enforcing CT on Symantec are
- properly gated on the issuance date. These files also contain legacy
- Symantec roots to simulate a chain for testing the upcoming Symantec
- distrust events; see https://g.co/chrome/symantecpkicerts. (Note,
- however, that the leaf and root do not actually form a chain.)
+ properly gated on the issuance date. See
+ https://g.co/chrome/symantecpkicerts. (Note, however, that the leaf and
+ root do not actually form a chain.)
- tls_feature_extension.pem
A certificate that contains the TLS Feature Extension.
diff --git a/chromium/net/data/ssl/certificates/common_name_only.pem b/chromium/net/data/ssl/certificates/common_name_only.pem
new file mode 100644
index 00000000000..5f7811a0a46
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/common_name_only.pem
@@ -0,0 +1,109 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCp1J9FuvCmfgoP
+pUn3w+iVRBwBOCXlZyzRcfRsiOfEGNnY8gEDNoyccKFHnj5rtJ/kQc9IgcZC2nob
+qUSdHBEhUjKZbDZXOTXlBmpVY3qw0edMgwS9SSmaM5axPXEqJn7KShyzEC+3qux1
+T+gH8DBgwiP2qjM1A6nqf0/QDDms15sKhZJm9Z/MBpbpO/4zPjYSdsADv9sc7uyU
+xRnNp3PQWu/hZjgg9w0tZWOzBaKHTHJLV+wH8frRqwLdHoB+gSIUfmNnGHKe59ia
+rWjGU4l5b4kOVS8e5dSfdvNLbUM8z8dMvRq68fJnCJLkqnV7cehYmi+c6iGvDbkV
+y7vVzfWnAgMBAAECggEALyW5+c/GE1KWVHWcrU4T+axo4eXGj4MvLA4ovyDaxtPn
+VpUItu2j56JVA97okVoZsXKbqxNsCQ9CKv+47qzmDIwXRASIqXpWffhj+MSfQQtk
+3Rbab/optIdx5E6cZgk91cbxZLyvopuu/XprfhiuNY5wEYB6qtMTjug9LhLWyCa3
+N2tTlIi8qMa79HPYcJ3l7en8jXrx+/856hCGGXXNP6H3HP4Kf171tZryDuekJhwt
+pm6chDeFMkvJVa8GflKUxC5aVqhb84apCArvuaP/IXlDf0mEcyToyTjQaHitWtYo
+BqueC3wMU5e5TvfQ3CKutWP3L9fQzU/mzpbEAuMMcQKBgQDUU47C0xwaIhfTyY2V
+j9xDoEyJiRiaw0wUg2WtlNyIfUCOJSFxHeXqCmu1TurBxoNprlWZCf+myBR7hKXV
+XbjRSluo7EFe6qF5ZxfVkTgaggSUmqd65kCDGyWQTZQ4tw+qal6T3TekJOwoAPa0
+ifKfPmzW/uleFwsXRJb5ydNA3QKBgQDMw13gt6s9xSAjvmZwdHdwb7712K4RrcoL
+vrdOI6HEVDYsu2+zJxEtp0koE1Dk5LBUP4VAaDw1ABcx+Qon29mFy/orc8uH0PEu
+SES6kZxr70eKJ67jvgs370m8zM+IJsC4RJ1wu09Q0vsdJ2TZLG5jlQD1no08Ta37
+Wv27zenGUwKBgH7ukPsBj9xDo3D2HlFaFnjLPNZAAliLBlGBF+kEhC6Iim4v3mUs
+VYVrw2Y5jnhXf7pPAVcjNhVzqWMKMsVyaQmdZVyAGLhwliXorsP7M8oNDkX0iskb
+G1gFg5hX+JNLRO9A9dd5uUjE1fU4VkQp78SpYhHJhKO+LOA1HfioYkV1AoGALHAt
+3Iof2M0CN5+nvboY/cbSq6o1xNJxqfDe+U9UWTZpd3XKPRg6ay0F/HOMt9BF0FLk
+yWCVyG7XmdnRcWsOHzJwfaOoxTX8Ua4PdGoLh4UrgnkwRG7HIoGFADt2wraeVp9V
+h9Su1vyi0OXuxg8VefkpdyTMxAybuJQ7wtliZc8CgYEAouBfKjc3xn/jrf++kgie
+taZ+ormKZs2mfTfcEMeQv7Bd7sEUWCoRevdorTlHaw1DKBqFq56Y1v3ppH83C6DH
+5v1+43M6zq7qWGSgf5nbQ1ZBMUR0FMcBujc9JFX52Zc7ScvE1hwMT3lBJut/ln5W
+h1oQd50MoCr4WE39Em4/H3o=
+-----END PRIVATE KEY-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 24 (0x18)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Dec 20 00:00:00 2017 GMT
+ Not After : Dec 20 00:00:00 2020 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
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:a9:d4:9f:45:ba:f0:a6:7e:0a:0f:a5:49:f7:c3:
+ e8:95:44:1c:01:38:25:e5:67:2c:d1:71:f4:6c:88:
+ e7:c4:18:d9:d8:f2:01:03:36:8c:9c:70:a1:47:9e:
+ 3e:6b:b4:9f:e4:41:cf:48:81:c6:42:da:7a:1b:a9:
+ 44:9d:1c:11:21:52:32:99:6c:36:57:39:35:e5:06:
+ 6a:55:63:7a:b0:d1:e7:4c:83:04:bd:49:29:9a:33:
+ 96:b1:3d:71:2a:26:7e:ca:4a:1c:b3:10:2f:b7:aa:
+ ec:75:4f:e8:07:f0:30:60:c2:23:f6:aa:33:35:03:
+ a9:ea:7f:4f:d0:0c:39:ac:d7:9b:0a:85:92:66:f5:
+ 9f:cc:06:96:e9:3b:fe:33:3e:36:12:76:c0:03:bf:
+ db:1c:ee:ec:94:c5:19:cd:a7:73:d0:5a:ef:e1:66:
+ 38:20:f7:0d:2d:65:63:b3:05:a2:87:4c:72:4b:57:
+ ec:07:f1:fa:d1:ab:02:dd:1e:80:7e:81:22:14:7e:
+ 63:67:18:72:9e:e7:d8:9a:ad:68:c6:53:89:79:6f:
+ 89:0e:55:2f:1e:e5:d4:9f:76:f3:4b:6d:43:3c:cf:
+ c7:4c:bd:1a:ba:f1:f2:67:08:92:e4:aa:75:7b:71:
+ e8:58:9a:2f:9c:ea:21:af:0d:b9:15:cb:bb:d5:cd:
+ f5:a7
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 41:E5:87:59:14:3F:3E:99:24:67:DF:F8:B7:59:F6:81:3D:9C:F7:14
+ 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
+ Signature Algorithm: sha256WithRSAEncryption
+ 39:41:78:9d:38:e1:d2:7e:92:34:7a:da:32:6c:2d:51:d6:a4:
+ c1:d9:84:5f:24:2e:8f:ce:a8:60:29:ba:01:01:4b:a3:e0:fe:
+ 56:9c:5a:0b:8b:9f:b1:b6:55:89:0e:40:8f:09:0c:10:f1:dc:
+ 9a:3d:85:7c:ef:83:f9:0e:42:81:89:ac:a4:11:b9:e9:fd:db:
+ 58:54:63:51:66:5c:0e:0e:42:68:58:d9:0e:aa:54:70:6d:e7:
+ 51:e5:8b:fd:d0:da:dd:7b:b9:97:55:42:42:e7:39:b4:4b:4b:
+ c4:89:90:d1:6e:4b:0a:fd:cc:a8:a3:a7:70:ed:d6:e8:c4:09:
+ 80:d7:b0:09:ae:db:d2:4b:4f:0a:ec:73:28:bf:6f:cb:61:bd:
+ ab:5f:9a:2d:81:5e:e0:be:8c:32:d1:24:ea:a3:83:04:b8:81:
+ 97:e2:26:91:a2:fa:da:18:fa:54:58:46:d9:38:9b:66:b0:80:
+ 1d:a3:55:5b:86:7d:77:ca:0c:ba:e1:e6:c5:8c:e3:08:73:0f:
+ 73:b7:8b:42:75:6b:62:6e:bf:73:2d:4c:11:07:b4:b7:a0:72:
+ 0d:23:08:4b:65:8e:fd:1d:61:15:e6:d0:a5:ad:31:0b:d4:35:
+ 3a:f7:aa:e7:50:38:a2:dc:b0:24:52:9d:86:fc:ce:1a:d8:29:
+ 4b:de:82:af
+-----BEGIN CERTIFICATE-----
+MIIDrTCCApWgAwIBAgIBGDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MTIyMDAw
+MDAwMFoXDTIwMTIyMDAwMDAwMFowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKnUn0W68KZ+Cg+lSffD6JVEHAE4JeVnLNFx9GyI58QY2djyAQM2jJxw
+oUeePmu0n+RBz0iBxkLaehupRJ0cESFSMplsNlc5NeUGalVjerDR50yDBL1JKZoz
+lrE9cSomfspKHLMQL7eq7HVP6AfwMGDCI/aqMzUDqep/T9AMOazXmwqFkmb1n8wG
+luk7/jM+NhJ2wAO/2xzu7JTFGc2nc9Ba7+FmOCD3DS1lY7MFoodMcktX7Afx+tGr
+At0egH6BIhR+Y2cYcp7n2JqtaMZTiXlviQ5VLx7l1J9280ttQzzPx0y9Grrx8mcI
+kuSqdXtx6FiaL5zqIa8NuRXLu9XN9acCAwEAAaNvMG0wDAYDVR0TAQH/BAIwADAd
+BgNVHQ4EFgQUQeWHWRQ/PpkkZ9/4t1n2gT2c9xQwHwYDVR0jBBgwFoAUmyYLipip
+ux25HxzjGkAz7Y4XiKswHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0G
+CSqGSIb3DQEBCwUAA4IBAQA5QXidOOHSfpI0etoybC1R1qTB2YRfJC6PzqhgKboB
+AUuj4P5WnFoLi5+xtlWJDkCPCQwQ8dyaPYV874P5DkKBiaykEbnp/dtYVGNRZlwO
+DkJoWNkOqlRwbedR5Yv90Nrde7mXVUJC5zm0S0vEiZDRbksK/cyoo6dw7dboxAmA
+17AJrtvSS08K7HMov2/LYb2rX5otgV7gvowy0STqo4MEuIGX4iaRovraGPpUWEbZ
+OJtmsIAdo1Vbhn13ygy64ebFjOMIcw9zt4tCdWtibr9zLUwRB7S3oHINIwhLZY79
+HWEV5tClrTEL1DU696rnUDii3LAkUp2G/M4a2ClL3oKv
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw b/chromium/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw
new file mode 100644
index 00000000000..3a22aa7dd4c
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/crlset_by_leaf_subject_no_spki.raw
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/crlset_by_root_subject.raw b/chromium/net/data/ssl/certificates/crlset_by_root_subject.raw
new file mode 100644
index 00000000000..95404126d17
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/crlset_by_root_subject.raw
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw b/chromium/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw
new file mode 100644
index 00000000000..d556a83ada6
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/crlset_by_root_subject_no_spki.raw
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/dec_2017.pem b/chromium/net/data/ssl/certificates/dec_2017.pem
new file mode 100644
index 00000000000..e0dff799390
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/dec_2017.pem
@@ -0,0 +1,84 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 25 (0x19)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Dec 20 00:00:00 2017 GMT
+ Not After : Dec 20 00:00:00 2020 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
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d0:c1:27:76:2d:56:e6:b9:e3:23:b9:b6:c3:0e:
+ f4:8c:cb:73:85:0e:45:ed:b8:ea:e6:21:b6:60:56:
+ 1d:b7:24:72:b9:51:72:68:07:22:9f:8f:fd:47:c7:
+ da:9b:7b:5c:ad:e8:f5:6a:72:4d:8b:e4:55:fc:c6:
+ 41:d8:53:5e:0a:ba:35:4e:bc:98:21:d0:c2:ae:f7:
+ ff:ec:8f:26:eb:a1:71:74:11:b7:21:fd:38:04:5a:
+ e5:42:3d:02:28:05:3a:8d:2d:9b:5e:7b:39:35:e4:
+ fe:59:a8:98:39:c7:6c:d1:9e:1a:d7:c3:11:78:cb:
+ 44:72:e4:a0:89:83:e2:f8:de:c9:46:3a:c5:71:7f:
+ af:ee:e5:ba:1f:fa:97:19:f0:d0:5c:32:81:d3:7d:
+ 80:99:70:49:2a:ba:c8:40:b0:32:51:ec:16:3b:4d:
+ 61:05:e2:dc:b9:24:f0:a6:6b:ad:cd:53:1d:cd:9a:
+ ba:bb:df:96:f1:ac:e6:5e:03:cb:98:07:da:21:6e:
+ 8c:ac:56:37:39:15:d4:ab:b0:43:d1:64:7a:05:59:
+ f8:f8:bd:4e:31:c7:8c:d6:23:e8:3d:99:ea:75:78:
+ 25:8d:1a:83:32:39:ec:ec:69:ef:76:cc:b6:cf:06:
+ 0e:1d:ca:ac:8c:b7:10:a7:d2:ec:18:86:7c:6f:20:
+ 9c:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 4F:62:A1:56:D4:81:D5:18:65:C6:E0:DC:91:72:07:32:58:0C:79:EE
+ 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
+ a5:16:f1:6f:8d:ab:b2:d7:c1:f6:98:98:d4:2d:8d:0f:85:09:
+ 65:73:f4:72:40:66:8b:28:f3:e4:d8:b8:8e:21:2b:9f:27:f2:
+ ab:0f:b6:e7:94:9a:1c:b1:58:9a:71:5e:79:d4:1b:9b:11:f3:
+ 52:ee:a2:00:85:75:d5:a0:6e:af:11:39:cd:72:f8:a8:57:09:
+ 09:4f:df:e7:42:26:63:08:a2:fb:19:ff:ab:97:e4:f1:01:7c:
+ df:e5:87:58:e7:90:e6:61:c0:f8:35:89:5f:4b:f2:f0:ae:cb:
+ 1a:69:3b:1f:0b:ac:38:18:28:5a:ca:92:75:fa:ee:56:69:dd:
+ dc:e8:c4:db:8f:84:20:d2:50:ee:34:32:e6:2f:90:aa:12:3d:
+ db:56:a3:38:0f:80:b7:f5:32:b6:12:b8:30:1c:14:84:83:4e:
+ 7b:42:49:16:ef:1e:b0:3a:f5:03:30:72:86:1f:0d:77:1a:7b:
+ 44:8b:60:e4:34:49:d8:b0:af:8d:a6:f1:08:70:b3:69:54:5f:
+ e0:2f:6d:42:2f:ff:68:07:fd:cf:c1:f7:fa:e7:5f:fe:1f:93:
+ ba:02:01:29:69:37:97:6a:16:03:7f:2d:0c:b2:2a:d8:43:13:
+ ed:cf:1b:2d:1f:b0:f3:b6:e1:98:cb:92:d3:26:5e:f4:a7:a3:
+ 90:de:6a:ab
+-----BEGIN CERTIFICATE-----
+MIIDvzCCAqegAwIBAgIBGTANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MTIyMDAw
+MDAwMFoXDTIwMTIyMDAwMDAwMFowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBANDBJ3YtVua54yO5tsMO9IzLc4UORe246uYhtmBWHbckcrlRcmgHIp+P
+/UfH2pt7XK3o9WpyTYvkVfzGQdhTXgq6NU68mCHQwq73/+yPJuuhcXQRtyH9OARa
+5UI9AigFOo0tm157OTXk/lmomDnHbNGeGtfDEXjLRHLkoImD4vjeyUY6xXF/r+7l
+uh/6lxnw0FwygdN9gJlwSSq6yECwMlHsFjtNYQXi3Lkk8KZrrc1THc2aurvflvGs
+5l4Dy5gH2iFujKxWNzkV1KuwQ9FkegVZ+Pi9TjHHjNYj6D2Z6nV4JY0agzI57Oxp
+73bMts8GDh3KrIy3EKfS7BiGfG8gnL8CAwEAAaOBgDB+MAwGA1UdEwEB/wQCMAAw
+HQYDVR0OBBYEFE9ioVbUgdUYZcbg3JFyBzJYDHnuMB8GA1UdIwQYMBaAFJsmC4qY
+qbsduR8c4xpAM+2OF4irMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAP
+BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQClFvFvjauy18H2mJjU
+LY0PhQllc/RyQGaLKPPk2LiOISufJ/KrD7bnlJocsViacV551BubEfNS7qIAhXXV
+oG6vETnNcvioVwkJT9/nQiZjCKL7Gf+rl+TxAXzf5YdY55DmYcD4NYlfS/Lwrssa
+aTsfC6w4GChaypJ1+u5Wad3c6MTbj4Qg0lDuNDLmL5CqEj3bVqM4D4C39TK2Ergw
+HBSEg057QkkW7x6wOvUDMHKGHw13GntEi2DkNEnYsK+NpvEIcLNpVF/gL21CL/9o
+B/3Pwff651/+H5O6AgEpaTeXahYDfy0MsirYQxPtzxstH7DztuGYy5LTJl70p6OQ
+3mqr
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic-chain.pem b/chromium/net/data/ssl/certificates/quic-chain.pem
new file mode 100644
index 00000000000..ab0893b282f
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic-chain.pem
@@ -0,0 +1,147 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Test Intermediate CA
+ Validity
+ Not Before: Dec 18 23:44:03 2017 GMT
+ Not After : Dec 16 23:44:03 2027 GMT
+ Subject: CN=test.example.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ 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 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ DNS:test.example.com
+ Signature Algorithm: sha256WithRSAEncryption
+ bd:55:54:e5:ac:2b:e6:6f:c9:45:b7:77:97:af:37:e6:6b:60:
+ cb:51:0f:b0:2c:40:71:39:73:7a:0b:6f:37:a5:cc:40:4f:d1:
+ 43:3d:8e:1d:37:ba:ff:2d:7b:80:21:fd:ec:e4:7c:20:6a:ce:
+ 6e:28:9b:c1:4e:9e:1e:17:1f:cb:04:61:c1:d0:72:0c:31:f6:
+ ee:2b:a9:9c:29:6b:45:bd:97:57:a6:25:f3:f0:6b:08:3f:4e:
+ 00:33:cf:47:3b:50:4a:15:a7:a0:c8:e0:8b:86:7b:48:3e:39:
+ 15:00:0a:aa:79:3c:8d:fd:d7:4a:68:2f:05:2b:60:2a:d1:7e:
+ 1c:bc:06:e9:b7:51:35:71:d7:6b:f4:b8:f3:17:d7:f1:d4:8d:
+ f8:0e:4a:11:34:4d:d9:19:70:33:0a:66:e6:4c:11:93:90:5c:
+ 5d:a1:f3:8a:1c:ce:0c:12:5e:a9:6b:e1:1f:eb:b3:65:b8:bc:
+ 1a:48:af:cc:af:fc:db:3e:0b:32:47:8d:fc:ed:b3:50:9a:65:
+ b8:19:eb:db:18:21:5f:e4:1d:c5:87:57:9b:5a:8a:59:16:84:
+ 8d:27:3e:f9:7a:c0:fa:e7:84:90:da:1a:03:98:b5:c6:a9:52:
+ ed:df:0e:7a:02:c7:e6:82:d2:06:cb:97:75:90:89:d6:d1:cf:
+ 43:74:09:f7
+-----BEGIN CERTIFICATE-----
+MIIDATCCAemgAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IEludGVybWVkaWF0ZSBDQTAeFw0xNzEyMTgyMzQ0MDNaFw0yNzEyMTYyMzQ0MDNa
+MBsxGTAXBgNVBAMMEHRlc3QuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCyVm9+1LS2TuMVjorpRgYVY0xtOjJnxxSkF/y3BJj7tRGu
+kxwgcxXNs7zuYYKOy7h4ym3mV3PzRW4ewyddr15SbRJHRHI9fYrBR1AZSiGkCLTM
+LpyiKs4bh4KuOiOw3dI+ZP7OpjU0kwf4iG7IvrILX5yWDnkcoyvJI1qKHx4X4qnU
+PEkiKUP6Y1U8cmJK0XJarnWoFGfrWIjOEQy/CWfyu8iAPkrwNa3S3EOjL9rGOxxu
+dnAxc8wzW0823POPn6YHbWHgZm8sdr2Fo4vQis7EvJfg7eEp36Fiua3YDxr4rkT+
+piiVxMzftfdtRq7vm69zUB2f8Meg7zdLE3OWJJUPAgMBAAGjTDBKMAwGA1UdEwEB
+/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdEQQUMBKC
+EHRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAL1VVOWsK+ZvyUW3
+d5evN+ZrYMtRD7AsQHE5c3oLbzelzEBP0UM9jh03uv8te4Ah/ezkfCBqzm4om8FO
+nh4XH8sEYcHQcgwx9u4rqZwpa0W9l1emJfPwawg/TgAzz0c7UEoVp6DI4IuGe0g+
+ORUACqp5PI3910poLwUrYCrRfhy8Bum3UTVx12v0uPMX1/HUjfgOShE0TdkZcDMK
+ZuZMEZOQXF2h84oczgwSXqlr4R/rs2W4vBpIr8yv/Ns+CzJHjfzts1CaZbgZ69sY
+IV/kHcWHV5tailkWhI0nPvl6wPrnhJDaGgOYtcapUu3fDnoCx+aC0gbLl3WQidbR
+z0N0Cfc=
+-----END CERTIFICATE-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Test Root CA
+ Validity
+ Not Before: Dec 18 23:44:03 2017 GMT
+ Not After : Dec 16 23:44:03 2027 GMT
+ Subject: CN=Test Intermediate CA
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e4:cd:89:4c:65:4f:4d:68:bd:2a:7a:4f:0b:10:
+ 3f:02:d6:2a:5b:5b:76:c8:97:59:67:19:6e:95:45:
+ c3:38:a4:c7:29:f5:f7:95:52:97:a3:01:19:b2:b3:
+ ec:09:97:08:4f:f1:db:43:67:50:59:ac:ca:9a:05:
+ 56:fc:73:42:f3:90:e1:e5:3e:03:75:35:33:d2:df:
+ aa:3d:f8:ca:16:5e:7e:ef:01:9c:2a:30:eb:c7:cc:
+ 06:04:90:14:c0:54:f5:96:22:26:30:39:73:c5:c0:
+ 9d:0d:b0:9f:b0:e5:cf:f6:b1:0c:10:ab:f0:c9:54:
+ a6:30:d5:b4:fd:a7:23:7f:1e:57:7b:72:d7:af:0d:
+ a2:3e:4d:b2:c5:51:70:2a:06:2f:66:21:ca:7f:7d:
+ 6b:60:24:5e:ed:5f:74:ee:4b:b1:f1:ec:54:a0:fb:
+ 89:05:69:94:78:9b:a4:85:8c:ea:e6:b5:d6:fd:c5:
+ 6d:98:28:e4:1d:81:1b:26:3b:21:c2:e4:df:bd:a1:
+ 0d:51:35:40:43:a0:a4:00:66:fa:97:46:d6:9d:95:
+ ca:da:62:f8:c7:60:6c:e4:89:c2:d0:74:30:fe:2a:
+ db:54:95:5b:68:5f:ca:bd:e9:af:27:13:fc:c4:6f:
+ e6:5d:05:92:cc:bc:e4:76:8a:2e:34:0b:5e:39:11:
+ 75:57
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ Signature Algorithm: sha256WithRSAEncryption
+ 60:4e:38:f3:7b:00:46:75:8f:d0:4e:08:76:2d:ed:9f:bf:cc:
+ 50:1b:bf:e4:6d:76:50:fe:fa:7d:46:90:1c:75:f1:3f:47:19:
+ eb:02:38:cb:3e:56:0f:8f:09:ae:a8:42:d0:e6:5a:31:54:24:
+ b2:fe:4b:a2:e4:44:14:64:44:d8:50:12:62:4a:06:60:29:22:
+ 95:bb:c8:7e:dd:d4:7d:a6:dd:3c:0d:fb:71:67:6f:9b:49:05:
+ 09:7c:5c:63:2b:df:71:aa:ae:92:28:98:73:c2:60:b6:54:10:
+ f6:f5:54:d6:93:0a:22:56:0a:fd:45:8a:a4:d7:a7:21:df:f5:
+ 53:07:1c:3b:63:c1:7c:4e:f0:3d:5c:c4:c9:cc:55:ae:ec:fb:
+ 2e:4f:b0:f9:5b:1d:c3:46:ba:38:f6:ff:8d:b3:3b:d0:7d:15:
+ 3f:fd:6a:bd:a1:59:18:ff:57:fc:d6:c0:3d:7e:75:61:ff:13:
+ 09:81:5f:38:82:22:78:78:97:5e:e6:7c:fb:16:a8:92:40:97:
+ eb:7c:a5:37:da:ca:5f:28:69:e4:63:b7:07:61:ad:e8:5a:e8:
+ 06:55:c0:34:7c:30:66:1e:9a:7e:ed:cb:c8:14:c1:e3:b3:ac:
+ 8d:89:9c:6b:b1:ea:eb:71:94:c0:1d:63:b7:d9:82:74:13:0c:
+ ee:8a:ca:dc
+-----BEGIN CERTIFICATE-----
+MIIC1DCCAbygAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxUZXN0
+IFJvb3QgQ0EwHhcNMTcxMjE4MjM0NDAzWhcNMjcxMjE2MjM0NDAzWjAfMR0wGwYD
+VQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAOTNiUxlT01ovSp6TwsQPwLWKltbdsiXWWcZbpVFwzikxyn195VS
+l6MBGbKz7AmXCE/x20NnUFmsypoFVvxzQvOQ4eU+A3U1M9Lfqj34yhZefu8BnCow
+68fMBgSQFMBU9ZYiJjA5c8XAnQ2wn7Dlz/axDBCr8MlUpjDVtP2nI38eV3ty168N
+oj5NssVRcCoGL2Yhyn99a2AkXu1fdO5LsfHsVKD7iQVplHibpIWM6ua11v3FbZgo
+5B2BGyY7IcLk372hDVE1QEOgpABm+pdG1p2Vytpi+MdgbOSJwtB0MP4q21SVW2hf
+yr3prycT/MRv5l0Fksy85HaKLjQLXjkRdVcCAwEAAaMjMCEwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGBOOPN7AEZ1
+j9BOCHYt7Z+/zFAbv+RtdlD++n1GkBx18T9HGesCOMs+Vg+PCa6oQtDmWjFUJLL+
+S6LkRBRkRNhQEmJKBmApIpW7yH7d1H2m3TwN+3Fnb5tJBQl8XGMr33GqrpIomHPC
+YLZUEPb1VNaTCiJWCv1FiqTXpyHf9VMHHDtjwXxO8D1cxMnMVa7s+y5PsPlbHcNG
+ujj2/42zO9B9FT/9ar2hWRj/V/zWwD1+dWH/EwmBXziCInh4l17mfPsWqJJAl+t8
+pTfayl8oaeRjtwdhreha6AZVwDR8MGYemn7ty8gUweOzrI2JnGux6utxlMAdY7fZ
+gnQTDO6Kytw=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic-leaf-cert.key b/chromium/net/data/ssl/certificates/quic-leaf-cert.key
new file mode 100644
index 00000000000..e509d72513b
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic-leaf-cert.key
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem b/chromium/net/data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem
new file mode 100644
index 00000000000..00983fc3aae
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic-leaf-cert.key.pkcs8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCyVm9+1LS2TuMV
+jorpRgYVY0xtOjJnxxSkF/y3BJj7tRGukxwgcxXNs7zuYYKOy7h4ym3mV3PzRW4e
+wyddr15SbRJHRHI9fYrBR1AZSiGkCLTMLpyiKs4bh4KuOiOw3dI+ZP7OpjU0kwf4
+iG7IvrILX5yWDnkcoyvJI1qKHx4X4qnUPEkiKUP6Y1U8cmJK0XJarnWoFGfrWIjO
+EQy/CWfyu8iAPkrwNa3S3EOjL9rGOxxudnAxc8wzW0823POPn6YHbWHgZm8sdr2F
+o4vQis7EvJfg7eEp36Fiua3YDxr4rkT+piiVxMzftfdtRq7vm69zUB2f8Meg7zdL
+E3OWJJUPAgMBAAECggEAWhFzcB/nQOfoonuCRrxZ2DV1ZPjueiE+mH2Q4bINvZo+
+WufrXawiB+jN86sFsC7NdRvvk1T5t5SKQDkZyaQHRCPYBmxYMhwUlvb4Sj15bgoD
+ndewvepWe+rdoja0zd/KDj8dvaqN1oankOr+4J4G992LDPI0UrVKKOSVFosOvMqh
+zAJy19KGzfSzBU40xnWk4MEq7ZPksdeMFN5Dv+C4lFCmd/ddTFQ7EcqeSRqv2JCC
+fAH9wF6GFUXfYqU7h3CTt686kxhbgle4U5rzr126ByZjysAKv5OnNOEDlNi8D5og
+SX/vjuek8eL3Ypmho1Wch+f3w315gs8KWQjx0lcv+QKBgQDlvCRPat/qu0v/hsE7
+iopkV5I3AghzfNXzaHFrwgkXFXu+pArTk3r22aY3strAXfiYp7Blz10+LUrZyvB6
+0wa//Mk3nZ67BcViy1HykJJd6hHXYXxqih8Ig0JQJrD12iEwo3RUZ/G+L4EVOcG/
+kS/C8sUbp3j6mqxJe18xgvCF0wKBgQDGugDL8xfzuqTT3XPhCTmUL1nAO3Xv0vRb
+Vuzx0bFeGvAPHWFAb2FtEkXc4pDCPb+73q9ByBwukVB0nPpiaPzlJHGMocBANxh6
+tvO/XMcfmQmhQ+2yXgXEb7/RamULdjn7dlE+0l8kvCI37LYB/lPq2cdA1vnugxkB
+55fls4GCVQKBgQC35snyQQ2KK/CEVmzsqtRpyqgjHJ+DQ1VJijvxFNyN/AaY71wz
+TgXLASPLxoLSJudP3Dya40oy8bLPcWLcD32BxmuU97oO4GnH0haBZDWmtC8gCMu9
+xV9eQyScYLybsceL1ezTfHnJ0uE0Co4MOb7QAeLDZmazxYlRMU9cpQLBPQKBgQCT
+yYwCIHy1kx41OUGOH3AklbonTZD9k2KJ8vEvPQSsuVfBxdWnN626kZZHGG8TJRzL
+uGWZhBoBP6wXrQ4/1VgNiLaxITF6D/8yc5B9xZ+IDiWtOnkw5t9fIMQEFx2iEoA4
+U9tD3utGxGqmMHGCtgLuaprVy4n/KJuWYQcDmiU8KQKBgQClNWD+p5caD82Z4QB5
+Y/lTbjmmF4nLHlwfLpWI+nJ76kvFMnLYgJY8oZgBwBZsEkQG8so/nejBFsYvIDeR
+5W7cQVJ+ED8GCF9O4H77U0R8rpuL4z61ni4rXHc9+rABaHBHJ1aF8h3SlceHVdow
+FBU427jUeVKBN9UnFo4wrogjMA==
+-----END PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.key.sct b/chromium/net/data/ssl/certificates/quic-leaf-cert.key.sct
index 0d19282b535..0d19282b535 100644
--- a/chromium/net/data/ssl/certificates/quic_test.example.com.key.sct
+++ b/chromium/net/data/ssl/certificates/quic-leaf-cert.key.sct
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/quic-root.pem b/chromium/net/data/ssl/certificates/quic-root.pem
new file mode 100644
index 00000000000..f25cd2eeed3
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/quic-root.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC1DCCAbygAwIBAgIJANU1FI5oBbmLMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
+BAMMDFRlc3QgUm9vdCBDQTAeFw0xNzEyMTgyMzQ0MDNaFw0yNzEyMTYyMzQ0MDNa
+MBcxFTATBgNVBAMMDFRlc3QgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBALqSSRbDX0cmxTOeBh4qqMtw8BA7J8l6CYZqeUgigR67xAvJGEqx
+WhYDBjodWIYucrwqkRuju1ufRXVNAD8rqs47db5NPDHH+FqN33RkSa9XIdOGdnHX
+NfCQ13Vpq9tnvZ3zCzvSWXDVYz6GcCBJ51tjWNZtX8O8N179HcVef3LhBGweAJJv
++FkOLiClZ1y2A5hfdmuYmIYy2Iwc7we/R6jm+Ns0pVA8NrLicEHzrxJLMlMD5+zd
+WjkY6Bv9OdPipmEr1/EP3957bZ7uIUZWEq79SnQ90sKkMVS+q7Ckz7PdMBJI+fZc
+HsjucLXL0tysbcF+CtYqHsbrazye0yERUFECAwEAAaMjMCEwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAJZRG2cJGaGF
+Tl8H6+SltT9dlZ//Z7ZNsWEfv8xehGrRHsV2kxXvuVf1K4EpP3FAEvDJgOvP1MkA
+rmcpI9SsY4cr0Zy/s+Ez8SwespXkSKvtCXCmq9/kpadFPDWwR1NAXVzSEuhXJxDR
+bA+boLCu6rMFbkoRi/aFYzro+9m8RsXlyYGVGspov411lu56huoJ3ooGTIfQM8or
+N6ZNWkb+RTUUj29o3qr3kiQv73mB6h47/3IkYC5mITl+vK3OtwIRwjLzXZuS40/W
+RlI+SRYG4/yTzgV1DB4JlVJl4qMsF3z1zY1P7WeCU4YqZoIam/Ig/ZzxfOFTczk8
+vw1/E4YbkfE=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_chain.crt b/chromium/net/data/ssl/certificates/quic_chain.crt
deleted file mode 100644
index 57a8f342837..00000000000
--- a/chromium/net/data/ssl/certificates/quic_chain.crt
+++ /dev/null
@@ -1,226 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 3 (0x3)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Intermediate CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Leaf certificate
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d5:ca:19:79:8e:a9:ab:46:f0:4e:b7:58:6d:b3:
- a3:9a:68:10:52:af:f0:00:94:ae:34:bd:b4:50:1f:
- a3:26:a4:9e:1c:90:37:5b:3d:e8:d7:3b:bc:93:fb:
- 00:fb:c7:49:54:9b:f1:d0:9a:f2:51:84:7b:59:8b:
- bd:66:f3:ae:92:5a:b9:63:8c:64:a7:d0:9e:e3:0c:
- 50:d2:cf:93:9d:e9:4a:11:57:93:c1:de:af:7b:5a:
- 44:1d:0a:8c:22:a6:1d:c6:ad:e9:8f:16:8d:4e:91:
- f1:d3:f1:f3:82:fe:f6:55:dc:72:f1:11:07:75:ec:
- bb:e9:3a:35:87:43:81:5e:dc:43:4a:b7:7c:a1:1a:
- d5:d2:c1:40:39:69:7d:89:ad:64:1b:31:34:a8:ea:
- 9e:5e:26:fc:71:d2:c6:6b:e5:c2:73:30:3f:59:a7:
- 35:8d:a9:a5:e9:3d:43:41:bd:54:f2:2a:e1:15:0c:
- 35:30:6b:8b:f2:77:ca:5c:07:8f:58:f4:54:77:5e:
- af:ce:b1:c1:2b:a7:bb:c0:e9:7d:ef:1a:d7:03:ee:
- 8f:67:ad:c6:e6:1d:a9:e7:91:3f:41:e7:d6:86:20:
- 8c:53:b3:d8:79:09:e2:4b:15:5a:d8:92:3b:62:4f:
- 68:e4:cb:d0:a4:4e:b6:7d:3e:5f:b0:24:ea:62:61:
- cf:7b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Key Encipherment
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:FALSE
- X509v3 Subject Alternative Name:
- DNS:test.example.com
- Signature Algorithm: sha1WithRSAEncryption
- 58:c3:dc:e3:4d:ec:76:c6:62:99:ba:ba:6d:da:e4:2f:ec:00:
- f8:fb:2a:e3:f6:a4:bc:37:c9:53:0f:73:2e:a6:79:8f:6b:ef:
- 87:16:56:7b:9e:6d:ac:1a:ec:8b:49:71:7d:f2:11:11:a4:0d:
- 5e:6e:be:93:6b:fe:cb:44:1b:4e:99:2a:d2:eb:d8:91:80:d7:
- c8:87:fd:c8:fa:cf:c2:68:06:07:2d:60:ae:56:c4:3c:49:4d:
- e3:05:3f:1b:15:a8:a9:ea:85:d8:af:d3:f5:be:b5:71:28:23:
- 8d:04:f1:c6:e1:fb:0c:1b:ac:5a:2d:e0:7f:fb:4e:79:47:29:
- b3:9c:27:09:7d:3c:84:0b:59:0a:03:c5:86:a9:aa:90:49:89:
- 0b:bc:8e:0e:2e:b1:67:ed:99:be:37:ee:75:7f:a9:fa:62:95:
- 44:02:1c:99:26:fa:a7:17:61:d2:ec:e1:ca:42:2b:69:97:8f:
- 71:dc:1b:41:7b:91:a8:d6:b2:82:05:ef:d0:0b:3c:46:a3:9d:
- 7c:06:81:da:de:b6:54:ad:97:bd:c2:03:02:ff:1b:64:17:25:
- 4a:4c:9b:85:c1:bb:6f:26:3a:b5:ba:9b:2d:17:b9:bd:36:b1:
- 43:48:29:f7:da:88:8d:ce:f0:ac:7f:03:a7:93:e1:e9:c1:58:
- 15:b3:30:22
------BEGIN CERTIFICATE-----
-MIIDIjCCAgygAwIBAgIBAzALBgkqhkiG9w0BAQUwLDEQMA4GA1UEChMHQWNtZSBD
-bzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMB4XDTEzMDEwMTEwMDAwMFoXDTIz
-MTIzMTEwMDAwMFowLTEQMA4GA1UEChMHQWNtZSBDbzEZMBcGA1UEAxMQTGVhZiBj
-ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANXKGXmO
-qatG8E63WG2zo5poEFKv8ACUrjS9tFAfoyaknhyQN1s96Nc7vJP7APvHSVSb8dCa
-8lGEe1mLvWbzrpJauWOMZKfQnuMMUNLPk53pShFXk8Her3taRB0KjCKmHcat6Y8W
-jU6R8dPx84L+9lXccvERB3Xsu+k6NYdDgV7cQ0q3fKEa1dLBQDlpfYmtZBsxNKjq
-nl4m/HHSxmvlwnMwP1mnNY2ppek9Q0G9VPIq4RUMNTBri/J3ylwHj1j0VHder86x
-wSunu8Dpfe8a1wPuj2etxuYdqeeRP0Hn1oYgjFOz2HkJ4ksVWtiSO2JPaOTL0KRO
-tn0+X7Ak6mJhz3sCAwEAAaNSMFAwDgYDVR0PAQH/BAQDAgCgMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwGwYDVR0RBBQwEoIQdGVzdC5leGFtcGxl
-LmNvbTALBgkqhkiG9w0BAQUDggEBAFjD3ONN7HbGYpm6um3a5C/sAPj7KuP2pLw3
-yVMPcy6meY9r74cWVnuebawa7ItJcX3yERGkDV5uvpNr/stEG06ZKtLr2JGA18iH
-/cj6z8JoBgctYK5WxDxJTeMFPxsVqKnqhdiv0/W+tXEoI40E8cbh+wwbrFot4H/7
-TnlHKbOcJwl9PIQLWQoDxYapqpBJiQu8jg4usWftmb437nV/qfpilUQCHJkm+qcX
-YdLs4cpCK2mXj3HcG0F7kajWsoIF79ALPEajnXwGgdretlStl73CAwL/G2QXJUpM
-m4XBu28mOrW6my0Xub02sUNIKffaiI3O8Kx/A6eT4enBWBWzMCI=
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Root CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Intermediate CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:cd:35:50:e7:0a:68:80:e5:2b:f0:01:2b:93:11:
- 0c:50:f7:23:e1:d8:d2:ed:48:9a:ea:3b:64:9f:82:
- fa:e4:ad:23:96:a8:a1:9b:31:d1:d6:4a:b2:79:f1:
- c1:80:03:18:41:54:a5:30:3a:82:bd:57:10:9c:fd:
- 5d:34:fd:19:d3:21:1b:cb:06:e7:66:40:e1:27:89:
- 98:82:2d:d7:2e:0d:5c:05:9a:74:0d:45:de:32:5e:
- 78:4e:81:b4:c8:60:97:f0:8b:2a:8c:e0:57:f6:b9:
- db:5a:53:64:1d:27:e0:93:47:d9:93:ee:ac:f6:7b:
- e7:d2:97:b1:a6:85:37:75:ff:aa:f7:8f:ae:92:4e:
- 30:0b:56:54:fd:32:f9:9d:3c:d8:2e:95:f5:64:17:
- ff:26:d2:65:e2:b1:78:6c:83:5d:67:a4:d8:ae:89:
- 6b:6e:b3:4b:35:a5:b1:03:3c:20:97:79:ed:0b:f8:
- de:25:a1:3a:50:70:40:ae:9e:04:75:a2:6a:2f:15:
- 84:5b:08:c3:e0:55:4e:47:db:bc:79:25:b0:2e:58:
- 0d:bc:aa:a6:f2:ee:cd:e6:b8:02:8c:5b:00:b3:3d:
- 44:d0:a6:bf:b3:e7:2e:9d:46:70:de:45:d1:bd:79:
- bd:c0:f2:47:0b:71:28:60:91:c2:98:73:15:2d:b4:
- b1:f3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- b5:66:2c:a1:f8:76:8a:3b:6c:06:2d:d5:1e:4b:25:5c:b8:6d:
- ee:0e:7e:09:a4:43:58:65:93:e9:da:6c:42:2e:5d:74:3f:79:
- 61:4d:e5:72:45:d7:2d:fd:73:8e:e2:98:fe:8e:4a:e4:11:6e:
- 94:5c:d9:84:c9:cb:a1:1c:fa:95:d9:15:c1:87:72:98:2e:63:
- df:67:4d:04:1f:da:d7:29:66:ec:20:ea:b6:5d:71:dd:bc:5a:
- 16:55:87:8f:51:9f:40:05:00:3b:21:ee:74:bc:3b:11:9a:10:
- ba:b4:e8:5e:6e:90:c3:22:ca:da:92:f8:fb:8e:73:fd:69:91:
- 13:48:11:01:58:ae:f4:b2:8c:38:56:f0:a5:3b:2a:64:5c:25:
- 9a:bb:fd:94:27:34:af:b4:21:4c:08:23:3c:fb:3f:08:6f:07:
- b8:05:9d:85:1d:73:0e:f0:83:f4:3c:9b:cc:aa:fd:3d:fa:82:
- a4:dd:01:10:9d:10:2c:c4:47:64:ca:b4:b5:6e:be:59:d1:d2:
- a1:6a:b5:d3:08:23:49:fc:4f:d4:f3:a5:63:b5:e1:34:19:9d:
- 8c:33:0f:8e:47:01:9a:eb:2a:eb:cb:f4:1a:0c:ee:8e:68:d3:
- c1:8e:fd:4b:93:ff:40:8c:3a:11:2b:62:a3:c1:a7:13:bd:26:
- 37:c5:85:c5
------BEGIN CERTIFICATE-----
-MIIC/zCCAemgAwIBAgIBAjALBgkqhkiG9w0BAQUwJDEQMA4GA1UEChMHQWNtZSBD
-bzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xMzAxMDExMDAwMDBaFw0yMzEyMzExMDAw
-MDBaMCwxEDAOBgNVBAoTB0FjbWUgQ28xGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM01UOcKaIDlK/ABK5MR
-DFD3I+HY0u1Imuo7ZJ+C+uStI5aooZsx0dZKsnnxwYADGEFUpTA6gr1XEJz9XTT9
-GdMhG8sG52ZA4SeJmIIt1y4NXAWadA1F3jJeeE6BtMhgl/CLKozgV/a521pTZB0n
-4JNH2ZPurPZ759KXsaaFN3X/qvePrpJOMAtWVP0y+Z082C6V9WQX/ybSZeKxeGyD
-XWek2K6Ja26zSzWlsQM8IJd57Qv43iWhOlBwQK6eBHWiai8VhFsIw+BVTkfbvHkl
-sC5YDbyqpvLuzea4AoxbALM9RNCmv7PnLp1GcN5F0b15vcDyRwtxKGCRwphzFS20
-sfMCAwEAAaM4MDYwDgYDVR0PAQH/BAQDAgAEMBMGA1UdJQQMMAoGCCsGAQUFBwMB
-MA8GA1UdEwEB/wQFMAMBAf8wCwYJKoZIhvcNAQEFA4IBAQC1Ziyh+HaKO2wGLdUe
-SyVcuG3uDn4JpENYZZPp2mxCLl10P3lhTeVyRdct/XOO4pj+jkrkEW6UXNmEycuh
-HPqV2RXBh3KYLmPfZ00EH9rXKWbsIOq2XXHdvFoWVYePUZ9ABQA7Ie50vDsRmhC6
-tOhebpDDIsrakvj7jnP9aZETSBEBWK70sow4VvClOypkXCWau/2UJzSvtCFMCCM8
-+z8Ibwe4BZ2FHXMO8IP0PJvMqv09+oKk3QEQnRAsxEdkyrS1br5Z0dKharXTCCNJ
-/E/U86VjteE0GZ2MMw+ORwGa6yrry/QaDO6OaNPBjv1Lk/9AjDoRK2KjwacTvSY3
-xYXF
------END CERTIFICATE-----
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Root CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e4:2b:91:c7:7d:ab:32:b7:38:e1:38:ae:c8:b9:
- 0b:15:1c:64:76:47:84:5d:cb:e7:e7:0c:30:77:84:
- 6a:8e:75:95:42:b2:78:c8:88:10:ac:98:47:97:38:
- d1:3a:7f:86:0d:20:f1:1d:70:84:a2:9d:ed:1a:28:
- af:5e:43:dd:31:a3:bb:b8:5c:c4:83:79:b8:83:9a:
- e7:a9:63:04:59:93:b6:26:67:2d:dd:e6:2d:bb:e4:
- 13:eb:d5:17:0b:de:63:46:76:6f:10:05:40:b0:16:
- fc:ea:f4:97:1c:d6:dc:fe:37:72:d5:40:df:e3:b4:
- d5:ac:cf:c9:ae:7c:21:49:01:1e:7e:d4:c1:e1:2a:
- 11:01:b4:70:3a:31:3d:9a:33:b7:7f:20:f2:8b:e7:
- 54:8e:06:f2:4b:5f:f0:e2:b9:8f:64:1f:50:bd:b3:
- a5:ac:69:44:42:6c:12:e9:11:9d:74:b4:49:77:e3:
- 0f:8b:9c:94:53:17:0c:23:ba:61:fa:70:3d:93:8d:
- ad:5f:dd:4f:32:84:5b:07:50:e4:58:c7:00:45:82:
- 1f:21:14:4c:bf:43:92:76:fb:24:09:33:df:58:8d:
- be:87:ee:b5:54:e4:d3:32:f6:b1:2d:69:74:86:ad:
- 1f:57:7e:9b:05:11:74:b5:c4:68:ac:9a:80:74:7a:
- 34:89
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 96:cd:db:46:6e:5b:de:fa:f1:d3:1c:e0:fe:47:67:2a:59:d5:
- f8:c4:0b:25:14:0b:06:8d:82:67:f4:a9:36:e8:53:bc:eb:40:
- 51:05:8a:42:09:e7:48:a3:7c:42:6d:c1:37:06:49:cf:58:87:
- d0:0e:c7:9e:4b:0e:34:72:f8:65:65:b2:c4:68:ca:a3:14:e9:
- 11:5c:da:78:4e:74:80:43:dc:b8:b6:ce:a8:0c:a2:8f:52:59:
- 89:e0:5a:01:e5:e9:b8:4b:31:91:25:bf:7d:e1:7c:86:e9:36:
- c1:5b:10:e5:2c:cc:6f:99:c4:66:79:30:41:1f:0b:f9:4b:ea:
- 1e:8a:45:73:3c:79:21:20:c8:80:c4:f4:e9:4f:85:69:7c:2e:
- 61:80:3a:4f:5b:92:be:97:12:75:9e:43:09:01:b6:b3:a1:c1:
- 5f:2d:86:be:d1:6c:55:ee:27:f8:bf:3a:bc:fb:b2:42:8a:6f:
- 51:a0:d3:46:54:f6:1e:73:42:2a:95:5e:eb:bc:40:6b:71:bf:
- 90:94:62:f4:90:17:82:e5:1e:33:db:f4:50:11:e5:55:10:09:
- 6a:11:a9:1e:d4:07:60:58:f7:16:b1:bd:8b:29:f6:3d:61:ad:
- 73:da:ae:e3:e4:6e:59:46:7f:c0:fb:fa:be:6d:7c:31:94:86:
- 2e:b3:29:7b
------BEGIN CERTIFICATE-----
-MIIC9zCCAeGgAwIBAgIBATALBgkqhkiG9w0BAQUwJDEQMA4GA1UEChMHQWNtZSBD
-bzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xMzAxMDExMDAwMDBaFw0yMzEyMzExMDAw
-MDBaMCQxEDAOBgNVBAoTB0FjbWUgQ28xEDAOBgNVBAMTB1Jvb3QgQ0EwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkK5HHfasytzjhOK7IuQsVHGR2R4Rd
-y+fnDDB3hGqOdZVCsnjIiBCsmEeXONE6f4YNIPEdcISine0aKK9eQ90xo7u4XMSD
-ebiDmuepYwRZk7YmZy3d5i275BPr1RcL3mNGdm8QBUCwFvzq9Jcc1tz+N3LVQN/j
-tNWsz8mufCFJAR5+1MHhKhEBtHA6MT2aM7d/IPKL51SOBvJLX/DiuY9kH1C9s6Ws
-aURCbBLpEZ10tEl34w+LnJRTFwwjumH6cD2Tja1f3U8yhFsHUORYxwBFgh8hFEy/
-Q5J2+yQJM99Yjb6H7rVU5NMy9rEtaXSGrR9XfpsFEXS1xGismoB0ejSJAgMBAAGj
-ODA2MA4GA1UdDwEB/wQEAwIABDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMB
-Af8EBTADAQH/MAsGCSqGSIb3DQEBBQOCAQEAls3bRm5b3vrx0xzg/kdnKlnV+MQL
-JRQLBo2CZ/SpNuhTvOtAUQWKQgnnSKN8Qm3BNwZJz1iH0A7HnksONHL4ZWWyxGjK
-oxTpEVzaeE50gEPcuLbOqAyij1JZieBaAeXpuEsxkSW/feF8huk2wVsQ5SzMb5nE
-ZnkwQR8L+UvqHopFczx5ISDIgMT06U+FaXwuYYA6T1uSvpcSdZ5DCQG2s6HBXy2G
-vtFsVe4n+L86vPuyQopvUaDTRlT2HnNCKpVe67xAa3G/kJRi9JAXguUeM9v0UBHl
-VRAJahGpHtQHYFj3FrG9iyn2PWGtc9qu4+RuWUZ/wPv6vm18MZSGLrMpew==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_intermediate.crt b/chromium/net/data/ssl/certificates/quic_intermediate.crt
deleted file mode 100644
index 29e3a66fd37..00000000000
--- a/chromium/net/data/ssl/certificates/quic_intermediate.crt
+++ /dev/null
@@ -1,75 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Root CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Intermediate CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:cd:35:50:e7:0a:68:80:e5:2b:f0:01:2b:93:11:
- 0c:50:f7:23:e1:d8:d2:ed:48:9a:ea:3b:64:9f:82:
- fa:e4:ad:23:96:a8:a1:9b:31:d1:d6:4a:b2:79:f1:
- c1:80:03:18:41:54:a5:30:3a:82:bd:57:10:9c:fd:
- 5d:34:fd:19:d3:21:1b:cb:06:e7:66:40:e1:27:89:
- 98:82:2d:d7:2e:0d:5c:05:9a:74:0d:45:de:32:5e:
- 78:4e:81:b4:c8:60:97:f0:8b:2a:8c:e0:57:f6:b9:
- db:5a:53:64:1d:27:e0:93:47:d9:93:ee:ac:f6:7b:
- e7:d2:97:b1:a6:85:37:75:ff:aa:f7:8f:ae:92:4e:
- 30:0b:56:54:fd:32:f9:9d:3c:d8:2e:95:f5:64:17:
- ff:26:d2:65:e2:b1:78:6c:83:5d:67:a4:d8:ae:89:
- 6b:6e:b3:4b:35:a5:b1:03:3c:20:97:79:ed:0b:f8:
- de:25:a1:3a:50:70:40:ae:9e:04:75:a2:6a:2f:15:
- 84:5b:08:c3:e0:55:4e:47:db:bc:79:25:b0:2e:58:
- 0d:bc:aa:a6:f2:ee:cd:e6:b8:02:8c:5b:00:b3:3d:
- 44:d0:a6:bf:b3:e7:2e:9d:46:70:de:45:d1:bd:79:
- bd:c0:f2:47:0b:71:28:60:91:c2:98:73:15:2d:b4:
- b1:f3
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- b5:66:2c:a1:f8:76:8a:3b:6c:06:2d:d5:1e:4b:25:5c:b8:6d:
- ee:0e:7e:09:a4:43:58:65:93:e9:da:6c:42:2e:5d:74:3f:79:
- 61:4d:e5:72:45:d7:2d:fd:73:8e:e2:98:fe:8e:4a:e4:11:6e:
- 94:5c:d9:84:c9:cb:a1:1c:fa:95:d9:15:c1:87:72:98:2e:63:
- df:67:4d:04:1f:da:d7:29:66:ec:20:ea:b6:5d:71:dd:bc:5a:
- 16:55:87:8f:51:9f:40:05:00:3b:21:ee:74:bc:3b:11:9a:10:
- ba:b4:e8:5e:6e:90:c3:22:ca:da:92:f8:fb:8e:73:fd:69:91:
- 13:48:11:01:58:ae:f4:b2:8c:38:56:f0:a5:3b:2a:64:5c:25:
- 9a:bb:fd:94:27:34:af:b4:21:4c:08:23:3c:fb:3f:08:6f:07:
- b8:05:9d:85:1d:73:0e:f0:83:f4:3c:9b:cc:aa:fd:3d:fa:82:
- a4:dd:01:10:9d:10:2c:c4:47:64:ca:b4:b5:6e:be:59:d1:d2:
- a1:6a:b5:d3:08:23:49:fc:4f:d4:f3:a5:63:b5:e1:34:19:9d:
- 8c:33:0f:8e:47:01:9a:eb:2a:eb:cb:f4:1a:0c:ee:8e:68:d3:
- c1:8e:fd:4b:93:ff:40:8c:3a:11:2b:62:a3:c1:a7:13:bd:26:
- 37:c5:85:c5
------BEGIN CERTIFICATE-----
-MIIC/zCCAemgAwIBAgIBAjALBgkqhkiG9w0BAQUwJDEQMA4GA1UEChMHQWNtZSBD
-bzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xMzAxMDExMDAwMDBaFw0yMzEyMzExMDAw
-MDBaMCwxEDAOBgNVBAoTB0FjbWUgQ28xGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM01UOcKaIDlK/ABK5MR
-DFD3I+HY0u1Imuo7ZJ+C+uStI5aooZsx0dZKsnnxwYADGEFUpTA6gr1XEJz9XTT9
-GdMhG8sG52ZA4SeJmIIt1y4NXAWadA1F3jJeeE6BtMhgl/CLKozgV/a521pTZB0n
-4JNH2ZPurPZ759KXsaaFN3X/qvePrpJOMAtWVP0y+Z082C6V9WQX/ybSZeKxeGyD
-XWek2K6Ja26zSzWlsQM8IJd57Qv43iWhOlBwQK6eBHWiai8VhFsIw+BVTkfbvHkl
-sC5YDbyqpvLuzea4AoxbALM9RNCmv7PnLp1GcN5F0b15vcDyRwtxKGCRwphzFS20
-sfMCAwEAAaM4MDYwDgYDVR0PAQH/BAQDAgAEMBMGA1UdJQQMMAoGCCsGAQUFBwMB
-MA8GA1UdEwEB/wQFMAMBAf8wCwYJKoZIhvcNAQEFA4IBAQC1Ziyh+HaKO2wGLdUe
-SyVcuG3uDn4JpENYZZPp2mxCLl10P3lhTeVyRdct/XOO4pj+jkrkEW6UXNmEycuh
-HPqV2RXBh3KYLmPfZ00EH9rXKWbsIOq2XXHdvFoWVYePUZ9ABQA7Ie50vDsRmhC6
-tOhebpDDIsrakvj7jnP9aZETSBEBWK70sow4VvClOypkXCWau/2UJzSvtCFMCCM8
-+z8Ibwe4BZ2FHXMO8IP0PJvMqv09+oKk3QEQnRAsxEdkyrS1br5Z0dKharXTCCNJ
-/E/U86VjteE0GZ2MMw+ORwGa6yrry/QaDO6OaNPBjv1Lk/9AjDoRK2KjwacTvSY3
-xYXF
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_intermediate.key b/chromium/net/data/ssl/certificates/quic_intermediate.key
deleted file mode 100644
index a8d1b8cfaa9..00000000000
--- a/chromium/net/data/ssl/certificates/quic_intermediate.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAzTVQ5wpogOUr8AErkxEMUPcj4djS7Uia6jtkn4L65K0jlqih
-mzHR1kqyefHBgAMYQVSlMDqCvVcQnP1dNP0Z0yEbywbnZkDhJ4mYgi3XLg1cBZp0
-DUXeMl54ToG0yGCX8IsqjOBX9rnbWlNkHSfgk0fZk+6s9nvn0pexpoU3df+q94+u
-kk4wC1ZU/TL5nTzYLpX1ZBf/JtJl4rF4bINdZ6TYrolrbrNLNaWxAzwgl3ntC/je
-JaE6UHBArp4EdaJqLxWEWwjD4FVOR9u8eSWwLlgNvKqm8u7N5rgCjFsAsz1E0Ka/
-s+cunUZw3kXRvXm9wPJHC3EoYJHCmHMVLbSx8wIDAQABAoIBAQCSQevVoA93vt8g
-AlWCTmZO1raWY6mCQXtYcth28C3OCrEQ0kPMjyeV6ktmqq5VhN8mwSOzSiCgvosy
-uUpTWAmt9y0N+W+364oOWf1+2xlA03jA7aLFSwThNX/dxIiLQH1KjoXXPpazXShA
-KqtyNFfV4SHsU/KnAwzphgCyRMSQrk/5YZfdfkbnhKhXGtdBmja+4wB7khOcv5Vb
-+S2FAxftWdyTo3AOSwSED5Evq8gML4RWl46bZ5r2Gu6W+eBxDyRT+iftNLOMO6PL
-7ivn3mbZSBUxOZPvKNh6sxrUsSnxUrcZ5d819yiRolKywY5lM+BrqP9CFMfEKFP9
-R9zooJdhAoGBAOLXZviVGzOgLB418GKkw5NReeiKNPPX+w7vX+VYTiw60yRf87iS
-RhgqTXQDYKExgOO/giEJ0M3VJ6RU8MqqeHtDoKPjzZmGXs/zB0WSPIYa1A4QjQHO
-UNE1OvTwxHQCKZg0u46AZMnZWHpt005iVQ4LG8uHpUYdYxLn0LfPTvWpAoGBAOeW
-Cecnv/1GU5ft4Y8LDlFzwFzgRjRBMuX8erQz6lJUlnWLq/ZwSbag0qK+9iVfrvUT
-F9zNpfgFFsyMI8OPeJsEJkvQEZA4XDEZyvZCstjxWvI81T1bnc1/JU+YeaFcqSDq
-X7+ARNquoH9ntbXRRW4ACafQdY3KNqeBCpKBlfQ7AoGAVK/cNoPcMuribajvhLRE
-e7RYUfN/D2YbyZiecY4FKUgQ2ayk3cxmNNFeNyino6ZKmzw9Bb6XYLDqatR3TQJV
-lpdJ2sXKVT2wGex+U3/j7qEHd/S/3+O5klFQIG/et/yysKtHNk1C04S8HoDv+XyG
-ioalKtgKYOHJwh4fcvAHZ3kCgYAen25rzIvMl/IR0vjSi2m3R5EWNunRmxV55+rp
-zTuc62aB4Jg6nBqDNbzknE+8HWzrJz0ui1r48uNS5O0NvPj7to7B05+e7HT0YS6/
-ZY50tWWLRpQD6wtw0vFCFy1uMuyCV7uVfQadzB2Y+0PB6Qw/QW4FbME+oJCdkaiu
-OshzZQKBgQCXKYjh2fwBozDn7u8OQZ6sJt74EOZqAMfv7NQ2xbD5Jg5ABnOcFrXu
-FWvE9KoiJYmDD26lFIbmQ9KlAsQjKrOiRit50IALrlfATRYpEGnlO8M+c209+5wx
-FVncGUcoKbzLIrIJz7Cfd3MLbB8wSO8RBpeTa0IU5XhkTnk130Ue7A==
------END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_root.crt b/chromium/net/data/ssl/certificates/quic_root.crt
deleted file mode 100644
index 730bfcd6816..00000000000
--- a/chromium/net/data/ssl/certificates/quic_root.crt
+++ /dev/null
@@ -1,74 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Root CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Root CA
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e4:2b:91:c7:7d:ab:32:b7:38:e1:38:ae:c8:b9:
- 0b:15:1c:64:76:47:84:5d:cb:e7:e7:0c:30:77:84:
- 6a:8e:75:95:42:b2:78:c8:88:10:ac:98:47:97:38:
- d1:3a:7f:86:0d:20:f1:1d:70:84:a2:9d:ed:1a:28:
- af:5e:43:dd:31:a3:bb:b8:5c:c4:83:79:b8:83:9a:
- e7:a9:63:04:59:93:b6:26:67:2d:dd:e6:2d:bb:e4:
- 13:eb:d5:17:0b:de:63:46:76:6f:10:05:40:b0:16:
- fc:ea:f4:97:1c:d6:dc:fe:37:72:d5:40:df:e3:b4:
- d5:ac:cf:c9:ae:7c:21:49:01:1e:7e:d4:c1:e1:2a:
- 11:01:b4:70:3a:31:3d:9a:33:b7:7f:20:f2:8b:e7:
- 54:8e:06:f2:4b:5f:f0:e2:b9:8f:64:1f:50:bd:b3:
- a5:ac:69:44:42:6c:12:e9:11:9d:74:b4:49:77:e3:
- 0f:8b:9c:94:53:17:0c:23:ba:61:fa:70:3d:93:8d:
- ad:5f:dd:4f:32:84:5b:07:50:e4:58:c7:00:45:82:
- 1f:21:14:4c:bf:43:92:76:fb:24:09:33:df:58:8d:
- be:87:ee:b5:54:e4:d3:32:f6:b1:2d:69:74:86:ad:
- 1f:57:7e:9b:05:11:74:b5:c4:68:ac:9a:80:74:7a:
- 34:89
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 96:cd:db:46:6e:5b:de:fa:f1:d3:1c:e0:fe:47:67:2a:59:d5:
- f8:c4:0b:25:14:0b:06:8d:82:67:f4:a9:36:e8:53:bc:eb:40:
- 51:05:8a:42:09:e7:48:a3:7c:42:6d:c1:37:06:49:cf:58:87:
- d0:0e:c7:9e:4b:0e:34:72:f8:65:65:b2:c4:68:ca:a3:14:e9:
- 11:5c:da:78:4e:74:80:43:dc:b8:b6:ce:a8:0c:a2:8f:52:59:
- 89:e0:5a:01:e5:e9:b8:4b:31:91:25:bf:7d:e1:7c:86:e9:36:
- c1:5b:10:e5:2c:cc:6f:99:c4:66:79:30:41:1f:0b:f9:4b:ea:
- 1e:8a:45:73:3c:79:21:20:c8:80:c4:f4:e9:4f:85:69:7c:2e:
- 61:80:3a:4f:5b:92:be:97:12:75:9e:43:09:01:b6:b3:a1:c1:
- 5f:2d:86:be:d1:6c:55:ee:27:f8:bf:3a:bc:fb:b2:42:8a:6f:
- 51:a0:d3:46:54:f6:1e:73:42:2a:95:5e:eb:bc:40:6b:71:bf:
- 90:94:62:f4:90:17:82:e5:1e:33:db:f4:50:11:e5:55:10:09:
- 6a:11:a9:1e:d4:07:60:58:f7:16:b1:bd:8b:29:f6:3d:61:ad:
- 73:da:ae:e3:e4:6e:59:46:7f:c0:fb:fa:be:6d:7c:31:94:86:
- 2e:b3:29:7b
------BEGIN CERTIFICATE-----
-MIIC9zCCAeGgAwIBAgIBATALBgkqhkiG9w0BAQUwJDEQMA4GA1UEChMHQWNtZSBD
-bzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xMzAxMDExMDAwMDBaFw0yMzEyMzExMDAw
-MDBaMCQxEDAOBgNVBAoTB0FjbWUgQ28xEDAOBgNVBAMTB1Jvb3QgQ0EwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkK5HHfasytzjhOK7IuQsVHGR2R4Rd
-y+fnDDB3hGqOdZVCsnjIiBCsmEeXONE6f4YNIPEdcISine0aKK9eQ90xo7u4XMSD
-ebiDmuepYwRZk7YmZy3d5i275BPr1RcL3mNGdm8QBUCwFvzq9Jcc1tz+N3LVQN/j
-tNWsz8mufCFJAR5+1MHhKhEBtHA6MT2aM7d/IPKL51SOBvJLX/DiuY9kH1C9s6Ws
-aURCbBLpEZ10tEl34w+LnJRTFwwjumH6cD2Tja1f3U8yhFsHUORYxwBFgh8hFEy/
-Q5J2+yQJM99Yjb6H7rVU5NMy9rEtaXSGrR9XfpsFEXS1xGismoB0ejSJAgMBAAGj
-ODA2MA4GA1UdDwEB/wQEAwIABDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMB
-Af8EBTADAQH/MAsGCSqGSIb3DQEBBQOCAQEAls3bRm5b3vrx0xzg/kdnKlnV+MQL
-JRQLBo2CZ/SpNuhTvOtAUQWKQgnnSKN8Qm3BNwZJz1iH0A7HnksONHL4ZWWyxGjK
-oxTpEVzaeE50gEPcuLbOqAyij1JZieBaAeXpuEsxkSW/feF8huk2wVsQ5SzMb5nE
-ZnkwQR8L+UvqHopFczx5ISDIgMT06U+FaXwuYYA6T1uSvpcSdZ5DCQG2s6HBXy2G
-vtFsVe4n+L86vPuyQopvUaDTRlT2HnNCKpVe67xAa3G/kJRi9JAXguUeM9v0UBHl
-VRAJahGpHtQHYFj3FrG9iyn2PWGtc9qu4+RuWUZ/wPv6vm18MZSGLrMpew==
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_root.key b/chromium/net/data/ssl/certificates/quic_root.key
deleted file mode 100644
index 9791d1fdb48..00000000000
--- a/chromium/net/data/ssl/certificates/quic_root.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEA5CuRx32rMrc44TiuyLkLFRxkdkeEXcvn5wwwd4RqjnWVQrJ4
-yIgQrJhHlzjROn+GDSDxHXCEop3tGiivXkPdMaO7uFzEg3m4g5rnqWMEWZO2Jmct
-3eYtu+QT69UXC95jRnZvEAVAsBb86vSXHNbc/jdy1UDf47TVrM/JrnwhSQEeftTB
-4SoRAbRwOjE9mjO3fyDyi+dUjgbyS1/w4rmPZB9QvbOlrGlEQmwS6RGddLRJd+MP
-i5yUUxcMI7ph+nA9k42tX91PMoRbB1DkWMcARYIfIRRMv0OSdvskCTPfWI2+h+61
-VOTTMvaxLWl0hq0fV36bBRF0tcRorJqAdHo0iQIDAQABAoIBAC9L/Mb+fMthgY/m
-IQ0IloyEuyptfrm2t9aEB1PvBeuL4inWNwVSdypf0o89PtnCb3YvOuvgVA4lcG24
-u0luBd7xUstPp4idZasaJCVPmio7XUmun6pcuWQ2Tg7XuBREwA1uJW2LuTIHQdwu
-YVigDWVA9zPPY9metaBB3kul/XxVM7+fXheCHzXTzJEaAw+7Gexe8QYuq4ftcocD
-f7O/j/ts3IrKa1Xrl5RFC/tCNwpZ3yrp/Scdit32wbvCQwcdZ6/dDu6BWY4GJm8q
-z7kaDZkXQa50EzT9g+DPTLC3qA2USh8M+NfqVjdHYkAqj64StCjvXHboTbDdZXoz
-HvsONNUCgYEA/THRfqRpRPHW9ONSyRma6+XtzrCepVn/ceguO9bfD0e2+l1/6uXQ
-hctuwelRD89Z6Ir5kW2I8fRT0mPhCcuv5TW1hOiwK6WKasYxRu3ox+bZiAoRsEBd
-Xm4bvr814E/QO5DsDd5KMdEPb6ulStI1y94atCjX50r+vZWMGG82dK8CgYEA5rLF
-FPBt+049Wq8bIXXVbInwPD0hHeIrhfTqsDeuLwYsmf7o29dU7sjDFS5x1cCfVsqO
-UpXM5J4C3lhDC9ZTX0vVgT/TROq7etRZeBHVN+CJS0jgeMjUqWQTZYPMzE0Bu8/P
-+9mqSZzkwipesG4JpdSkt/1IOIoDrbK8mYpDqEcCgYEA5wfGOOCcjaR+mAW1THpo
-ukebrrXKjOaKB83sIf32m2K8u8cFKbl5hBwUfCwBI4P4bhAhmWlxRBXFRnyMovuR
-DHztnNEVrz3mB3fBDw+XEJC8fT1y1nhkuf2Oo4amCn/JahDa0+y5lqtEgokE0jjt
-jZCknS+Hki0ENMl4g/M2pVECgYB8oF6vbSM8+4tRjf8OGGXveKT7JdraFfCFMUYH
-ZE0IwkEeAAMzoCQVywb4TlrYqnJppIs2Og6yAlpyWyP9JQ9tD76LUDuFo3kcZdLf
-dmLFCNuifAAnv/aCe7muwYDFbWReXWlyGKhRlBxQeCsnDIrRtwo1CvMU+Bn8n+4a
-1AKwyQKBgGpBZwN28VjqYkM5fO6RDNBvgQ1ApfSh/Kfwg0MrO8uhmvlWDuWCoei4
-v08pchPRO75ktIv4r9bR7ylTpB9JhCe2kNABWma4mnlUg4+nmiWMTZo6Pyabstkt
-yzGIGZYdMDzOBjph7JxQZhGijz3uVc9CiFg+2AElbpCYDRHn5N3s
------END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.crt b/chromium/net/data/ssl/certificates/quic_test.example.com.crt
deleted file mode 100644
index b8123386fa9..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test.example.com.crt
+++ /dev/null
@@ -1,77 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 3 (0x3)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Intermediate CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=Leaf certificate
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:d5:ca:19:79:8e:a9:ab:46:f0:4e:b7:58:6d:b3:
- a3:9a:68:10:52:af:f0:00:94:ae:34:bd:b4:50:1f:
- a3:26:a4:9e:1c:90:37:5b:3d:e8:d7:3b:bc:93:fb:
- 00:fb:c7:49:54:9b:f1:d0:9a:f2:51:84:7b:59:8b:
- bd:66:f3:ae:92:5a:b9:63:8c:64:a7:d0:9e:e3:0c:
- 50:d2:cf:93:9d:e9:4a:11:57:93:c1:de:af:7b:5a:
- 44:1d:0a:8c:22:a6:1d:c6:ad:e9:8f:16:8d:4e:91:
- f1:d3:f1:f3:82:fe:f6:55:dc:72:f1:11:07:75:ec:
- bb:e9:3a:35:87:43:81:5e:dc:43:4a:b7:7c:a1:1a:
- d5:d2:c1:40:39:69:7d:89:ad:64:1b:31:34:a8:ea:
- 9e:5e:26:fc:71:d2:c6:6b:e5:c2:73:30:3f:59:a7:
- 35:8d:a9:a5:e9:3d:43:41:bd:54:f2:2a:e1:15:0c:
- 35:30:6b:8b:f2:77:ca:5c:07:8f:58:f4:54:77:5e:
- af:ce:b1:c1:2b:a7:bb:c0:e9:7d:ef:1a:d7:03:ee:
- 8f:67:ad:c6:e6:1d:a9:e7:91:3f:41:e7:d6:86:20:
- 8c:53:b3:d8:79:09:e2:4b:15:5a:d8:92:3b:62:4f:
- 68:e4:cb:d0:a4:4e:b6:7d:3e:5f:b0:24:ea:62:61:
- cf:7b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature, Key Encipherment
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:FALSE
- X509v3 Subject Alternative Name:
- DNS:test.example.com
- Signature Algorithm: sha1WithRSAEncryption
- 58:c3:dc:e3:4d:ec:76:c6:62:99:ba:ba:6d:da:e4:2f:ec:00:
- f8:fb:2a:e3:f6:a4:bc:37:c9:53:0f:73:2e:a6:79:8f:6b:ef:
- 87:16:56:7b:9e:6d:ac:1a:ec:8b:49:71:7d:f2:11:11:a4:0d:
- 5e:6e:be:93:6b:fe:cb:44:1b:4e:99:2a:d2:eb:d8:91:80:d7:
- c8:87:fd:c8:fa:cf:c2:68:06:07:2d:60:ae:56:c4:3c:49:4d:
- e3:05:3f:1b:15:a8:a9:ea:85:d8:af:d3:f5:be:b5:71:28:23:
- 8d:04:f1:c6:e1:fb:0c:1b:ac:5a:2d:e0:7f:fb:4e:79:47:29:
- b3:9c:27:09:7d:3c:84:0b:59:0a:03:c5:86:a9:aa:90:49:89:
- 0b:bc:8e:0e:2e:b1:67:ed:99:be:37:ee:75:7f:a9:fa:62:95:
- 44:02:1c:99:26:fa:a7:17:61:d2:ec:e1:ca:42:2b:69:97:8f:
- 71:dc:1b:41:7b:91:a8:d6:b2:82:05:ef:d0:0b:3c:46:a3:9d:
- 7c:06:81:da:de:b6:54:ad:97:bd:c2:03:02:ff:1b:64:17:25:
- 4a:4c:9b:85:c1:bb:6f:26:3a:b5:ba:9b:2d:17:b9:bd:36:b1:
- 43:48:29:f7:da:88:8d:ce:f0:ac:7f:03:a7:93:e1:e9:c1:58:
- 15:b3:30:22
------BEGIN CERTIFICATE-----
-MIIDIjCCAgygAwIBAgIBAzALBgkqhkiG9w0BAQUwLDEQMA4GA1UEChMHQWNtZSBD
-bzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMB4XDTEzMDEwMTEwMDAwMFoXDTIz
-MTIzMTEwMDAwMFowLTEQMA4GA1UEChMHQWNtZSBDbzEZMBcGA1UEAxMQTGVhZiBj
-ZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANXKGXmO
-qatG8E63WG2zo5poEFKv8ACUrjS9tFAfoyaknhyQN1s96Nc7vJP7APvHSVSb8dCa
-8lGEe1mLvWbzrpJauWOMZKfQnuMMUNLPk53pShFXk8Her3taRB0KjCKmHcat6Y8W
-jU6R8dPx84L+9lXccvERB3Xsu+k6NYdDgV7cQ0q3fKEa1dLBQDlpfYmtZBsxNKjq
-nl4m/HHSxmvlwnMwP1mnNY2ppek9Q0G9VPIq4RUMNTBri/J3ylwHj1j0VHder86x
-wSunu8Dpfe8a1wPuj2etxuYdqeeRP0Hn1oYgjFOz2HkJ4ksVWtiSO2JPaOTL0KRO
-tn0+X7Ak6mJhz3sCAwEAAaNSMFAwDgYDVR0PAQH/BAQDAgCgMBMGA1UdJQQMMAoG
-CCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwGwYDVR0RBBQwEoIQdGVzdC5leGFtcGxl
-LmNvbTALBgkqhkiG9w0BAQUDggEBAFjD3ONN7HbGYpm6um3a5C/sAPj7KuP2pLw3
-yVMPcy6meY9r74cWVnuebawa7ItJcX3yERGkDV5uvpNr/stEG06ZKtLr2JGA18iH
-/cj6z8JoBgctYK5WxDxJTeMFPxsVqKnqhdiv0/W+tXEoI40E8cbh+wwbrFot4H/7
-TnlHKbOcJwl9PIQLWQoDxYapqpBJiQu8jg4usWftmb437nV/qfpilUQCHJkm+qcX
-YdLs4cpCK2mXj3HcG0F7kajWsoIF79ALPEajnXwGgdretlStl73CAwL/G2QXJUpM
-m4XBu28mOrW6my0Xub02sUNIKffaiI3O8Kx/A6eT4enBWBWzMCI=
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.key b/chromium/net/data/ssl/certificates/quic_test.example.com.key
deleted file mode 100644
index 9449ec673d7..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test.example.com.key
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA1coZeY6pq0bwTrdYbbOjmmgQUq/wAJSuNL20UB+jJqSeHJA3
-Wz3o1zu8k/sA+8dJVJvx0JryUYR7WYu9ZvOuklq5Y4xkp9Ce4wxQ0s+TnelKEVeT
-wd6ve1pEHQqMIqYdxq3pjxaNTpHx0/Hzgv72Vdxy8REHdey76To1h0OBXtxDSrd8
-oRrV0sFAOWl9ia1kGzE0qOqeXib8cdLGa+XCczA/Wac1jaml6T1DQb1U8irhFQw1
-MGuL8nfKXAePWPRUd16vzrHBK6e7wOl97xrXA+6PZ63G5h2p55E/QefWhiCMU7PY
-eQniSxVa2JI7Yk9o5MvQpE62fT5fsCTqYmHPewIDAQABAoIBABIwh8pX4Qe5mWiZ
-IOT0i87vW7QtU/Y4sDm8ikLm7jKzfuBfRNZ2hgEKDBlrGcJSSmLwgbqF9GgLJZOQ
-2CSSRyAcp/lYUJgWn+4hdh75mk2tM6gWE3RDRhrwqyrtYs7v40isM1sBSDSPJkwq
-IdXba4oSn5TzJfdalQJa+YLws2kmnKL2cHvHJudazeV3JScfqOkjjYT1HZVFiech
-KQOJo1d3guvyLzzqDJq/BkUvaAQepJu8oXGhq0lApXPit5aRRft4Fw+ewAbU9t7r
-KzRp7YusZ1EQ2A5vn1F9o/JGRERL42BqwjRqfhHnK084Y4GhbpMrMkV0ae5i7xhK
-npKHXIECgYEA5tW5imZhPtBWSSA1w+MTIoqXPrK3eirmgmHSeYtMbfcUwuSiQOXk
-pqEJ9PoVmvNOuQPdbR4kfLuPUJecT+qEMPJAN3aWZYmSUi/6O1fml6DDvf0dx/LW
-4mZ9Mu3DGGmK+zxplwv4IkkOWIu6hPsioyoMd+QxhIk2o7eBViev7IkCgYEA7Rip
-T8k/5PFxs99OasNlu3fJxRbEeJEiZaW21gcK36LosNITgEQs3r2Q6us0hsfUCvEr
-+QAjNOk6zsUlTbJYymshStBPh3OTf2zYwg8SXfuAoFDYTNk2uML2alvBRkIKYSVV
-J2Lv2GoYxE1oTIgBDj3Jv4+xPZPx0AYmYsa6AuMCgYAd8wbirQva8X7wd+xh4Plf
-lumuqdNiV2SW8Ag12tvsvI0GCFIA55L2B5jaHwRkmULSgGzfNnT3dgJPK4yNVdkW
-3Kd2Sr2SqPnCDhWCU5JIhARBhzCw+5Hjx/ZggDa62R6+IAV3IodsM1xYIrDthgPl
-dZQujf3au07KiQmP2xBZOQKBgQDACJ5xwgXfT/ORBYgFDxgh2+bvm/4rzRl4DN1m
-wrN66P7g4HXtCMry6cUrkK+tjsJeznGYLxVU8Kax/Jm3MYGbCWQgrVIM2n6X0bhK
-jVyKBH9s2a4nqDMbOMXO5VxIpIq1nkA3M3oh5eUDcdLNUcbRGxiB8EdVIbPUknaa
-wGy+kwKBgQDE90KVnTzZQ6D20pAAvYaFCGkWUvKzf/C7NZcGH+UcWok3BCrkNiGK
-YTEbEs6h26Q8S7Vm7FiRnfVQEW4HPFuQ8wpnYrYFJbfRbGsG8agxju25Kg+EBJGU
-uu83oQ8zNiK/LMtNEGcQotXSVxAUdg1AoS5p1UX9cgmM9MZhkkbJIw==
------END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8 b/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8
deleted file mode 100644
index 5f341e52106..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8
+++ /dev/null
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8.pem b/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8.pem
deleted file mode 100644
index e52b455f53f..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test.example.com.key.pkcs8.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVyhl5jqmrRvBO
-t1hts6OaaBBSr/AAlK40vbRQH6MmpJ4ckDdbPejXO7yT+wD7x0lUm/HQmvJRhHtZ
-i71m866SWrljjGSn0J7jDFDSz5Od6UoRV5PB3q97WkQdCowiph3GremPFo1OkfHT
-8fOC/vZV3HLxEQd17LvpOjWHQ4Fe3ENKt3yhGtXSwUA5aX2JrWQbMTSo6p5eJvxx
-0sZr5cJzMD9ZpzWNqaXpPUNBvVTyKuEVDDUwa4vyd8pcB49Y9FR3Xq/OscErp7vA
-6X3vGtcD7o9nrcbmHannkT9B59aGIIxTs9h5CeJLFVrYkjtiT2jky9CkTrZ9Pl+w
-JOpiYc97AgMBAAECggEAEjCHylfhB7mZaJkg5PSLzu9btC1T9jiwObyKQubuMrN+
-4F9E1naGAQoMGWsZwlJKYvCBuoX0aAslk5DYJJJHIByn+VhQmBaf7iF2HvmaTa0z
-qBYTdENGGvCrKu1izu/jSKwzWwFINI8mTCoh1dtrihKflPMl91qVAlr5gvCzaSac
-ovZwe8cm51rN5XclJx+o6SONhPUdlUWJ5yEpA4mjV3eC6/IvPOoMmr8GRS9oBB6k
-m7yhcaGrSUClc+K3lpFF+3gXD57ABtT23usrNGnti6xnURDYDm+fUX2j8kZEREvj
-YGrCNGp+EecrTzhjgaFukysyRXRp7mLvGEqekodcgQKBgQDm1bmKZmE+0FZJIDXD
-4xMiipc+srd6KuaCYdJ5i0xt9xTC5KJA5eSmoQn0+hWa8065A91tHiR8u49Ql5xP
-6oQw8kA3dpZliZJSL/o7V+aXoMO9/R3H8tbiZn0y7cMYaYr7PGmXC/giSQ5Yi7qE
-+yKjKgx35DGEiTajt4FWJ6/siQKBgQDtGKlPyT/k8XGz305qw2W7d8nFFsR4kSJl
-pbbWBwrfouiw0hOARCzevZDq6zSGx9QK8Sv5ACM06TrOxSVNsljKayFK0E+Hc5N/
-bNjCDxJd+4CgUNhM2Ta4wvZqW8FGQgphJVUnYu/YahjETWhMiAEOPcm/j7E9k/HQ
-BiZixroC4wKBgB3zBuKtC9rxfvB37GHg+V+W6a6p02JXZJbwCDXa2+y8jQYIUgDn
-kvYHmNofBGSZQtKAbN82dPd2Ak8rjI1V2Rbcp3ZKvZKo+cIOFYJTkkiEBEGHMLD7
-kePH9mCANrrZHr4gBXcih2wzXFgisO2GA+V1lC6N/dq7TsqJCY/bEFk5AoGBAMAI
-nnHCBd9P85EFiAUPGCHb5u+b/ivNGXgM3WbCs3ro/uDgde0IyvLpxSuQr62Owl7O
-cZgvFVTwprH8mbcxgZsJZCCtUgzafpfRuEqNXIoEf2zZrieoMxs4xc7lXEikirWe
-QDczeiHl5QNx0s1RxtEbGIHwR1Uhs9SSdprAbL6TAoGBAMT3QpWdPNlDoPbSkAC9
-hoUIaRZS8rN/8Ls1lwYf5RxaiTcEKuQ2IYphMRsSzqHbpDxLtWbsWJGd9VARbgc8
-W5DzCmditgUlt9FsawbxqDGO7bkqD4QEkZS67zehDzM2Ir8sy00QZxCi1dJXEBR2
-DUChLmnVRf1yCYz0xmGSRskj
------END PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.crt b/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.crt
deleted file mode 100644
index ff8a18def0a..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.crt
+++ /dev/null
@@ -1,60 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 4 (0x4)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: O=Acme Co, CN=Intermediate CA
- Validity
- Not Before: Jan 1 10:00:00 2013 GMT
- Not After : Dec 31 10:00:00 2023 GMT
- Subject: O=Acme Co, CN=ECDSA Leaf certificate
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (256 bit)
- pub:
- 04:05:26:22:0e:77:27:83:00:d0:6b:c0:86:af:f4:
- f9:99:a8:28:a2:ed:5c:c7:5a:dc:29:72:79:4b:ef:
- e8:85:aa:3a:9b:84:3d:e3:21:b3:6b:0a:79:52:89:
- ce:bf:f1:a5:42:8b:ad:5e:34:66:5c:e5:e3:6d:aa:
- d0:8f:b3:ff:d8
- ASN1 OID: prime256v1
- X509v3 extensions:
- X509v3 Key Usage: critical
- Digital Signature
- X509v3 Extended Key Usage:
- TLS Web Server Authentication
- X509v3 Basic Constraints: critical
- CA:FALSE
- X509v3 Subject Alternative Name:
- DNS:test.example.com
- Signature Algorithm: sha1WithRSAEncryption
- 40:cb:4b:4f:63:13:8a:4e:b9:76:f6:01:82:f1:29:6d:64:d5:
- ab:87:2f:5f:4f:e9:97:f7:0d:1c:95:f1:c1:7e:9e:26:c1:f8:
- b5:6c:5c:7d:7a:54:95:96:0c:ad:72:27:e5:47:2d:13:11:0e:
- 56:d7:37:0e:9b:ea:1e:93:dc:78:e4:12:3b:bd:d5:21:44:92:
- cb:bf:f1:36:f5:67:3a:85:92:78:da:1b:c6:01:04:4e:6d:a7:
- 1b:0e:3b:96:59:a2:da:96:db:8e:97:be:dc:f0:7e:54:3b:12:
- 3a:e9:44:a0:56:e4:a5:9f:f4:58:7a:22:b9:85:be:b7:ad:51:
- 05:95:70:ba:d0:69:11:f1:2d:47:32:98:bf:e8:1c:9d:f9:19:
- 29:f8:17:72:30:bb:3d:4a:d7:f5:cc:50:55:14:a9:6b:37:e7:
- 08:f2:b6:87:4d:d8:3d:fb:eb:0d:45:3b:bc:3c:c1:92:2d:69:
- 17:39:4b:b4:ff:04:21:ec:cc:74:ff:37:b4:6d:6f:b1:5d:89:
- 9c:32:ee:99:60:52:87:15:8f:b7:50:ba:2d:f5:fd:11:f1:f8:
- 38:94:b6:db:7f:cb:fa:2f:d1:41:26:cc:fa:ec:4d:49:ed:d8:
- a8:8a:13:e7:14:32:6a:c6:6a:66:c9:5b:81:92:ca:cf:b4:7c:
- c8:91:cc:a8
------BEGIN CERTIFICATE-----
-MIICXTCCAUegAwIBAgIBBDALBgkqhkiG9w0BAQUwLDEQMA4GA1UEChMHQWNtZSBD
-bzEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMB4XDTEzMDEwMTEwMDAwMFoXDTIz
-MTIzMTEwMDAwMFowMzEQMA4GA1UEChMHQWNtZSBDbzEfMB0GA1UEAxMWRUNEU0Eg
-TGVhZiBjZXJ0aWZpY2F0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAUmIg53
-J4MA0GvAhq/0+ZmoKKLtXMda3ClyeUvv6IWqOpuEPeMhs2sKeVKJzr/xpUKLrV40
-Zlzl422q0I+z/9ijUjBQMA4GA1UdDwEB/wQEAwIAgDATBgNVHSUEDDAKBggrBgEF
-BQcDATAMBgNVHRMBAf8EAjAAMBsGA1UdEQQUMBKCEHRlc3QuZXhhbXBsZS5jb20w
-CwYJKoZIhvcNAQEFA4IBAQBAy0tPYxOKTrl29gGC8SltZNWrhy9fT+mX9w0clfHB
-fp4mwfi1bFx9elSVlgytciflRy0TEQ5W1zcOm+oek9x45BI7vdUhRJLLv/E29Wc6
-hZJ42hvGAQRObacbDjuWWaLaltuOl77c8H5UOxI66USgVuSln/RYeiK5hb63rVEF
-lXC60GkR8S1HMpi/6Byd+Rkp+BdyMLs9Stf1zFBVFKlrN+cI8raHTdg9++sNRTu8
-PMGSLWkXOUu0/wQh7Mx0/ze0bW+xXYmcMu6ZYFKHFY+3ULot9f0R8fg4lLbbf8v6
-L9FBJsz67E1J7dioihPnFDJqxmpmyVuBksrPtHzIkcyo
------END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.key b/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.key
deleted file mode 100644
index 0e2f2763b2b..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.key
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIPqnEQNfDLijySw1wwD3RNPQvgPyAPvaZarw327ZM2lwoAoGCCqGSM49
-AwEHoUQDQgAEBSYiDncngwDQa8CGr/T5magoou1cx1rcKXJ5S+/ohao6m4Q94yGz
-awp5UonOv/GlQoutXjRmXOXjbarQj7P/2A==
------END EC PRIVATE KEY-----
diff --git a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.sct b/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.sct
deleted file mode 100644
index 37582658969..00000000000
--- a/chromium/net/data/ssl/certificates/quic_test_ecc.example.com.sct
+++ /dev/null
Binary files differ
diff --git a/chromium/net/data/ssl/certificates/sha1_leaf.pem b/chromium/net/data/ssl/certificates/sha1_leaf.pem
new file mode 100644
index 00000000000..598b48d8821
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/sha1_leaf.pem
@@ -0,0 +1,112 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCt5Mpt4Jw+UG9v
+qfdbenxHoJJ8YcG9PZssBRhmA4GIwNGoYqG5D50gMxppUybpdZtQus+FF/lS8v2R
+0+my4D3cgLo+eIebg2oqhz/x5QLQlWsGvcjcn6bTg0INuK9vn9HNqeMQkDotxK9X
+zvcbKazzxzV1K81PGgocpjhj10qdOZoboDu+eTN8bFe13uRNFG13l1nQmU0B6R6n
+BreDtxggA/C9H0x9YjRVyDamxwXe5c1yrye2HZXdxJneEEm+CMUSjKXlpK1it/+U
+1mafGMtrSdl++aspmO3lZ61TUNdSqdSUBGL8azw7AzewvRj48KN8V4EPG7WUvu4a
+CrZpy3O1AgMBAAECggEAcz5ibcliouWZxK4m0YhuXuXqzuXWiP0QHm9OCSWfrirj
+h62+MjBH2LQld9H0wtn/UdRMfY8y3CdPp1qC0dpNBRqG06n7bTP9oyu5VC2K3QN5
+R6F1QcnIvPqLRx6znc2UNLG3Wx3KgNSNxCrUlzradUD7i6i4ywid1PjP/FMNDv6q
+k07xSxc0VpWwkUC0j3uau0qewfnjP3+Toe7au4vHhy+Opyudsu4WETlbhkZq2mlD
+bgUS8/06FOjlf/2tfnElysL2NPvj0sFpm1yUckxZVjiepJ8QfqU46zsxUTqKrtca
+b6kYiJmB30wSxwnsweBhJ6w7UOOV6kmB6scc5OD2IQKBgQDgZESH7yLkqBdY1qFE
+AfWvyMfIe/buB8UNLcicGuSPkjdtCzsXoDgzXxt37RSLFMsPTDBM51KPAzJkWaeM
+Jksbivw/+bEFTyY/AaYreiRHrpIXvLM/mNJFZ514ImZ+mY8YU7nuTZRMn7Ysfs9c
+kHc7r3ET65KOcnXtPVGk6h2rHQKBgQDGY4dc0vWHktGLLqmgIJZHVcojj4NLuX67
+KCj1/DhNFpJhq24MKucxmaOlXXXPgEGTA/JwWnolo1fcT2Vv4LrlgL75SYVHOF71
+2PTIrlM3w6lOJNyzyD3Sjh2wZ87u993P2z6Z/qDWOMTdfD/jvyoU/k1uq6rTxJzy
+SktzfqRveQKBgBwI6vcAzZ870Q7sYeGZTRTVRQCrXEKI/fmTisjWI1A8uGgLSyq8
+fckNTOVC3Zoy0tvqbO5uyEXN5HHdMa206xVZ3AIyNAexx9l/Xz93VykNinskvFBp
+y3uYYngr9BpFHTew3j4Du0+HdL9CaK3r7rmqRbpzaDAb5NfrHVQ5W9ORAoGASfSq
+bnkaHKsnwFnp1A6x1u/tRepnCKCi1MQ42NJobpxef1h30sNfokbjEW9QzsTCLTsI
+csfXxxYoV7GlX9qH8axYBPhaXd1u0PlK71DFJwGiqMXnHIImQcrG2I8qPj1ai/Tw
+VlnsvU82XFbIPm9yEZdnaD1Ill8yHsSBchGg3QkCgYEAxZcgtHjspR9TTzuyl8qm
+gciF8YDwYIIHqOPnVKoC6+EQJf/BJnTU5naf56sa4aMg9eqqNA5eG0aohM1uZJAJ
+TaxkXZ8wTCwFoIh6O05+SD4bHDWvr7Sur1z0HeasYH2OPf/H/N0Xuq10rphCr7dx
+HYbEecCcSPrbEtOR7++xRvA=
+-----END PRIVATE KEY-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 23 (0x17)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Dec 20 00:00:00 2017 GMT
+ Not After : Dec 20 00:00:00 2020 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
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ad:e4:ca:6d:e0:9c:3e:50:6f:6f:a9:f7:5b:7a:
+ 7c:47:a0:92:7c:61:c1:bd:3d:9b:2c:05:18:66:03:
+ 81:88:c0:d1:a8:62:a1:b9:0f:9d:20:33:1a:69:53:
+ 26:e9:75:9b:50:ba:cf:85:17:f9:52:f2:fd:91:d3:
+ e9:b2:e0:3d:dc:80:ba:3e:78:87:9b:83:6a:2a:87:
+ 3f:f1:e5:02:d0:95:6b:06:bd:c8:dc:9f:a6:d3:83:
+ 42:0d:b8:af:6f:9f:d1:cd:a9:e3:10:90:3a:2d:c4:
+ af:57:ce:f7:1b:29:ac:f3:c7:35:75:2b:cd:4f:1a:
+ 0a:1c:a6:38:63:d7:4a:9d:39:9a:1b:a0:3b:be:79:
+ 33:7c:6c:57:b5:de:e4:4d:14:6d:77:97:59:d0:99:
+ 4d:01:e9:1e:a7:06:b7:83:b7:18:20:03:f0:bd:1f:
+ 4c:7d:62:34:55:c8:36:a6:c7:05:de:e5:cd:72:af:
+ 27:b6:1d:95:dd:c4:99:de:10:49:be:08:c5:12:8c:
+ a5:e5:a4:ad:62:b7:ff:94:d6:66:9f:18:cb:6b:49:
+ d9:7e:f9:ab:29:98:ed:e5:67:ad:53:50:d7:52:a9:
+ d4:94:04:62:fc:6b:3c:3b:03:37:b0:bd:18:f8:f0:
+ a3:7c:57:81:0f:1b:b5:94:be:ee:1a:0a:b6:69:cb:
+ 73:b5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 18:9A:76:1E:86:4C:EF:67:5D:20:7F:24:4C:DC:3F:AE:B5:B5:5C:A1
+ 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: sha1WithRSAEncryption
+ a0:b6:c2:65:a0:9b:25:b7:c9:81:9a:dc:63:aa:ae:6e:f3:8a:
+ 62:92:66:6e:ad:3d:a7:fd:26:d4:ea:7b:7c:00:80:2b:73:db:
+ 36:86:fe:b1:b5:8a:05:40:d3:3c:6f:1d:11:1b:b2:a0:0d:f6:
+ 26:aa:ac:63:62:61:c0:7e:b0:7d:da:73:2c:14:71:41:fd:93:
+ f5:76:cd:21:13:42:df:e5:b0:26:e8:d0:ec:a2:e4:26:b8:ba:
+ e8:bd:49:f9:38:7f:92:1c:a2:7e:8f:b3:d3:e6:0a:51:60:88:
+ c4:ab:08:65:14:53:fd:c3:70:8a:6f:49:99:d7:09:38:00:20:
+ b5:3d:3c:f1:7c:2c:ab:67:4d:df:1d:c2:1e:24:d3:31:60:71:
+ be:b3:85:7e:a7:1e:ce:41:1f:21:58:63:83:3c:e5:91:4a:18:
+ 4d:6c:97:13:d5:df:34:c7:22:0a:92:3a:fb:03:3a:b8:62:2b:
+ 7e:be:03:fb:39:74:03:1d:f3:c7:55:28:e7:ed:cd:28:75:2b:
+ 75:c5:38:b7:fd:da:98:60:61:0a:aa:eb:17:1a:26:e1:74:7e:
+ 84:e8:76:bf:15:18:e3:b2:4e:25:41:cb:2b:19:c9:63:6f:aa:
+ 8a:58:c7:01:2a:cd:fc:04:ea:63:7f:b3:ed:5d:96:a2:b0:26:
+ 63:8d:0d:3f
+-----BEGIN CERTIFICATE-----
+MIIDvzCCAqegAwIBAgIBFzANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MTIyMDAw
+MDAwMFoXDTIwMTIyMDAwMDAwMFowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAK3kym3gnD5Qb2+p91t6fEegknxhwb09mywFGGYDgYjA0ahiobkPnSAz
+GmlTJul1m1C6z4UX+VLy/ZHT6bLgPdyAuj54h5uDaiqHP/HlAtCVawa9yNyfptOD
+Qg24r2+f0c2p4xCQOi3Er1fO9xsprPPHNXUrzU8aChymOGPXSp05mhugO755M3xs
+V7Xe5E0UbXeXWdCZTQHpHqcGt4O3GCAD8L0fTH1iNFXINqbHBd7lzXKvJ7Ydld3E
+md4QSb4IxRKMpeWkrWK3/5TWZp8Yy2tJ2X75qymY7eVnrVNQ11Kp1JQEYvxrPDsD
+N7C9GPjwo3xXgQ8btZS+7hoKtmnLc7UCAwEAAaOBgDB+MAwGA1UdEwEB/wQCMAAw
+HQYDVR0OBBYEFBiadh6GTO9nXSB/JEzcP661tVyhMB8GA1UdIwQYMBaAFJsmC4qY
+qbsduR8c4xpAM+2OF4irMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAP
+BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBBQUAA4IBAQCgtsJloJslt8mBmtxj
+qq5u84pikmZurT2n/SbU6nt8AIArc9s2hv6xtYoFQNM8bx0RG7KgDfYmqqxjYmHA
+frB92nMsFHFB/ZP1ds0hE0Lf5bAm6NDsouQmuLrovUn5OH+SHKJ+j7PT5gpRYIjE
+qwhlFFP9w3CKb0mZ1wk4ACC1PTzxfCyrZ03fHcIeJNMxYHG+s4V+px7OQR8hWGOD
+POWRShhNbJcT1d80xyIKkjr7Azq4Yit+vgP7OXQDHfPHVSjn7c0odSt1xTi3/dqY
+YGEKqusXGibhdH6E6Ha/FRjjsk4lQcsrGcljb6qKWMcBKs38BOpjf7PtXZaisCZj
+jQ0/
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/scripts/crlsetutil.py b/chromium/net/data/ssl/scripts/crlsetutil.py
index 2fcad54c5a9..c96d818f7f2 100755
--- a/chromium/net/data/ssl/scripts/crlsetutil.py
+++ b/chromium/net/data/ssl/scripts/crlsetutil.py
@@ -162,6 +162,39 @@ def pem_cert_file_to_spki_hash(pem_filename):
return der_cert_to_spki_hash(_pem_cert_to_binary(pem_filename))
+def der_cert_to_subject_hash(der_bytes):
+ """Returns SHA256(subject) of a DER-encoded certificate
+
+ Args:
+ der_bytes: A DER-encoded certificate (RFC 5280)
+
+ Returns:
+ The SHA-256 hash of the certificate's subject.
+ """
+ iterator = ASN1Iterator(der_bytes)
+ iterator.step_into() # enter certificate structure
+ iterator.step_into() # enter TBSCertificate
+ iterator.step_over() # over version
+ iterator.step_over() # over serial
+ iterator.step_over() # over signature algorithm
+ iterator.step_over() # over issuer name
+ iterator.step_over() # over validity
+ return hashlib.sha256(iterator.contents()).digest()
+
+
+def pem_cert_file_to_subject_hash(pem_filename):
+ """Gets the SHA-256 hash of the subject of a cert in a file
+
+ Args:
+ pem_filename: A file containing a PEM-encoded certificate.
+
+ Returns:
+ The SHA-256 hash of the subject of the first certificate in the file, as a
+ byte sequence
+ """
+ return der_cert_to_subject_hash(_pem_cert_to_binary(pem_filename))
+
+
def main():
parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
parser.add_option('-o', '--output',
@@ -179,6 +212,13 @@ def main():
pem_cert_file_to_spki_hash(pem_file): serials
for pem_file, serials in config.get('BlockedByHash', {}).iteritems()
}
+ limited_subjects = {
+ pem_cert_file_to_subject_hash(pem_file).encode('base64').strip(): [
+ pem_cert_file_to_spki_hash(filename).encode('base64').strip()
+ for filename in allowed_pems
+ ]
+ for pem_file, allowed_pems in config.get('LimitedSubjects', {}).iteritems()
+ }
header_json = {
'Version': 0,
'ContentType': 'CRLSet',
@@ -186,6 +226,7 @@ def main():
'DeltaFrom': 0,
'NumParents': len(parents),
'BlockedSPKIs': blocked_spkis,
+ 'LimitedSubjects': limited_subjects,
}
header = json.dumps(header_json)
outfile.write(struct.pack('<H', len(header)))
diff --git a/chromium/net/data/ssl/scripts/ee.cnf b/chromium/net/data/ssl/scripts/ee.cnf
index 3d42df1b65b..d5811b914d7 100644
--- a/chromium/net/data/ssl/scripts/ee.cnf
+++ b/chromium/net/data/ssl/scripts/ee.cnf
@@ -17,6 +17,9 @@ L = Mountain View
O = Test CA
CN = 127.0.0.1
+[req_no_san]
+basicConstraints = critical, CA:false
+
[req_duplicate_cn_1]
O = Foo
CN = Duplicate
diff --git a/chromium/net/data/ssl/scripts/generate-quic-chain.sh b/chromium/net/data/ssl/scripts/generate-quic-chain.sh
new file mode 100755
index 00000000000..707ecda67a5
--- /dev/null
+++ b/chromium/net/data/ssl/scripts/generate-quic-chain.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This script generates a test chain of (end-entity, intermediate, root)
+# certificates used to run a test QUIC server.
+
+try() {
+ "$@" || (e=$?; echo "$@" > /dev/stderr; exit $e)
+}
+
+try rm -rf out
+try mkdir out
+
+# Create the serial number files.
+try /bin/sh -c "echo 01 > out/quic-test-root-serial"
+try /bin/sh -c "echo 01 > out/quic-test-intermediate-serial"
+
+# Create the signers' DB files.
+touch out/quic-test-root-index.txt
+touch out/quic-test-intermediate-index.txt
+
+# Generate the keys
+try openssl genrsa -out out/quic-test-root.key 2048
+try openssl genrsa -out out/quic-test-intermediate.key 2048
+try openssl genrsa -out out/quic-test-cert.key 2048
+
+# Generate the root certificate
+CA_COMMON_NAME="Test Root CA" \
+ CA_DIR=out \
+ CA_NAME=test-root \
+ try openssl req \
+ -new \
+ -key out/quic-test-root.key \
+ -out out/quic-test-root.csr \
+ -config quic-test.cnf
+
+CA_COMMON_NAME="Test Root CA" \
+ CA_DIR=out \
+ CA_NAME=quic-test-root \
+ try openssl x509 \
+ -req -days 3650 \
+ -in out/quic-test-root.csr \
+ -out out/quic-test-root.pem \
+ -signkey out/quic-test-root.key \
+ -extfile quic-test.cnf \
+ -extensions ca_cert \
+ -text
+
+# Generate the intermediate
+CA_COMMON_NAME="Test Intermediate CA" \
+ CA_DIR=out \
+ CA_NAME=quic-test-root \
+ try openssl req \
+ -new \
+ -key out/quic-test-intermediate.key \
+ -out out/quic-test-intermediate.csr \
+ -config quic-test.cnf
+
+CA_COMMON_NAME="Test Intermediate CA" \
+ CA_DIR=out \
+ CA_NAME=quic-test-root \
+ try openssl ca \
+ -batch \
+ -in out/quic-test-intermediate.csr \
+ -out out/quic-test-intermediate.pem \
+ -config quic-test.cnf \
+ -extensions ca_cert
+
+# Generate the leaf
+CA_COMMON_NAME="test.example.com" \
+CA_DIR=out \
+CA_NAME=quic-test-intermediate \
+try openssl req \
+ -new \
+ -key out/quic-test-cert.key \
+ -out out/quic-test-cert.csr \
+ -config quic-test.cnf
+
+CA_COMMON_NAME="Test Intermediate CA" \
+ HOST_NAME="test.example.com" \
+ CA_DIR=out \
+ CA_NAME=quic-test-intermediate \
+ try openssl ca \
+ -batch \
+ -in out/quic-test-cert.csr \
+ -out out/quic-test-cert.pem \
+ -config quic-test.cnf \
+ -extensions user_cert
+
+# Copy to the file names that are actually checked in.
+try openssl pkcs8 -topk8 -inform pem -outform der -in out/quic-test-cert.key -out ../certificates/quic-leaf-cert.key -nocrypt
+try cat out/quic-test-cert.pem out/quic-test-intermediate.pem > ../certificates/quic-chain.pem
+try cp out/quic-test-root.pem ../certificates/quic-root.pem
+try openssl pkcs8 -nocrypt -inform der -outform pem -in ../certificates/quic-leaf-cert.key -out ../certificates/quic-leaf-cert.key.pkcs8.pem
diff --git a/chromium/net/data/ssl/scripts/generate-test-certs.sh b/chromium/net/data/ssl/scripts/generate-test-certs.sh
index ca8a3ca7ea6..622897b7b89 100755
--- a/chromium/net/data/ssl/scripts/generate-test-certs.sh
+++ b/chromium/net/data/ssl/scripts/generate-test-certs.sh
@@ -423,6 +423,61 @@ openssl req -x509 -newkey rsa:2048 \
-extensions req_extensions_with_tls_feature \
-nodes -config ee.cnf
+# SHA-1 certificate issued by locally trusted CA
+openssl req \
+ -config ../scripts/ee.cnf \
+ -newkey rsa:2048 \
+ -text \
+ -keyout out/sha1_leaf.key \
+ -out out/sha1_leaf.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 171220000000Z \
+ -enddate 201220000000Z \
+ -in out/sha1_leaf.req \
+ -out out/sha1_leaf.pem \
+ -config ca.cnf \
+ -md sha1
+/bin/sh -c "cat out/sha1_leaf.key out/sha1_leaf.pem \
+ > ../certificates/sha1_leaf.pem"
+
+# Certificate with only a common name (no SAN) issued by a locally trusted CA
+openssl req \
+ -config ../scripts/ee.cnf \
+ -reqexts req_no_san \
+ -newkey rsa:2048 \
+ -text \
+ -keyout out/common_name_only.key \
+ -out out/common_name_only.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 171220000000Z \
+ -enddate 201220000000Z \
+ -in out/common_name_only.req \
+ -out out/common_name_only.pem \
+ -config ca.cnf
+/bin/sh -c "cat out/common_name_only.key out/common_name_only.pem \
+ > ../certificates/common_name_only.pem"
+
+# Issued after 1 Dec 2017 (Symantec Legacy Distrust Date)
+openssl req \
+ -config ../scripts/ee.cnf \
+ -newkey rsa:2048 \
+ -text \
+ -out out/dec_2017.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 171220000000Z \
+ -enddate 201220000000Z \
+ -in out/dec_2017.req \
+ -out ../certificates/dec_2017.pem \
+ -config ca.cnf
# Regenerate CRLSets
## Block a leaf cert directly by SPKI
@@ -454,3 +509,35 @@ python crlsetutil.py -o ../certificates/crlset_by_intermediate_serial.raw \
}
}
CRLSETBYINTERMEDIATESERIAL
+
+## Block a subject with a single-entry allowlist of SPKI hashes.
+python crlsetutil.py -o ../certificates/crlset_by_root_subject.raw \
+<<CRLSETBYROOTSUBJECT
+{
+ "LimitedSubjects": {
+ "../certificates/root_ca_cert.pem": [
+ "../certificates/root_ca_cert.pem"
+ ]
+ }
+}
+CRLSETBYROOTSUBJECT
+
+## Block a subject with an empty allowlist of SPKI hashes.
+python crlsetutil.py -o ../certificates/crlset_by_root_subject_no_spki.raw \
+<<CRLSETBYROOTSUBJECTNOSPKI
+{
+ "LimitedSubjects": {
+ "../certificates/root_ca_cert.pem": []
+ }
+}
+CRLSETBYROOTSUBJECTNOSPKI
+
+## Block a subject with an empty allowlist of SPKI hashes.
+python crlsetutil.py -o ../certificates/crlset_by_leaf_subject_no_spki.raw \
+<<CRLSETBYLEAFSUBJECTNOSPKI
+{
+ "LimitedSubjects": {
+ "../certificates/ok_cert.pem": []
+ }
+}
+CRLSETBYLEAFSUBJECTNOSPKI
diff --git a/chromium/net/data/ssl/scripts/quic-test.cnf.txt b/chromium/net/data/ssl/scripts/quic-test.cnf.txt
new file mode 100644
index 00000000000..c8daaf30d0a
--- /dev/null
+++ b/chromium/net/data/ssl/scripts/quic-test.cnf.txt
@@ -0,0 +1,54 @@
+CA_DIR=out
+CA_NAME=quic-test-root
+HOST_NAME=test.example.com
+
+[ca]
+default_ca = CA_root
+preserve = yes
+
+[CA_root]
+dir = ${ENV::CA_DIR}
+key_size = 2048
+algo = sha256
+database = $dir/${ENV::CA_NAME}-index.txt
+new_certs_dir = $dir
+serial = $dir/${ENV::CA_NAME}-serial
+certificate = $dir/${ENV::CA_NAME}.pem
+private_key = $dir/${ENV::CA_NAME}.key
+RANDFILE = $dir/.rand
+default_days = 3650
+default_crl_days = 30
+default_md = sha256
+policy = policy_anything
+unique_subject = no
+copy_extensions = copy
+
+[user_cert]
+basicConstraints = critical, CA:false
+extendedKeyUsage = serverAuth, clientAuth
+subjectAltName = DNS:${ENV::HOST_NAME}
+
+[ca_cert]
+basicConstraints = critical, CA:true
+keyUsage = critical, keyCertSign, cRLSign
+
+[policy_anything]
+# Default signing policy
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = optional
+emailAddress = optional
+
+[req]
+default_bits = 2048
+default_md = sha256
+string_mask = utf8only
+prompt = no
+encrypt_key = no
+distinguished_name = req_env_dn
+
+[req_env_dn]
+CN = ${ENV::CA_COMMON_NAME}
diff --git a/chromium/net/data/ssl/symantec/README.md b/chromium/net/data/ssl/symantec/README.md
index f4926bbefc9..4d8219d121e 100644
--- a/chromium/net/data/ssl/symantec/README.md
+++ b/chromium/net/data/ssl/symantec/README.md
@@ -1,15 +1,17 @@
# Symantec Certificates
This directory contains the set of known active and legacy root certificates
-operated by Symantec Corporation. In order for certificates issued from
-roots to be trusted, it is required that the certificates be logged using
-Certificate Transparency.
+that were operated by Symantec Corporation. In order for certificates issued
+from these roots to be trusted, it is required that they comply with the
+policies outlined at <https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html>.
-For details about why, see <https://security.googleblog.com/2015/10/sustaining-digital-certificate-security.html>
+The exceptions to this are:
+ * Pre-existing independently operated sub-CAs, whose keys were and are not
+ controled by Symantec and which maintain current and appropriate audits.
+ * The set of Managed CAs in accordance with the above policies.
-The exception to this is sub-CAs which have been disclosed as independently
-operated, whose keys are not in control of Symantec, and which are
-maintaining a current and appropriate audit.
+In addition to the above, no changes exist from the Certificate Transparency
+requirement outlined at <https://security.googleblog.com/2015/10/sustaining-digital-certificate-security.html>
## Roots
@@ -34,6 +36,14 @@ The following command can be used to match certificates and their key hashes:
* [ac2b922ecfd5e01711772fea8ed372de9d1e2245fce3f57a9cdbec77296a424b.pem](excluded/ac2b922ecfd5e01711772fea8ed372de9d1e2245fce3f57a9cdbec77296a424b.pem)
* [a4fe7c7f15155f3f0aef7aaa83cf6e06deb97ca3f909df920ac1490882d488ed.pem](excluded/a4fe7c7f15155f3f0aef7aaa83cf6e06deb97ca3f909df920ac1490882d488ed.pem)
+### DigiCert
+
+[WebTrust Audit](https://cert.webtrust.org/ViewSeal?id=2228)
+[Certification Practices Statement](https://www.digicert.com/CPS)
+
+ * [8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem](excluded/8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem)
+ * [b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem](excluded/b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem)
+
### Google
[WebTrust Audit](https://cert.webtrust.org/ViewSeal?id=1941)
@@ -41,3 +51,9 @@ The following command can be used to match certificates and their key hashes:
* [c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36.pem](excluded/c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36.pem)
+## Excluded Managed CAs
+
+### DigiCert
+
+ * [7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem](managed/7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem)
+ * [ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem](managed/ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem)
diff --git a/chromium/net/data/ssl/symantec/excluded/8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem b/chromium/net/data/ssl/symantec/excluded/8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem
new file mode 100644
index 00000000000..f6d561eb172
--- /dev/null
+++ b/chromium/net/data/ssl/symantec/excluded/8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26.pem
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 63:18:0d:38:fb:80:97:78:a9:d0:35:a3:16:18:f8:40
+ Signature Algorithm: sha256WithRSAEncryption
+ 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 6 00:00:00 2017 GMT
+ Not After : Nov 5 23:59:59 2022 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:bb:37:cd:34:dc:7b:6b:c9:b2:68:90:ad:4a:75:
+ ff:46:ba:21:0a:08:8d:f5:19:54:c9:fb:88:db:f3:
+ ae:f2:3a:89:91:3c:7a:e6:ab:06:1a:6b:cf:ac:2d:
+ e8:5e:09:24:44:ba:62:9a:7e:d6:a3:a8:7e:e0:54:
+ 75:20:05:ac:50:b7:9c:63:1a:6c:30:dc:da:1f:19:
+ b1:d7:1e:de:fd:d7:e0:cb:94:83:37:ae:ec:1f:43:
+ 4e:dd:7b:2c:d2:bd:2e:a5:2f:e4:a9:b8:ad:3a:d4:
+ 99:a4:b6:25:e9:9b:6b:00:60:92:60:ff:4f:21:49:
+ 18:f7:67:90:ab:61:06:9c:8f:f2:ba:e9:b4:e9:92:
+ 32:6b:b5:f3:57:e8:5d:1b:cd:8c:1d:ab:95:04:95:
+ 49:f3:35:2d:96:e3:49:6d:dd:77:e3:fb:49:4b:b4:
+ ac:55:07:a9:8f:95:b3:b4:23:bb:4c:6d:45:f0:f6:
+ a9:b2:95:30:b4:fd:4c:55:8c:27:4a:57:14:7c:82:
+ 9d:cd:73:92:d3:16:4a:06:0c:8c:50:d1:8f:1e:09:
+ be:17:a1:e6:21:ca:fd:83:e5:10:bc:83:a5:0a:c4:
+ 67:28:f6:73:14:14:3d:46:76:c3:87:14:89:21:34:
+ 4d:af:0f:45:0c:a6:49:a1:ba:bb:9c:c5:b1:33:83:
+ 29:85
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 4E:22:54:20:18:95:E6:E3:6E:E6:0F:FA:FA:B9:12:ED:06:17:8F:39
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://d.symcb.com/cps
+ User Notice:
+ Explicit Text: https://d.symcb.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s.symcb.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://s.symcd.com
+
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 50:dd:d3:56:29:25:01:8a:9e:a7:e5:7d:4d:b9:af:1b:8c:a2:
+ d2:27:35:e5:9d:eb:1c:6a:f3:c4:08:ca:45:06:52:08:28:7d:
+ a6:73:a9:8b:d9:7a:ff:c2:44:88:04:3a:ec:a8:03:b7:b0:17:
+ 26:a0:93:7e:9f:c5:77:d0:ee:49:7a:5a:ed:10:01:58:4b:24:
+ 43:5d:fb:bb:f1:99:47:9f:a9:2f:57:9f:e3:3d:41:44:08:43:
+ 3f:85:d3:74:c7:c5:9d:2e:91:a3:24:ca:9f:b3:41:06:e6:a1:
+ e3:f9:46:b1:a6:e7:16:0f:8e:39:c1:e6:b8:ce:52:bb:85:44:
+ 7e:30:0f:1f:ab:46:1d:d4:71:0a:8f:87:3c:4d:c8:1a:40:81:
+ cc:6b:82:87:af:8e:3c:71:0e:bd:7b:70:8f:10:24:61:44:d8:
+ 3e:44:02:93:d8:8e:d2:95:a5:73:2e:f6:81:ff:cc:b2:9b:6a:
+ 0c:08:4b:28:aa:24:53:f1:d6:d7:83:7e:5a:28:46:26:9b:39:
+ f7:3b:f9:a7:07:b6:c6:51:df:c4:52:b9:08:7f:b1:55:6a:68:
+ 18:65:dd:5f:4b:34:1e:83:57:07:a9:fd:23:6b:a7:87:a6:fa:
+ b6:6d:39:7e:71:61:47:6a:af:fc:e0:a9:47:7b:94:61:d0:2b:
+ 26:a5:9c:e7
+-----BEGIN CERTIFICATE-----
+MIIE3zCCA8egAwIBAgIQYxgNOPuAl3ip0DWjFhj4QDANBgkqhkiG9w0BAQsFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTcxMTA2MDAwMDAwWhcNMjIxMTA1MjM1OTU5WjBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs3zTTce2vJsmiQrUp1/0a6
+IQoIjfUZVMn7iNvzrvI6iZE8euarBhprz6wt6F4JJES6Ypp+1qOofuBUdSAFrFC3
+nGMabDDc2h8Zsdce3v3X4MuUgzeu7B9DTt17LNK9LqUv5Km4rTrUmaS2JembawBg
+kmD/TyFJGPdnkKthBpyP8rrptOmSMmu181foXRvNjB2rlQSVSfM1LZbjSW3dd+P7
+SUu0rFUHqY+Vs7Qju0xtRfD2qbKVMLT9TFWMJ0pXFHyCnc1zktMWSgYMjFDRjx4J
+vheh5iHK/YPlELyDpQrEZyj2cxQUPUZ2w4cUiSE0Ta8PRQymSaG6u5zFsTODKYUC
+AwEAAaOCAScwggEjMB0GA1UdDgQWBBROIlQgGJXm427mD/r6uRLtBhePOTAPBgNV
+HRMBAf8EBTADAQH/MF8GA1UdIARYMFYwVAYEVR0gADBMMCMGCCsGAQUFBwIBFhdo
+dHRwczovL2Quc3ltY2IuY29tL2NwczAlBggrBgEFBQcCAjAZDBdodHRwczovL2Qu
+c3ltY2IuY29tL3JwYTAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vcy5zeW1jYi5j
+b20vcGNhMy1nNS5jcmwwDgYDVR0PAQH/BAQDAgGGMC4GCCsGAQUFBwEBBCIwIDAe
+BggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMB8GA1UdIwQYMBaAFH/TZafC
+3ey78DAJ80M5+gKvMzEzMA0GCSqGSIb3DQEBCwUAA4IBAQBQ3dNWKSUBip6n5X1N
+ua8bjKLSJzXlnescavPECMpFBlIIKH2mc6mL2Xr/wkSIBDrsqAO3sBcmoJN+n8V3
+0O5JelrtEAFYSyRDXfu78ZlHn6kvV5/jPUFECEM/hdN0x8WdLpGjJMqfs0EG5qHj
++UaxpucWD445wea4zlK7hUR+MA8fq0Yd1HEKj4c8TcgaQIHMa4KHr448cQ69e3CP
+ECRhRNg+RAKT2I7SlaVzLvaB/8yym2oMCEsoqiRT8dbXg35aKEYmmzn3O/mnB7bG
+Ud/EUrkIf7FVamgYZd1fSzQeg1cHqf0ja6eHpvq2bTl+cWFHaq/84KlHe5Rh0Csm
+pZzn
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/symantec/excluded/b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem b/chromium/net/data/ssl/symantec/excluded/b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem
new file mode 100644
index 00000000000..73543a32ea0
--- /dev/null
+++ b/chromium/net/data/ssl/symantec/excluded/b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97.pem
@@ -0,0 +1,76 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 3d:cd:5f:22:5e:a4:c9:6d:4b:90:94:a0:2d:2b:56:c6
+ 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 6 00:00:00 2017 GMT
+ Not After : Nov 5 23:59:59 2022 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (384 bit)
+ pub:
+ 04:dd:a7:d9:bb:8a:b8:0b:fb:0b:7f:21:d2:f0:be:
+ be:73:f3:33:5d:1a:bc:34:ea:de:c6:9b:bc:d0:95:
+ f6:f0:cc:d0:0b:ba:61:5b:51:46:7e:9e:2d:9f:ee:
+ 8e:63:0c:17:ec:07:70:f5:cf:84:2e:40:83:9c:e8:
+ 3f:41:6d:3b:ad:d3:a4:14:59:36:78:9d:03:43:ee:
+ 10:13:6c:72:de:ae:88:a7:a1:6b:b5:43:ce:67:dc:
+ 23:ff:03:1c:a3:e2:3e
+ ASN1 OID: secp384r1
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ X509v3 Subject Key Identifier:
+ B3:DB:48:A4:F9:A1:C5:D8:AE:36:41:CC:11:63:69:62:29:BC:4B:C6
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://d.symcb.com/cps
+ User Notice:
+ Explicit Text: https://d.symcb.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s.symcb.com/pca3-g4.crl
+
+ Authority Information Access:
+ OCSP - URI:http://s.symcd.com
+
+ X509v3 Authority Key Identifier:
+ keyid: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:31:00:f7:91:70:39:bc:f0:9b:8f:73:b1:c1:bf:cb:
+ 62:a2:06:ef:04:f3:eb:bf:ee:4a:cf:a9:fb:02:21:17:c1:af:
+ 77:bc:cc:34:ff:2d:79:54:b3:8e:57:46:fb:9e:9d:f8:05:02:
+ 30:26:bf:8d:dd:63:bd:65:80:46:cd:4f:12:82:21:79:e4:cf:
+ 71:09:3b:fd:ac:90:3f:34:3d:ba:0c:0c:d9:5f:80:88:88:c9:
+ 92:af:93:24:4e:44:c9:1c:ed:40:24:15:23
+-----BEGIN CERTIFICATE-----
+MIIDkDCCAxagAwIBAgIQPc1fIl6kyW1LkJSgLStWxjAKBggqhkjOPQQDAzCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzQwHhcNMTcxMTA2MDAwMDAwWhcNMjIxMTA1MjM1OTU5WjBhMQswCQYD
+VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln
+aWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABN2n2buKuAv7C38h0vC+vnPzM10avDTq3sabvNCV
+9vDM0Au6YVtRRn6eLZ/ujmMMF+wHcPXPhC5Ag5zoP0FtO63TpBRZNnidA0PuEBNs
+ct6uiKeha7VDzmfcI/8DHKPiPqOCAScwggEjMA4GA1UdDwEB/wQEAwIBhjAdBgNV
+HQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwDwYDVR0TAQH/BAUwAwEB/zBfBgNV
+HSAEWDBWMFQGBFUdIAAwTDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNv
+bS9jcHMwJQYIKwYBBQUHAgIwGQwXaHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEwLwYD
+VR0fBCgwJjAkoCKgIIYeaHR0cDovL3Muc3ltY2IuY29tL3BjYTMtZzQuY3JsMC4G
+CCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMB8G
+A1UdIwQYMBaAFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUC
+MQD3kXA5vPCbj3Oxwb/LYqIG7wTz67/uSs+p+wIhF8Gvd7zMNP8teVSzjldG+56d
++AUCMCa/jd1jvWWARs1PEoIheeTPcQk7/ayQPzQ9ugwM2V+AiIjJkq+TJE5EyRzt
+QCQVIw==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/symantec/managed/7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem b/chromium/net/data/ssl/symantec/managed/7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem
new file mode 100644
index 00000000000..b1efd7972ca
--- /dev/null
+++ b/chromium/net/data/ssl/symantec/managed/7cac9a0ff315387750ba8bafdb1c2bc29b3f0bba16362ca93a90f84da2df5f3e.pem
@@ -0,0 +1,73 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 79:c6:70:41:b4:62:32:04:39:4d:d0:42:fb:6e:96:80
+ 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 6 00:00:00 2017 GMT
+ Not After : Nov 5 23:59:59 2022 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Transition ECC Root
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:5a:ff:46:dc:c9:ae:bd:2c:e7:1c:56:97:e4:fa:
+ eb:d5:c6:ff:75:53:23:5e:c6:b0:7d:ac:ac:57:3a:
+ 9f:94:50:07:0d:f1:f3:4d:51:0d:7d:fd:88:41:82:
+ 3f:1c:7f:fb:c3:1e:fa:f6:eb:d4:37:ff:fe:18:9d:
+ 01:83:2a:80:3a
+ ASN1 OID: prime256v1
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ CF:37:24:66:74:19:7E:7F:A3:64:E4:BD:99:36:34:8B:7D:FB:42:BE
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://d.symcb.com/cps
+ User Notice:
+ Explicit Text: https://d.symcb.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s.symcb.com/pca3-g4.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://s.symcd.com
+
+ X509v3 Authority Key Identifier:
+ keyid: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:64:02:30:58:17:b0:44:e7:e3:c4:09:ba:de:bd:db:84:d9:
+ ca:b1:71:fb:68:5d:56:7a:68:d8:3a:ce:e3:a0:af:02:5e:80:
+ 7b:60:f0:97:de:0d:13:26:35:50:fe:ba:84:bd:d9:1b:02:30:
+ 08:2c:18:cf:8f:72:e1:b5:dc:2a:91:76:09:00:bf:80:3a:f0:
+ 79:4b:29:7f:89:c2:db:b6:4d:26:c6:6d:94:14:a6:40:78:9a:
+ ac:ab:af:96:52:63:f9:51:31:52:f6:f8
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAv6gAwIBAgIQecZwQbRiMgQ5TdBC+26WgDAKBggqhkjOPQQDAzCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzQwHhcNMTcxMTA2MDAwMDAwWhcNMjIxMTA1MjM1OTU5WjBmMQswCQYD
+VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln
+aWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBUcmFuc2l0aW9uIEVDQyBSb290
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWv9G3MmuvSznHFaX5Prr1cb/dVMj
+XsawfaysVzqflFAHDfHzTVENff2IQYI/HH/7wx769uvUN//+GJ0BgyqAOqOCAScw
+ggEjMB0GA1UdDgQWBBTPNyRmdBl+f6Nk5L2ZNjSLfftCvjAPBgNVHRMBAf8EBTAD
+AQH/MF8GA1UdIARYMFYwVAYEVR0gADBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Qu
+c3ltY2IuY29tL2NwczAlBggrBgEFBQcCAjAZDBdodHRwczovL2Quc3ltY2IuY29t
+L3JwYTAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vcy5zeW1jYi5jb20vcGNhMy1n
+NC5jcmwwDgYDVR0PAQH/BAQDAgGGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcw
+AYYSaHR0cDovL3Muc3ltY2QuY29tMB8GA1UdIwQYMBaAFLMWkf3upm7ktS5Jj4d4
+gYDs5bG1MAoGCCqGSM49BAMDA2cAMGQCMFgXsETn48QJut6924TZyrFx+2hdVnpo
+2DrO46CvAl6Ae2Dwl94NEyY1UP66hL3ZGwIwCCwYz49y4bXcKpF2CQC/gDrweUsp
+f4nC27ZNJsZtlBSmQHiarKuvllJj+VExUvb4
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/symantec/managed/ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem b/chromium/net/data/ssl/symantec/managed/ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem
new file mode 100644
index 00000000000..8f9d5c77e7b
--- /dev/null
+++ b/chromium/net/data/ssl/symantec/managed/ac50b5fb738aed6cb781cc35fbfff7786f77109ada7c08867c04a573fd5cf9ee.pem
@@ -0,0 +1,103 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 78:ae:a4:31:c1:5c:eb:75:7b:0d:8a:61:0a:74:8e:67
+ Signature Algorithm: sha256WithRSAEncryption
+ 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 6 00:00:00 2017 GMT
+ Not After : Nov 5 23:59:59 2022 GMT
+ Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Transition RSA Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b0:3e:d8:46:63:32:df:49:1f:61:6d:ae:df:c9:
+ 7f:2b:b1:63:a1:a7:e6:46:35:34:0e:d4:a5:3d:12:
+ af:04:6a:d5:f8:ba:a7:65:93:ec:66:c5:ca:eb:68:
+ 01:24:69:1f:af:b0:a3:59:af:3c:5b:39:44:29:60:
+ 6e:8b:41:98:49:21:d8:18:13:d3:41:55:fe:aa:22:
+ 7e:a7:51:4a:a6:d0:23:5f:73:84:a2:9c:b4:cb:17:
+ d0:65:24:87:e9:80:cb:b7:3c:a1:10:f5:97:b5:0d:
+ 9d:ec:f7:ba:5b:a3:0b:65:eb:12:75:a9:46:74:0d:
+ 80:d7:08:13:93:21:57:c6:38:3d:a8:4b:3b:0b:6f:
+ 18:e5:b3:4c:f7:c2:cd:18:f9:58:2d:03:33:1b:fc:
+ 16:dd:90:4e:c2:1f:37:9c:d6:7b:61:96:f1:c5:26:
+ 87:52:e3:e2:a4:f8:15:e5:4c:22:e9:09:2b:95:d1:
+ 93:f9:3a:39:76:74:2a:0b:80:be:be:0e:d3:10:0b:
+ e2:e1:48:a6:24:05:69:3d:17:fd:c7:37:21:b2:b0:
+ e3:77:47:39:87:01:e0:4e:db:23:e8:f9:39:9f:36:
+ 46:66:23:1e:c7:22:51:44:3f:33:c5:f5:76:a9:f8:
+ 06:b0:79:cc:ee:41:dc:71:8e:0d:50:8e:b0:3c:48:
+ ab:f5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 90:47:8A:1B:84:D3:A0:DF:A4:24:D6:19:B4:17:F5:21:A3:B2:9B:A8
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Certificate Policies:
+ Policy: X509v3 Any Policy
+ CPS: https://d.symcb.com/cps
+ User Notice:
+ Explicit Text: https://d.symcb.com/rpa
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://s.symcb.com/pca3-g5.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Certificate Sign, CRL Sign
+ Authority Information Access:
+ OCSP - URI:http://s.symcd.com
+
+ X509v3 Authority Key Identifier:
+ keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 89:c4:a9:58:d9:16:5d:80:c5:9d:b0:ec:c5:56:48:5a:51:29:
+ 5a:01:89:94:56:cd:cd:2a:b9:b0:16:b7:4b:ea:17:69:f0:7c:
+ 4c:28:fe:73:85:4f:3c:f9:85:83:99:11:43:f7:5a:e0:a2:f8:
+ 43:8c:9a:2c:e3:83:f8:05:50:99:dc:f0:e7:ef:36:3b:36:48:
+ ff:5d:a3:18:d0:cb:c1:41:68:18:f1:f6:8f:0c:97:1c:4c:2a:
+ 69:17:dc:3f:24:20:5a:e4:26:61:c8:fe:e5:92:10:bf:4d:9e:
+ ec:f2:6e:ca:67:1e:46:b8:e3:f8:b0:69:e7:51:cf:26:cf:05:
+ 91:cf:1d:b7:c6:3a:89:41:78:2b:6e:eb:13:7a:4b:9d:da:88:
+ 0e:bd:53:08:8d:38:4d:17:5c:65:c9:42:d3:9b:35:36:e2:7e:
+ 60:df:e6:c3:24:e3:d0:fc:8b:36:1e:5a:38:bc:d4:c7:8c:3b:
+ 07:35:64:22:46:de:66:8a:34:5b:50:c5:42:95:68:dd:0c:84:
+ be:2c:e4:e4:2e:42:00:60:f9:1e:d7:0d:3d:40:a6:f0:3b:5d:
+ 9b:17:07:b7:f2:30:47:e4:8b:06:d7:a2:06:37:2b:3c:a2:a9:
+ 82:e8:0d:a3:e3:1b:4c:e5:91:43:fe:3d:78:b9:03:8a:e0:d6:
+ c1:05:a8:2c
+-----BEGIN CERTIFICATE-----
+MIIE5DCCA8ygAwIBAgIQeK6kMcFc63V7DYphCnSOZzANBgkqhkiG9w0BAQsFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMTcxMTA2MDAwMDAwWhcNMjIxMTA1MjM1OTU5WjBmMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBUcmFuc2l0aW9uIFJTQSBS
+b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsD7YRmMy30kfYW2u
+38l/K7FjoafmRjU0DtSlPRKvBGrV+LqnZZPsZsXK62gBJGkfr7CjWa88WzlEKWBu
+i0GYSSHYGBPTQVX+qiJ+p1FKptAjX3OEopy0yxfQZSSH6YDLtzyhEPWXtQ2d7Pe6
+W6MLZesSdalGdA2A1wgTkyFXxjg9qEs7C28Y5bNM98LNGPlYLQMzG/wW3ZBOwh83
+nNZ7YZbxxSaHUuPipPgV5Uwi6QkrldGT+To5dnQqC4C+vg7TEAvi4UimJAVpPRf9
+xzchsrDjd0c5hwHgTtsj6Pk5nzZGZiMexyJRRD8zxfV2qfgGsHnM7kHccY4NUI6w
+PEir9QIDAQABo4IBJzCCASMwHQYDVR0OBBYEFJBHihuE06DfpCTWGbQX9SGjspuo
+MA8GA1UdEwEB/wQFMAMBAf8wXwYDVR0gBFgwVjBUBgRVHSAAMEwwIwYIKwYBBQUH
+AgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkMF2h0dHBz
+Oi8vZC5zeW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5
+bWNiLmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAYYwLgYIKwYBBQUHAQEE
+IjAgMB4GCCsGAQUFBzABhhJodHRwOi8vcy5zeW1jZC5jb20wHwYDVR0jBBgwFoAU
+f9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAInEqVjZFl2A
+xZ2w7MVWSFpRKVoBiZRWzc0qubAWt0vqF2nwfEwo/nOFTzz5hYOZEUP3WuCi+EOM
+mizjg/gFUJnc8OfvNjs2SP9doxjQy8FBaBjx9o8MlxxMKmkX3D8kIFrkJmHI/uWS
+EL9NnuzybspnHka44/iwaedRzybPBZHPHbfGOolBeCtu6xN6S53aiA69UwiNOE0X
+XGXJQtObNTbifmDf5sMk49D8izYeWji81MeMOwc1ZCJG3maKNFtQxUKVaN0MhL4s
+5OQuQgBg+R7XDT1ApvA7XZsXB7fyMEfkiwbXogY3KzyiqYLoDaPjG0zlkUP+PXi5
+A4rg1sEFqCw=
+-----END CERTIFICATE-----
diff --git a/chromium/net/der/parser.cc b/chromium/net/der/parser.cc
index be1c484af44..4a43c2f275b 100644
--- a/chromium/net/der/parser.cc
+++ b/chromium/net/der/parser.cc
@@ -11,34 +11,6 @@ namespace net {
namespace der {
-namespace {
-
-bool TagFromCBS(unsigned tag_value, Tag* out) {
- unsigned tag_number = tag_value & CBS_ASN1_TAG_NUMBER_MASK;
- if (tag_number >= 31) {
- // Tag can only represent small tag numbers.
- return false;
- }
- *out = static_cast<Tag>(tag_number);
- if (tag_value & CBS_ASN1_CONSTRUCTED) {
- *out |= kTagConstructed;
- }
- switch (tag_value & CBS_ASN1_CLASS_MASK) {
- case CBS_ASN1_APPLICATION:
- *out |= kTagApplication;
- break;
- case CBS_ASN1_CONTEXT_SPECIFIC:
- *out |= kTagContextSpecific;
- break;
- case CBS_ASN1_PRIVATE:
- *out |= kTagPrivate;
- break;
- }
- return true;
-}
-
-} // namespace
-
Parser::Parser() : advance_len_(0) {
CBS_init(&cbs_, nullptr, 0);
}
@@ -53,10 +25,11 @@ bool Parser::PeekTagAndValue(Tag* tag, Input* out) {
size_t header_len;
unsigned tag_value;
if (!CBS_get_any_asn1_element(&peeker, &tmp_out, &tag_value, &header_len) ||
- !CBS_skip(&tmp_out, header_len) || !TagFromCBS(tag_value, tag)) {
+ !CBS_skip(&tmp_out, header_len)) {
return false;
}
advance_len_ = CBS_len(&tmp_out) + header_len;
+ *tag = tag_value;
*out = Input(CBS_data(&tmp_out), CBS_len(&tmp_out));
return true;
}
diff --git a/chromium/net/der/parser_unittest.cc b/chromium/net/der/parser_unittest.cc
index d3f86fcb0a7..781bd34f3b2 100644
--- a/chromium/net/der/parser_unittest.cc
+++ b/chromium/net/der/parser_unittest.cc
@@ -13,12 +13,12 @@ namespace der {
namespace test {
TEST(ParserTest, ConsumesAllBytesOfTLV) {
- const uint8_t der[] = {0x04, 0x00};
+ const uint8_t der[] = {0x04 /* OCTET STRING */, 0x00};
Parser parser((Input(der)));
Tag tag;
Input value;
ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
- ASSERT_EQ(0x04, tag);
+ ASSERT_EQ(kOctetString, tag);
ASSERT_FALSE(parser.HasMore());
}
@@ -66,39 +66,40 @@ TEST(ParserTest, FailsIfLengthOverlapsAnotherTLV) {
}
TEST(ParserTest, CanSkipOptionalTagAtEndOfInput) {
- const uint8_t der[] = {0x02, 0x01, 0x01};
+ const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01};
Parser parser((Input(der)));
Tag tag;
Input value;
ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
bool present;
- ASSERT_TRUE(parser.ReadOptionalTag(0x02, &value, &present));
+ ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &value, &present));
ASSERT_FALSE(present);
ASSERT_FALSE(parser.HasMore());
}
TEST(ParserTest, SkipOptionalTagDoesntConsumePresentNonMatchingTLVs) {
- const uint8_t der[] = {0x02, 0x01, 0x01};
+ const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01};
Parser parser((Input(der)));
bool present;
- ASSERT_TRUE(parser.SkipOptionalTag(0x04, &present));
+ ASSERT_TRUE(parser.SkipOptionalTag(kOctetString, &present));
ASSERT_FALSE(present);
- ASSERT_TRUE(parser.SkipOptionalTag(0x02, &present));
+ ASSERT_TRUE(parser.SkipOptionalTag(kInteger, &present));
ASSERT_TRUE(present);
ASSERT_FALSE(parser.HasMore());
}
-TEST(ParserTest, TagNumbersAboveThirtyUnsupported) {
+TEST(ParserTest, TagNumbersAboveThirtySupported) {
// Context-specific class, tag number 31, length 0.
const uint8_t der[] = {0x9f, 0x1f, 0x00};
Parser parser((Input(der)));
Tag tag;
Input value;
- ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value));
- ASSERT_TRUE(parser.HasMore());
+ ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value));
+ EXPECT_EQ(kTagContextSpecific | 31u, tag);
+ ASSERT_FALSE(parser.HasMore());
}
TEST(ParserTest, ParseTags) {
diff --git a/chromium/net/der/tag.cc b/chromium/net/der/tag.cc
index bdd5a6bfc9a..a2b00747e3e 100644
--- a/chromium/net/der/tag.cc
+++ b/chromium/net/der/tag.cc
@@ -10,10 +10,9 @@ namespace net {
namespace der {
-Tag ContextSpecificConstructed(uint8_t class_number) {
- DCHECK_EQ(class_number, class_number & kTagNumberMask);
- return (class_number & kTagNumberMask) | kTagConstructed |
- kTagContextSpecific;
+Tag ContextSpecificConstructed(uint8_t tag_number) {
+ DCHECK_EQ(tag_number, tag_number & kTagNumberMask);
+ return (tag_number & kTagNumberMask) | kTagConstructed | kTagContextSpecific;
}
Tag ContextSpecificPrimitive(uint8_t base) {
diff --git a/chromium/net/der/tag.h b/chromium/net/der/tag.h
index a168df66686..82d3b257e78 100644
--- a/chromium/net/der/tag.h
+++ b/chromium/net/der/tag.h
@@ -8,63 +8,66 @@
#include <stdint.h>
#include "net/base/net_export.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
namespace net {
namespace der {
-// This Tag type represents the identifier for an ASN.1 tag as encoded with DER.
-// It follows the same bit-for-bit representation (including the class, tag
-// number, and primitive/constructed bit) as DER. Constants are provided for
-// universal class types, and functions are provided for building context
-// specific tags. Tags can also be built from the provided constants and
-// bitmasks.
-using Tag = uint8_t;
+// This Tag type represents the identifier for an ASN.1 tag as encoded with
+// DER. It matches the BoringSSL CBS and CBB in-memory representation for a
+// tag.
+//
+// Callers must not assume it matches the DER representation for small tag
+// numbers. Instead, constants are provided for universal class types, and
+// functions are provided for building context specific tags. Tags can also be
+// built from the provided constants and bitmasks.
+using Tag = unsigned;
// Universal class primitive types
-const Tag kBool = 0x01;
-const Tag kInteger = 0x02;
-const Tag kBitString = 0x03;
-const Tag kOctetString = 0x04;
-const Tag kNull = 0x05;
-const Tag kOid = 0x06;
-const Tag kEnumerated = 0x0A;
-const Tag kUtf8String = 0x0C;
-const Tag kPrintableString = 0x13;
-const Tag kTeletexString = 0x14;
-const Tag kIA5String = 0x16;
-const Tag kUtcTime = 0x17;
-const Tag kGeneralizedTime = 0x18;
-const Tag kUniversalString = 0x1C;
-const Tag kBmpString = 0x1E;
+const Tag kBool = CBS_ASN1_BOOLEAN;
+const Tag kInteger = CBS_ASN1_INTEGER;
+const Tag kBitString = CBS_ASN1_BITSTRING;
+const Tag kOctetString = CBS_ASN1_OCTETSTRING;
+const Tag kNull = CBS_ASN1_NULL;
+const Tag kOid = CBS_ASN1_OBJECT;
+const Tag kEnumerated = CBS_ASN1_ENUMERATED;
+const Tag kUtf8String = CBS_ASN1_UTF8STRING;
+const Tag kPrintableString = CBS_ASN1_PRINTABLESTRING;
+const Tag kTeletexString = CBS_ASN1_T61STRING;
+const Tag kIA5String = CBS_ASN1_IA5STRING;
+const Tag kUtcTime = CBS_ASN1_UTCTIME;
+const Tag kGeneralizedTime = CBS_ASN1_GENERALIZEDTIME;
+const Tag kUniversalString = CBS_ASN1_UNIVERSALSTRING;
+const Tag kBmpString = CBS_ASN1_BMPSTRING;
// Universal class constructed types
-const Tag kSequence = 0x30;
-const Tag kSet = 0x31;
+const Tag kSequence = CBS_ASN1_SEQUENCE;
+const Tag kSet = CBS_ASN1_SET;
// Primitive/constructed bits
-const uint8_t kTagPrimitive = 0x00;
-const uint8_t kTagConstructed = 0x20;
+const unsigned kTagPrimitive = 0x00;
+const unsigned kTagConstructed = CBS_ASN1_CONSTRUCTED;
// Tag classes
-const uint8_t kTagUniversal = 0x00;
-const uint8_t kTagApplication = 0x40;
-const uint8_t kTagContextSpecific = 0x80;
-const uint8_t kTagPrivate = 0xC0;
+const unsigned kTagUniversal = 0x00;
+const unsigned kTagApplication = CBS_ASN1_APPLICATION;
+const unsigned kTagContextSpecific = CBS_ASN1_CONTEXT_SPECIFIC;
+const unsigned kTagPrivate = CBS_ASN1_PRIVATE;
// Masks for the 3 components of a tag (class, primitive/constructed, number)
-const uint8_t kTagNumberMask = 0x1F;
-const uint8_t kTagConstructionMask = 0x20;
-const uint8_t kTagClassMask = 0xC0;
+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.
//
// The ASN.1 keyword for this is:
-// [class_number] EXPLICIT
+// [tag_number] EXPLICIT
//
// (Note, the EXPLICIT may be omitted if the entire schema is in
// EXPLICIT mode, the default)
-NET_EXPORT Tag ContextSpecificConstructed(uint8_t class_number);
+NET_EXPORT Tag ContextSpecificConstructed(uint8_t tag_number);
NET_EXPORT Tag ContextSpecificPrimitive(uint8_t base);
diff --git a/chromium/net/disk_cache/OWNERS b/chromium/net/disk_cache/OWNERS
index 854e7d8ff3d..7e2c65ec292 100644
--- a/chromium/net/disk_cache/OWNERS
+++ b/chromium/net/disk_cache/OWNERS
@@ -1,4 +1,4 @@
-morlovich@chromium.org
jkarlin@chromium.org
+morlovich@chromium.org
# COMPONENT: Internals>Network>Cache
diff --git a/chromium/net/disk_cache/backend_unittest.cc b/chromium/net/disk_cache/backend_unittest.cc
index 80057fc25d5..6bd72f90fdd 100644
--- a/chromium/net/disk_cache/backend_unittest.cc
+++ b/chromium/net/disk_cache/backend_unittest.cc
@@ -1473,6 +1473,12 @@ void DiskCacheBackendTest::BackendTrimInvalidEntry2() {
ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
EXPECT_GE(30, cache_->GetEntryCount());
ANNOTATE_IGNORE_READS_AND_WRITES_END();
+
+ // For extra messiness, the integrity check for the cache can actually cause
+ // evictions if it's over-capacity, which would race with above. So change the
+ // size we pass to CheckCacheIntegrity (but don't mess with existing backend's
+ // state.
+ size_ = 0;
}
// We'll be leaking memory from this test.
@@ -2168,7 +2174,7 @@ void DiskCacheBackendTest::BackendTransaction(const std::string& name,
cache_.reset();
cache_impl_ = NULL;
- ASSERT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask));
+ ASSERT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, MaxSize(), mask));
success_ = true;
}
@@ -2427,7 +2433,8 @@ TEST_F(DiskCacheBackendTest, DeleteOld) {
ASSERT_THAT(cb.GetResult(rv), IsOk());
base::ThreadRestrictions::SetIOAllowed(prev);
cache_.reset();
- EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
+ EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, /*max_size = */ 0,
+ mask_));
}
#endif
diff --git a/chromium/net/disk_cache/blockfile/file.h b/chromium/net/disk_cache/blockfile/file.h
index 0e34fabf3d6..6aa6ba25b3e 100644
--- a/chromium/net/disk_cache/blockfile/file.h
+++ b/chromium/net/disk_cache/blockfile/file.h
@@ -68,6 +68,8 @@ class NET_EXPORT_PRIVATE File : public base::RefCounted<File> {
size_t GetLength();
// Blocks until |num_pending_io| IO operations complete.
+ // TODO(fdoray): Rename to WaitForPendingIOForTesting() since this should only
+ // be called in tests.
static void WaitForPendingIO(int* num_pending_io);
// Drops current pending operations without waiting for them to complete.
diff --git a/chromium/net/disk_cache/blockfile/file_posix.cc b/chromium/net/disk_cache/blockfile/file_posix.cc
index 69058f1f28c..e1d0b3639e6 100644
--- a/chromium/net/disk_cache/blockfile/file_posix.cc
+++ b/chromium/net/disk_cache/blockfile/file_posix.cc
@@ -9,36 +9,14 @@
#include <utility>
#include "base/bind.h"
-#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/run_loop.h"
-#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_scheduler.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
-namespace {
-
-// The maximum number of threads for this pool.
-const int kMaxThreads = 5;
-
-class FileWorkerPool : public base::SequencedWorkerPool {
- public:
- FileWorkerPool()
- : base::SequencedWorkerPool(kMaxThreads,
- "CachePool",
- base::TaskPriority::USER_BLOCKING) {}
-
- protected:
- ~FileWorkerPool() override = default;
-};
-
-base::LazyInstance<FileWorkerPool>::Leaky s_worker_pool =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
namespace disk_cache {
File::File(base::File file)
@@ -95,11 +73,11 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset,
return false;
}
- base::PostTaskAndReplyWithResult(
- s_worker_pool.Pointer(), FROM_HERE,
- base::Bind(&File::DoRead, base::Unretained(this), buffer, buffer_len,
- offset),
- base::Bind(&File::OnOperationComplete, this, callback));
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+ base::BindOnce(&File::DoRead, base::Unretained(this), buffer, buffer_len,
+ offset),
+ base::BindOnce(&File::OnOperationComplete, this, callback));
*completed = false;
return true;
@@ -119,11 +97,15 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset,
return false;
}
- base::PostTaskAndReplyWithResult(
- s_worker_pool.Pointer(), FROM_HERE,
- base::Bind(&File::DoWrite, base::Unretained(this), buffer, buffer_len,
- offset),
- base::Bind(&File::OnOperationComplete, this, callback));
+ // The priority is USER_BLOCKING because the cache waits for the write to
+ // finish before it reads from the network again.
+ // TODO(fdoray): Consider removing this from the critical path of network
+ // requests and changing the priority to BACKGROUND.
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+ base::BindOnce(&File::DoWrite, base::Unretained(this), buffer, buffer_len,
+ offset),
+ base::BindOnce(&File::OnOperationComplete, this, callback));
*completed = false;
return true;
@@ -151,10 +133,11 @@ size_t File::GetLength() {
// Static.
void File::WaitForPendingIO(int* num_pending_io) {
- // We are running unit tests so we should wait for all callbacks. Sadly, the
- // worker pool only waits for tasks on the worker pool, not the "Reply" tasks
- // so we have to let the current message loop to run.
- s_worker_pool.Get().FlushForTesting();
+ // We are running unit tests so we should wait for all callbacks.
+
+ // This waits for callbacks running on worker threads.
+ base::TaskScheduler::GetInstance()->FlushForTesting();
+ // This waits for the "Reply" tasks running on the current MessageLoop.
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/net/disk_cache/blockfile/file_win.cc b/chromium/net/disk_cache/blockfile/file_win.cc
index 219df2a7449..e2ea893a219 100644
--- a/chromium/net/disk_cache/blockfile/file_win.cc
+++ b/chromium/net/disk_cache/blockfile/file_win.cc
@@ -15,6 +15,7 @@
namespace {
+class CompletionHandler;
// Structure used for asynchronous operations.
struct MyOverlapped {
MyOverlapped(disk_cache::File* file, size_t offset,
@@ -26,6 +27,7 @@ struct MyOverlapped {
base::MessageLoopForIO::IOContext context_;
scoped_refptr<disk_cache::File> file_;
+ scoped_refptr<CompletionHandler> completion_handler_;
disk_cache::FileIOCallback* callback_;
};
@@ -33,14 +35,43 @@ static_assert(offsetof(MyOverlapped, context_) == 0,
"should start with overlapped");
// Helper class to handle the IO completion notifications from the message loop.
-class CompletionHandler : public base::MessageLoopForIO::IOHandler {
+class CompletionHandler : public base::MessageLoopForIO::IOHandler,
+ public base::RefCounted<CompletionHandler> {
+ public:
+ CompletionHandler() = default;
+ static CompletionHandler* Get();
+
+ private:
+ friend class base::RefCounted<CompletionHandler>;
+ ~CompletionHandler() override {}
+
+ // implement base::MessageLoopForIO::IOHandler.
void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
DWORD actual_bytes,
DWORD error) override;
+
+ DISALLOW_COPY_AND_ASSIGN(CompletionHandler);
+};
+
+class CompletionHandlerHolder {
+ public:
+ CompletionHandlerHolder() { completion_handler_ = new CompletionHandler; }
+
+ CompletionHandler* completion_handler() { return completion_handler_.get(); }
+
+ private:
+ scoped_refptr<CompletionHandler> completion_handler_;
};
-static base::LazyInstance<CompletionHandler>::DestructorAtExit
- g_completion_handler = LAZY_INSTANCE_INITIALIZER;
+static base::LazyInstance<CompletionHandlerHolder>::DestructorAtExit
+ g_completion_handler_holder = LAZY_INSTANCE_INITIALIZER;
+
+CompletionHandler* CompletionHandler::Get() {
+ if (auto* holder = g_completion_handler_holder.Pointer()) {
+ return holder->completion_handler();
+ }
+ return nullptr;
+}
void CompletionHandler::OnIOCompleted(
base::MessageLoopForIO::IOContext* context,
@@ -65,6 +96,7 @@ MyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset,
context_.overlapped.Offset = static_cast<DWORD>(offset);
file_ = file;
callback_ = callback;
+ completion_handler_ = CompletionHandler::Get();
}
} // namespace
@@ -89,7 +121,7 @@ bool File::Init(const base::FilePath& name) {
return false;
base::MessageLoopForIO::current()->RegisterIOHandler(
- base_file_.GetPlatformFile(), g_completion_handler.Pointer());
+ base_file_.GetPlatformFile(), CompletionHandler::Get());
init_ = true;
sync_base_file_ =
@@ -244,7 +276,7 @@ void File::WaitForPendingIO(int* num_pending_io) {
while (*num_pending_io) {
// Asynchronous IO operations may be in flight and the completion may end
// up calling us back so let's wait for them.
- base::MessageLoopForIO::IOHandler* handler = g_completion_handler.Pointer();
+ base::MessageLoopForIO::IOHandler* handler = CompletionHandler::Get();
base::MessageLoopForIO::current()->WaitForIOCompletion(100, handler);
}
}
diff --git a/chromium/net/disk_cache/blockfile/mapped_file_win.cc b/chromium/net/disk_cache/blockfile/mapped_file_win.cc
index 9a128a36d0e..706ae09221a 100644
--- a/chromium/net/disk_cache/blockfile/mapped_file_win.cc
+++ b/chromium/net/disk_cache/blockfile/mapped_file_win.cc
@@ -10,6 +10,8 @@
#include "base/logging.h"
#include "net/disk_cache/disk_cache.h"
+#include <windows.h>
+
namespace disk_cache {
void* MappedFile::Init(const base::FilePath& name, size_t size) {
diff --git a/chromium/net/disk_cache/blockfile/rankings.cc b/chromium/net/disk_cache/blockfile/rankings.cc
index 68d2c3be92d..41a47a3965b 100644
--- a/chromium/net/disk_cache/blockfile/rankings.cc
+++ b/chromium/net/disk_cache/blockfile/rankings.cc
@@ -9,6 +9,7 @@
#include <limits>
#include "base/macros.h"
+#include "build/build_config.h"
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/backend_impl.h"
#include "net/disk_cache/blockfile/disk_format.h"
@@ -17,6 +18,10 @@
#include "net/disk_cache/blockfile/histogram_macros.h"
#include "net/disk_cache/blockfile/stress_support.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
// Provide a BackendImpl object to macros from histogram_macros.h.
#define CACHE_UMA_BACKEND_IMPL_OBJ backend_
diff --git a/chromium/net/disk_cache/blockfile/sparse_control.cc b/chromium/net/disk_cache/blockfile/sparse_control.cc
index 3391533b40c..c18c4d0e683 100644
--- a/chromium/net/disk_cache/blockfile/sparse_control.cc
+++ b/chromium/net/disk_cache/blockfile/sparse_control.cc
@@ -16,6 +16,7 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "net/base/interval.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/blockfile/backend_impl.h"
@@ -768,68 +769,82 @@ int SparseControl::DoGetAvailableRange() {
if (!child_)
return child_len_; // Move on to the next child.
- // Bits on the bitmap should only be set when the corresponding block was
- // fully written (it's really being used). If a block is partially used, it
- // has to start with valid data, the length of the valid data is saved in
- // |header.last_block_len| and the block itself should match
- // |header.last_block|.
+ // Blockfile splits sparse files into multiple child entries, each responsible
+ // for managing 1MiB of address space. This method is responsible for
+ // implementing GetAvailableRange within a single child.
+ //
+ // Input:
+ // |child_offset_|, |child_len_|:
+ // describe range in current child's address space the client requested.
+ // |offset_| is equivalent to |child_offset_| but in global address space.
+ //
+ // For example if this were child [2] and the original call was for
+ // [0x200005, 0x200007) then |offset_| would be 0x200005, |child_offset_|
+ // would be 5, and |child_len| would be 2.
//
- // In other words, (|header.last_block| + |header.last_block_len|) is the
- // offset where the last write ended, and data in that block (which is not
- // marked as used because it is not full) will only be reused if the next
- // write continues at that point.
+ // Output:
+ // If nothing found:
+ // return |child_len_|
//
- // This code has to find if there is any data between child_offset_ and
- // child_offset_ + child_len_.
+ // If something found:
+ // |result_| gets the length of the available range.
+ // |offset_| gets the global address of beginning of the available range.
+ // |range_found_| get true to signal SparseControl::GetAvailableRange().
+ // return 0 to exit loop.
+ net::Interval<int> to_find(child_offset_, child_offset_ + child_len_);
+
+ // Within each child, valid portions are mostly tracked via the |child_map_|
+ // bitmap which marks which 1KiB 'blocks' have valid data. Scan the bitmap
+ // for the first contiguous range of set bits that's relevant to the range
+ // [child_offset_, child_offset_ + len)
+ int first_bit = child_offset_ >> 10;
int last_bit = (child_offset_ + child_len_ + kBlockSize - 1) >> 10;
- int start = child_offset_ >> 10;
- int partial_start_bytes = PartialBlockLength(start);
- int found = start;
+ int found = first_bit;
int bits_found = child_map_.FindBits(&found, last_bit, true);
- bool is_last_block_in_range = start < child_data_.header.last_block &&
- child_data_.header.last_block < last_bit;
+ net::Interval<int> bitmap_range(found * kBlockSize,
+ found * kBlockSize + bits_found * kBlockSize);
- int block_offset = child_offset_ & (kBlockSize - 1);
- if (!bits_found && partial_start_bytes <= block_offset) {
- if (!is_last_block_in_range)
- return child_len_;
- found = last_bit - 1; // There are some bytes here.
+ // Bits on the bitmap should only be set when the corresponding block was
+ // fully written (it's really being used). If a block is partially used, it
+ // has to start with valid data, the length of the valid data is saved in
+ // |header.last_block_len| and the block number saved in |header.last_block|.
+ // This is updated after every write; with |header.last_block| set to -1
+ // if no sub-KiB range is being tracked.
+ net::Interval<int> last_write_range;
+ if (child_data_.header.last_block >= 0) {
+ last_write_range =
+ net::Interval<int>(child_data_.header.last_block * kBlockSize,
+ child_data_.header.last_block * kBlockSize +
+ child_data_.header.last_block_len);
}
- // We are done. Just break the loop and reset result_ to our real result.
- range_found_ = true;
-
- int bytes_found = bits_found << 10;
- bytes_found += PartialBlockLength(found + bits_found);
-
- // found now points to the first bytes. Lets see if we have data before it.
- int empty_start = std::max((found << 10) - child_offset_, 0);
- if (empty_start >= child_len_)
- return child_len_;
-
- // At this point we have bytes_found stored after (found << 10), and we want
- // child_len_ bytes after child_offset_. The first empty_start bytes after
- // child_offset_ are invalid.
+ // Often |last_write_range| is contiguously after |bitmap_range|, but not
+ // always. See if they can be combined.
+ if (!last_write_range.Empty() && !bitmap_range.Empty() &&
+ bitmap_range.max() == last_write_range.min()) {
+ bitmap_range.SetMax(last_write_range.max());
+ last_write_range.Clear();
+ }
- if (start == found)
- bytes_found -= block_offset;
+ // Do any of them have anything relevant?
+ bitmap_range.IntersectWith(to_find);
+ last_write_range.IntersectWith(to_find);
- // If the user is searching past the end of this child, bits_found is the
- // right result; otherwise, we have some empty space at the start of this
- // query that we have to subtract from the range that we searched.
- result_ = std::min(bytes_found, child_len_ - empty_start);
+ // Now return the earliest non-empty interval, if any.
+ net::Interval<int> result_range = bitmap_range;
+ if (bitmap_range.Empty() || (!last_write_range.Empty() &&
+ last_write_range.min() < bitmap_range.min()))
+ result_range = last_write_range;
- if (partial_start_bytes) {
- result_ = std::min(partial_start_bytes - block_offset, child_len_);
- empty_start = 0;
+ if (result_range.Empty()) {
+ // Nothing found, so we just skip over this child.
+ return child_len_;
}
- // Only update offset_ when this query found zeros at the start.
- if (empty_start)
- offset_ += empty_start;
-
- // This will actually break the loop.
- buf_len_ = 0;
+ // Package up our results.
+ range_found_ = true;
+ offset_ += result_range.min() - child_offset_;
+ result_ = result_range.max() - result_range.min();
return 0;
}
diff --git a/chromium/net/disk_cache/disk_cache_perftest.cc b/chromium/net/disk_cache/disk_cache_perftest.cc
index d5e9431eb90..8df5c2007f9 100644
--- a/chromium/net/disk_cache/disk_cache_perftest.cc
+++ b/chromium/net/disk_cache/disk_cache_perftest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <limits>
+#include <memory>
#include <string>
#include "base/barrier_closure.h"
@@ -40,6 +41,17 @@ using base::Time;
namespace {
+const size_t kNumEntries = 10000;
+const int kHeadersSize = 2000;
+
+const int kBodySize = 72 * 1024 - 1;
+
+// HttpCache likes this chunk size.
+const int kChunkSize = 32 * 1024;
+
+// As of 2017-01-12, this is a typical per-tab limit on HTTP connections.
+const int kMaxParallelOperations = 10;
+
void MaybeSetFdLimit(unsigned int max_descriptors) {
#if defined(OS_POSIX)
base::SetFdLimit(max_descriptors);
@@ -51,6 +63,11 @@ struct TestEntry {
int data_len;
};
+enum class WhatToRead {
+ HEADERS_ONLY,
+ HEADERS_AND_BODY,
+};
+
class DiskCachePerfTest : public DiskCacheTestWithCache {
public:
DiskCachePerfTest()
@@ -65,26 +82,29 @@ class DiskCachePerfTest : public DiskCacheTestWithCache {
MaybeSetFdLimit(saved_fd_limit_);
}
+ const std::vector<TestEntry>& entries() const { return entries_; }
+
protected:
- enum class WhatToRead {
- HEADERS_ONLY,
- HEADERS_AND_BODY,
- };
// Helper methods for constructing tests.
- bool TimeWrite();
- bool TimeRead(WhatToRead what_to_read, const char* timer_message);
+ bool TimeWrites();
+ bool TimeReads(WhatToRead what_to_read, const char* timer_message);
void ResetAndEvictSystemDiskCache();
+ // Callbacks used within tests for intermediate operations.
+ void WriteCallback(const net::CompletionCallback& final_callback,
+ scoped_refptr<net::IOBuffer> headers_buffer,
+ scoped_refptr<net::IOBuffer> body_buffer,
+ disk_cache::Entry* cache_entry,
+ int entry_index,
+ size_t write_offset,
+ int result);
+
// Complete perf tests.
void CacheBackendPerformance();
const size_t kFdLimitForCacheTests = 8192;
- const int kNumEntries = 1000;
- const int kHeadersSize = 800;
- const int kBodySize = 256 * 1024 - 1;
-
std::vector<TestEntry> entries_;
private:
@@ -92,109 +112,291 @@ class DiskCachePerfTest : public DiskCacheTestWithCache {
base::test::ScopedTaskEnvironment scoped_task_environment_;
};
-// Creates num_entries on the cache, and writes kHeaderSize bytes of metadata
-// and up to kBodySize of data to each entry.
-bool DiskCachePerfTest::TimeWrite() {
- // TODO(gavinp): This test would be significantly more realistic if it didn't
- // do single reads and writes. Perhaps entries should be written 64kb at a
- // time. As well, not all entries should be created and written essentially
- // simultaneously; some number of entries in flight at a time would be a
- // likely better testing load.
- scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kHeadersSize));
- scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kBodySize));
+class WriteHandler {
+ public:
+ WriteHandler(const DiskCachePerfTest* test,
+ disk_cache::Backend* cache,
+ net::CompletionCallback final_callback)
+ : test_(test), cache_(cache), final_callback_(final_callback) {
+ CacheTestFillBuffer(headers_buffer_->data(), kHeadersSize, false);
+ CacheTestFillBuffer(body_buffer_->data(), kChunkSize, false);
+ }
- CacheTestFillBuffer(buffer1->data(), kHeadersSize, false);
- CacheTestFillBuffer(buffer2->data(), kBodySize, false);
+ void Run();
- int expected = 0;
+ protected:
+ void CreateNextEntry();
- MessageLoopHelper helper;
- CallbackTest callback(&helper, true);
+ void CreateCallback(std::unique_ptr<disk_cache::Entry*> unique_entry_ptr,
+ int data_len,
+ int result);
+ void WriteDataCallback(disk_cache::Entry* entry,
+ int next_offset,
+ int data_len,
+ int expected_result,
+ int result);
- base::PerfTimeLogger timer("Write disk cache entries");
+ private:
+ bool CheckForErrorAndCancel(int result);
- for (int i = 0; i < kNumEntries; i++) {
- TestEntry entry;
- entry.key = GenerateKey(true);
- entry.data_len = base::RandInt(0, kBodySize);
- entries_.push_back(entry);
+ const DiskCachePerfTest* test_;
+ disk_cache::Backend* cache_;
+ net::CompletionCallback final_callback_;
- disk_cache::Entry* cache_entry;
- net::TestCompletionCallback cb;
- int rv = cache_->CreateEntry(entry.key, &cache_entry, cb.callback());
- if (net::OK != cb.GetResult(rv))
- break;
- int ret = cache_entry->WriteData(
- 0, 0, buffer1.get(), kHeadersSize,
- base::Bind(&CallbackTest::Run, base::Unretained(&callback)), false);
- if (net::ERR_IO_PENDING == ret)
- expected++;
- else if (kHeadersSize != ret)
- break;
-
- ret = cache_entry->WriteData(
- 1, 0, buffer2.get(), entry.data_len,
- base::Bind(&CallbackTest::Run, base::Unretained(&callback)), false);
- if (net::ERR_IO_PENDING == ret)
- expected++;
- else if (entry.data_len != ret)
- break;
- cache_entry->Close();
+ size_t next_entry_index_ = 0;
+ size_t pending_operations_count_ = 0;
+
+ int pending_result_ = net::OK;
+
+ scoped_refptr<net::IOBuffer> headers_buffer_ =
+ new net::IOBuffer(kHeadersSize);
+ scoped_refptr<net::IOBuffer> body_buffer_ = new net::IOBuffer(kChunkSize);
+};
+
+void WriteHandler::Run() {
+ for (int i = 0; i < kMaxParallelOperations; ++i) {
+ ++pending_operations_count_;
+ CreateNextEntry();
}
+}
- helper.WaitUntilCacheIoFinished(expected);
- timer.Done();
+void WriteHandler::CreateNextEntry() {
+ ASSERT_GT(kNumEntries, next_entry_index_);
+ TestEntry test_entry = test_->entries()[next_entry_index_++];
+ disk_cache::Entry** entry_ptr = new disk_cache::Entry*();
+ std::unique_ptr<disk_cache::Entry*> unique_entry_ptr(entry_ptr);
+ net::CompletionCallback callback =
+ base::Bind(&WriteHandler::CreateCallback, base::Unretained(this),
+ base::Passed(&unique_entry_ptr), test_entry.data_len);
+ int result = cache_->CreateEntry(test_entry.key, entry_ptr, callback);
+ if (result != net::ERR_IO_PENDING)
+ callback.Run(result);
+}
- return expected == helper.callbacks_called();
+void WriteHandler::CreateCallback(std::unique_ptr<disk_cache::Entry*> entry_ptr,
+ int data_len,
+ int result) {
+ if (CheckForErrorAndCancel(result))
+ return;
+
+ disk_cache::Entry* entry = *entry_ptr;
+
+ net::CompletionCallback callback =
+ base::Bind(&WriteHandler::WriteDataCallback, base::Unretained(this),
+ entry, 0, data_len, kHeadersSize);
+ int new_result = entry->WriteData(0, 0, headers_buffer_.get(), kHeadersSize,
+ callback, false);
+ if (new_result != net::ERR_IO_PENDING)
+ callback.Run(new_result);
}
-// Reads the data and metadata from each entry listed on |entries|.
-bool DiskCachePerfTest::TimeRead(WhatToRead what_to_read,
- const char* timer_message) {
- scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kHeadersSize));
- scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kBodySize));
+void WriteHandler::WriteDataCallback(disk_cache::Entry* entry,
+ int next_offset,
+ int data_len,
+ int expected_result,
+ int result) {
+ if (CheckForErrorAndCancel(result)) {
+ entry->Close();
+ return;
+ }
+ DCHECK_LE(next_offset, data_len);
+ if (next_offset == data_len) {
+ entry->Close();
+ if (next_entry_index_ < kNumEntries) {
+ CreateNextEntry();
+ } else {
+ --pending_operations_count_;
+ if (pending_operations_count_ == 0)
+ final_callback_.Run(net::OK);
+ }
+ return;
+ }
- CacheTestFillBuffer(buffer1->data(), kHeadersSize, false);
- CacheTestFillBuffer(buffer2->data(), kBodySize, false);
+ int write_size = std::min(kChunkSize, data_len - next_offset);
+ net::CompletionCallback callback =
+ base::Bind(&WriteHandler::WriteDataCallback, base::Unretained(this),
+ entry, next_offset + write_size, data_len, write_size);
+ int new_result = entry->WriteData(1, next_offset, body_buffer_.get(),
+ write_size, callback, true);
+ if (new_result != net::ERR_IO_PENDING)
+ callback.Run(new_result);
+}
+
+bool WriteHandler::CheckForErrorAndCancel(int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ if (result != net::OK && !(result > 0))
+ pending_result_ = result;
+ if (pending_result_ != net::OK) {
+ --pending_operations_count_;
+ if (pending_operations_count_ == 0)
+ final_callback_.Run(pending_result_);
+ return true;
+ }
+ return false;
+}
- int expected = 0;
+class ReadHandler {
+ public:
+ ReadHandler(const DiskCachePerfTest* test,
+ WhatToRead what_to_read,
+ disk_cache::Backend* cache,
+ net::CompletionCallback final_callback)
+ : test_(test),
+ what_to_read_(what_to_read),
+ cache_(cache),
+ final_callback_(final_callback) {
+ for (int i = 0; i < kMaxParallelOperations; ++i)
+ read_buffers_[i] = new net::IOBuffer(std::max(kHeadersSize, kChunkSize));
+ }
- MessageLoopHelper helper;
- CallbackTest callback(&helper, true);
+ void Run();
- base::PerfTimeLogger timer(timer_message);
+ protected:
+ void OpenNextEntry(int parallel_operation_index);
+
+ void OpenCallback(int parallel_operation_index,
+ std::unique_ptr<disk_cache::Entry*> unique_entry_ptr,
+ int data_len,
+ int result);
+ void ReadDataCallback(int parallel_operation_index,
+ disk_cache::Entry* entry,
+ int next_offset,
+ int data_len,
+ int expected_result,
+ int result);
- for (int i = 0; i < kNumEntries; i++) {
- disk_cache::Entry* cache_entry;
- net::TestCompletionCallback cb;
- int rv = cache_->OpenEntry(entries_[i].key, &cache_entry, cb.callback());
- if (net::OK != cb.GetResult(rv))
- break;
- int ret = cache_entry->ReadData(
- 0, 0, buffer1.get(), kHeadersSize,
- base::Bind(&CallbackTest::Run, base::Unretained(&callback)));
- if (net::ERR_IO_PENDING == ret)
- expected++;
- else if (kHeadersSize != ret)
- break;
-
- if (what_to_read == WhatToRead::HEADERS_AND_BODY) {
- ret = cache_entry->ReadData(
- 1, 0, buffer2.get(), entries_[i].data_len,
- base::Bind(&CallbackTest::Run, base::Unretained(&callback)));
- if (net::ERR_IO_PENDING == ret)
- expected++;
- else if (entries_[i].data_len != ret)
- break;
+ private:
+ bool CheckForErrorAndCancel(int result);
+
+ const DiskCachePerfTest* test_;
+ const WhatToRead what_to_read_;
+
+ disk_cache::Backend* cache_;
+ net::CompletionCallback final_callback_;
+
+ size_t next_entry_index_ = 0;
+ size_t pending_operations_count_ = 0;
+
+ int pending_result_ = net::OK;
+
+ scoped_refptr<net::IOBuffer> read_buffers_[kMaxParallelOperations];
+};
+
+void ReadHandler::Run() {
+ for (int i = 0; i < kMaxParallelOperations; ++i) {
+ OpenNextEntry(pending_operations_count_);
+ ++pending_operations_count_;
+ }
+}
+
+void ReadHandler::OpenNextEntry(int parallel_operation_index) {
+ ASSERT_GT(kNumEntries, next_entry_index_);
+ TestEntry test_entry = test_->entries()[next_entry_index_++];
+ disk_cache::Entry** entry_ptr = new disk_cache::Entry*();
+ std::unique_ptr<disk_cache::Entry*> unique_entry_ptr(entry_ptr);
+ net::CompletionCallback callback =
+ base::Bind(&ReadHandler::OpenCallback, base::Unretained(this),
+ parallel_operation_index, base::Passed(&unique_entry_ptr),
+ test_entry.data_len);
+ int result = cache_->OpenEntry(test_entry.key, entry_ptr, callback);
+ if (result != net::ERR_IO_PENDING)
+ callback.Run(result);
+}
+
+void ReadHandler::OpenCallback(int parallel_operation_index,
+ std::unique_ptr<disk_cache::Entry*> entry_ptr,
+ int data_len,
+ int result) {
+ if (CheckForErrorAndCancel(result))
+ return;
+
+ disk_cache::Entry* entry = *entry_ptr;
+
+ EXPECT_EQ(data_len, entry->GetDataSize(1));
+
+ net::CompletionCallback callback =
+ base::Bind(&ReadHandler::ReadDataCallback, base::Unretained(this),
+ parallel_operation_index, entry, 0, data_len, kHeadersSize);
+ int new_result =
+ entry->ReadData(0, 0, read_buffers_[parallel_operation_index].get(),
+ kChunkSize, callback);
+ if (new_result != net::ERR_IO_PENDING)
+ callback.Run(new_result);
+}
+
+void ReadHandler::ReadDataCallback(int parallel_operation_index,
+ disk_cache::Entry* entry,
+ int next_offset,
+ int data_len,
+ int expected_result,
+ int result) {
+ if (CheckForErrorAndCancel(result)) {
+ entry->Close();
+ return;
+ }
+ DCHECK_LE(next_offset, data_len);
+ if (what_to_read_ == WhatToRead::HEADERS_ONLY || next_offset == data_len) {
+ entry->Close();
+ if (next_entry_index_ < kNumEntries) {
+ OpenNextEntry(parallel_operation_index);
+ } else {
+ --pending_operations_count_;
+ if (pending_operations_count_ == 0)
+ final_callback_.Run(net::OK);
}
+ return;
+ }
+
+ int expected_read_size = std::min(kChunkSize, data_len - next_offset);
+ net::CompletionCallback callback = base::Bind(
+ &ReadHandler::ReadDataCallback, base::Unretained(this),
+ parallel_operation_index, entry, next_offset + expected_read_size,
+ data_len, expected_read_size);
+ int new_result = entry->ReadData(
+ 1, next_offset, read_buffers_[parallel_operation_index].get(), kChunkSize,
+ callback);
+ if (new_result != net::ERR_IO_PENDING)
+ callback.Run(new_result);
+}
- cache_entry->Close();
+bool ReadHandler::CheckForErrorAndCancel(int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ if (result != net::OK && !(result > 0))
+ pending_result_ = result;
+ if (pending_result_ != net::OK) {
+ --pending_operations_count_;
+ if (pending_operations_count_ == 0)
+ final_callback_.Run(pending_result_);
+ return true;
}
+ return false;
+}
- helper.WaitUntilCacheIoFinished(expected);
- timer.Done();
+bool DiskCachePerfTest::TimeWrites() {
+ for (size_t i = 0; i < kNumEntries; i++) {
+ TestEntry entry;
+ entry.key = GenerateKey(true);
+ entry.data_len = base::RandInt(0, kBodySize);
+ entries_.push_back(entry);
+ }
+
+ net::TestCompletionCallback cb;
+
+ base::PerfTimeLogger timer("Write disk cache entries");
+
+ WriteHandler write_handler(this, cache_.get(), cb.callback());
+ write_handler.Run();
+ return cb.WaitForResult() == net::OK;
+}
+
+bool DiskCachePerfTest::TimeReads(WhatToRead what_to_read,
+ const char* timer_message) {
+ base::PerfTimeLogger timer(timer_message);
- return (expected == helper.callbacks_called());
+ net::TestCompletionCallback cb;
+ ReadHandler read_handler(this, what_to_read, cache_.get(), cb.callback());
+ read_handler.Run();
+ return cb.WaitForResult() == net::OK;
}
TEST_F(DiskCachePerfTest, BlockfileHashes) {
@@ -233,26 +435,28 @@ void DiskCachePerfTest::ResetAndEvictSystemDiskCache() {
}
void DiskCachePerfTest::CacheBackendPerformance() {
+ LOG(ERROR) << "Using cache at:" << cache_path_.MaybeAsASCII();
+ SetMaxSize(500 * 1024 * 1024);
InitCache();
- EXPECT_TRUE(TimeWrite());
+ EXPECT_TRUE(TimeWrites());
disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
base::RunLoop().RunUntilIdle();
ResetAndEvictSystemDiskCache();
- EXPECT_TRUE(TimeRead(WhatToRead::HEADERS_ONLY,
- "Read disk cache headers only (cold)"));
- EXPECT_TRUE(TimeRead(WhatToRead::HEADERS_ONLY,
- "Read disk cache headers only (warm)"));
+ EXPECT_TRUE(TimeReads(WhatToRead::HEADERS_ONLY,
+ "Read disk cache headers only (cold)"));
+ EXPECT_TRUE(TimeReads(WhatToRead::HEADERS_ONLY,
+ "Read disk cache headers only (warm)"));
disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
base::RunLoop().RunUntilIdle();
ResetAndEvictSystemDiskCache();
- EXPECT_TRUE(
- TimeRead(WhatToRead::HEADERS_AND_BODY, "Read disk cache entries (cold)"));
- EXPECT_TRUE(
- TimeRead(WhatToRead::HEADERS_AND_BODY, "Read disk cache entries (warm)"));
+ EXPECT_TRUE(TimeReads(WhatToRead::HEADERS_AND_BODY,
+ "Read disk cache entries (cold)"));
+ EXPECT_TRUE(TimeReads(WhatToRead::HEADERS_AND_BODY,
+ "Read disk cache entries (warm)"));
disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting();
base::RunLoop().RunUntilIdle();
diff --git a/chromium/net/disk_cache/disk_cache_test_base.cc b/chromium/net/disk_cache/disk_cache_test_base.cc
index 727dbb8fa9f..b5483cf2d6a 100644
--- a/chromium/net/disk_cache/disk_cache_test_base.cc
+++ b/chromium/net/disk_cache/disk_cache_test_base.cc
@@ -117,7 +117,7 @@ void DiskCacheTestWithCache::SimulateCrash() {
cache_impl_->ClearRefCountForTest();
cache_.reset();
- EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
+ EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, size_, mask_));
CreateBackend(disk_cache::kNoRandom);
}
@@ -287,7 +287,7 @@ void DiskCacheTestWithCache::TearDown() {
cache_.reset();
if (!memory_only_ && !simple_cache_mode_ && integrity_) {
- EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, mask_));
+ EXPECT_TRUE(CheckCacheIntegrity(cache_path_, new_eviction_, size_, mask_));
}
scoped_task_env_->RunUntilIdle();
if (simple_cache_mode_ && simple_file_tracker_)
diff --git a/chromium/net/disk_cache/disk_cache_test_base.h b/chromium/net/disk_cache/disk_cache_test_base.h
index cfa463cbeb1..b70ee389781 100644
--- a/chromium/net/disk_cache/disk_cache_test_base.h
+++ b/chromium/net/disk_cache/disk_cache_test_base.h
@@ -108,6 +108,9 @@ class DiskCacheTestWithCache : public DiskCacheTest {
void SetMaxSize(int size);
+ // Returns value last given to SetMaxSize (or 0).
+ int MaxSize() const { return size_; }
+
// Deletes and re-creates the files on initialization errors.
void SetForceCreation() {
force_creation_ = true;
diff --git a/chromium/net/disk_cache/disk_cache_test_util.cc b/chromium/net/disk_cache/disk_cache_test_util.cc
index 69314c5e544..7382adaaa79 100644
--- a/chromium/net/disk_cache/disk_cache_test_util.cc
+++ b/chromium/net/disk_cache/disk_cache_test_util.cc
@@ -61,9 +61,12 @@ bool DeleteCache(const base::FilePath& path) {
bool CheckCacheIntegrity(const base::FilePath& path,
bool new_eviction,
+ int max_size,
uint32_t mask) {
std::unique_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
path, mask, base::ThreadTaskRunnerHandle::Get(), NULL));
+ if (max_size)
+ cache->SetMaxSize(max_size);
if (!cache.get())
return false;
if (new_eviction)
diff --git a/chromium/net/disk_cache/disk_cache_test_util.h b/chromium/net/disk_cache/disk_cache_test_util.h
index 2f59a46de7e..02dd6f491c0 100644
--- a/chromium/net/disk_cache/disk_cache_test_util.h
+++ b/chromium/net/disk_cache/disk_cache_test_util.h
@@ -29,9 +29,11 @@ void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls);
// Generates a random key of up to 200 bytes.
std::string GenerateKey(bool same_length);
-// Returns true if the cache is not corrupt.
+// Returns true if the cache is not corrupt. Assumes blockfile cache.
+// |max_size|, if non-zero, will be set as its size.
bool CheckCacheIntegrity(const base::FilePath& path,
bool new_eviction,
+ int max_size,
uint32_t mask);
// -----------------------------------------------------------------------
diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc
index ae97a761cb6..4363813551a 100644
--- a/chromium/net/disk_cache/entry_unittest.cc
+++ b/chromium/net/disk_cache/entry_unittest.cc
@@ -1835,6 +1835,91 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) {
GetAvailableRange();
}
+TEST_F(DiskCacheEntryTest, GetAvailableRangeBlockFileDiscontinuous) {
+ // crbug.com/791056 --- blockfile problem when there is a sub-KiB write before
+ // a bunch of full 1KiB blocks, and a GetAvailableRange is issued to which
+ // both are a potentially relevant.
+ InitCache();
+
+ std::string key("the first key");
+ disk_cache::Entry* entry;
+ ASSERT_THAT(CreateEntry(key, &entry), IsOk());
+
+ scoped_refptr<net::IOBuffer> buf_2k(new net::IOBuffer(2 * 1024));
+ CacheTestFillBuffer(buf_2k->data(), 2 * 1024, false);
+
+ const int kSmallSize = 612; // sub-1k
+ scoped_refptr<net::IOBuffer> buf_small(new net::IOBuffer(kSmallSize));
+ CacheTestFillBuffer(buf_small->data(), kSmallSize, false);
+
+ // Sets some bits for blocks representing 1K ranges [1024, 3072),
+ // which will be relevant for the next GetAvailableRange call.
+ EXPECT_EQ(2 * 1024, WriteSparseData(entry, /* offset = */ 1024, buf_2k.get(),
+ /* size = */ 2 * 1024));
+
+ // Now record a partial write from start of the first kb.
+ EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 0,
+ buf_small.get(), kSmallSize));
+
+ // Try to query a range starting from that block 0.
+ // The cache tracks: [0, 612) [1024, 3072).
+ // The request is for: [812, 2059) so response should be [1024, 2059), which
+ // has lenth = 1035. Previously this return a negative number for rv.
+ int64_t start = -1;
+ net::TestCompletionCallback cb;
+ int rv = entry->GetAvailableRange(812, 1247, &start, cb.callback());
+ EXPECT_EQ(1035, cb.GetResult(rv));
+ EXPECT_EQ(1024, start);
+
+ // Now query [512, 1536). This matches both [512, 612) and [1024, 1536),
+ // so this should return [512, 612).
+ rv = entry->GetAvailableRange(512, 1024, &start, cb.callback());
+ EXPECT_EQ(100, cb.GetResult(rv));
+ EXPECT_EQ(512, start);
+
+ // Now query next portion, [612, 1636). This now just should produce
+ // [1024, 1636)
+ rv = entry->GetAvailableRange(612, 1024, &start, cb.callback());
+ EXPECT_EQ(612, cb.GetResult(rv));
+ EXPECT_EQ(1024, start);
+
+ // Do a continuous small write, this one at [3072, 3684).
+ // This means the cache tracks [1024, 3072) via bitmaps and [3072, 3684)
+ // as the last write.
+ EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 3072,
+ buf_small.get(), kSmallSize));
+
+ // Query [2048, 4096). Should get [2048, 3684)
+ rv = entry->GetAvailableRange(2048, 2048, &start, cb.callback());
+ EXPECT_EQ(1636, cb.GetResult(rv));
+ EXPECT_EQ(2048, start);
+
+ // Now write at [4096, 4708). Since only one sub-kb thing is tracked, this
+ // now tracks [1024, 3072) via bitmaps and [4096, 4708) as the last write.
+ EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 4096,
+ buf_small.get(), kSmallSize));
+
+ // Query [2048, 4096). Should get [2048, 3072)
+ rv = entry->GetAvailableRange(2048, 2048, &start, cb.callback());
+ EXPECT_EQ(1024, cb.GetResult(rv));
+ EXPECT_EQ(2048, start);
+
+ // Query 2K more after that: [3072, 5120). Should get [4096, 4708)
+ rv = entry->GetAvailableRange(3072, 2048, &start, cb.callback());
+ EXPECT_EQ(612, cb.GetResult(rv));
+ EXPECT_EQ(4096, start);
+
+ // Also double-check that offsets within later children are correctly
+ // computed.
+ EXPECT_EQ(kSmallSize, WriteSparseData(entry, /* offset = */ 0x200400,
+ buf_small.get(), kSmallSize));
+ rv = entry->GetAvailableRange(0x100000, 0x200000, &start, cb.callback());
+ EXPECT_EQ(kSmallSize, cb.GetResult(rv));
+ EXPECT_EQ(0x200400, start);
+
+ entry->Close();
+}
+
// Tests that non-sequential writes that are not aligned with the minimum sparse
// data granularity (1024 bytes) do in fact result in dropped data.
TEST_F(DiskCacheEntryTest, SparseWriteDropped) {
@@ -2716,6 +2801,92 @@ TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) {
entry->Doom(); // Should not crash.
}
+TEST_F(DiskCacheEntryTest, SimpleCacheCreateAfterDiskLayerDoom) {
+ // Code coverage for what happens when a queued create runs after failure
+ // was noticed at SimpleSynchronousEntry layer.
+ SetSimpleCacheMode();
+ // Disable optimistic ops so we can block on CreateEntry and start
+ // WriteData off with an empty op queue.
+ SetCacheType(net::APP_CACHE);
+ InitCache();
+
+ const char key[] = "the key";
+ const int kSize1 = 10;
+ scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
+ CacheTestFillBuffer(buffer1->data(), kSize1, false);
+
+ disk_cache::Entry* entry = nullptr;
+ ASSERT_EQ(net::OK, CreateEntry(key, &entry));
+ ASSERT_TRUE(entry != nullptr);
+
+ // Make an empty _1 file, to cause a stream 2 write to fail.
+ base::FilePath entry_file1_path = cache_path_.AppendASCII(
+ disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 1));
+ base::File entry_file1(entry_file1_path,
+ base::File::FLAG_WRITE | base::File::FLAG_CREATE);
+ ASSERT_TRUE(entry_file1.IsValid());
+
+ entry->WriteData(2, 0, buffer1.get(), kSize1, net::CompletionCallback(),
+ /* truncate= */ true);
+ entry->Close();
+
+ // At this point we have put WriteData & Close on the queue, and WriteData
+ // started, but we haven't given the event loop control so the failure
+ // hasn't been reported and handled here, so the entry is still active
+ // for the key. Queue up another create for same key, and run through the
+ // events.
+ disk_cache::Entry* entry2 = nullptr;
+ ASSERT_EQ(net::ERR_FAILED, CreateEntry(key, &entry2));
+ ASSERT_TRUE(entry2 == nullptr);
+
+ EXPECT_EQ(0, cache_->GetEntryCount());
+
+ // Should be able to create properly next time, though.
+ disk_cache::Entry* entry3 = nullptr;
+ ASSERT_EQ(net::OK, CreateEntry(key, &entry3));
+ ASSERT_TRUE(entry3 != nullptr);
+ entry3->Close();
+}
+
+TEST_F(DiskCacheEntryTest, SimpleCacheQueuedOpenOnDoomedEntry) {
+ // This tests the following sequence of ops:
+ // A = Create(K);
+ // Close(A);
+ // B = Open(K);
+ // Doom(K);
+ // Close(B);
+ //
+ // ... where the execution of the Open sits on the queue all the way till
+ // Doom. Currently this fails the open.
+
+ SetSimpleCacheMode();
+ // Disable optimistic ops so we can block on CreateEntry and start
+ // WriteData off with an empty op queue.
+ SetCacheType(net::APP_CACHE);
+ InitCache();
+
+ const char key[] = "the key";
+
+ disk_cache::Entry* entry = nullptr;
+ ASSERT_EQ(net::OK, CreateEntry(key, &entry)); // event loop!
+ ASSERT_TRUE(entry != nullptr);
+
+ entry->Close();
+
+ disk_cache::Entry* entry2 = nullptr;
+ // Done via cache_ -> no event loop.
+ net::TestCompletionCallback cb;
+ ASSERT_EQ(net::ERR_IO_PENDING,
+ cache_->OpenEntry(key, &entry2, cb.callback()));
+
+ cache_->DoomEntry(key, base::Bind([](int) {}));
+ // Now event loop.
+ EXPECT_EQ(net::ERR_FAILED, cb.WaitForResult());
+ ASSERT_TRUE(entry2 == nullptr);
+
+ EXPECT_EQ(0, cache_->GetEntryCount());
+}
+
bool TruncatePath(const base::FilePath& file_path, int64_t length) {
base::File file(file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN);
if (!file.IsValid())
@@ -3645,7 +3816,15 @@ TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) {
EXPECT_THAT(cb1.GetResult(rv1), IsError(net::ERR_FAILED));
ASSERT_THAT(cb2.GetResult(rv2), IsOk());
+
+ // Try to get an alias for entry2. Open should succeed, and return the same
+ // pointer.
+ disk_cache::Entry* entry3 = nullptr;
+ ASSERT_EQ(net::OK, OpenEntry("key", &entry3));
+ EXPECT_EQ(entry3, entry2);
+
entry2->Close();
+ entry3->Close();
}
// Checking one more scenario of overlapped reading of a bad entry.
diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.cc b/chromium/net/disk_cache/simple/simple_backend_impl.cc
index e08ae98fb4b..52f76002e24 100644
--- a/chromium/net/disk_cache/simple/simple_backend_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_backend_impl.cc
@@ -20,8 +20,8 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/single_thread_task_runner.h"
#include "base/sys_info.h"
#include "base/task_runner_util.h"
@@ -70,7 +70,7 @@ scoped_refptr<base::SequencedTaskRunner> FallbackToInternalIfNull(
bool g_fd_limit_histogram_has_been_populated = false;
-void MaybeHistogramFdLimit(net::CacheType cache_type) {
+void MaybeHistogramFdLimit() {
if (g_fd_limit_histogram_has_been_populated)
return;
@@ -96,14 +96,13 @@ void MaybeHistogramFdLimit(net::CacheType cache_type) {
}
#endif
- SIMPLE_CACHE_UMA(ENUMERATION,
- "FileDescriptorLimitStatus", cache_type,
- fd_limit_status, FD_LIMIT_STATUS_MAX);
+ UMA_HISTOGRAM_ENUMERATION("SimpleCache.FileDescriptorLimitStatus",
+ fd_limit_status, FD_LIMIT_STATUS_MAX);
if (fd_limit_status == FD_LIMIT_STATUS_SUCCEEDED) {
- SIMPLE_CACHE_UMA(SPARSE_SLOWLY,
- "FileDescriptorLimitSoft", cache_type, soft_fd_limit);
- SIMPLE_CACHE_UMA(SPARSE_SLOWLY,
- "FileDescriptorLimitHard", cache_type, hard_fd_limit);
+ base::UmaHistogramSparse("SimpleCache.FileDescriptorLimitSoft",
+ soft_fd_limit);
+ base::UmaHistogramSparse("SimpleCache.FileDescriptorLimitHard",
+ hard_fd_limit);
}
g_fd_limit_histogram_has_been_populated = true;
@@ -246,7 +245,7 @@ SimpleBackendImpl::SimpleBackendImpl(
// backends, as default (if first call).
if (orig_max_size_ < 0)
orig_max_size_ = 0;
- MaybeHistogramFdLimit(cache_type_);
+ MaybeHistogramFdLimit();
}
SimpleBackendImpl::~SimpleBackendImpl() {
@@ -291,19 +290,25 @@ int SimpleBackendImpl::GetMaxFileSize() const {
void SimpleBackendImpl::OnDoomStart(uint64_t entry_hash) {
DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash));
entries_pending_doom_.insert(
- std::make_pair(entry_hash, std::vector<Closure>()));
+ std::make_pair(entry_hash, std::vector<PostDoomWaiter>()));
}
void SimpleBackendImpl::OnDoomComplete(uint64_t entry_hash) {
DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash));
- std::unordered_map<uint64_t, std::vector<Closure>>::iterator it =
+ std::unordered_map<uint64_t, std::vector<PostDoomWaiter>>::iterator it =
entries_pending_doom_.find(entry_hash);
- std::vector<Closure> to_run_closures;
- to_run_closures.swap(it->second);
+ std::vector<PostDoomWaiter> to_handle_waiters;
+ to_handle_waiters.swap(it->second);
entries_pending_doom_.erase(it);
- for (auto& closure : to_run_closures)
- closure.Run();
+ SIMPLE_CACHE_UMA(COUNTS_1000, "NumOpsBlockedByPendingDoom", cache_type_,
+ to_handle_waiters.size());
+
+ for (const PostDoomWaiter& post_doom : to_handle_waiters) {
+ SIMPLE_CACHE_UMA(TIMES, "QueueLatency.PendingDoom", cache_type_,
+ (base::TimeTicks::Now() - post_doom.time_queued));
+ post_doom.run_post_doom.Run();
+ }
}
void SimpleBackendImpl::DoomEntries(std::vector<uint64_t>* entry_hashes,
@@ -381,14 +386,14 @@ int SimpleBackendImpl::OpenEntry(const std::string& key,
const CompletionCallback& callback) {
const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
- std::vector<Closure>* post_doom = nullptr;
+ std::vector<PostDoomWaiter>* post_doom = nullptr;
scoped_refptr<SimpleEntryImpl> simple_entry =
CreateOrFindActiveOrDoomedEntry(entry_hash, key, &post_doom);
if (!simple_entry) {
Callback<int(const net::CompletionCallback&)> operation =
base::Bind(&SimpleBackendImpl::OpenEntry,
base::Unretained(this), key, entry);
- post_doom->push_back(
+ post_doom->emplace_back(
base::Bind(&RunOperationAndCallback, operation, callback));
return net::ERR_IO_PENDING;
}
@@ -401,7 +406,7 @@ int SimpleBackendImpl::CreateEntry(const std::string& key,
DCHECK_LT(0u, key.size());
const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
- std::vector<Closure>* post_doom = nullptr;
+ std::vector<PostDoomWaiter>* post_doom = nullptr;
scoped_refptr<SimpleEntryImpl> simple_entry =
CreateOrFindActiveOrDoomedEntry(entry_hash, key, &post_doom);
@@ -421,13 +426,13 @@ int SimpleBackendImpl::CreateEntry(const std::string& key,
std::pair<EntryMap::iterator, bool> insert_result =
active_entries_.insert(
EntryMap::value_type(entry_hash, simple_entry.get()));
- post_doom->push_back(base::Bind(
+ post_doom->emplace_back(base::Bind(
&SimpleEntryImpl::NotifyDoomBeforeCreateComplete, simple_entry));
DCHECK(insert_result.second);
} else {
Callback<int(const net::CompletionCallback&)> operation = base::Bind(
&SimpleBackendImpl::CreateEntry, base::Unretained(this), key, entry);
- post_doom->push_back(
+ post_doom->emplace_back(
base::Bind(&RunOperationAndCallback, operation, callback));
return net::ERR_IO_PENDING;
}
@@ -440,7 +445,7 @@ int SimpleBackendImpl::DoomEntry(const std::string& key,
const net::CompletionCallback& callback) {
const uint64_t entry_hash = simple_util::GetEntryHashKey(key);
- std::vector<Closure>* post_doom = nullptr;
+ std::vector<PostDoomWaiter>* post_doom = nullptr;
scoped_refptr<SimpleEntryImpl> simple_entry =
CreateOrFindActiveOrDoomedEntry(entry_hash, key, &post_doom);
if (!simple_entry) {
@@ -450,7 +455,7 @@ int SimpleBackendImpl::DoomEntry(const std::string& key,
// create for our key, in which case we still have work to do.
Callback<int(const net::CompletionCallback&)> operation =
base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key);
- post_doom->push_back(
+ post_doom->emplace_back(
base::Bind(&RunOperationAndCallback, operation, callback));
return net::ERR_IO_PENDING;
}
@@ -603,6 +608,17 @@ void SimpleBackendImpl::SetEntryInMemoryData(const std::string& key,
index_->SetEntryInMemoryData(entry_hash, data);
}
+SimpleBackendImpl::PostDoomWaiter::PostDoomWaiter() {}
+
+SimpleBackendImpl::PostDoomWaiter::PostDoomWaiter(
+ const base::Closure& to_run_post_doom)
+ : time_queued(base::TimeTicks::Now()), run_post_doom(to_run_post_doom) {}
+
+SimpleBackendImpl::PostDoomWaiter::PostDoomWaiter(const PostDoomWaiter& other)
+ : time_queued(other.time_queued), run_post_doom(other.run_post_doom) {}
+
+SimpleBackendImpl::PostDoomWaiter::~PostDoomWaiter() {}
+
void SimpleBackendImpl::InitializeIndex(const CompletionCallback& callback,
const DiskStatResult& result) {
if (result.net_error == net::OK) {
@@ -682,11 +698,11 @@ scoped_refptr<SimpleEntryImpl>
SimpleBackendImpl::CreateOrFindActiveOrDoomedEntry(
const uint64_t entry_hash,
const std::string& key,
- std::vector<Closure>** post_doom) {
+ std::vector<PostDoomWaiter>** post_doom) {
DCHECK_EQ(entry_hash, simple_util::GetEntryHashKey(key));
// If there is a doom pending, we would want to serialize after it.
- std::unordered_map<uint64_t, std::vector<Closure>>::iterator doom_it =
+ std::unordered_map<uint64_t, std::vector<PostDoomWaiter>>::iterator doom_it =
entries_pending_doom_.find(entry_hash);
if (doom_it != entries_pending_doom_.end()) {
*post_doom = &doom_it->second;
@@ -720,14 +736,14 @@ SimpleBackendImpl::CreateOrFindActiveOrDoomedEntry(
int SimpleBackendImpl::OpenEntryFromHash(uint64_t entry_hash,
Entry** entry,
const CompletionCallback& callback) {
- std::unordered_map<uint64_t, std::vector<Closure>>::iterator it =
+ std::unordered_map<uint64_t, std::vector<PostDoomWaiter>>::iterator it =
entries_pending_doom_.find(entry_hash);
if (it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
base::Bind(&SimpleBackendImpl::OpenEntryFromHash,
base::Unretained(this), entry_hash, entry);
- it->second.push_back(base::Bind(&RunOperationAndCallback,
- operation, callback));
+ it->second.emplace_back(
+ base::Bind(&RunOperationAndCallback, operation, callback));
return net::ERR_IO_PENDING;
}
@@ -750,14 +766,14 @@ int SimpleBackendImpl::DoomEntryFromHash(uint64_t entry_hash,
Entry** entry = new Entry*();
std::unique_ptr<Entry*> scoped_entry(entry);
- std::unordered_map<uint64_t, std::vector<Closure>>::iterator pending_it =
- entries_pending_doom_.find(entry_hash);
+ std::unordered_map<uint64_t, std::vector<PostDoomWaiter>>::iterator
+ pending_it = entries_pending_doom_.find(entry_hash);
if (pending_it != entries_pending_doom_.end()) {
Callback<int(const net::CompletionCallback&)> operation =
base::Bind(&SimpleBackendImpl::DoomEntryFromHash,
base::Unretained(this), entry_hash);
- pending_it->second.push_back(base::Bind(&RunOperationAndCallback,
- operation, callback));
+ pending_it->second.emplace_back(
+ base::Bind(&RunOperationAndCallback, operation, callback));
return net::ERR_IO_PENDING;
}
diff --git a/chromium/net/disk_cache/simple/simple_backend_impl.h b/chromium/net/disk_cache/simple/simple_backend_impl.h
index 0da30fb6fca..b2ed0169823 100644
--- a/chromium/net/disk_cache/simple/simple_backend_impl.h
+++ b/chromium/net/disk_cache/simple/simple_backend_impl.h
@@ -150,6 +150,17 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
int net_error;
};
+ struct PostDoomWaiter {
+ PostDoomWaiter();
+ // Also initializes |time_queued|.
+ explicit PostDoomWaiter(const base::Closure& to_run_post_doom);
+ explicit PostDoomWaiter(const PostDoomWaiter& other);
+ ~PostDoomWaiter();
+
+ base::TimeTicks time_queued;
+ base::Closure run_post_doom;
+ };
+
void InitializeIndex(const CompletionCallback& callback,
const DiskStatResult& result);
@@ -187,7 +198,7 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
scoped_refptr<SimpleEntryImpl> CreateOrFindActiveOrDoomedEntry(
uint64_t entry_hash,
const std::string& key,
- std::vector<base::Closure>** post_doom);
+ std::vector<PostDoomWaiter>** post_doom);
// Given a hash, will try to open the corresponding Entry. If we have an Entry
// corresponding to |hash| in the map of active entries, opens it. Otherwise,
@@ -245,9 +256,9 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
// The set of all entries which are currently being doomed. To avoid races,
// these entries cannot have Doom/Create/Open operations run until the doom
- // is complete. The base::Closure map target is used to store deferred
- // operations to be run at the completion of the Doom.
- std::unordered_map<uint64_t, std::vector<base::Closure>>
+ // is complete. The base::Closure |PostDoomWaiter::run_post_doom| field is
+ // used to store deferred operations to be run at the completion of the Doom.
+ std::unordered_map<uint64_t, std::vector<PostDoomWaiter>>
entries_pending_doom_;
net::NetLog* const net_log_;
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc
index 7123aac04ab..dda8a1e5e2d 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc
@@ -216,7 +216,7 @@ SimpleEntryImpl::SimpleEntryImpl(
"arrays should be the same size");
static_assert(arraysize(data_size_) == arraysize(crc_check_state_),
"arrays should be the same size");
- MakeUninitialized();
+ ResetEntry();
net_log_.BeginEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY,
CreateNetLogSimpleEntryConstructionCallback(this));
}
@@ -628,8 +628,10 @@ void SimpleEntryImpl::PostClientCallback(const CompletionCallback& callback,
base::Bind(&InvokeCallbackIfBackendIsAlive, backend_, callback, result));
}
-void SimpleEntryImpl::MakeUninitialized() {
- state_ = STATE_UNINITIALIZED;
+void SimpleEntryImpl::ResetEntry() {
+ // If we're doomed, we can't really do anything else with the entry, since
+ // we no longer own the name and are disconnected from the active entry table.
+ state_ = doomed_ ? STATE_FAILURE : STATE_UNINITIALIZED;
std::memset(crc32s_end_offset_, 0, sizeof(crc32s_end_offset_));
std::memset(crc32s_, 0, sizeof(crc32s_));
std::memset(have_written_, 0, sizeof(have_written_));
@@ -1213,12 +1215,11 @@ void SimpleEntryImpl::DoomEntryInternal(const CompletionCallback& callback) {
state_ = STATE_IO_PENDING;
return;
}
- PostTaskAndReplyWithResult(
- worker_pool_.get(),
- FROM_HERE,
- base::Bind(&SimpleSynchronousEntry::DoomEntry, path_, entry_hash_),
- base::Bind(
- &SimpleEntryImpl::DoomOperationComplete, this, callback, state_));
+ PostTaskAndReplyWithResult(worker_pool_.get(), FROM_HERE,
+ base::Bind(&SimpleSynchronousEntry::DoomEntry,
+ path_, cache_type_, entry_hash_),
+ base::Bind(&SimpleEntryImpl::DoomOperationComplete,
+ this, callback, state_));
state_ = STATE_IO_PENDING;
}
@@ -1236,14 +1237,29 @@ void SimpleEntryImpl::CreationOperationComplete(
"EntryCreationResult", cache_type_,
in_results->result == net::OK);
if (in_results->result != net::OK) {
- if (in_results->result != net::ERR_FILE_EXISTS)
- MarkAsDoomed();
+ if (in_results->result != net::ERR_FILE_EXISTS) {
+ // Here we keep index up-to-date, but don't remove ourselves from active
+ // entries since we may have queued operations, and it would be
+ // problematic to run further Creates, Opens, or Dooms if we are not
+ // the active entry. We can only do this because OpenEntryInternal
+ // and CreateEntryInternal have to start from STATE_UNINITIALIZED, so
+ // nothing else is going on which may be confused.
+ if (backend_)
+ backend_->index()->Remove(entry_hash_);
+ }
net_log_.AddEventWithNetErrorCode(end_event_type, net::ERR_FAILED);
PostClientCallback(completion_callback, net::ERR_FAILED);
- MakeUninitialized();
+ ResetEntry();
return;
}
+
+ // Make sure to keep the index up-to-date. We likely already did this when
+ // CreateEntry was called, but it's possible we were sitting on a queue
+ // after an op that removed us.
+ if (backend_ && !doomed_)
+ backend_->index()->Insert(entry_hash_);
+
// If out_entry is NULL, it means we already called ReturnEntryToCaller from
// the optimistic Create case.
if (out_entry)
@@ -1461,7 +1477,7 @@ void SimpleEntryImpl::CloseOperationComplete() {
STATE_UNINITIALIZED == state_);
net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_CLOSE_END);
AdjustOpenEntryCountBy(cache_type_, -1);
- MakeUninitialized();
+ ResetEntry();
RunNextOperationIfNeeded();
}
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.h b/chromium/net/disk_cache/simple/simple_entry_impl.h
index e2fddd5b74f..1a7027dab61 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.h
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.h
@@ -142,8 +142,8 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
enum State {
// The state immediately after construction, but before |synchronous_entry_|
- // has been assigned. This is the state at construction, and is the only
- // legal state to destruct an entry in.
+ // has been assigned. This is the state at construction, and is one of the
+ // two states (along with failure) one can destruct an entry in.
STATE_UNINITIALIZED,
// This entry is available for regular IO.
@@ -175,8 +175,11 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
// not expect).
void PostClientCallback(const CompletionCallback& callback, int result);
- // Sets entry to STATE_UNINITIALIZED.
- void MakeUninitialized();
+ // Clears entry state enough to prepare it for re-use. This will generally
+ // put it back into STATE_UNINITIALIZED, except if the entry is doomed and
+ // therefore disconnected from ownership of corresponding filename, in which
+ // case it will be put into STATE_FAILURE.
+ void ResetEntry();
// Return this entry to a user of the API in |out_entry|. Increments the user
// count.
diff --git a/chromium/net/disk_cache/simple/simple_histogram_macros.h b/chromium/net/disk_cache/simple/simple_histogram_macros.h
index edccfc079ac..fa302c31662 100644
--- a/chromium/net/disk_cache/simple/simple_histogram_macros.h
+++ b/chromium/net/disk_cache/simple/simple_histogram_macros.h
@@ -6,7 +6,6 @@
#define NET_DISK_CACHE_SIMPLE_SIMPLE_HISTOGRAM_MACROS_H_
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "net/base/cache_type.h"
// This file contains macros used to report histograms. The main issue is that
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
index 74b07f632aa..f2b1e89bbce 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -292,8 +292,12 @@ void SimpleSynchronousEntry::CreateEntry(
// static
int SimpleSynchronousEntry::DoomEntry(const FilePath& path,
+ net::CacheType cache_type,
uint64_t entry_hash) {
+ base::TimeTicks start = base::TimeTicks::Now();
const bool deleted_well = DeleteFilesForEntryHash(path, entry_hash);
+ SIMPLE_CACHE_UMA(TIMES, "DiskDoomLatency", cache_type,
+ base::TimeTicks::Now() - start);
return deleted_well ? net::OK : net::ERR_FAILED;
}
@@ -1004,7 +1008,6 @@ bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) {
SimpleFileTracker::FileHandle file =
file_tracker_->Acquire(this, SubFileForFileIndex(i));
bool success = file.IsOK() && file->GetInfo(&file_info);
- base::Time file_last_modified;
if (!success) {
DLOG(WARNING) << "Could not get platform file info.";
continue;
@@ -1461,7 +1464,7 @@ int SimpleSynchronousEntry::GetEOFRecordData(base::File* file,
void SimpleSynchronousEntry::Doom() const {
DCHECK_EQ(0u, entry_file_key_.doom_generation);
- DeleteFilesForEntryHash(path_, entry_file_key_.entry_hash);
+ DoomEntry(path_, cache_type_, entry_file_key_.entry_hash);
}
// static
diff --git a/chromium/net/disk_cache/simple/simple_synchronous_entry.h b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
index 38779a7ef7e..b2bdde1b1c3 100644
--- a/chromium/net/disk_cache/simple/simple_synchronous_entry.h
+++ b/chromium/net/disk_cache/simple/simple_synchronous_entry.h
@@ -179,7 +179,9 @@ class SimpleSynchronousEntry {
// Deletes an entry from the file system without affecting the state of the
// corresponding instance, if any (allowing operations to continue to be
// executed through that instance). Returns a net error code.
- static int DoomEntry(const base::FilePath& path, uint64_t entry_hash);
+ static int DoomEntry(const base::FilePath& path,
+ net::CacheType cache_type,
+ uint64_t entry_hash);
// Like |DoomEntry()| above, except that it truncates the entry files rather
// than deleting them. Used when dooming entries after the backend has
diff --git a/chromium/net/dns/address_sorter_posix_unittest.cc b/chromium/net/dns/address_sorter_posix_unittest.cc
index 3871e7ee183..204fc87e64c 100644
--- a/chromium/net/dns/address_sorter_posix_unittest.cc
+++ b/chromium/net/dns/address_sorter_posix_unittest.cc
@@ -16,6 +16,7 @@
#include "net/socket/socket_performance_watcher.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -42,7 +43,10 @@ class TestUDPClientSocket : public DatagramClientSocket {
NOTIMPLEMENTED();
return OK;
}
- int Write(IOBuffer*, int, const CompletionCallback&) override {
+ int Write(IOBuffer*,
+ int,
+ const CompletionCallback&,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
NOTIMPLEMENTED();
return OK;
}
@@ -74,6 +78,7 @@ class TestUDPClientSocket : public DatagramClientSocket {
NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override {
return NetworkChangeNotifier::kInvalidNetworkHandle;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
int Connect(const IPEndPoint& remote) override {
if (connected_)
diff --git a/chromium/net/dns/dns_config_service.h b/chromium/net/dns/dns_config_service.h
index 603fb4ccc0f..6ccd52f3f72 100644
--- a/chromium/net/dns/dns_config_service.h
+++ b/chromium/net/dns/dns_config_service.h
@@ -34,7 +34,7 @@ const int64_t kDnsDefaultTimeoutMs = 1000;
struct NET_EXPORT_PRIVATE DnsConfig {
DnsConfig();
DnsConfig(const DnsConfig& other);
- virtual ~DnsConfig();
+ ~DnsConfig();
bool Equals(const DnsConfig& d) const;
diff --git a/chromium/net/dns/dns_config_service_posix.cc b/chromium/net/dns/dns_config_service_posix.cc
index 60d6abe860a..f2e66331e33 100644
--- a/chromium/net/dns/dns_config_service_posix.cc
+++ b/chromium/net/dns/dns_config_service_posix.cc
@@ -11,7 +11,6 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
-#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/macros.h"
@@ -20,11 +19,6 @@
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
@@ -272,8 +266,6 @@ class DnsConfigServicePosix::Watcher {
}
void OnConfigChangedDelayed(bool succeeded) {
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/configchanged");
service_->OnConfigChanged(succeeded);
}
@@ -305,8 +297,6 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
}
void DoWork() override {
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/configreader");
base::TimeTicks start_time = base::TimeTicks::Now();
ConfigParsePosixResult result = ReadDnsConfig(&dns_config_);
if (dns_config_for_testing_) {
@@ -333,8 +323,6 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
void OnWorkFinished() override {
DCHECK(!IsCancelled());
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/configreaderfinished");
if (success_) {
service_->OnConfigRead(dns_config_);
} else {
@@ -359,54 +347,27 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
};
// A SerialWorker that reads the HOSTS file and runs Callback.
-class DnsConfigServicePosix::HostsReader
- : public SerialWorker,
- public base::trace_event::MemoryDumpProvider {
+class DnsConfigServicePosix::HostsReader : public SerialWorker {
public:
explicit HostsReader(DnsConfigServicePosix* service)
: service_(service),
file_path_hosts_(service->file_path_hosts_),
- success_(false),
- hosts_size_(0) {
- base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- this, "DnsConfigServicePosix::HostsReader",
- base::ThreadTaskRunnerHandle::Get());
- }
-
- bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) override {
- base::trace_event::MemoryAllocatorDump* dump =
- pmd->CreateAllocatorDump("net/dns_config_service_posix_hosts_reader");
- dump->AddScalar("hosts_entry_count",
- base::trace_event::MemoryAllocatorDump::kUnitsObjects,
- hosts_.size());
- dump->AddScalar("hosts_file_size",
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- hosts_size_);
- return true;
- }
+ success_(false) {}
private:
- ~HostsReader() override {
- base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
- this);
- }
+ ~HostsReader() override {}
void DoWork() override {
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/hostsreader");
base::TimeTicks start_time = base::TimeTicks::Now();
base::ScopedBlockingCall scoped_blocking_call(
base::BlockingType::MAY_BLOCK);
- success_ = ParseHostsFile(file_path_hosts_, &hosts_, &hosts_size_);
+ success_ = ParseHostsFile(file_path_hosts_, &hosts_);
UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_);
UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration",
base::TimeTicks::Now() - start_time);
}
void OnWorkFinished() override {
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/hostsreaderfinished");
if (success_) {
service_->OnHostsRead(hosts_);
} else {
@@ -423,7 +384,6 @@ class DnsConfigServicePosix::HostsReader
// Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsHosts hosts_;
bool success_;
- int64_t hosts_size_;
DISALLOW_COPY_AND_ASSIGN(HostsReader);
};
diff --git a/chromium/net/dns/dns_config_service_win.cc b/chromium/net/dns/dns_config_service_win.cc
index 2152cb7dd54..e6c99443075 100644
--- a/chromium/net/dns/dns_config_service_win.cc
+++ b/chromium/net/dns/dns_config_service_win.cc
@@ -698,8 +698,7 @@ class DnsConfigServiceWin::HostsReader : public SerialWorker {
base::ScopedBlockingCall scoped_blocking_call(
base::BlockingType::MAY_BLOCK);
HostsParseWinResult result = HOSTS_PARSE_WIN_UNREADABLE_HOSTS_FILE;
- int64_t file_size;
- if (ParseHostsFile(path_, &hosts_, &file_size))
+ if (ParseHostsFile(path_, &hosts_))
result = AddLocalhostEntries(&hosts_);
success_ = (result == HOSTS_PARSE_WIN_OK);
UMA_HISTOGRAM_ENUMERATION("AsyncDNS.HostsParseWin",
diff --git a/chromium/net/dns/dns_hosts.cc b/chromium/net/dns/dns_hosts.cc
index b9f1a27e9a6..8de7607c605 100644
--- a/chromium/net/dns/dns_hosts.cc
+++ b/chromium/net/dns/dns_hosts.cc
@@ -188,9 +188,7 @@ void ParseHosts(const std::string& contents, DnsHosts* dns_hosts) {
ParseHostsWithCommaMode(contents, dns_hosts, comma_mode);
}
-bool ParseHostsFile(const base::FilePath& path,
- DnsHosts* dns_hosts,
- int64_t* file_size) {
+bool ParseHostsFile(const base::FilePath& path, DnsHosts* dns_hosts) {
dns_hosts->clear();
// Missing file indicates empty HOSTS.
if (!base::PathExists(path))
@@ -213,7 +211,6 @@ bool ParseHostsFile(const base::FilePath& path,
return false;
ParseHosts(contents, dns_hosts);
- *file_size = size;
return true;
}
diff --git a/chromium/net/dns/dns_hosts.h b/chromium/net/dns/dns_hosts.h
index 79f7b63eeb7..423258ba2dc 100644
--- a/chromium/net/dns/dns_hosts.h
+++ b/chromium/net/dns/dns_hosts.h
@@ -68,8 +68,9 @@ void NET_EXPORT_PRIVATE ParseHosts(const std::string& contents,
// As above but reads the file pointed to by |path|.
bool NET_EXPORT_PRIVATE ParseHostsFile(const base::FilePath& path,
- DnsHosts* dns_hosts,
- int64_t* file_size);
+ DnsHosts* dns_hosts);
+
+
} // namespace net
diff --git a/chromium/net/dns/dns_transaction.cc b/chromium/net/dns/dns_transaction.cc
index 47906fdedfb..07fa7487b2a 100644
--- a/chromium/net/dns/dns_transaction.cc
+++ b/chromium/net/dns/dns_transaction.cc
@@ -43,11 +43,39 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
namespace {
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("dns_transaction", R"(
+ semantics {
+ sender: "DNS Transaction"
+ description:
+ "DNS Transaction implements a stub DNS resolver as defined in RFC "
+ "1034."
+ trigger:
+ "Any network request that may require DNS resolution, including "
+ "navigations, connecting to a proxy server, detecting proxy "
+ "settings, getting proxy config, certificate checking, and more."
+ data:
+ "Domain name that needs resolution."
+ destination: OTHER
+ destination_other:
+ "The connection is made to a DNS server based on user's network "
+ "settings."
+ }
+ policy {
+ cookies_allowed: NO
+ setting:
+ "This feature cannot be disabled. Without DNS Transactions Chrome "
+ "cannot resolve host names."
+ policy_exception_justification:
+ "Essential for Chrome's navigation."
+ })");
+
// Count labels in the fully-qualified name in DNS format.
int CountLabels(const std::string& name) {
size_t count = 0;
@@ -71,6 +99,26 @@ std::unique_ptr<base::Value> NetLogStartCallback(
return std::move(dict);
}
+// Values are used in UMA histograms. Do not change existing values.
+enum MalformedResponseResult {
+ MALFORMED_OK = 0,
+ MALFORMED_MALFORMED = 1,
+ MALFORMED_FAILED = 2,
+ MALFORMED_MAX
+};
+
+void RecordMalformedResponseHistogram(int net_error) {
+ MalformedResponseResult error_type;
+ if (net_error == OK)
+ error_type = MALFORMED_OK;
+ else if (net_error == ERR_DNS_MALFORMED_RESPONSE)
+ error_type = MALFORMED_MALFORMED;
+ else
+ error_type = MALFORMED_FAILED;
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.ResultAfterMalformedResponse", error_type,
+ MALFORMED_MAX);
+}
+
// ----------------------------------------------------------------------------
// A single asynchronous DNS exchange, which consists of sending out a
@@ -205,10 +253,15 @@ class DnsUDPAttempt : public DnsAttempt {
} while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
set_result(rv);
- // If we received a malformed response, and are now waiting for another one,
- // indicate to the transaction that the server might be misbehaving.
- if (rv == ERR_IO_PENDING && received_malformed_response_)
- return ERR_DNS_MALFORMED_RESPONSE;
+ if (received_malformed_response_) {
+ // If we received a malformed response, and are now waiting for another
+ // one, indicate to the transaction that the server might be misbehaving.
+ if (rv == ERR_IO_PENDING)
+ return ERR_DNS_MALFORMED_RESPONSE;
+
+ // This is a new response after the original malformed one.
+ RecordMalformedResponseHistogram(rv);
+ }
if (rv == OK) {
DCHECK_EQ(STATE_NONE, next_state_);
UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.UDPAttemptSuccess",
@@ -222,10 +275,10 @@ class DnsUDPAttempt : public DnsAttempt {
int DoSendQuery() {
next_state_ = STATE_SEND_QUERY_COMPLETE;
- return socket()->Write(query_->io_buffer(),
- query_->io_buffer()->size(),
- base::Bind(&DnsUDPAttempt::OnIOComplete,
- base::Unretained(this)));
+ return socket()->Write(
+ query_->io_buffer(), query_->io_buffer()->size(),
+ base::Bind(&DnsUDPAttempt::OnIOComplete, base::Unretained(this)),
+ kTrafficAnnotation);
}
int DoSendQueryComplete(int rv) {
@@ -263,6 +316,7 @@ class DnsUDPAttempt : public DnsAttempt {
// Our solution is to make another attempt, in case the query truly
// failed, but keep this attempt alive, in case it was a false alarm.
received_malformed_response_ = true;
+ RecordMalformedResponseHistogram(ERR_DNS_MALFORMED_RESPONSE);
next_state_ = STATE_READ_RESPONSE;
return OK;
}
@@ -417,9 +471,9 @@ class DnsTCPAttempt : public DnsAttempt {
if (buffer_->BytesRemaining() > 0) {
next_state_ = STATE_SEND_LENGTH;
return socket_->Write(
- buffer_.get(),
- buffer_->BytesRemaining(),
- base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
+ buffer_.get(), buffer_->BytesRemaining(),
+ base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)),
+ kTrafficAnnotation);
}
buffer_ = new DrainableIOBuffer(query_->io_buffer(),
query_->io_buffer()->size());
@@ -436,9 +490,9 @@ class DnsTCPAttempt : public DnsAttempt {
if (buffer_->BytesRemaining() > 0) {
next_state_ = STATE_SEND_QUERY;
return socket_->Write(
- buffer_.get(),
- buffer_->BytesRemaining(),
- base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
+ buffer_.get(), buffer_->BytesRemaining(),
+ base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)),
+ kTrafficAnnotation);
}
buffer_ =
new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size());
diff --git a/chromium/net/dns/dns_transaction_unittest.cc b/chromium/net/dns/dns_transaction_unittest.cc
index faf2faa8731..ce7bea01b3e 100644
--- a/chromium/net/dns/dns_transaction_unittest.cc
+++ b/chromium/net/dns/dns_transaction_unittest.cc
@@ -12,11 +12,11 @@
#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/sys_byteorder.h"
-#include "base/test/test_timeouts.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/time/time.h"
#include "net/base/ip_address.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/dns_query.h"
@@ -27,6 +27,7 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/test/net_test_suite.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -38,6 +39,8 @@ class NetLog;
namespace {
+base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1);
+
std::string DomainFromDot(const base::StringPiece& dotted) {
std::string out;
EXPECT_TRUE(DNSDomainFromDot(dotted, &out));
@@ -239,7 +242,6 @@ class TransactionHelper {
qtype_(qtype),
expected_answer_count_(expected_answer_count),
cancel_in_callback_(false),
- quit_in_callback_(false),
completed_(false) {}
// Mark that the transaction shall be destroyed immediately upon callback.
@@ -247,11 +249,6 @@ class TransactionHelper {
cancel_in_callback_ = true;
}
- // Mark to call MessageLoop::QuitWhenIdle() upon callback.
- void set_quit_in_callback() {
- quit_in_callback_ = true;
- }
-
void StartTransaction(DnsTransactionFactory* factory) {
EXPECT_EQ(NULL, transaction_.get());
transaction_ = factory->CreateTransaction(
@@ -281,10 +278,6 @@ class TransactionHelper {
return;
}
- // Tell MessageLoop to quit now, in case any ASSERT_* fails.
- if (quit_in_callback_)
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
-
if (expected_answer_count_ >= 0) {
ASSERT_THAT(rv, IsOk());
ASSERT_TRUE(response != NULL);
@@ -314,11 +307,16 @@ class TransactionHelper {
return has_completed();
}
- // Use when some of the responses are timeouts.
- bool RunUntilDone(DnsTransactionFactory* factory) {
- set_quit_in_callback();
- StartTransaction(factory);
- base::RunLoop().Run();
+ bool FastForwardByTimeout(DnsSession* session,
+ unsigned server_index,
+ int attempt) {
+ NetTestSuite::GetScopedTaskEnvironment()->FastForwardBy(
+ session->NextTimeout(server_index, attempt));
+ return has_completed();
+ }
+
+ bool FastForwardAll() {
+ NetTestSuite::GetScopedTaskEnvironment()->FastForwardUntilNoTasksRemain();
return has_completed();
}
@@ -328,7 +326,6 @@ class TransactionHelper {
std::unique_ptr<DnsTransaction> transaction_;
int expected_answer_count_;
bool cancel_in_callback_;
- bool quit_in_callback_;
bool completed_;
};
@@ -449,12 +446,14 @@ class DnsTransactionTest : public testing::Test {
}
void SetUp() override {
+ NetTestSuite::SetScopedTaskEnvironment(
+ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
// By default set one server,
ConfigureNumServers(1);
// and no retransmissions,
config_.attempts = 1;
- // but long enough timeout for memory tests.
- config_.timeout = TestTimeouts::action_timeout();
+ // and an arbitrary timeout.
+ config_.timeout = kTimeout;
ConfigureFactory();
}
@@ -463,6 +462,7 @@ class DnsTransactionTest : public testing::Test {
for (size_t i = 0; i < socket_data_.size(); ++i) {
EXPECT_TRUE(socket_data_[i]->GetProvider()->AllWriteDataConsumed()) << i;
}
+ NetTestSuite::ResetScopedTaskEnvironment();
}
protected:
@@ -594,7 +594,6 @@ TEST_F(DnsTransactionTest, CancelFromCallback) {
TEST_F(DnsTransactionTest, MismatchedResponseSync) {
config_.attempts = 2;
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
// Attempt receives mismatched response followed by valid response.
@@ -607,12 +606,11 @@ TEST_F(DnsTransactionTest, MismatchedResponseSync) {
AddSocketData(std::move(data));
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
TEST_F(DnsTransactionTest, MismatchedResponseAsync) {
config_.attempts = 2;
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
// First attempt receives mismatched response followed by valid response.
@@ -627,11 +625,10 @@ TEST_F(DnsTransactionTest, MismatchedResponseAsync) {
AddQueryAndTimeout(kT0HostName, kT0Qtype);
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
TEST_F(DnsTransactionTest, MismatchedResponseFail) {
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
// Attempt receives mismatched response but times out because only one attempt
@@ -640,12 +637,12 @@ TEST_F(DnsTransactionTest, MismatchedResponseFail) {
kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.Run(transaction_factory_.get()));
+ EXPECT_TRUE(helper0.FastForwardByTimeout(session_.get(), 0, 0));
}
TEST_F(DnsTransactionTest, MismatchedResponseNxdomain) {
config_.attempts = 2;
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
// First attempt receives mismatched response followed by valid NXDOMAIN
@@ -679,8 +676,6 @@ TEST_F(DnsTransactionTest, NoDomain) {
TEST_F(DnsTransactionTest, Timeout) {
config_.attempts = 3;
- // Use short timeout to speed up the test.
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
AddQueryAndTimeout(kT0HostName, kT0Qtype);
@@ -688,8 +683,12 @@ TEST_F(DnsTransactionTest, Timeout) {
AddQueryAndTimeout(kT0HostName, kT0Qtype);
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
- EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
+
+ // Finish when the third attempt times out.
+ EXPECT_FALSE(helper0.Run(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.FastForwardByTimeout(session_.get(), 0, 0));
+ EXPECT_FALSE(helper0.FastForwardByTimeout(session_.get(), 0, 1));
+ EXPECT_TRUE(helper0.FastForwardByTimeout(session_.get(), 0, 2));
}
TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
@@ -698,8 +697,6 @@ TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
// The next request should start from the next server.
config_.rotate = true;
ConfigureNumServers(3);
- // Use short timeout to speed up the test.
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
// Responses for first request.
@@ -716,7 +713,8 @@ TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED);
TransactionHelper helper1(kT1HostName, kT1Qtype, ERR_NAME_NOT_RESOLVED);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.Run(transaction_factory_.get()));
+ EXPECT_TRUE(helper0.FastForwardAll());
EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
unsigned kOrder[] = {
@@ -982,7 +980,6 @@ TEST_F(DnsTransactionTest, TCPMalformed) {
}
TEST_F(DnsTransactionTest, TCPTimeout) {
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
@@ -990,7 +987,8 @@ TEST_F(DnsTransactionTest, TCPTimeout) {
kT0Qtype, ASYNC, true));
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
- EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.Run(transaction_factory_.get()));
+ EXPECT_TRUE(helper0.FastForwardAll());
}
TEST_F(DnsTransactionTest, TCPReadReturnsZeroAsync) {
@@ -1057,7 +1055,6 @@ TEST_F(DnsTransactionTest, TCPConnectionClosedSynchronous) {
TEST_F(DnsTransactionTest, MismatchedThenNxdomainThenTCP) {
config_.attempts = 2;
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
std::unique_ptr<DnsSocketData> data(
new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false));
@@ -1080,7 +1077,6 @@ TEST_F(DnsTransactionTest, MismatchedThenNxdomainThenTCP) {
TEST_F(DnsTransactionTest, MismatchedThenOkThenTCP) {
config_.attempts = 2;
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
std::unique_ptr<DnsSocketData> data(
new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false));
@@ -1104,7 +1100,6 @@ TEST_F(DnsTransactionTest, MismatchedThenOkThenTCP) {
}
TEST_F(DnsTransactionTest, InvalidQuery) {
- config_.timeout = TestTimeouts::tiny_timeout();
ConfigureFactory();
TransactionHelper helper0(".", dns_protocol::kTypeA, ERR_INVALID_ARGUMENT);
diff --git a/chromium/net/dns/host_cache.cc b/chromium/net/dns/host_cache.cc
index 70e66a7f83b..41cab7cdf6e 100644
--- a/chromium/net/dns/host_cache.cc
+++ b/chromium/net/dns/host_cache.cc
@@ -418,19 +418,12 @@ size_t HostCache::max_entries() const {
// static
std::unique_ptr<HostCache> HostCache::CreateDefaultCache() {
-// Cache capacity is determined by the field trial.
#if defined(ENABLE_BUILT_IN_DNS)
const size_t kDefaultMaxEntries = 1000;
#else
const size_t kDefaultMaxEntries = 100;
#endif
- const size_t kSaneMaxEntries = 1 << 20;
- size_t max_entries = 0;
- base::StringToSizeT(base::FieldTrialList::FindFullName("HostCacheSize"),
- &max_entries);
- if ((max_entries == 0) || (max_entries > kSaneMaxEntries))
- max_entries = kDefaultMaxEntries;
- return std::make_unique<HostCache>(max_entries);
+ return std::make_unique<HostCache>(kDefaultMaxEntries);
}
void HostCache::EvictOneEntry(base::TimeTicks now) {
@@ -551,4 +544,31 @@ void HostCache::RecordEraseAll(EraseReason reason, base::TimeTicks now) {
RecordErase(reason, now, it.second);
}
+bool HostCache::HasEntry(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) {
+ net::HostCache::Key cache_key;
+ hostname.CopyToString(&cache_key.hostname);
+
+ const HostCache::Entry* entry =
+ LookupStale(cache_key, base::TimeTicks::Now(), stale_out);
+ if (!entry) {
+ // Might not have found the cache entry because the address_family or
+ // host_resolver_flags in cache_key do not match those used for the
+ // original DNS lookup. Try another common combination of address_family
+ // and host_resolver_flags in an attempt to find a matching cache entry.
+ cache_key.address_family = net::ADDRESS_FAMILY_IPV4;
+ cache_key.host_resolver_flags =
+ net::HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
+ entry = LookupStale(cache_key, base::TimeTicks::Now(), stale_out);
+ if (!entry)
+ return false;
+ }
+
+ if (source_out != nullptr)
+ *source_out = entry->source();
+
+ return true;
+}
+
} // namespace net
diff --git a/chromium/net/dns/host_cache.h b/chromium/net/dns/host_cache.h
index e131de9733d..cb9c6eafbd2 100644
--- a/chromium/net/dns/host_cache.h
+++ b/chromium/net/dns/host_cache.h
@@ -180,6 +180,16 @@ class NET_EXPORT HostCache {
base::TimeTicks now,
base::TimeDelta ttl);
+ // Checks whether an entry exists for |hostname|.
+ // If so, returns true and writes the source (e.g. DNS, HOSTS file, etc.) to
+ // |source_out| and the staleness to |stale_out| (if they are not null).
+ // It tries using two common address_family and host_resolver_flag
+ // combinations when performing lookups in the cache; this means false
+ // negatives are possible, but unlikely.
+ bool HasEntry(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out);
+
// Marks all entries as stale on account of a network change.
void OnNetworkChange();
diff --git a/chromium/net/dns/host_resolver.h b/chromium/net/dns/host_resolver.h
index d11564698d2..87cf01d51e1 100644
--- a/chromium/net/dns/host_resolver.h
+++ b/chromium/net/dns/host_resolver.h
@@ -180,6 +180,14 @@ class NET_EXPORT HostResolver {
AddressList* addresses,
const NetLogWithSource& net_log) = 0;
+ // Like |ResolveFromCache()|, but can return a stale result if the
+ // implementation supports it. Fills in |*stale_info| if a response is
+ // returned to indicate how stale (or not) it is.
+ virtual int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) = 0;
+
// Enable or disable the built-in asynchronous DnsClient.
virtual void SetDnsClientEnabled(bool enabled);
@@ -187,6 +195,17 @@ class NET_EXPORT HostResolver {
// Used primarily to clear the cache and for getting debug information.
virtual HostCache* GetHostCache();
+ // Checks whether this HostResolver has cached a resolution for the given
+ // hostname (or IP address literal). If so, returns true and writes the source
+ // of the resolution (e.g. DNS, HOSTS file, etc.) to |source_out| and the
+ // staleness of the resolution to |stale_out| (if they are not null).
+ // It tries using two common address_family and host_resolver_flag
+ // combinations when checking the cache; this means false negatives are
+ // possible, but unlikely.
+ virtual bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const = 0;
+
// Returns the current DNS configuration |this| is using, as a Value, or
// nullptr if it's configured to always use the system host resolver.
virtual std::unique_ptr<base::Value> GetDnsConfigAsValue() const;
diff --git a/chromium/net/dns/host_resolver_impl.cc b/chromium/net/dns/host_resolver_impl.cc
index b9854252a1b..032ba4c69a6 100644
--- a/chromium/net/dns/host_resolver_impl.cc
+++ b/chromium/net/dns/host_resolver_impl.cc
@@ -36,8 +36,8 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -766,8 +766,6 @@ class HostResolverImpl::ProcTask
// mutate.
void DoLookup(const base::TimeTicks& start_time,
const uint32_t attempt_number) {
- TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION scoped_heap_context(
- "net/dns/proctask");
AddressList results;
int os_error = 0;
int error = params_.resolver_proc->Resolve(key_.hostname,
@@ -1524,8 +1522,8 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
} else {
UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS);
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.DNS.DnsTask.Errors",
- std::abs(dns_task_error_));
+ base::UmaHistogramSparse("Net.DNS.DnsTask.Errors",
+ std::abs(dns_task_error_));
resolver_->OnDnsTaskResolve(dns_task_error_);
} else {
UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.FallbackFail", duration);
@@ -1711,11 +1709,9 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
if (category == RESOLVE_FAIL || category == RESOLVE_ABORT) {
if (duration < base::TimeDelta::FromMilliseconds(10))
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.DNS.ResolveError.Fast",
- std::abs(error));
+ base::UmaHistogramSparse("Net.DNS.ResolveError.Fast", std::abs(error));
else
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.DNS.ResolveError.Slow",
- std::abs(error));
+ base::UmaHistogramSparse("Net.DNS.ResolveError.Slow", std::abs(error));
}
}
@@ -2113,6 +2109,15 @@ HostCache* HostResolverImpl::GetHostCache() {
return cache_.get();
}
+bool HostResolverImpl::HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const {
+ if (!cache_)
+ return false;
+
+ return cache_->HasEntry(hostname, source_out, stale_out);
+}
+
std::unique_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const {
// Check if async DNS is disabled.
if (!dns_client_.get())
@@ -2574,8 +2579,8 @@ void HostResolverImpl::OnDnsTaskResolve(int net_error) {
AbortDnsTasks();
UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false);
- UMA_HISTOGRAM_SPARSE_SLOWLY("AsyncDNS.DnsClientDisabledReason",
- std::abs(net_error));
+ base::UmaHistogramSparse("AsyncDNS.DnsClientDisabledReason",
+ std::abs(net_error));
}
void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
diff --git a/chromium/net/dns/host_resolver_impl.h b/chromium/net/dns/host_resolver_impl.h
index 5de489cabd2..58300e55ca8 100644
--- a/chromium/net/dns/host_resolver_impl.h
+++ b/chromium/net/dns/host_resolver_impl.h
@@ -141,17 +141,19 @@ class NET_EXPORT HostResolverImpl
int ResolveFromCache(const RequestInfo& info,
AddressList* addresses,
const NetLogWithSource& source_net_log) override;
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) override;
void SetDnsClientEnabled(bool enabled) override;
+
HostCache* GetHostCache() override;
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override;
+
std::unique_ptr<base::Value> GetDnsConfigAsValue() const override;
- // Like |ResolveFromCache()|, but can return a stale result if the
- // implementation supports it. Fills in |*stale_info| if a response is
- // returned to indicate how stale (or not) it is.
- int ResolveStaleFromCache(const RequestInfo& info,
- AddressList* addresses,
- HostCache::EntryStaleness* stale_info,
- const NetLogWithSource& source_net_log);
// Returns the number of host cache entries that were restored, or 0 if there
// is no cache.
size_t LastRestoredCacheSize() const;
diff --git a/chromium/net/dns/host_resolver_mojo.cc b/chromium/net/dns/host_resolver_mojo.cc
index 4015d0af41b..b76cbf04a3f 100644
--- a/chromium/net/dns/host_resolver_mojo.cc
+++ b/chromium/net/dns/host_resolver_mojo.cc
@@ -107,10 +107,28 @@ int HostResolverMojo::ResolveFromCache(const RequestInfo& info,
return ResolveFromCacheInternal(info, CacheKeyForRequest(info), addresses);
}
+int HostResolverMojo::ResolveStaleFromCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) {
+ NOTREACHED();
+ return ERR_UNEXPECTED;
+}
+
HostCache* HostResolverMojo::GetHostCache() {
return host_cache_.get();
}
+bool HostResolverMojo::HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const {
+ if (!host_cache_)
+ return false;
+
+ return host_cache_->HasEntry(hostname, source_out, stale_out);
+}
+
int HostResolverMojo::ResolveFromCacheInternal(const RequestInfo& info,
const HostCache::Key& key,
AddressList* addresses) {
diff --git a/chromium/net/dns/host_resolver_mojo.h b/chromium/net/dns/host_resolver_mojo.h
index 602660adb8e..80920d2a979 100644
--- a/chromium/net/dns/host_resolver_mojo.h
+++ b/chromium/net/dns/host_resolver_mojo.h
@@ -43,7 +43,14 @@ class HostResolverMojo : public HostResolver {
int ResolveFromCache(const RequestInfo& info,
AddressList* addresses,
const NetLogWithSource& source_net_log) override;
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) override;
HostCache* GetHostCache() override;
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override;
private:
class Job;
diff --git a/chromium/net/dns/mapped_host_resolver.cc b/chromium/net/dns/mapped_host_resolver.cc
index 4508df25828..2a409faaaae 100644
--- a/chromium/net/dns/mapped_host_resolver.cc
+++ b/chromium/net/dns/mapped_host_resolver.cc
@@ -43,6 +43,19 @@ int MappedHostResolver::ResolveFromCache(const RequestInfo& original_info,
return impl_->ResolveFromCache(info, addresses, net_log);
}
+int MappedHostResolver::ResolveStaleFromCache(
+ const RequestInfo& original_info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) {
+ RequestInfo info = original_info;
+ int rv = ApplyRules(&info);
+ if (rv != OK)
+ return rv;
+
+ return impl_->ResolveStaleFromCache(info, addresses, stale_info, net_log);
+}
+
void MappedHostResolver::SetDnsClientEnabled(bool enabled) {
impl_->SetDnsClientEnabled(enabled);
}
@@ -51,6 +64,12 @@ HostCache* MappedHostResolver::GetHostCache() {
return impl_->GetHostCache();
}
+bool MappedHostResolver::HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const {
+ return impl_->HasCached(hostname, source_out, stale_out);
+}
+
std::unique_ptr<base::Value> MappedHostResolver::GetDnsConfigAsValue() const {
return impl_->GetDnsConfigAsValue();
}
diff --git a/chromium/net/dns/mapped_host_resolver.h b/chromium/net/dns/mapped_host_resolver.h
index 5ae459cbae5..559aa3e5ad8 100644
--- a/chromium/net/dns/mapped_host_resolver.h
+++ b/chromium/net/dns/mapped_host_resolver.h
@@ -54,8 +54,17 @@ class NET_EXPORT MappedHostResolver : public HostResolver {
int ResolveFromCache(const RequestInfo& info,
AddressList* addresses,
const NetLogWithSource& net_log) override;
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) override;
void SetDnsClientEnabled(bool enabled) override;
+
HostCache* GetHostCache() override;
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override;
+
std::unique_ptr<base::Value> GetDnsConfigAsValue() const override;
void SetNoIPv6OnWifi(bool no_ipv6_on_wifi) override;
bool GetNoIPv6OnWifi() override;
diff --git a/chromium/net/dns/mdns_client_impl.cc b/chromium/net/dns/mdns_client_impl.cc
index a4902c47b62..04e2bb5ecd4 100644
--- a/chromium/net/dns/mdns_client_impl.cc
+++ b/chromium/net/dns/mdns_client_impl.cc
@@ -417,19 +417,18 @@ void MDnsClientImpl::Core::QueryCache(
}
MDnsClientImpl::MDnsClientImpl()
- : clock_(new base::DefaultClock),
- cleanup_timer_(new base::Timer(false, false)) {
-}
+ : clock_(base::DefaultClock::GetInstance()),
+ cleanup_timer_(new base::Timer(false, false)) {}
-MDnsClientImpl::MDnsClientImpl(std::unique_ptr<base::Clock> clock,
+MDnsClientImpl::MDnsClientImpl(base::Clock* clock,
std::unique_ptr<base::Timer> timer)
- : clock_(std::move(clock)), cleanup_timer_(std::move(timer)) {}
+ : clock_(clock), cleanup_timer_(std::move(timer)) {}
MDnsClientImpl::~MDnsClientImpl() = default;
bool MDnsClientImpl::StartListening(MDnsSocketFactory* socket_factory) {
DCHECK(!core_.get());
- core_.reset(new Core(clock_.get(), cleanup_timer_.get()));
+ core_.reset(new Core(clock_, cleanup_timer_.get()));
if (!core_->Init(socket_factory)) {
core_.reset();
return false;
@@ -450,7 +449,7 @@ std::unique_ptr<MDnsListener> MDnsClientImpl::CreateListener(
const std::string& name,
MDnsListener::Delegate* delegate) {
return std::unique_ptr<MDnsListener>(
- new MDnsListenerImpl(rrtype, name, clock_.get(), delegate, this));
+ new MDnsListenerImpl(rrtype, name, clock_, delegate, this));
}
std::unique_ptr<MDnsTransaction> MDnsClientImpl::CreateTransaction(
diff --git a/chromium/net/dns/mdns_client_impl.h b/chromium/net/dns/mdns_client_impl.h
index ad478981b12..c35aaa8bd5d 100644
--- a/chromium/net/dns/mdns_client_impl.h
+++ b/chromium/net/dns/mdns_client_impl.h
@@ -209,11 +209,11 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL);
// Test constructor, takes a mock clock and mock timer.
- MDnsClientImpl(std::unique_ptr<base::Clock> clock,
+ MDnsClientImpl(base::Clock* clock,
std::unique_ptr<base::Timer> cleanup_timer);
std::unique_ptr<Core> core_;
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
std::unique_ptr<base::Timer> cleanup_timer_;
DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl);
diff --git a/chromium/net/dns/mdns_client_unittest.cc b/chromium/net/dns/mdns_client_unittest.cc
index 76eb1064a07..a8dff273d7c 100644
--- a/chromium/net/dns/mdns_client_unittest.cc
+++ b/chromium/net/dns/mdns_client_unittest.cc
@@ -361,9 +361,9 @@ class PtrRecordCopyContainer {
int ttl_;
};
-class MockClock : public base::DefaultClock {
+class MockClock : public base::Clock {
public:
- MockClock() : base::DefaultClock() {}
+ MockClock() = default;
virtual ~MockClock() = default;
MOCK_METHOD0(Now, base::Time());
@@ -557,15 +557,14 @@ TEST_F(MDnsTest, CacheCleanupWithShortTTL) {
// Use a nonzero starting time as a base.
base::Time start_time = base::Time() + base::TimeDelta::FromSeconds(1);
- MockClock* clock = new MockClock;
+ MockClock clock;
MockTimer* timer = new MockTimer;
- test_client_.reset(
- new MDnsClientImpl(base::WrapUnique(clock), base::WrapUnique(timer)));
+ test_client_.reset(new MDnsClientImpl(&clock, base::WrapUnique(timer)));
test_client_->StartListening(&socket_factory_);
EXPECT_CALL(*timer, StartObserver(_, _, _)).Times(1);
- EXPECT_CALL(*clock, Now())
+ EXPECT_CALL(clock, Now())
.Times(3)
.WillRepeatedly(Return(start_time))
.RetiresOnSaturation();
@@ -600,10 +599,10 @@ TEST_F(MDnsTest, CacheCleanupWithShortTTL) {
// Set the clock to 2.0s, which should clean up the 'privet' record, but not
// the printer. The mock clock will change Now() mid-execution from 2s to 4s.
// Note: expectations are FILO-ordered -- t+2 seconds is returned, then t+4.
- EXPECT_CALL(*clock, Now())
+ EXPECT_CALL(clock, Now())
.WillOnce(Return(start_time + base::TimeDelta::FromSeconds(4)))
.RetiresOnSaturation();
- EXPECT_CALL(*clock, Now())
+ EXPECT_CALL(clock, Now())
.WillOnce(Return(start_time + base::TimeDelta::FromSeconds(2)))
.RetiresOnSaturation();
diff --git a/chromium/net/dns/mock_host_resolver.cc b/chromium/net/dns/mock_host_resolver.cc
index 2bb24418fae..c146a1fc596 100644
--- a/chromium/net/dns/mock_host_resolver.cc
+++ b/chromium/net/dns/mock_host_resolver.cc
@@ -149,6 +149,18 @@ int MockHostResolverBase::ResolveFromCache(const RequestInfo& info,
return rv;
}
+int MockHostResolverBase::ResolveStaleFromCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) {
+ num_resolve_from_cache_++;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ next_request_id_++;
+ int rv = ResolveFromIPLiteralOrCache(info, addresses);
+ return rv;
+}
+
void MockHostResolverBase::DetachRequest(size_t id) {
RequestMap::iterator it = requests_.find(id);
CHECK(it != requests_.end());
@@ -159,6 +171,16 @@ HostCache* MockHostResolverBase::GetHostCache() {
return cache_.get();
}
+bool MockHostResolverBase::HasCached(
+ base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const {
+ if (!cache_)
+ return false;
+
+ return cache_->HasEntry(hostname, source_out, stale_out);
+}
+
void MockHostResolverBase::ResolveAllPending() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(ondemand_mode_);
@@ -184,8 +206,10 @@ MockHostResolverBase::MockHostResolverBase(bool use_caching)
}
}
-int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info,
- AddressList* addresses) {
+int MockHostResolverBase::ResolveFromIPLiteralOrCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info) {
IPAddress ip_address;
if (ip_address.AssignFromIPLiteral(info.hostname())) {
// This matches the behavior HostResolverImpl.
@@ -204,7 +228,11 @@ int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info,
HostCache::Key key(info.hostname(),
info.address_family(),
info.host_resolver_flags());
- const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now());
+ const HostCache::Entry* entry;
+ if (stale_info)
+ entry = cache_->LookupStale(key, base::TimeTicks::Now(), stale_info);
+ else
+ entry = cache_->Lookup(key, base::TimeTicks::Now());
if (entry) {
rv = entry->error();
if (rv == OK)
@@ -501,6 +529,21 @@ int HangingHostResolver::ResolveFromCache(const RequestInfo& info,
return ERR_DNS_CACHE_MISS;
}
+int HangingHostResolver::ResolveStaleFromCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) {
+ return ERR_DNS_CACHE_MISS;
+}
+
+bool HangingHostResolver::HasCached(
+ base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const {
+ return false;
+}
+
//-----------------------------------------------------------------------------
ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() = default;
diff --git a/chromium/net/dns/mock_host_resolver.h b/chromium/net/dns/mock_host_resolver.h
index 3576a38e0e5..ce43c8c2b86 100644
--- a/chromium/net/dns/mock_host_resolver.h
+++ b/chromium/net/dns/mock_host_resolver.h
@@ -91,7 +91,14 @@ class MockHostResolverBase
int ResolveFromCache(const RequestInfo& info,
AddressList* addresses,
const NetLogWithSource& net_log) override;
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) override;
HostCache* GetHostCache() override;
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override;
// Detach cancelled request.
void DetachRequest(size_t id);
@@ -129,8 +136,10 @@ class MockHostResolverBase
// Resolve as IP or from |cache_| return cached error or
// DNS_CACHE_MISS if failed.
- int ResolveFromIPLiteralOrCache(const RequestInfo& info,
- AddressList* addresses);
+ int ResolveFromIPLiteralOrCache(
+ const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info = nullptr);
// Resolve via |proc_|.
int ResolveProc(const RequestInfo& info, AddressList* addresses);
// Resolve request stored in |requests_|. Pass rv to callback.
@@ -286,6 +295,13 @@ class HangingHostResolver : public HostResolver {
int ResolveFromCache(const RequestInfo& info,
AddressList* addresses,
const NetLogWithSource& net_log) override;
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& source_net_log) override;
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override;
};
// This class sets the default HostResolverProc for a particular scope. The
diff --git a/chromium/net/dns/mojo_host_struct_traits.cc b/chromium/net/dns/mojo_host_struct_traits.cc
index 44b7efc441d..4ba742da3df 100644
--- a/chromium/net/dns/mojo_host_struct_traits.cc
+++ b/chromium/net/dns/mojo_host_struct_traits.cc
@@ -8,47 +8,12 @@
#include "base/memory/ptr_util.h"
#include "net/base/address_list.h"
+#include "net/interfaces/address_family_traits.h"
#include "net/interfaces/ip_endpoint_struct_traits.h"
namespace mojo {
// static
-bool EnumTraits<net::interfaces::AddressFamily, net::AddressFamily>::FromMojom(
- net::interfaces::AddressFamily address_family,
- net::AddressFamily* out) {
- using net::interfaces::AddressFamily;
- switch (address_family) {
- case AddressFamily::UNSPECIFIED:
- *out = net::ADDRESS_FAMILY_UNSPECIFIED;
- return true;
- case AddressFamily::IPV4:
- *out = net::ADDRESS_FAMILY_IPV4;
- return true;
- case AddressFamily::IPV6:
- *out = net::ADDRESS_FAMILY_IPV6;
- return true;
- }
- return false;
-}
-
-// static
-net::interfaces::AddressFamily
-EnumTraits<net::interfaces::AddressFamily, net::AddressFamily>::ToMojom(
- net::AddressFamily address_family) {
- using net::interfaces::AddressFamily;
- switch (address_family) {
- case net::ADDRESS_FAMILY_UNSPECIFIED:
- return AddressFamily::UNSPECIFIED;
- case net::ADDRESS_FAMILY_IPV4:
- return AddressFamily::IPV4;
- case net::ADDRESS_FAMILY_IPV6:
- return AddressFamily::IPV6;
- }
- NOTREACHED();
- return AddressFamily::UNSPECIFIED;
-}
-
-// static
bool StructTraits<net::interfaces::HostResolverRequestInfoDataView,
std::unique_ptr<net::HostResolver::RequestInfo>>::
Read(net::interfaces::HostResolverRequestInfoDataView data,
diff --git a/chromium/net/dns/mojo_host_struct_traits.h b/chromium/net/dns/mojo_host_struct_traits.h
index 29a5f6c7d6f..f39b844c41b 100644
--- a/chromium/net/dns/mojo_host_struct_traits.h
+++ b/chromium/net/dns/mojo_host_struct_traits.h
@@ -9,19 +9,12 @@
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "net/dns/host_resolver.h"
+#include "net/interfaces/address_family.mojom.h"
#include "net/interfaces/host_resolver_service.mojom.h"
namespace mojo {
template <>
-struct EnumTraits<net::interfaces::AddressFamily, net::AddressFamily> {
- static net::interfaces::AddressFamily ToMojom(
- net::AddressFamily address_family);
- static bool FromMojom(net::interfaces::AddressFamily address_family,
- net::AddressFamily* out);
-};
-
-template <>
struct StructTraits<net::interfaces::HostResolverRequestInfoDataView,
std::unique_ptr<net::HostResolver::RequestInfo>> {
static base::StringPiece host(
diff --git a/chromium/net/dns/serial_worker_unittest.cc b/chromium/net/dns/serial_worker_unittest.cc
index d52c0fd4d67..fddb0cee717 100644
--- a/chromium/net/dns/serial_worker_unittest.cc
+++ b/chromium/net/dns/serial_worker_unittest.cc
@@ -70,7 +70,7 @@ class SerialWorkerTest : public testing::Test {
protected:
void BreakCallback(const std::string& breakpoint) {
breakpoint_ = breakpoint;
- base::RunLoop::QuitCurrentDeprecated();
+ run_loop_->Quit();
}
void BreakNow(const std::string& b) {
@@ -80,7 +80,11 @@ class SerialWorkerTest : public testing::Test {
}
void RunUntilBreak(const std::string& b) {
- base::RunLoop().Run();
+ base::RunLoop run_loop;
+ ASSERT_FALSE(run_loop_);
+ run_loop_ = &run_loop;
+ run_loop_->Run();
+ run_loop_ = nullptr;
ASSERT_EQ(breakpoint_, b);
}
@@ -140,6 +144,9 @@ class SerialWorkerTest : public testing::Test {
scoped_refptr<TestSerialWorker> worker_;
std::string breakpoint_;
+ base::RunLoop* run_loop_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(SerialWorkerTest);
};
TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
diff --git a/chromium/net/ftp/ftp_network_transaction.cc b/chromium/net/ftp/ftp_network_transaction.cc
index 566bbe4f5ad..e8ec85ab330 100644
--- a/chromium/net/ftp/ftp_network_transaction.cc
+++ b/chromium/net/ftp/ftp_network_transaction.cc
@@ -254,11 +254,14 @@ int FtpNetworkTransaction::Stop(int error) {
return OK;
}
-int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
- const CompletionCallback& callback,
- const NetLogWithSource& net_log) {
+int FtpNetworkTransaction::Start(
+ const FtpRequestInfo* request_info,
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
net_log_ = net_log;
request_ = request_info;
+ traffic_annotation_ = MutableNetworkTrafficAnnotationTag(traffic_annotation);
ctrl_response_buffer_ = std::make_unique<FtpCtrlResponseBuffer>(net_log_);
@@ -736,8 +739,9 @@ int FtpNetworkTransaction::DoCtrlReadComplete(int result) {
int FtpNetworkTransaction::DoCtrlWrite() {
next_state_ = STATE_CTRL_WRITE_COMPLETE;
- return ctrl_socket_->Write(
- write_buf_.get(), write_buf_->BytesRemaining(), io_callback_);
+ return ctrl_socket_->Write(write_buf_.get(), write_buf_->BytesRemaining(),
+ io_callback_,
+ NetworkTrafficAnnotationTag(traffic_annotation_));
}
int FtpNetworkTransaction::DoCtrlWriteComplete(int result) {
diff --git a/chromium/net/ftp/ftp_network_transaction.h b/chromium/net/ftp/ftp_network_transaction.h
index 9731ae7ad8a..a6769ce4bba 100644
--- a/chromium/net/ftp/ftp_network_transaction.h
+++ b/chromium/net/ftp/ftp_network_transaction.h
@@ -22,6 +22,7 @@
#include "net/ftp/ftp_response_info.h"
#include "net/ftp/ftp_transaction.h"
#include "net/log/net_log_with_source.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -39,7 +40,8 @@ class NET_EXPORT_PRIVATE FtpNetworkTransaction : public FtpTransaction {
// FtpTransaction methods:
int Start(const FtpRequestInfo* request_info,
const CompletionCallback& callback,
- const NetLogWithSource& net_log) override;
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int RestartWithAuth(const AuthCredentials& credentials,
const CompletionCallback& callback) override;
int Read(IOBuffer* buf,
@@ -204,6 +206,7 @@ class NET_EXPORT_PRIVATE FtpNetworkTransaction : public FtpTransaction {
NetLogWithSource net_log_;
const FtpRequestInfo* request_;
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
FtpResponseInfo response_;
// Cancels the outstanding request on destruction.
diff --git a/chromium/net/ftp/ftp_network_transaction_unittest.cc b/chromium/net/ftp/ftp_network_transaction_unittest.cc
index 9ca3f5e040a..b8bc320b737 100644
--- a/chromium/net/ftp/ftp_network_transaction_unittest.cc
+++ b/chromium/net/ftp/ftp_network_transaction_unittest.cc
@@ -16,6 +16,7 @@
#include "net/ftp/ftp_request_info.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -819,9 +820,10 @@ class FtpNetworkTransactionTest
mock_socket_factory_->AddSocketDataProvider(data_socket.get());
FtpRequestInfo request_info = GetRequestInfo(request);
EXPECT_EQ(LOAD_STATE_IDLE, transaction_->GetLoadState());
- ASSERT_EQ(ERR_IO_PENDING,
- transaction_->Start(&request_info, callback_.callback(),
- NetLogWithSource()));
+ ASSERT_EQ(
+ ERR_IO_PENDING,
+ transaction_->Start(&request_info, callback_.callback(),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS));
EXPECT_NE(LOAD_STATE_IDLE, transaction_->GetLoadState());
ASSERT_EQ(expected_result, callback_.WaitForResult());
if (expected_result == OK) {
@@ -870,9 +872,10 @@ TEST_P(FtpNetworkTransactionTest, FailedLookup) {
host_resolver_->set_rules(rules.get());
EXPECT_EQ(LOAD_STATE_IDLE, transaction_->GetLoadState());
- ASSERT_EQ(ERR_IO_PENDING,
- transaction_->Start(&request_info, callback_.callback(),
- NetLogWithSource()));
+ ASSERT_EQ(
+ ERR_IO_PENDING,
+ transaction_->Start(&request_info, callback_.callback(),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
EXPECT_EQ(LOAD_STATE_IDLE, transaction_->GetLoadState());
}
@@ -1141,9 +1144,10 @@ TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
// Start the transaction.
- ASSERT_EQ(ERR_IO_PENDING,
- transaction_->Start(&request_info, callback_.callback(),
- NetLogWithSource()));
+ ASSERT_EQ(
+ ERR_IO_PENDING,
+ transaction_->Start(&request_info, callback_.callback(),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_THAT(callback_.WaitForResult(), IsOk());
// The transaction fires the callback when we can start reading data. That
@@ -1336,9 +1340,10 @@ TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
- ASSERT_EQ(ERR_IO_PENDING,
- transaction_->Start(&request_info, callback_.callback(),
- NetLogWithSource()));
+ ASSERT_EQ(
+ ERR_IO_PENDING,
+ transaction_->Start(&request_info, callback_.callback(),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_THAT(callback_.WaitForResult(), IsError(ERR_FTP_FAILED));
MockRead ctrl_reads[] = {
@@ -1369,9 +1374,10 @@ TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
- ASSERT_EQ(ERR_IO_PENDING,
- transaction_->Start(&request_info, callback_.callback(),
- NetLogWithSource()));
+ ASSERT_EQ(
+ ERR_IO_PENDING,
+ transaction_->Start(&request_info, callback_.callback(),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_THAT(callback_.WaitForResult(), IsError(ERR_FTP_FAILED));
MockRead ctrl_reads[] = {
diff --git a/chromium/net/ftp/ftp_transaction.h b/chromium/net/ftp/ftp_transaction.h
index 1da3aeff205..f037b99b456 100644
--- a/chromium/net/ftp/ftp_transaction.h
+++ b/chromium/net/ftp/ftp_transaction.h
@@ -11,6 +11,7 @@
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"
#include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -42,7 +43,8 @@ class NET_EXPORT_PRIVATE FtpTransaction {
// Profiling information for the request is saved to |net_log| if non-NULL.
virtual int Start(const FtpRequestInfo* request_info,
const CompletionCallback& callback,
- const NetLogWithSource& net_log) = 0;
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
// Restarts the FTP transaction with authentication credentials.
virtual int RestartWithAuth(const AuthCredentials& credentials,
diff --git a/chromium/net/http/OWNERS b/chromium/net/http/OWNERS
index b15901669dd..b33c90cb2d0 100644
--- a/chromium/net/http/OWNERS
+++ b/chromium/net/http/OWNERS
@@ -1,2 +1,3 @@
+per-file http_cache_*=shivanisha@chromium.org
per-file transport_security_state_static.*=elawrence@chromium.org
-per-file transport_security_state_static.*=palmer@chromium.org \ No newline at end of file
+per-file transport_security_state_static.*=palmer@chromium.org
diff --git a/chromium/net/http/http_basic_state.cc b/chromium/net/http/http_basic_state.cc
index 0690de6b52f..cee4a407afa 100644
--- a/chromium/net/http/http_basic_state.cc
+++ b/chromium/net/http/http_basic_state.cc
@@ -23,12 +23,17 @@ HttpBasicState::HttpBasicState(std::unique_ptr<ClientSocketHandle> connection,
: read_buf_(new GrowableIOBuffer()),
connection_(std::move(connection)),
using_proxy_(using_proxy),
+ can_send_early_(false),
http_09_on_non_default_ports_enabled_(
- http_09_on_non_default_ports_enabled) {}
+ http_09_on_non_default_ports_enabled) {
+ CHECK(connection_) << "ClientSocketHandle passed to HttpBasicState must "
+ "not be NULL. See crbug.com/790776";
+}
HttpBasicState::~HttpBasicState() = default;
int HttpBasicState::Initialize(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) {
@@ -39,6 +44,7 @@ int HttpBasicState::Initialize(const HttpRequestInfo* request_info,
connection_.get(), request_info, read_buf_.get(), net_log));
parser_->set_http_09_on_non_default_ports_enabled(
http_09_on_non_default_ports_enabled_);
+ can_send_early_ = can_send_early;
return OK;
}
diff --git a/chromium/net/http/http_basic_state.h b/chromium/net/http/http_basic_state.h
index c89beab1274..5ce7945e3fa 100644
--- a/chromium/net/http/http_basic_state.h
+++ b/chromium/net/http/http_basic_state.h
@@ -35,6 +35,7 @@ class NET_EXPORT_PRIVATE HttpBasicState {
// Initialize() must be called before using any of the other methods.
int Initialize(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback);
@@ -43,6 +44,7 @@ class NET_EXPORT_PRIVATE HttpBasicState {
bool using_proxy() const { return using_proxy_; }
+ bool can_send_early() const { return can_send_early_; }
bool http_09_on_non_default_ports_enabled() const {
return http_09_on_non_default_ports_enabled_;
}
@@ -69,6 +71,8 @@ class NET_EXPORT_PRIVATE HttpBasicState {
const bool using_proxy_;
+ bool can_send_early_;
+
const bool http_09_on_non_default_ports_enabled_;
GURL url_;
diff --git a/chromium/net/http/http_basic_state_unittest.cc b/chromium/net/http/http_basic_state_unittest.cc
index c0d337ab3e1..0d6621cc41c 100644
--- a/chromium/net/http/http_basic_state_unittest.cc
+++ b/chromium/net/http/http_basic_state_unittest.cc
@@ -46,7 +46,7 @@ TEST(HttpBasicStateTest, ReleaseConnectionWorks) {
TEST(HttpBasicStateTest, InitializeWorks) {
HttpBasicState state(std::make_unique<ClientSocketHandle>(), false, false);
const HttpRequestInfo request_info;
- EXPECT_EQ(OK, state.Initialize(&request_info, LOW, NetLogWithSource(),
+ EXPECT_EQ(OK, state.Initialize(&request_info, false, LOW, NetLogWithSource(),
CompletionCallback()));
EXPECT_TRUE(state.parser());
}
@@ -54,7 +54,7 @@ TEST(HttpBasicStateTest, InitializeWorks) {
TEST(HttpBasicStateTest, DeleteParser) {
HttpBasicState state(std::make_unique<ClientSocketHandle>(), false, false);
const HttpRequestInfo request_info;
- state.Initialize(&request_info, LOW, NetLogWithSource(),
+ state.Initialize(&request_info, false, LOW, NetLogWithSource(),
CompletionCallback());
EXPECT_TRUE(state.parser());
state.DeleteParser();
@@ -68,7 +68,7 @@ TEST(HttpBasicStateTest, GenerateRequestLineNoProxy) {
HttpRequestInfo request_info;
request_info.url = GURL("http://www.example.com/path?foo=bar#hoge");
request_info.method = "PUT";
- state.Initialize(&request_info, LOW, NetLogWithSource(),
+ state.Initialize(&request_info, false, LOW, NetLogWithSource(),
CompletionCallback());
EXPECT_EQ("PUT /path?foo=bar HTTP/1.1\r\n", state.GenerateRequestLine());
}
@@ -80,7 +80,7 @@ TEST(HttpBasicStateTest, GenerateRequestLineWithProxy) {
HttpRequestInfo request_info;
request_info.url = GURL("http://www.example.com/path?foo=bar#hoge");
request_info.method = "PUT";
- state.Initialize(&request_info, LOW, NetLogWithSource(),
+ state.Initialize(&request_info, false, LOW, NetLogWithSource(),
CompletionCallback());
EXPECT_EQ("PUT http://www.example.com/path?foo=bar HTTP/1.1\r\n",
state.GenerateRequestLine());
diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc
index 2fc6c4e500e..aada0abbb97 100644
--- a/chromium/net/http/http_basic_stream.cc
+++ b/chromium/net/http/http_basic_stream.cc
@@ -11,6 +11,7 @@
#include "net/http/http_response_body_drainer.h"
#include "net/http/http_stream_parser.h"
#include "net/socket/client_socket_handle.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -24,10 +25,11 @@ HttpBasicStream::HttpBasicStream(std::unique_ptr<ClientSocketHandle> connection,
HttpBasicStream::~HttpBasicStream() = default;
int HttpBasicStream::InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) {
- state_.Initialize(request_info, priority, net_log, callback);
+ state_.Initialize(request_info, can_send_early, priority, net_log, callback);
return OK;
}
@@ -42,7 +44,9 @@ int HttpBasicStream::SendRequest(const HttpRequestHeaders& headers,
raw_headers.Add(it.name(), it.value());
request_headers_callback_.Run(std::move(raw_headers));
}
- return parser()->SendRequest(state_.GenerateRequestLine(), headers, response,
+ // TODO(crbug.com/656607): Add propoer annotation.
+ return parser()->SendRequest(state_.GenerateRequestLine(), headers,
+ NO_TRAFFIC_ANNOTATION_BUG_656607, response,
callback);
}
diff --git a/chromium/net/http/http_basic_stream.h b/chromium/net/http/http_basic_stream.h
index d1f54930a3d..15b74c60235 100644
--- a/chromium/net/http/http_basic_stream.h
+++ b/chromium/net/http/http_basic_stream.h
@@ -40,6 +40,7 @@ class NET_EXPORT_PRIVATE HttpBasicStream : public HttpStream {
// HttpStream methods:
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override;
diff --git a/chromium/net/http/http_cache.cc b/chromium/net/http/http_cache.cc
index 0653b25b36a..f731201556c 100644
--- a/chromium/net/http/http_cache.cc
+++ b/chromium/net/http/http_cache.cc
@@ -321,7 +321,7 @@ HttpCache::HttpCache(std::unique_ptr<HttpTransactionFactory> network_layer,
fail_conditionalization_for_test_(false),
mode_(NORMAL),
network_layer_(std::move(network_layer)),
- clock_(new base::DefaultClock()),
+ clock_(base::DefaultClock::GetInstance()),
weak_factory_(this) {
HttpNetworkSession* session = network_layer_->GetSession();
// Session may be NULL in unittests.
@@ -839,8 +839,10 @@ int HttpCache::DoneWithResponseHeaders(ActiveEntry* entry,
// through done_headers_queue for performance benefit. (Also, in case of
// writer transaction, the consumer sometimes depend on synchronous behaviour
// e.g. while computing raw headers size. (crbug.com/711766))
- if ((transaction->mode() & Transaction::WRITE) && !entry->writers) {
- AddTransactionToWriters(entry, transaction);
+ if ((transaction->mode() & Transaction::WRITE) && !entry->writers &&
+ entry->readers.empty()) {
+ AddTransactionToWriters(entry, transaction,
+ CanTransactionJoinExistingWriters(transaction));
ProcessQueuedTransactions(entry);
return OK;
}
@@ -1058,19 +1060,30 @@ void HttpCache::ProcessAddToEntryQueue(ActiveEntry* entry) {
transaction->io_callback().Run(OK);
}
-bool HttpCache::CanTransactionJoinExistingWriters(Transaction* transaction) {
- return (transaction->method() == "GET" && !transaction->partial());
+HttpCache::ParallelWritingPattern HttpCache::CanTransactionJoinExistingWriters(
+ Transaction* transaction) {
+ if (transaction->method() != "GET")
+ return PARALLEL_WRITING_NOT_JOIN_METHOD_NOT_GET;
+ if (transaction->partial())
+ return PARALLEL_WRITING_NOT_JOIN_RANGE;
+ if (transaction->mode() == Transaction::READ)
+ return PARALLEL_WRITING_NOT_JOIN_READ_ONLY;
+ return PARALLEL_WRITING_JOIN;
}
void HttpCache::ProcessDoneHeadersQueue(ActiveEntry* entry) {
- DCHECK(!entry->writers || entry->writers->CanAddWriters());
+ ParallelWritingPattern writers_pattern;
+ DCHECK(!entry->writers || entry->writers->CanAddWriters(&writers_pattern));
DCHECK(!entry->done_headers_queue.empty());
Transaction* transaction = entry->done_headers_queue.front();
+ ParallelWritingPattern parallel_writing_pattern =
+ CanTransactionJoinExistingWriters(transaction);
if (IsWritingInProgress(entry)) {
- if (!CanTransactionJoinExistingWriters(transaction) ||
- transaction->mode() == Transaction::READ) {
+ transaction->MaybeSetParallelWritingPatternForMetrics(
+ parallel_writing_pattern);
+ if (parallel_writing_pattern != PARALLEL_WRITING_JOIN) {
// TODO(shivanisha): Returning from here instead of checking the next
// transaction in the queue because the FIFO order is maintained
// throughout, until it becomes a reader or writer. May be at this point
@@ -1079,11 +1092,14 @@ void HttpCache::ProcessDoneHeadersQueue(ActiveEntry* entry) {
// transactions.
return;
}
- AddTransactionToWriters(entry, transaction);
+ AddTransactionToWriters(entry, transaction, parallel_writing_pattern);
} else { // no writing in progress
if (transaction->mode() & Transaction::WRITE) {
if (transaction->partial()) {
- AddTransactionToWriters(entry, transaction);
+ if (entry->readers.empty())
+ AddTransactionToWriters(entry, transaction, parallel_writing_pattern);
+ else
+ return;
} else {
// Add the transaction to readers since the response body should have
// already been written. (If it was the first writer about to start
@@ -1093,10 +1109,14 @@ void HttpCache::ProcessDoneHeadersQueue(ActiveEntry* entry) {
transaction->WriteModeTransactionAboutToBecomeReader();
auto return_val = entry->readers.insert(transaction);
DCHECK(return_val.second);
+ transaction->MaybeSetParallelWritingPatternForMetrics(
+ PARALLEL_WRITING_NONE_CACHE_READ);
}
} else { // mode READ
auto return_val = entry->readers.insert(transaction);
DCHECK(return_val.second);
+ transaction->MaybeSetParallelWritingPatternForMetrics(
+ PARALLEL_WRITING_NONE_CACHE_READ);
}
}
@@ -1108,21 +1128,26 @@ void HttpCache::ProcessDoneHeadersQueue(ActiveEntry* entry) {
transaction->io_callback().Run(OK);
}
-void HttpCache::AddTransactionToWriters(ActiveEntry* entry,
- Transaction* transaction) {
+void HttpCache::AddTransactionToWriters(
+ ActiveEntry* entry,
+ Transaction* transaction,
+ ParallelWritingPattern parallel_writing_pattern) {
if (!entry->writers) {
entry->writers = std::make_unique<Writers>(this, entry);
+ transaction->MaybeSetParallelWritingPatternForMetrics(
+ PARALLEL_WRITING_CREATE);
+ } else {
+ ParallelWritingPattern writers_pattern;
+ DCHECK(entry->writers->CanAddWriters(&writers_pattern));
+ DCHECK_EQ(PARALLEL_WRITING_JOIN, writers_pattern);
}
- DCHECK(entry->writers->CanAddWriters());
-
Writers::TransactionInfo info(transaction->partial(),
transaction->is_truncated(),
*(transaction->GetResponseInfo()));
- entry->writers->AddTransaction(
- transaction,
- !CanTransactionJoinExistingWriters(transaction) /* is_exclusive */,
- transaction->priority(), info);
+
+ entry->writers->AddTransaction(transaction, parallel_writing_pattern,
+ transaction->priority(), info);
}
bool HttpCache::CanTransactionWriteResponseHeaders(ActiveEntry* entry,
@@ -1255,10 +1280,19 @@ void HttpCache::OnProcessQueuedTransactions(ActiveEntry* entry) {
// If another transaction is writing the response, let validated transactions
// wait till the response is complete. If the response is not yet started, the
// done_headers_queue transaction should start writing it.
- if ((!entry->writers || entry->writers->CanAddWriters()) &&
- !entry->done_headers_queue.empty()) {
- ProcessDoneHeadersQueue(entry);
- return;
+ if (!entry->done_headers_queue.empty()) {
+ ParallelWritingPattern reason = PARALLEL_WRITING_NONE;
+ if (entry->writers && !entry->writers->CanAddWriters(&reason)) {
+ if (reason != PARALLEL_WRITING_NONE) {
+ for (auto* done_headers_transaction : entry->done_headers_queue) {
+ done_headers_transaction->MaybeSetParallelWritingPatternForMetrics(
+ reason);
+ }
+ }
+ } else {
+ ProcessDoneHeadersQueue(entry);
+ return;
+ }
}
if (!entry->add_to_entry_queue.empty())
diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h
index 975812e6506..0dabe1b3c81 100644
--- a/chromium/net/http/http_cache.h
+++ b/chromium/net/http/http_cache.h
@@ -109,6 +109,36 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
int max_bytes_;
};
+ // Whether a transaction can join parallel writing or not is a function of the
+ // transaction as well as the current writers (if present). This enum
+ // captures that decision as well as when a Writers object is first created.
+ // This is also used to log metrics so should be consistent with the values in
+ // enums.xml and should only be appended to.
+ enum ParallelWritingPattern {
+ // Used as the default value till the transaction is in initial headers
+ // phase.
+ PARALLEL_WRITING_NONE,
+ // The transaction creates a writers object. This is only logged for
+ // transactions that did not fail to join existing writers earlier.
+ PARALLEL_WRITING_CREATE,
+ // The transaction joins existing writers.
+ PARALLEL_WRITING_JOIN,
+ // The transaction cannot join existing writers since either itself or
+ // existing writers instance is serving a range request.
+ PARALLEL_WRITING_NOT_JOIN_RANGE,
+ // The transaction cannot join existing writers since either itself or
+ // existing writers instance is serving a non GET request.
+ PARALLEL_WRITING_NOT_JOIN_METHOD_NOT_GET,
+ // The transaction cannot join existing writers since it does not have cache
+ // write privileges.
+ PARALLEL_WRITING_NOT_JOIN_READ_ONLY,
+ // Writers does not exist and the transaction does not need to create one
+ // since it is going to read from the cache.
+ PARALLEL_WRITING_NONE_CACHE_READ,
+ // On adding a value here, make sure to add in enums.xml as well.
+ PARALLEL_WRITING_MAX
+ };
+
// The number of minutes after a resource is prefetched that it can be used
// again without validation.
static const int kPrefetchReuseMins = 5;
@@ -170,10 +200,8 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
Mode mode() { return mode_; }
// Get/Set the cache's clock. These are public only for testing.
- void SetClockForTesting(std::unique_ptr<base::Clock> clock) {
- clock_ = std::move(clock);
- }
- base::Clock* clock() const { return clock_.get(); }
+ void SetClockForTesting(base::Clock* clock) { clock_ = clock; }
+ base::Clock* clock() const { return clock_; }
// Close currently active sockets so that fresh page loads will not use any
// recycled connections. For sockets currently in use, they may not close
@@ -477,10 +505,11 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
// already.
void ProcessAddToEntryQueue(ActiveEntry* entry);
- // Returns true if the transaction can join other transactions for writing to
- // the cache simultaneously. It is only supported for GET requests and
- // non-range requests.
- bool CanTransactionJoinExistingWriters(Transaction* transaction);
+ // Returns if the transaction can join other transactions for writing to
+ // the cache simultaneously. It is only supported for non-Read only,
+ // GET requests which are not range requests.
+ ParallelWritingPattern CanTransactionJoinExistingWriters(
+ Transaction* transaction);
// Invoked when a transaction that has already completed the response headers
// phase can resume reading/writing the response body. It will invoke the IO
@@ -489,7 +518,9 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
void ProcessDoneHeadersQueue(ActiveEntry* entry);
// Adds a transaction to writers.
- void AddTransactionToWriters(ActiveEntry* entry, Transaction* transaction);
+ void AddTransactionToWriters(ActiveEntry* entry,
+ Transaction* transaction,
+ ParallelWritingPattern parallel_writing_pattern);
// Returns true if this transaction can write headers to the entry.
bool CanTransactionWriteResponseHeaders(ActiveEntry* entry,
@@ -566,7 +597,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
std::unique_ptr<PlaybackCacheMap> playback_cache_map_;
// A clock that can be swapped out for testing.
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index 7b491f92496..0dbacd48f37 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -19,8 +19,8 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h" // For HexEncode.
#include "base/strings/string_util.h" // For LowerCaseEqualsASCII.
@@ -179,6 +179,7 @@ HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache)
validation_cause_(VALIDATION_CAUSE_UNDEFINED),
cant_conditionalize_zero_freshness_from_memhint_(false),
recorded_histograms_(false),
+ parallel_writing_pattern_(PARALLEL_WRITING_NONE),
moved_network_transaction_to_writers_(false),
websocket_handshake_stream_base_create_helper_(NULL),
in_do_loop_(false),
@@ -558,10 +559,12 @@ void HttpCache::Transaction::PopulateNetErrorDetails(
void HttpCache::Transaction::SetPriority(RequestPriority priority) {
priority_ = priority;
- if (network_trans_) {
- DCHECK(!InWriters());
+
+ if (network_trans_)
network_trans_->SetPriority(priority_);
- } else if (InWriters()) {
+
+ if (InWriters()) {
+ DCHECK(!network_trans_ || partial_);
entry_->writers->UpdatePriority();
}
}
@@ -662,6 +665,15 @@ void HttpCache::Transaction::WriteModeTransactionAboutToBecomeReader() {
}
}
+void HttpCache::Transaction::MaybeSetParallelWritingPatternForMetrics(
+ HttpCache::ParallelWritingPattern pattern) {
+ // It's possible a transaction could not join existing writers and then
+ // creates a new writers. In that case the original reason for not being able
+ // to join writers should be logged.
+ if (parallel_writing_pattern_ == PARALLEL_WRITING_NONE)
+ parallel_writing_pattern_ = pattern;
+}
+
//-----------------------------------------------------------------------------
// A few common patterns: (Foo* means Foo -> FooComplete)
@@ -2982,11 +2994,14 @@ int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) {
io_buf_len_ = data->pickle()->size();
- // Summarize some info on cacheability in memory.
- cache_->GetCurrentBackend()->SetEntryInMemoryData(
- cache_key_, ComputeUnusablePerCachingHeaders()
- ? HINT_UNUSABLE_PER_CACHING_HEADERS
- : 0);
+ // Summarize some info on cacheability in memory. Don't do it if doomed
+ // since then |entry_| isn't definitive for |cache_key_|.
+ if (!entry_->doomed) {
+ cache_->GetCurrentBackend()->SetEntryInMemoryData(
+ cache_key_, ComputeUnusablePerCachingHeaders()
+ ? HINT_UNUSABLE_PER_CACHING_HEADERS
+ : 0);
+ }
return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(),
io_buf_len_, io_callback_, true);
@@ -3039,11 +3054,11 @@ int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
DLOG(ERROR) << "ReadData failed: " << result;
const int result_for_histogram = std::max(0, -result);
if (restart) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable",
- result_for_histogram);
+ base::UmaHistogramSparse("HttpCache.ReadErrorRestartable",
+ result_for_histogram);
} else {
- UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorNonRestartable",
- result_for_histogram);
+ base::UmaHistogramSparse("HttpCache.ReadErrorNonRestartable",
+ result_for_histogram);
}
// Avoid using this entry in the future.
@@ -3236,6 +3251,9 @@ void HttpCache::Transaction::RecordHistograms() {
DCHECK(!recorded_histograms_);
recorded_histograms_ = true;
+ UMA_HISTOGRAM_ENUMERATION("HttpCache.ParallelWritingPattern",
+ parallel_writing_pattern_, PARALLEL_WRITING_MAX);
+
if (CacheEntryStatus::ENTRY_UNDEFINED == cache_entry_status_)
return;
diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h
index 385ab2ae7e6..fe8ac18463f 100644
--- a/chromium/net/http/http_cache_transaction.h
+++ b/chromium/net/http/http_cache_transaction.h
@@ -190,6 +190,12 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction {
// entry has finished writing.
void WriteModeTransactionAboutToBecomeReader();
+ // Invoked when HttpCache decides whether this transaction should join
+ // parallel writing or create a new writers object. This is then used
+ // for logging metrics. Can be called repeatedly, but doesn't change once the
+ // value has been set to something other than PARALLEL_WRITING_NONE.
+ void MaybeSetParallelWritingPatternForMetrics(ParallelWritingPattern pattern);
+
private:
static const size_t kNumValidationHeaders = 2;
// Helper struct to pair a header name with its value, for
@@ -624,6 +630,7 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction {
base::TimeDelta stale_entry_age_;
bool cant_conditionalize_zero_freshness_from_memhint_;
bool recorded_histograms_;
+ ParallelWritingPattern parallel_writing_pattern_;
NetworkTransactionInfo network_transaction_info_;
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index 4a6fbe801a6..f834fa62a41 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -22,6 +22,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/test/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_request_args.h"
@@ -796,6 +797,8 @@ TEST(HttpCache, ReleaseBuffer) {
TEST(HttpCache, SimpleGETWithDiskFailures) {
MockHttpCache cache;
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
cache.disk_cache()->set_soft_failures(true);
@@ -812,6 +815,11 @@ TEST(HttpCache, SimpleGETWithDiskFailures) {
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(2, cache.disk_cache()->create_count());
+
+ // Since the transactions were in headers phase when failed,
+ // PARALLEL_WRITING_NONE should be logged.
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_NONE), 2);
}
// Tests that disk failures after the transaction has started don't cause the
@@ -988,6 +996,8 @@ TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
MockHttpCache cache;
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
// write to the cache
RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
@@ -1001,6 +1011,12 @@ TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_CREATE), 1);
+ histograms.ExpectBucketCount(
+ histogram_name,
+ static_cast<int>(HttpCache::PARALLEL_WRITING_NONE_CACHE_READ), 1);
}
TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
@@ -1721,6 +1737,8 @@ TEST(HttpCache, RangeGET_ParallelValidationNoMatchDoomEntry1) {
// Tests parallel validation on range requests with non-overlapping ranges.
TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
MockHttpCache cache;
ScopedMockTransaction transaction(kRangeGET_TransactionOK);
@@ -1815,6 +1833,56 @@ TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ histograms.ExpectBucketCount(
+ histogram_name,
+ static_cast<int>(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE), 1);
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_CREATE), 2);
+}
+
+// Tests that a request does not create Writers when readers is not empty.
+TEST(HttpCache, RangeGET_DoNotCreateWritersWhenReaderExists) {
+ MockHttpCache cache;
+
+ // Save a request in the cache so that the next request can become a
+ // reader.
+ MockTransaction transaction(kRangeGET_Transaction);
+ transaction.request_headers = EXTRA_HEADER;
+ AddMockTransaction(&transaction);
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Let this request be a reader since it doesn't need validation as per its
+ // load flag.
+ transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
+ MockHttpRequest request(transaction);
+ Context context;
+ context.result = cache.CreateTransaction(&context.trans);
+ ASSERT_THAT(context.result, IsOk());
+ context.result = context.trans->Start(&request, context.callback.callback(),
+ NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, cache.GetCountReaders(transaction.url));
+ RemoveMockTransaction(&transaction);
+
+ // A range request should now "not" create Writers while readers is still
+ // non-empty.
+ MockTransaction range_transaction(kRangeGET_Transaction);
+ range_transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
+ AddMockTransaction(&range_transaction);
+ MockHttpRequest range_request(range_transaction);
+ Context range_context;
+ range_context.result = cache.CreateTransaction(&range_context.trans);
+ ASSERT_THAT(range_context.result, IsOk());
+ range_context.result = range_context.trans->Start(
+ &range_request, range_context.callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, cache.GetCountReaders(transaction.url));
+ EXPECT_FALSE(cache.IsWriterPresent(transaction.url));
+ EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(transaction.url));
+
+ RemoveMockTransaction(&range_transaction);
}
// Tests parallel validation on range requests can be successfully restarted
@@ -2795,6 +2863,8 @@ TEST(HttpCache, SimpleGET_ParallelWritingCacheWriteFailed) {
// like the code should disallow two POSTs without LOAD_ONLY_FROM_CACHE with the
// same upload data identifier to map to the same entry.
TEST(HttpCache, SimplePOST_ParallelWritingDisallowed) {
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
MockHttpCache cache;
MockTransaction transaction(kSimplePOST_Transaction);
@@ -2851,11 +2921,19 @@ TEST(HttpCache, SimplePOST_ParallelWritingDisallowed) {
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ histograms.ExpectBucketCount(
+ histogram_name,
+ static_cast<int>(HttpCache::PARALLEL_WRITING_NOT_JOIN_METHOD_NOT_GET), 1);
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_CREATE), 1);
}
// Tests the case when parallel writing succeeds. Tests both idle and waiting
// transactions.
TEST(HttpCache, SimpleGET_ParallelWritingSuccess) {
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
MockHttpCache cache;
MockHttpRequest request(kSimpleGET_Transaction);
@@ -2930,6 +3008,15 @@ TEST(HttpCache, SimpleGET_ParallelWritingSuccess) {
auto& c = context_list[i];
ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
}
+
+ // Verify metrics.
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_CREATE), 1);
+ histograms.ExpectBucketCount(
+ histogram_name, static_cast<int>(HttpCache::PARALLEL_WRITING_JOIN), 2);
+ histograms.ExpectBucketCount(
+ histogram_name,
+ static_cast<int>(HttpCache::PARALLEL_WRITING_NOT_JOIN_READ_ONLY), 1);
}
// Tests that network transaction's info is saved correctly when a writer
@@ -3428,6 +3515,77 @@ TEST(HttpCache, SimpleGET_DoomWithPending) {
}
}
+TEST(HttpCache, DoomDoesNotSetHints) {
+ // Test that a doomed writer doesn't set in-memory index hints.
+ MockHttpCache cache;
+ cache.disk_cache()->set_support_in_memory_entry_data(true);
+
+ // Request 1 is a normal one to a no-cache/no-etag resource, to potentially
+ // set a "this is unvalidatable" hint in the cache. We also need it to
+ // actually write out to the doomed entry after request 2 does its thing,
+ // so its transaction is paused.
+ MockTransaction no_cache_transaction(kSimpleGET_Transaction);
+ no_cache_transaction.response_headers = "Cache-Control: no-cache\n";
+ AddMockTransaction(&no_cache_transaction);
+ MockHttpRequest request1(no_cache_transaction);
+
+ Context c1;
+ c1.result = cache.CreateTransaction(&c1.trans);
+ ASSERT_THAT(c1.result, IsOk());
+ c1.trans->SetBeforeNetworkStartCallback(
+ base::Bind([](bool* defer) { *defer = true; }));
+ c1.result =
+ c1.trans->Start(&request1, c1.callback.callback(), NetLogWithSource());
+ ASSERT_THAT(c1.result, IsError(ERR_IO_PENDING));
+
+ // It starts, copies over headers info, but doesn't get to proceed.
+ base::RunLoop().RunUntilIdle();
+ RemoveMockTransaction(&no_cache_transaction);
+
+ // Request 2 sets LOAD_BYPASS_CACHE to force the first one to be doomed ---
+ // it'll want to be a writer.
+ MockHttpRequest request2(kSimpleGET_Transaction);
+ request2.load_flags = LOAD_BYPASS_CACHE;
+
+ Context c2;
+ c2.result = cache.CreateTransaction(&c2.trans);
+ ASSERT_THAT(c2.result, IsOk());
+ c2.result =
+ c2.trans->Start(&request2, c2.callback.callback(), NetLogWithSource());
+ ASSERT_THAT(c2.result, IsError(ERR_IO_PENDING));
+
+ // Run Request2, then let the first one wrap up.
+ base::RunLoop().RunUntilIdle();
+ c2.callback.WaitForResult();
+ ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
+
+ c1.trans->ResumeNetworkStart();
+ c1.callback.WaitForResult();
+ ReadAndVerifyTransaction(c1.trans.get(), no_cache_transaction);
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, cache.disk_cache()->create_count());
+
+ // Request 3 tries to read from cache, and it should successfully do so. It's
+ // run after the previous two transactions finish so it doesn't try to
+ // cooperate with them, and is entirely driven by the state of the cache.
+ MockHttpRequest request3(kSimpleGET_Transaction);
+ Context context3;
+ context3.result = cache.CreateTransaction(&context3.trans);
+ ASSERT_THAT(context3.result, IsOk());
+ context3.result = context3.trans->Start(
+ &request3, context3.callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(context3.result, IsError(ERR_IO_PENDING));
+ context3.result = context3.callback.WaitForResult();
+ ReadAndVerifyTransaction(context3.trans.get(), kSimpleGET_Transaction);
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, cache.disk_cache()->create_count());
+}
+
// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
// We may attempt to delete an entry synchronously with the act of adding a new
// transaction to said entry.
@@ -4936,6 +5094,8 @@ TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
MockHttpCache cache;
+ base::HistogramTester histograms;
+ const std::string histogram_name = "HttpCache.ParallelWritingPattern";
// Test that we hit the cache for POST requests.
@@ -4965,6 +5125,10 @@ TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ histograms.ExpectBucketCount(
+ histogram_name,
+ static_cast<int>(HttpCache::PARALLEL_WRITING_NONE_CACHE_READ), 1);
}
// Test that we don't hit the cache for POST requests if there is a byte range.
@@ -8957,9 +9121,9 @@ TEST(HttpCache, SkipVaryCheckStar) {
// transactions unless LOAD_SKIP_CACHE_VALIDATION is set.
TEST(HttpCache, ValidLoadOnlyFromCache) {
MockHttpCache cache;
- base::SimpleTestClock* clock = new base::SimpleTestClock();
- cache.http_cache()->SetClockForTesting(base::WrapUnique(clock));
- cache.network_layer()->SetClock(clock);
+ base::SimpleTestClock clock;
+ cache.http_cache()->SetClockForTesting(&clock);
+ cache.network_layer()->SetClock(&clock);
// Write a resource that will expire in 100 seconds.
ScopedMockTransaction transaction(kSimpleGET_Transaction);
@@ -8967,7 +9131,7 @@ TEST(HttpCache, ValidLoadOnlyFromCache) {
RunTransactionTest(cache.http_cache(), transaction);
// Move forward in time such that the cached response is no longer valid.
- clock->Advance(base::TimeDelta::FromSeconds(101));
+ clock.Advance(base::TimeDelta::FromSeconds(101));
// Skipping cache validation should still return a response.
transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
@@ -9844,9 +10008,8 @@ class HttpCachePrefetchValidationTest : public ::testing::Test {
HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
- clock_ = new base::SimpleTestClock();
- cache_.http_cache()->SetClockForTesting(base::WrapUnique(clock_));
- cache_.network_layer()->SetClock(clock_);
+ cache_.http_cache()->SetClockForTesting(&clock_);
+ cache_.network_layer()->SetClock(&clock_);
transaction_.response_headers = "Cache-Control: max-age=100\n";
}
@@ -9859,7 +10022,7 @@ class HttpCachePrefetchValidationTest : public ::testing::Test {
}
void AdvanceTime(int seconds) {
- clock_->Advance(base::TimeDelta::FromSeconds(seconds));
+ clock_.Advance(base::TimeDelta::FromSeconds(seconds));
}
int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
@@ -9874,7 +10037,7 @@ class HttpCachePrefetchValidationTest : public ::testing::Test {
MockHttpCache cache_;
ScopedMockTransaction transaction_;
std::string response_headers_;
- base::SimpleTestClock* clock_;
+ base::SimpleTestClock clock_;
};
TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
diff --git a/chromium/net/http/http_cache_writers.cc b/chromium/net/http/http_cache_writers.cc
index 0fcf1c6af52..31b4f15b116 100644
--- a/chromium/net/http/http_cache_writers.cc
+++ b/chromium/net/http/http_cache_writers.cc
@@ -103,12 +103,14 @@ bool HttpCache::Writers::StopCaching(bool keep_entry) {
return true;
}
-void HttpCache::Writers::AddTransaction(Transaction* transaction,
- bool is_exclusive,
- RequestPriority priority,
- const TransactionInfo& info) {
+void HttpCache::Writers::AddTransaction(
+ Transaction* transaction,
+ ParallelWritingPattern initial_writing_pattern,
+ RequestPriority priority,
+ const TransactionInfo& info) {
DCHECK(transaction);
- DCHECK(CanAddWriters());
+ ParallelWritingPattern writers_pattern;
+ DCHECK(CanAddWriters(&writers_pattern));
DCHECK_EQ(0u, all_writers_.count(transaction));
@@ -117,6 +119,15 @@ void HttpCache::Writers::AddTransaction(Transaction* transaction,
should_keep_entry_ =
IsValidResponseForWriter(info.partial != nullptr, &(info.response_info));
+ if (all_writers_.empty()) {
+ DCHECK_EQ(PARALLEL_WRITING_NONE, parallel_writing_pattern_);
+ parallel_writing_pattern_ = initial_writing_pattern;
+ if (parallel_writing_pattern_ != PARALLEL_WRITING_JOIN)
+ is_exclusive_ = true;
+ } else {
+ DCHECK_EQ(PARALLEL_WRITING_JOIN, parallel_writing_pattern_);
+ }
+
if (info.partial && !info.truncated) {
DCHECK(!partial_do_not_truncate_);
partial_do_not_truncate_ = true;
@@ -125,11 +136,6 @@ void HttpCache::Writers::AddTransaction(Transaction* transaction,
std::pair<Transaction*, TransactionInfo> writer(transaction, info);
all_writers_.insert(writer);
- if (is_exclusive) {
- DCHECK_EQ(1u, all_writers_.size());
- is_exclusive_ = true;
- }
-
priority_ = std::max(priority, priority_);
if (network_transaction_) {
network_transaction_->SetPriority(priority_);
@@ -227,7 +233,8 @@ bool HttpCache::Writers::ContainsOnlyIdleWriters() const {
return waiting_for_read_.empty() && !active_transaction_;
}
-bool HttpCache::Writers::CanAddWriters() {
+bool HttpCache::Writers::CanAddWriters(ParallelWritingPattern* reason) {
+ *reason = PARALLEL_WRITING_NONE;
// While cleaning up writers (truncation) we should delay adding new writers.
// The caller can try again later.
if (next_state_ == State::ASYNC_OP_COMPLETE_PRE_TRUNCATE ||
@@ -236,6 +243,7 @@ bool HttpCache::Writers::CanAddWriters() {
return false;
}
+ *reason = parallel_writing_pattern_;
if (all_writers_.empty())
return true;
diff --git a/chromium/net/http/http_cache_writers.h b/chromium/net/http/http_cache_writers.h
index 9fbd265c193..2b45c1e0b85 100644
--- a/chromium/net/http/http_cache_writers.h
+++ b/chromium/net/http/http_cache_writers.h
@@ -78,15 +78,16 @@ class NET_EXPORT_PRIVATE HttpCache::Writers {
// Adds an HttpCache::Transaction to Writers.
// Should only be invoked if CanAddWriters() returns true.
- // If |is_exclusive| is true, it makes writing an exclusive operation
- // implying that Writers can contain at most one transaction till the
- // completion of the response body. It is illegal to invoke with is_exclusive
- // as true if there is already a transaction present.
+ // |parallel_writing_pattern| governs whether writing is an exclusive
+ // operation implying that Writers can contain at most one transaction till
+ // the completion of the response body. It is illegal to invoke with
+ // |parallel_writing_pattern| as PARALLEL_WRITING_NOT_JOIN* if there is
+ // already a transaction present.
// |transaction| can be destroyed at any point and it should invoke
// HttpCache::DoneWithEntry() during its destruction. This will also ensure
// any pointers in |info| are not accessed after the transaction is destroyed.
void AddTransaction(Transaction* transaction,
- bool is_exclusive,
+ ParallelWritingPattern initial_writing_pattern,
RequestPriority priority,
const TransactionInfo& info);
@@ -108,8 +109,9 @@ class NET_EXPORT_PRIVATE HttpCache::Writers {
return all_writers_.count(const_cast<Transaction*>(transaction)) > 0;
}
- // Returns true if more writers can be added for shared writing.
- bool CanAddWriters();
+ // Returns true if more writers can be added for shared writing. Also fills in
+ // the |reason| for why a transaction cannot be added.
+ bool CanAddWriters(ParallelWritingPattern* reason);
// Returns if only one transaction can be a member of writers.
bool IsExclusive() const { return is_exclusive_; }
@@ -274,6 +276,7 @@ class NET_EXPORT_PRIVATE HttpCache::Writers {
// True if multiple transactions are not allowed e.g. for partial requests.
bool is_exclusive_ = false;
+ ParallelWritingPattern parallel_writing_pattern_ = PARALLEL_WRITING_NONE;
// Current priority of the request. It is always the maximum of all the writer
// transactions.
diff --git a/chromium/net/http/http_cache_writers_unittest.cc b/chromium/net/http/http_cache_writers_unittest.cc
index cb05ec48c86..4d65c6294c9 100644
--- a/chromium/net/http/http_cache_writers_unittest.cc
+++ b/chromium/net/http/http_cache_writers_unittest.cc
@@ -90,7 +90,9 @@ class WritersTest : public testing::Test {
return transaction;
}
- void CreateWritersAddTransaction(bool is_exclusive = false) {
+ void CreateWritersAddTransaction(
+ HttpCache::ParallelWritingPattern parallel_writing_pattern_ =
+ HttpCache::PARALLEL_WRITING_JOIN) {
TestCompletionCallback callback;
// Create and Start a mock network transaction.
@@ -113,7 +115,7 @@ class WritersTest : public testing::Test {
*(transaction->GetResponseInfo()));
info.response_info = response_info_;
- writers_->AddTransaction(transaction.get(), is_exclusive,
+ writers_->AddTransaction(transaction.get(), parallel_writing_pattern_,
transaction->priority(), info);
writers_->SetNetworkTransaction(transaction.get(),
std::move(network_transaction));
@@ -121,9 +123,11 @@ class WritersTest : public testing::Test {
transactions_.push_back(std::move(transaction));
}
- void CreateWritersAddTransactionPriority(net::RequestPriority priority,
- bool is_exclusive = false) {
- CreateWritersAddTransaction(is_exclusive);
+ void CreateWritersAddTransactionPriority(
+ net::RequestPriority priority,
+ HttpCache::ParallelWritingPattern parallel_writing_pattern_ =
+ HttpCache::PARALLEL_WRITING_JOIN) {
+ CreateWritersAddTransaction(parallel_writing_pattern_);
TestHttpCacheTransaction* transaction = transactions_.begin()->get();
transaction->SetPriority(priority);
}
@@ -140,8 +144,9 @@ class WritersTest : public testing::Test {
transaction->is_truncated(),
*(transaction->GetResponseInfo()));
info.response_info = response_info_;
- writers_->AddTransaction(transaction.get(), false, transaction->priority(),
- info);
+ writers_->AddTransaction(transaction.get(),
+ HttpCache::PARALLEL_WRITING_JOIN,
+ transaction->priority(), info);
transactions_.push_back(std::move(transaction));
}
@@ -322,7 +327,7 @@ class WritersTest : public testing::Test {
EXPECT_TRUE(writers_->IsEmpty());
// Cannot add more writers while we are in truncation pending state.
- EXPECT_FALSE(writers_->CanAddWriters());
+ EXPECT_FALSE(CanAddWriters());
// Complete the Read and the entry should be truncated.
base::RunLoop().RunUntilIdle();
@@ -341,7 +346,7 @@ class WritersTest : public testing::Test {
writers_->StopCaching(false /* keep_entry */);
// Cannot add more writers while we are in network read only state.
- EXPECT_FALSE(writers_->CanAddWriters());
+ EXPECT_FALSE(CanAddWriters());
// Complete the Read and the entry should be truncated.
base::RunLoop().RunUntilIdle();
@@ -438,6 +443,11 @@ class WritersTest : public testing::Test {
EXPECT_FALSE(ShouldKeepEntry());
}
+ bool CanAddWriters() {
+ HttpCache::ParallelWritingPattern parallel_writing_pattern_;
+ return writers_->CanAddWriters(&parallel_writing_pattern_);
+ }
+
MockHttpCache cache_;
std::unique_ptr<HttpCache::Writers> writers_;
disk_cache::Entry* disk_entry_;
@@ -476,10 +486,10 @@ TEST_F(WritersTest, AddManyTransactions) {
// Tests that CanAddWriters should return false if it is writing exclusively.
TEST_F(WritersTest, AddTransactionsExclusive) {
- CreateWritersAddTransaction(true /* is_exclusive */);
+ CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_FALSE(writers_->CanAddWriters());
+ EXPECT_FALSE(CanAddWriters());
}
// Tests StopCaching should not stop caching if there are multiple writers.
@@ -487,11 +497,11 @@ TEST_F(WritersTest, StopCachingMultipleWriters) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
EXPECT_FALSE(StopCaching());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
}
// Tests StopCaching should stop caching if there is a single writer.
@@ -500,7 +510,7 @@ TEST_F(WritersTest, StopCaching) {
EXPECT_FALSE(writers_->IsEmpty());
EXPECT_TRUE(StopCaching());
- EXPECT_FALSE(writers_->CanAddWriters());
+ EXPECT_FALSE(CanAddWriters());
}
// Tests StopCaching should be successful when invoked mid-read.
@@ -545,7 +555,7 @@ TEST_F(WritersTest, ReadMultiple) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -557,7 +567,7 @@ TEST_F(WritersTest, ReadMultipleDifferentBufferSizes) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
std::vector<int> buffer_lengths{20, 10};
@@ -570,7 +580,7 @@ TEST_F(WritersTest, ReadMultipleDifferentBufferSizes1) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
std::vector<int> buffer_lengths{10, 20};
@@ -583,7 +593,7 @@ TEST_F(WritersTest, ReadMultipleDeleteActiveTransaction) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -596,7 +606,7 @@ TEST_F(WritersTest, ReadMultipleDeleteActiveTransaction) {
TEST_F(WritersTest, MidReadDeleteActiveTransaction) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
MidReadDeleteActiveTransaction();
}
@@ -606,7 +616,7 @@ TEST_F(WritersTest, ReadMultipleDeleteWaitingTransaction) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -620,7 +630,7 @@ TEST_F(WritersTest, ReadMultipleDeleteIdleTransaction) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -633,7 +643,7 @@ TEST_F(WritersTest, ReadMultipleCacheWriteFailed) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -658,7 +668,7 @@ TEST_F(WritersTest, ReadMultipleNetworkReadFailed) {
CreateWritersAddTransaction();
EXPECT_FALSE(writers_->IsEmpty());
- EXPECT_TRUE(writers_->CanAddWriters());
+ EXPECT_TRUE(CanAddWriters());
AddTransactionToExistingWriters();
AddTransactionToExistingWriters();
@@ -691,7 +701,7 @@ TEST_F(WritersTest, TruncateEntryFail) {
// Set network read only.
TEST_F(WritersTest, StopCachingWithKeepEntry) {
- CreateWritersAddTransaction(true /* is exclusive */);
+ CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
EXPECT_FALSE(writers_->network_read_only());
writers_->StopCaching(true /* keep_entry */);
@@ -700,7 +710,7 @@ TEST_F(WritersTest, StopCachingWithKeepEntry) {
}
TEST_F(WritersTest, StopCachingWithNotKeepEntry) {
- CreateWritersAddTransaction(true /* is exclusive */);
+ CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
EXPECT_FALSE(writers_->network_read_only());
writers_->StopCaching(false /* keep_entry */);
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index bcced4e441f..4b1fe0d8ebe 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -5,7 +5,7 @@
#include "net/http/http_network_session.h"
#include <inttypes.h>
-#include <memory>
+
#include <utility>
#include "base/atomic_sequence_num.h"
@@ -125,14 +125,20 @@ HttpNetworkSession::Params::Params()
quic_migrate_sessions_early(false),
quic_migrate_sessions_on_network_change_v2(false),
quic_migrate_sessions_early_v2(false),
+ quic_max_time_on_non_default_network(
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs)),
+ quic_max_migrations_to_non_default_network_on_path_degrading(
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading),
quic_allow_server_migration(false),
quic_allow_remote_alt_svc(false),
quic_disable_bidirectional_streams(false),
quic_force_hol_blocking(false),
quic_race_cert_verification(false),
quic_estimate_initial_rtt(false),
+ quic_headers_include_h2_stream_dependency(false),
enable_token_binding(false),
- http_09_on_non_default_ports_enabled(false) {
+ http_09_on_non_default_ports_enabled(false),
+ disable_idle_sockets_close_on_memory_pressure(false) {
quic_supported_versions.push_back(QUIC_VERSION_39);
}
@@ -206,9 +212,12 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
params.quic_migrate_sessions_early,
params.quic_migrate_sessions_on_network_change_v2,
params.quic_migrate_sessions_early_v2,
+ params.quic_max_time_on_non_default_network,
+ params.quic_max_migrations_to_non_default_network_on_path_degrading,
params.quic_allow_server_migration,
params.quic_race_cert_verification,
params.quic_estimate_initial_rtt,
+ params.quic_headers_include_h2_stream_dependency,
params.quic_connection_options,
params.quic_client_connection_options,
params.enable_token_binding),
@@ -223,9 +232,8 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
AddDefaultHttp2Settings(params.http2_settings),
params.time_func,
context.proxy_delegate),
- http_stream_factory_(new HttpStreamFactoryImpl(this, false)),
- http_stream_factory_for_websocket_(new HttpStreamFactoryImpl(this, true)),
- network_stream_throttler_(new NetworkThrottleManagerImpl()),
+ http_stream_factory_(std::make_unique<HttpStreamFactoryImpl>(this)),
+ network_stream_throttler_(std::make_unique<NetworkThrottleManagerImpl>()),
params_(params),
context_(context) {
DCHECK(proxy_service_);
@@ -248,14 +256,20 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
http_server_properties_->SetMaxServerConfigsStoredInProperties(
params.quic_max_server_configs_stored_in_properties);
- memory_pressure_listener_.reset(new base::MemoryPressureListener(base::Bind(
- &HttpNetworkSession::OnMemoryPressure, base::Unretained(this))));
+ if (!params_.disable_idle_sockets_close_on_memory_pressure) {
+ memory_pressure_listener_.reset(
+ new base::MemoryPressureListener(base::BindRepeating(
+ &HttpNetworkSession::OnMemoryPressure, base::Unretained(this))));
+ }
+
base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
}
HttpNetworkSession::~HttpNetworkSession() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
response_drainers_.clear();
+ // TODO(bnc): CloseAllSessions() is also called in SpdySessionPool destructor,
+ // one of the two calls should be removed.
spdy_session_pool_.CloseAllSessions();
base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
}
@@ -359,6 +373,11 @@ std::unique_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const {
params_.quic_migrate_sessions_on_network_change_v2);
dict->SetBoolean("migrate_sessions_early_v2",
params_.quic_migrate_sessions_early_v2);
+ dict->SetInteger("max_time_on_non_default_network_seconds",
+ params_.quic_max_time_on_non_default_network.InSeconds());
+ dict->SetInteger(
+ "max_num_migrations_to_non_default_network_on_path_degrading",
+ params_.quic_max_migrations_to_non_default_network_on_path_degrading);
dict->SetBoolean("allow_server_migration",
params_.quic_allow_server_migration);
dict->SetBoolean("estimate_initial_rtt", params_.quic_estimate_initial_rtt);
@@ -480,10 +499,13 @@ ClientSocketPoolManager* HttpNetworkSession::GetSocketPoolManager(
void HttpNetworkSession::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
+ DCHECK(!params_.disable_idle_sockets_close_on_memory_pressure);
+
switch (memory_pressure_level) {
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
- case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
break;
+
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
CloseIdleConnections();
break;
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index 59d19493752..2a20aad3a37 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -175,6 +175,13 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
// If true, connection migration v2 may be used to migrate active QUIC
// sessions to alternative network if current network connectivity is poor.
bool quic_migrate_sessions_early_v2;
+ // Maximum time the session could be on the non-default network before
+ // migrates back to default network. Defaults to
+ // kMaxTimeOnNonDefaultNetwork.
+ base::TimeDelta quic_max_time_on_non_default_network;
+ // Maximum number of migrations to the non-default network on path
+ // degrading per network for each session.
+ int quic_max_migrations_to_non_default_network_on_path_degrading;
// If true, allows migration of QUIC connections to a server-specified
// alternate server address.
bool quic_allow_server_migration;
@@ -189,6 +196,9 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
bool quic_race_cert_verification;
// If true, estimate the initial RTT for QUIC connections based on network.
bool quic_estimate_initial_rtt;
+ // If true, client headers will include HTTP/2 stream dependency info
+ // derived from the request priority.
+ bool quic_headers_include_h2_stream_dependency;
// If non-empty, QUIC will only be spoken to hosts in this list.
base::flat_set<std::string> quic_host_whitelist;
@@ -198,6 +208,9 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
// Enable HTTP/0.9 for HTTP/HTTPS on ports other than the default one for
// each protocol.
bool http_09_on_non_default_ports_enabled;
+
+ // If true, idle sockets won't be closed when memory pressure happens.
+ bool disable_idle_sockets_close_on_memory_pressure;
};
// Structure with pointers to the dependencies of the HttpNetworkSession.
@@ -277,9 +290,6 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
HttpStreamFactory* http_stream_factory() {
return http_stream_factory_.get();
}
- HttpStreamFactory* http_stream_factory_for_websocket() {
- return http_stream_factory_for_websocket_.get();
- }
NetworkThrottleManager* throttler() {
return network_stream_throttler_.get();
}
@@ -358,7 +368,6 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
QuicStreamFactory quic_stream_factory_;
SpdySessionPool spdy_session_pool_;
std::unique_ptr<HttpStreamFactory> http_stream_factory_;
- std::unique_ptr<HttpStreamFactory> http_stream_factory_for_websocket_;
std::map<HttpResponseBodyDrainer*, std::unique_ptr<HttpResponseBodyDrainer>>
response_drainers_;
std::unique_ptr<NetworkThrottleManager> network_stream_throttler_;
diff --git a/chromium/net/http/http_network_session_peer.cc b/chromium/net/http/http_network_session_peer.cc
index 9b33d98bac0..e9c629e8a92 100644
--- a/chromium/net/http/http_network_session_peer.cc
+++ b/chromium/net/http/http_network_session_peer.cc
@@ -29,11 +29,6 @@ void HttpNetworkSessionPeer::SetHttpStreamFactory(
session_->http_stream_factory_.swap(http_stream_factory);
}
-void HttpNetworkSessionPeer::SetHttpStreamFactoryForWebSocket(
- std::unique_ptr<HttpStreamFactory> http_stream_factory) {
- session_->http_stream_factory_for_websocket_.swap(http_stream_factory);
-}
-
void HttpNetworkSessionPeer::SetNetworkStreamThrottler(
std::unique_ptr<NetworkThrottleManager> network_throttle_manager) {
session_->network_stream_throttler_.swap(network_throttle_manager);
diff --git a/chromium/net/http/http_network_session_peer.h b/chromium/net/http/http_network_session_peer.h
index dae4f916df6..bb0d0c7dce3 100644
--- a/chromium/net/http/http_network_session_peer.h
+++ b/chromium/net/http/http_network_session_peer.h
@@ -29,8 +29,6 @@ class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
void SetHttpStreamFactory(
std::unique_ptr<HttpStreamFactory> http_stream_factory);
- void SetHttpStreamFactoryForWebSocket(
- std::unique_ptr<HttpStreamFactory> http_stream_factory_for_websocket);
void SetNetworkStreamThrottler(
std::unique_ptr<NetworkThrottleManager> network_throttle_manager);
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index a810d203821..44e52f436d4 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -86,6 +86,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
request_(NULL),
priority_(priority),
headers_valid_(false),
+ can_send_early_data_(false),
request_headers_(),
read_buf_len_(0),
total_received_bytes_(0),
@@ -133,6 +134,10 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
proxy_ssl_config_.rev_checking_enabled = false;
}
+ if (request_info->method != "POST") {
+ can_send_early_data_ = true;
+ }
+
if (request_->load_flags & LOAD_PREFETCH)
response_.unused_since_prefetch = true;
@@ -858,12 +863,10 @@ int HttpNetworkTransaction::DoCreateStream() {
DCHECK(!enable_alternative_services_);
if (ForWebSocketHandshake()) {
stream_request_ =
- session_->http_stream_factory_for_websocket()
- ->RequestWebSocketHandshakeStream(
- *request_, priority_, server_ssl_config_, proxy_ssl_config_,
- this, websocket_handshake_stream_base_create_helper_,
- enable_ip_based_pooling_, enable_alternative_services_,
- net_log_);
+ session_->http_stream_factory()->RequestWebSocketHandshakeStream(
+ *request_, priority_, server_ssl_config_, proxy_ssl_config_, this,
+ websocket_handshake_stream_base_create_helper_,
+ enable_ip_based_pooling_, enable_alternative_services_, net_log_);
} else {
stream_request_ = session_->http_stream_factory()->RequestStream(
*request_, priority_, server_ssl_config_, proxy_ssl_config_, this,
@@ -910,7 +913,8 @@ int HttpNetworkTransaction::DoInitStream() {
stream_->GetRemoteEndpoint(&remote_endpoint_);
- return stream_->InitializeStream(request_, priority_, net_log_, io_callback_);
+ return stream_->InitializeStream(request_, can_send_early_data_, priority_,
+ net_log_, io_callback_);
}
int HttpNetworkTransaction::DoInitStreamComplete(int result) {
@@ -1048,7 +1052,7 @@ int HttpNetworkTransaction::BuildRequestHeaders(
} else {
request_headers_.SetHeader(
HttpRequestHeaders::kContentLength,
- base::Uint64ToString(request_->upload_data_stream->size()));
+ base::NumberToString(request_->upload_data_stream->size()));
}
} else if (request_->method == "POST" || request_->method == "PUT") {
// An empty POST/PUT request still needs a content length. As for HEAD,
@@ -1562,6 +1566,8 @@ int HttpNetworkTransaction::HandleIOError(int error) {
break;
case ERR_SPDY_PING_FAILED:
case ERR_SPDY_SERVER_REFUSED_STREAM:
+ case ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE:
+ case ERR_SPDY_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER:
case ERR_QUIC_HANDSHAKE_FAILED:
if (HasExceededMaxRetries())
break;
diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h
index 866b5a28170..554a7258043 100644
--- a/chromium/net/http/http_network_transaction.h
+++ b/chromium/net/http/http_network_transaction.h
@@ -339,6 +339,9 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// True if we've validated the headers that the stream parser has returned.
bool headers_valid_;
+ // True if we can send the request over early data.
+ bool can_send_early_data_;
+
SSLConfig server_ssl_config_;
SSLConfig proxy_ssl_config_;
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 615019cca67..4f2f307f919 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -97,6 +97,7 @@
#include "net/test/gtest_util.h"
#include "net/test/net_test_suite.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -677,14 +678,18 @@ class CaptureGroupNameSocketPool : public ParentPool {
return last_group_name_;
}
+ bool socket_requested() const { return socket_requested_; }
+
int RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
const NetLogWithSource& net_log) override {
last_group_name_ = group_name;
+ socket_requested_ = true;
return ERR_IO_PENDING;
}
void CancelRequest(const std::string& group_name,
@@ -708,6 +713,7 @@ class CaptureGroupNameSocketPool : public ParentPool {
private:
std::string last_group_name_;
+ bool socket_requested_ = false;
};
typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
@@ -4484,6 +4490,225 @@ TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
session->CloseAllConnections();
}
+// Proxy resolver that returns a proxy with the same host and port for different
+// schemes, based on the path of the URL being requests.
+class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
+ public:
+ SameProxyWithDifferentSchemesProxyResolver() {}
+ ~SameProxyWithDifferentSchemesProxyResolver() override {}
+
+ static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
+
+ static HostPortPair ProxyHostPortPair() {
+ return HostPortPair::FromString(ProxyHostPortPairAsString());
+ }
+
+ // ProxyResolver implementation.
+ int GetProxyForURL(const GURL& url,
+ ProxyInfo* results,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request,
+ const NetLogWithSource& /*net_log*/) override {
+ *results = ProxyInfo();
+ if (url.path() == "/socks4") {
+ results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
+ return OK;
+ }
+ if (url.path() == "/socks5") {
+ results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
+ return OK;
+ }
+ if (url.path() == "/http") {
+ results->UsePacString("PROXY " + ProxyHostPortPairAsString());
+ return OK;
+ }
+ if (url.path() == "/https") {
+ results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
+ return OK;
+ }
+ NOTREACHED();
+ return ERR_NOT_IMPLEMENTED;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
+};
+
+class SameProxyWithDifferentSchemesProxyResolverFactory
+ : public ProxyResolverFactory {
+ public:
+ SameProxyWithDifferentSchemesProxyResolverFactory()
+ : ProxyResolverFactory(false) {}
+
+ int CreateProxyResolver(
+ const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
+ *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
+ return OK;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
+};
+
+// Check that when different proxy schemes are all applied to a proxy at the
+// same address, the sonnections are not grouped together. i.e., a request to
+// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
+// request to foo.com using proxy.com as an HTTP proxy.
+TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
+ session_deps_.proxy_service = std::make_unique<ProxyService>(
+ std::make_unique<ProxyConfigServiceFixed>(
+ ProxyConfig::CreateAutoDetect()),
+ std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
+ nullptr);
+
+ std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ MockWrite socks_writes[] = {
+ MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
+ kSOCKS4OkRequestLocalHostPort80Length),
+ MockWrite(SYNCHRONOUS,
+ "GET /socks4 HTTP/1.1\r\n"
+ "Host: test\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+ MockRead socks_reads[] = {
+ MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
+ MockRead("HTTP/1.0 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Content-Length: 15\r\n\r\n"
+ "SOCKS4 Response"),
+ };
+ StaticSocketDataProvider socks_data(socks_reads, arraysize(socks_reads),
+ socks_writes, arraysize(socks_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
+
+ const char kSOCKS5Request[] = {
+ 0x05, // Version
+ 0x01, // Command (CONNECT)
+ 0x00, // Reserved
+ 0x03, // Address type (DOMAINNAME)
+ 0x04, // Length of domain (4)
+ 't', 'e', 's', 't', // Domain string
+ 0x00, 0x50, // 16-bit port (80)
+ };
+ MockWrite socks5_writes[] = {
+ MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
+ MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
+ MockWrite(SYNCHRONOUS,
+ "GET /socks5 HTTP/1.1\r\n"
+ "Host: test\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+ MockRead socks5_reads[] = {
+ MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
+ MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
+ MockRead("HTTP/1.0 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Content-Length: 15\r\n\r\n"
+ "SOCKS5 Response"),
+ };
+ StaticSocketDataProvider socks5_data(socks5_reads, arraysize(socks5_reads),
+ socks5_writes, arraysize(socks5_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
+
+ MockWrite http_writes[] = {
+ MockWrite(SYNCHRONOUS,
+ "GET http://test/http HTTP/1.1\r\n"
+ "Host: test\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+ MockRead http_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Content-Length: 13\r\n\r\n"
+ "HTTP Response"),
+ };
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+ http_writes, arraysize(http_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&http_data);
+
+ MockWrite https_writes[] = {
+ MockWrite(SYNCHRONOUS,
+ "GET http://test/https HTTP/1.1\r\n"
+ "Host: test\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
+ MockRead https_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Content-Length: 14\r\n\r\n"
+ "HTTPS Response"),
+ };
+ StaticSocketDataProvider https_data(https_reads, arraysize(https_reads),
+ https_writes, arraysize(https_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&https_data);
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ struct TestCase {
+ GURL url;
+ std::string expected_response;
+ // How many idle sockets there should be in the SOCKS proxy socket pool
+ // after the test.
+ int expected_idle_socks_sockets;
+ // How many idle sockets there should be in the HTTP proxy socket pool after
+ // the test.
+ int expected_idle_http_sockets;
+ } const kTestCases[] = {
+ {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
+ {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
+ {GURL("http://test/http"), "HTTP Response", 2, 1},
+ {GURL("http://test/https"), "HTTPS Response", 2, 2},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = test_case.url;
+ std::unique_ptr<HttpNetworkTransaction> trans =
+ std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
+ session.get());
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ(200, response->headers->response_code());
+ std::string response_data;
+ EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
+ EXPECT_EQ(test_case.expected_response, response_data);
+
+ // Return the socket to the socket pool, so can make sure it's not used for
+ // the next requests.
+ trans.reset();
+ base::RunLoop().RunUntilIdle();
+
+ // Check the number of idle sockets in the pool, to make sure that used
+ // sockets are indeed being returned to the socket pool. If each request
+ // doesn't return an idle socket to the pool, the test would incorrectly
+ // pass.
+ EXPECT_EQ(
+ test_case.expected_idle_socks_sockets,
+ session
+ ->GetSocketPoolForSOCKSProxy(
+ HttpNetworkSession::NORMAL_SOCKET_POOL,
+ SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
+ ->IdleSocketCount());
+ EXPECT_EQ(
+ test_case.expected_idle_http_sockets,
+ session
+ ->GetSocketPoolForHTTPProxy(
+ HttpNetworkSession::NORMAL_SOCKET_POOL,
+ SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
+ ->IdleSocketCount());
+ }
+}
+
// Test the load timing for HTTPS requests with an HTTP proxy.
TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
HttpRequestInfo request1;
@@ -6879,6 +7104,82 @@ TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
}
+// Disable idle socket closing on memory pressure.
+// Grab a socket, use it, and put it back into the pool. Then, make
+// low memory notification and ensure the socket pool is NOT flushed.
+TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ // Disable idle socket closing on memory pressure.
+ session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
+ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
+ MockRead data_reads[] = {
+ // A part of the response body is received with the response headers.
+ MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
+ // The rest of the response body is received in two parts.
+ MockRead("lo"), MockRead(" world"),
+ MockRead("junk"), // Should not be read!!
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(response->headers);
+ std::string status_line = response->headers->GetStatusLine();
+ EXPECT_EQ("HTTP/1.1 200 OK", status_line);
+
+ // Make memory critical notification and ensure the transaction still has been
+ // operating right.
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+ base::RunLoop().RunUntilIdle();
+
+ // Socket should not be flushed as long as it is not idle.
+ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
+
+ std::string response_data;
+ rv = ReadTransaction(&trans, &response_data);
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_EQ("hello world", response_data);
+
+ // Empty the current queue. This is necessary because idle sockets are
+ // added to the connection pool asynchronously with a PostTask.
+ base::RunLoop().RunUntilIdle();
+
+ // We now check to make sure the socket was added back to the pool.
+ EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
+
+ // Idle sockets should NOT be flushed on moderate memory pressure.
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
+
+ // Idle sockets should NOT be flushed on critical memory pressure.
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
+}
+
// Grab an SSL socket, use it, and put it back into the pool. Then, make
// low memory notification and ensure the socket pool is flushed.
TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
@@ -8512,20 +8813,21 @@ TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
CreateMockWrite(stream2_priority, 3, ASYNC),
};
+ SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
+ NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
+
SpdySerializedFrame stream1_reply(
spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
- SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
- NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
const char kPushedData[] = "pushed";
SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
2, kPushedData, strlen(kPushedData), true));
MockRead spdy_reads[] = {
- CreateMockRead(stream1_reply, 1, ASYNC),
- CreateMockRead(stream2_syn, 2, ASYNC),
+ CreateMockRead(stream2_syn, 1, ASYNC),
+ CreateMockRead(stream1_reply, 2, ASYNC),
CreateMockRead(stream1_body, 4, ASYNC),
CreateMockRead(stream2_body, 5, ASYNC),
MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
@@ -9644,44 +9946,42 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
EXPECT_EQ(ERR_IO_PENDING,
GroupNameTransactionHelper(tests[i].url, session.get()));
- if (tests[i].ssl)
+ if (tests[i].ssl) {
EXPECT_EQ(tests[i].expected_group_name,
ssl_conn_pool->last_group_name_received());
- else
+ } else {
EXPECT_EQ(tests[i].expected_group_name,
transport_conn_pool->last_group_name_received());
+ }
+ // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
+ EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
+ // When SSL proxy is not in use, socket must be requested from
+ // |transport_conn_pool|.
+ EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
}
}
TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
const GroupNameTest tests[] = {
{
- "http_proxy",
- "http://www.example.org/http_proxy_normal",
- "www.example.org:80",
- false,
+ "http_proxy", "http://www.example.org/http_proxy_normal",
+ "http_proxy/www.example.org:80", false,
},
// SSL Tests
{
- "http_proxy",
- "https://www.example.org/http_connect_ssl",
- "ssl/www.example.org:443",
- true,
+ "http_proxy", "https://www.example.org/http_connect_ssl",
+ "http_proxy/ssl/www.example.org:443", true,
},
{
- "http_proxy",
- "https://host.with.alternate/direct",
- "ssl/host.with.alternate:443",
- true,
+ "http_proxy", "https://host.with.alternate/direct",
+ "http_proxy/ssl/host.with.alternate:443", true,
},
{
- "http_proxy",
- "ftp://ftp.google.com/http_proxy_normal",
- "ftp/ftp.google.com:21",
- false,
+ "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
+ "http_proxy/ftp/ftp.google.com:21", false,
},
};
@@ -13411,7 +13711,6 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
};
MockRead data_reads1[] = {
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
MockRead(ASYNC, 0, 0), // EOF
};
@@ -15430,6 +15729,7 @@ class FakeStream : public HttpStream,
RequestPriority priority() const { return priority_; }
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override {
@@ -15683,10 +15983,12 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
// the fact that the WebSocket code is not compiled on iOS makes that
// difficult.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override {
- state_.Initialize(request_info, priority, net_log, callback);
+ state_.Initialize(request_info, can_send_early, priority, net_log,
+ callback);
return OK;
}
@@ -15694,7 +15996,8 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
HttpResponseInfo* response,
const CompletionCallback& callback) override {
return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
- response, callback);
+ TRAFFIC_ANNOTATION_FOR_TESTS, response,
+ callback);
}
int ReadResponseHeaders(const CompletionCallback& callback) override {
@@ -15893,8 +16196,7 @@ TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
HttpNetworkSessionPeer peer(session.get());
FakeStreamFactory* fake_factory = new FakeStreamFactory();
FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
- peer.SetHttpStreamFactoryForWebSocket(
- std::unique_ptr<HttpStreamFactory>(fake_factory));
+ peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
HttpRequestInfo request;
HttpNetworkTransaction trans(LOW, session.get());
diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc
index 4be93e00bee..417a21b96cc 100644
--- a/chromium/net/http/http_proxy_client_socket.cc
+++ b/chromium/net/http/http_proxy_client_socket.cc
@@ -11,7 +11,6 @@
#include "net/base/auth.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
-#include "net/base/proxy_delegate.h"
#include "net/http/http_basic_stream.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
@@ -21,25 +20,24 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_handle.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
HttpProxyClientSocket::HttpProxyClientSocket(
- ClientSocketHandle* transport_socket,
+ std::unique_ptr<ClientSocketHandle> transport_socket,
const std::string& user_agent,
const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
HttpAuthController* http_auth_controller,
bool tunnel,
bool using_spdy,
NextProto negotiated_protocol,
- ProxyDelegate* proxy_delegate,
bool is_https_proxy)
: io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete,
base::Unretained(this))),
next_state_(STATE_NONE),
- transport_(transport_socket),
+ transport_(std::move(transport_socket)),
endpoint_(endpoint),
auth_(http_auth_controller),
tunnel_(tunnel),
@@ -47,9 +45,7 @@ HttpProxyClientSocket::HttpProxyClientSocket(
negotiated_protocol_(negotiated_protocol),
is_https_proxy_(is_https_proxy),
redirect_has_load_timing_info_(false),
- proxy_server_(proxy_server),
- proxy_delegate_(proxy_delegate),
- net_log_(transport_socket->socket()->NetLog()) {
+ net_log_(transport_->socket()->NetLog()) {
// Synthesize the bits of a request that we actually use.
request_.url = GURL("https://" + endpoint.ToString());
request_.method = "CONNECT";
@@ -207,6 +203,10 @@ int64_t HttpProxyClientSocket::GetTotalReceivedBytes() const {
return transport_->socket()->GetTotalReceivedBytes();
}
+void HttpProxyClientSocket::ApplySocketTag(const SocketTag& tag) {
+ return transport_->socket()->ApplySocketTag(tag);
+}
+
int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(user_callback_.is_null());
@@ -227,12 +227,16 @@ int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
return transport_->socket()->Read(buf, buf_len, callback);
}
-int HttpProxyClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int HttpProxyClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_EQ(STATE_DONE, next_state_);
DCHECK(user_callback_.is_null());
- return transport_->socket()->Write(buf, buf_len, callback);
+ return transport_->socket()->Write(buf, buf_len, callback,
+ traffic_annotation);
}
int HttpProxyClientSocket::SetReceiveBufferSize(int32_t size) {
@@ -396,10 +400,6 @@ int HttpProxyClientSocket::DoSendRequest() {
HttpRequestHeaders authorization_headers;
if (auth_->HaveAuth())
auth_->AddAuthorizationHeader(&authorization_headers);
- if (proxy_delegate_) {
- proxy_delegate_->OnBeforeTunnelRequest(proxy_server_,
- &authorization_headers);
- }
std::string user_agent;
if (!request_.extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
&user_agent)) {
@@ -417,8 +417,10 @@ int HttpProxyClientSocket::DoSendRequest() {
parser_buf_ = new GrowableIOBuffer();
http_stream_parser_.reset(new HttpStreamParser(
transport_.get(), &request_, parser_buf_.get(), net_log_));
- return http_stream_parser_->SendRequest(
- request_line_, request_headers_, &response_, io_callback_);
+ // TODO(crbug.com/656607): Add propoer annotation.
+ return http_stream_parser_->SendRequest(request_line_, request_headers_,
+ NO_TRAFFIC_ANNOTATION_BUG_656607,
+ &response_, io_callback_);
}
int HttpProxyClientSocket::DoSendRequestComplete(int result) {
@@ -446,13 +448,6 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) {
NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers));
- if (proxy_delegate_) {
- proxy_delegate_->OnTunnelHeadersReceived(
- HostPortPair::FromURL(request_.url),
- proxy_server_,
- *response_.headers);
- }
-
switch (response_.headers->response_code()) {
case 200: // OK
if (http_stream_parser_->IsMoreDataBuffered())
diff --git a/chromium/net/http/http_proxy_client_socket.h b/chromium/net/http/http_proxy_client_socket.h
index 7c05a29b6df..8444be2069f 100644
--- a/chromium/net/http/http_proxy_client_socket.h
+++ b/chromium/net/http/http_proxy_client_socket.h
@@ -23,6 +23,7 @@
#include "net/http/proxy_client_socket.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -31,22 +32,19 @@ class GrowableIOBuffer;
class HttpStream;
class HttpStreamParser;
class IOBuffer;
-class ProxyDelegate;
class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
public:
// Takes ownership of |transport_socket|, which should already be connected
// by the time Connect() is called. If tunnel is true then on Connect()
// this socket will establish an Http tunnel.
- HttpProxyClientSocket(ClientSocketHandle* transport_socket,
+ HttpProxyClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
const std::string& user_agent,
const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
HttpAuthController* http_auth_controller,
bool tunnel,
bool using_spdy,
NextProto negotiated_protocol,
- ProxyDelegate* proxy_delegate,
bool is_https_proxy);
// On destruction Disconnect() is called.
@@ -76,6 +74,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -83,7 +82,8 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
@@ -161,11 +161,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
bool redirect_has_load_timing_info_;
LoadTimingInfo redirect_load_timing_info_;
- const HostPortPair proxy_server_;
-
- // This delegate must outlive this proxy client socket.
- ProxyDelegate* proxy_delegate_;
-
const NetLogWithSource net_log_;
DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocket);
diff --git a/chromium/net/http/http_proxy_client_socket_fuzzer.cc b/chromium/net/http/http_proxy_client_socket_fuzzer.cc
index 33c076f7284..ac9702ab767 100644
--- a/chromium/net/http/http_proxy_client_socket_fuzzer.cc
+++ b/chromium/net/http/http_proxy_client_socket_fuzzer.cc
@@ -64,10 +64,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// is HTTPS.
bool is_https_proxy = data_provider.ConsumeBool();
net::HttpProxyClientSocket socket(
- socket_handle.release(), "Bond/007", net::HostPortPair("foo", 80),
- net::HostPortPair("proxy", 42), auth_controller.get(), true /* tunnel */,
- false /* using_spdy */, net::kProtoUnknown, nullptr /* proxy_delegate */,
- is_https_proxy);
+ std::move(socket_handle), "Bond/007", net::HostPortPair("foo", 80),
+ auth_controller.get(), true /* tunnel */, false /* using_spdy */,
+ net::kProtoUnknown, is_https_proxy);
int result = socket.Connect(callback.callback());
result = callback.GetResult(result);
diff --git a/chromium/net/http/http_proxy_client_socket_pool.cc b/chromium/net/http/http_proxy_client_socket_pool.cc
index ab7bbb30b67..1e3ec469be1 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool.cc
@@ -18,7 +18,6 @@
#include "base/values.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
-#include "net/base/proxy_delegate.h"
#include "net/http/http_network_session.h"
#include "net/http/http_proxy_client_socket_wrapper.h"
#include "net/log/net_log_source_type.h"
@@ -85,8 +84,7 @@ HttpProxySocketParams::HttpProxySocketParams(
HttpAuthHandlerFactory* http_auth_handler_factory,
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
- bool tunnel,
- ProxyDelegate* proxy_delegate)
+ bool tunnel)
: transport_params_(transport_params),
ssl_params_(ssl_params),
quic_version_(quic_version),
@@ -96,8 +94,7 @@ HttpProxySocketParams::HttpProxySocketParams(
endpoint_(endpoint),
http_auth_cache_(tunnel ? http_auth_cache : NULL),
http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
- tunnel_(tunnel),
- proxy_delegate_(proxy_delegate) {
+ tunnel_(tunnel) {
// If doing a QUIC proxy, |quic_version| must not be QUIC_VERSION_UNSUPPORTED,
// and |ssl_params| must be valid while |transport_params| is null.
// Otherwise, |quic_version| must be QUIC_VERSION_UNSUPPORTED, and exactly
@@ -105,6 +102,9 @@ HttpProxySocketParams::HttpProxySocketParams(
DCHECK(quic_version_ == QUIC_VERSION_UNSUPPORTED
? (bool)transport_params != (bool)ssl_params
: !transport_params && ssl_params);
+ // Exactly one of |transport_params_| and |ssl_params_| must be non-null.
+ DCHECK(transport_params_ || ssl_params_);
+ DCHECK(!transport_params_ || !ssl_params_);
}
const HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
@@ -120,6 +120,7 @@ HttpProxySocketParams::~HttpProxySocketParams() = default;
HttpProxyConnectJob::HttpProxyConnectJob(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<HttpProxySocketParams>& params,
const base::TimeDelta& timeout_duration,
@@ -131,6 +132,7 @@ HttpProxyConnectJob::HttpProxyConnectJob(
group_name,
base::TimeDelta() /* The socket takes care of timeouts */,
priority,
+ socket_tag,
respect_limits,
delegate,
NetLogWithSource::Make(net_log,
@@ -138,6 +140,7 @@ HttpProxyConnectJob::HttpProxyConnectJob(
client_socket_(new HttpProxyClientSocketWrapper(
group_name,
priority,
+ socket_tag,
respect_limits,
timeout_duration,
base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds),
@@ -153,7 +156,6 @@ HttpProxyConnectJob::HttpProxyConnectJob(
params->spdy_session_pool(),
params->quic_stream_factory(),
params->tunnel(),
- params->proxy_delegate(),
this->net_log())) {}
HttpProxyConnectJob::~HttpProxyConnectJob() = default;
@@ -201,13 +203,16 @@ HttpProxyClientSocketPool::HttpProxyConnectJobFactory::
: transport_pool_(transport_pool),
ssl_pool_(ssl_pool),
network_quality_provider_(network_quality_provider),
- transport_rtt_multiplier_(GetInt32Param("transport_rtt_multiplier", 5)),
+ ssl_http_rtt_multiplier_(GetInt32Param("ssl_http_rtt_multiplier", 5)),
+ non_ssl_http_rtt_multiplier_(
+ GetInt32Param("non_ssl_http_rtt_multiplier", 5)),
min_proxy_connection_timeout_(base::TimeDelta::FromSeconds(
GetInt32Param("min_proxy_connection_timeout_seconds", 8))),
max_proxy_connection_timeout_(base::TimeDelta::FromSeconds(
GetInt32Param("max_proxy_connection_timeout_seconds", 60))),
net_log_(net_log) {
- DCHECK_LT(0, transport_rtt_multiplier_);
+ DCHECK_LT(0, ssl_http_rtt_multiplier_);
+ DCHECK_LT(0, non_ssl_http_rtt_multiplier_);
DCHECK_LE(base::TimeDelta(), min_proxy_connection_timeout_);
DCHECK_LE(base::TimeDelta(), max_proxy_connection_timeout_);
DCHECK_LE(min_proxy_connection_timeout_, max_proxy_connection_timeout_);
@@ -218,23 +223,35 @@ HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
const std::string& group_name,
const PoolBase::Request& request,
ConnectJob::Delegate* delegate) const {
+ bool is_secure_connection = (request.params()->ssl_params() != nullptr);
+
return std::unique_ptr<ConnectJob>(new HttpProxyConnectJob(
- group_name, request.priority(), request.respect_limits(),
- request.params(), ConnectionTimeout(), transport_pool_, ssl_pool_,
- delegate, net_log_));
+ group_name, request.priority(), request.socket_tag(),
+ request.respect_limits(), request.params(),
+ ConnectionTimeoutWithConnectionProperty(is_secure_connection),
+ transport_pool_, ssl_pool_, delegate, net_log_));
}
base::TimeDelta
HttpProxyClientSocketPool::HttpProxyConnectJobFactory::ConnectionTimeout()
const {
+ // Take a conservative approach: Return the timeout for the secure proxies
+ // which is higher than the connection timeout for the insecure proxies.
+ return ConnectionTimeoutWithConnectionProperty(
+ true /* is_secure_connection */);
+}
+
+base::TimeDelta HttpProxyClientSocketPool::HttpProxyConnectJobFactory::
+ ConnectionTimeoutWithConnectionProperty(bool is_secure_connection) const {
if (IsInNetAdaptiveProxyConnectionTimeoutFieldTrial() &&
network_quality_provider_) {
- base::Optional<base::TimeDelta> transport_rtt_estimate =
- network_quality_provider_->GetTransportRTT();
- if (transport_rtt_estimate) {
- base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
- transport_rtt_multiplier_ *
- transport_rtt_estimate.value().InMilliseconds());
+ base::Optional<base::TimeDelta> http_rtt_estimate =
+ network_quality_provider_->GetHttpRTT();
+ if (http_rtt_estimate) {
+ int32_t multiplier = is_secure_connection ? ssl_http_rtt_multiplier_
+ : non_ssl_http_rtt_multiplier_;
+ base::TimeDelta timeout = base::TimeDelta::FromMicroseconds(
+ multiplier * http_rtt_estimate.value().InMicroseconds());
// Ensure that connection timeout is between
// |min_proxy_connection_timeout_| and |max_proxy_connection_timeout_|.
if (timeout < min_proxy_connection_timeout_)
@@ -290,6 +307,7 @@ HttpProxyClientSocketPool::~HttpProxyClientSocketPool() = default;
int HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -298,7 +316,8 @@ int HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params);
return base_.RequestSocket(group_name, *casted_socket_params, priority,
- respect_limits, handle, callback, net_log);
+ socket_tag, respect_limits, handle, callback,
+ net_log);
}
void HttpProxyClientSocketPool::RequestSockets(
diff --git a/chromium/net/http/http_proxy_client_socket_pool.h b/chromium/net/http/http_proxy_client_socket_pool.h
index 0df5e47f33e..09fa48d69c2 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.h
+++ b/chromium/net/http/http_proxy_client_socket_pool.h
@@ -31,7 +31,6 @@ class HttpAuthHandlerFactory;
class HttpProxyClientSocketWrapper;
class NetLog;
class NetworkQualityProvider;
-class ProxyDelegate;
class QuicStreamFactory;
class SSLClientSocketPool;
class SSLSocketParams;
@@ -57,8 +56,7 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
HttpAuthHandlerFactory* http_auth_handler_factory,
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
- bool tunnel,
- ProxyDelegate* proxy_delegate);
+ bool tunnel);
const scoped_refptr<TransportSocketParams>& transport_params() const {
return transport_params_;
@@ -82,10 +80,6 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
const HostResolver::RequestInfo& destination() const;
bool tunnel() const { return tunnel_; }
- ProxyDelegate* proxy_delegate() const {
- return proxy_delegate_;
- }
-
private:
friend class base::RefCounted<HttpProxySocketParams>;
~HttpProxySocketParams();
@@ -100,7 +94,6 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
HttpAuthCache* const http_auth_cache_;
HttpAuthHandlerFactory* const http_auth_handler_factory_;
const bool tunnel_;
- ProxyDelegate* proxy_delegate_;
DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
};
@@ -111,6 +104,7 @@ class HttpProxyConnectJob : public ConnectJob {
public:
HttpProxyConnectJob(const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<HttpProxySocketParams>& params,
const base::TimeDelta& timeout_duration,
@@ -165,6 +159,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketPool
int RequestSocket(const std::string& group_name,
const void* connect_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -218,9 +213,13 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketPool
bool CloseOneIdleConnection() override;
private:
+ FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest,
+ ProxyPoolTimeoutWithConnectionProperty);
+
typedef ClientSocketPoolBase<HttpProxySocketParams> PoolBase;
- class HttpProxyConnectJobFactory : public PoolBase::ConnectJobFactory {
+ class NET_EXPORT_PRIVATE HttpProxyConnectJobFactory
+ : public PoolBase::ConnectJobFactory {
public:
HttpProxyConnectJobFactory(TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
@@ -236,12 +235,30 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketPool
base::TimeDelta ConnectionTimeout() const override;
private:
+ FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest,
+ ProxyPoolTimeoutWithConnectionProperty);
+
+ // Returns proxy connection timeout for secure proxies if
+ // |is_secure_connection| is true. Otherwise, returns timeout for insecure
+ // proxies.
+ base::TimeDelta ConnectionTimeoutWithConnectionProperty(
+ bool is_secure_connection) const;
+
TransportClientSocketPool* const transport_pool_;
SSLClientSocketPool* const ssl_pool_;
- NetworkQualityProvider* network_quality_provider_;
- const int32_t transport_rtt_multiplier_;
+ NetworkQualityProvider* const network_quality_provider_;
+
+ // For secure proxies, the connection timeout is set to
+ // |ssl_http_rtt_multiplier_| times the HTTP RTT estimate. For insecure
+ // proxies, the connection timeout is set to |non_ssl_http_rtt_multiplier_|
+ // times the HTTP RTT estimate. In either case, the connection timeout
+ // is clamped to be between |min_proxy_connection_timeout_| and
+ // |max_proxy_connection_timeout_|.
+ const int32_t ssl_http_rtt_multiplier_;
+ const int32_t non_ssl_http_rtt_multiplier_;
const base::TimeDelta min_proxy_connection_timeout_;
const base::TimeDelta max_proxy_connection_timeout_;
+
NetLog* net_log_;
DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory);
diff --git a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
index 2cf01c156cd..c3c483693ab 100644
--- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -17,10 +17,9 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
+#include "build/build_config.h"
#include "net/base/net_errors.h"
-#include "net/base/proxy_delegate.h"
#include "net/base/test_completion_callback.h"
-#include "net/base/test_proxy_delegate.h"
#include "net/http/http_network_session.h"
#include "net/http/http_proxy_client_socket.h"
#include "net/http/http_response_headers.h"
@@ -28,6 +27,7 @@
#include "net/nqe/network_quality_estimator_test_util.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/spdy/core/spdy_protocol.h"
@@ -66,7 +66,7 @@ class HttpProxyClientSocketPoolTest
HttpProxyClientSocketPoolTest()
: transport_socket_pool_(kMaxSockets,
kMaxSocketsPerGroup,
- session_deps_.socket_factory.get()),
+ &socket_factory_),
ssl_socket_pool_(kMaxSockets,
kMaxSocketsPerGroup,
session_deps_.cert_verifier.get(),
@@ -75,7 +75,7 @@ class HttpProxyClientSocketPoolTest
NULL /* cert_transparency_verifier */,
NULL /* ct_policy_enforcer */,
std::string() /* ssl_session_cache_shard */,
- session_deps_.socket_factory.get(),
+ &socket_factory_,
&transport_socket_pool_,
NULL,
NULL,
@@ -98,7 +98,8 @@ class HttpProxyClientSocketPoolTest
// connection timeout based on the network quality.
void InitAdaptiveTimeoutFieldTrialWithParams(
bool use_default_params,
- int transport_rtt_multiplier,
+ int ssl_http_rtt_multiplier,
+ int non_ssl_http_rtt_multiplier,
base::TimeDelta min_proxy_connection_timeout,
base::TimeDelta max_proxy_connection_timeout) {
std::string trial_name = "NetAdaptiveProxyConnectionTimeout";
@@ -106,8 +107,10 @@ class HttpProxyClientSocketPoolTest
std::map<std::string, std::string> params;
if (!use_default_params) {
- params["transport_rtt_multiplier"] =
- base::IntToString(transport_rtt_multiplier);
+ params["ssl_http_rtt_multiplier"] =
+ base::IntToString(ssl_http_rtt_multiplier);
+ params["non_ssl_http_rtt_multiplier"] =
+ base::IntToString(non_ssl_http_rtt_multiplier);
params["min_proxy_connection_timeout_seconds"] =
base::IntToString(min_proxy_connection_timeout.InSeconds());
params["max_proxy_connection_timeout_seconds"] =
@@ -169,31 +172,24 @@ class HttpProxyClientSocketPoolTest
// Returns the a correctly constructed HttpProxyParms
// for the HTTP or HTTPS proxy.
- scoped_refptr<HttpProxySocketParams> CreateParams(
- bool tunnel,
- ProxyDelegate* proxy_delegate) {
- return scoped_refptr<HttpProxySocketParams>(new HttpProxySocketParams(
+ scoped_refptr<HttpProxySocketParams> CreateParams(bool tunnel) {
+ return base::MakeRefCounted<HttpProxySocketParams>(
CreateHttpProxyParams(), CreateHttpsProxyParams(),
QUIC_VERSION_UNSUPPORTED, std::string(),
HostPortPair("www.google.com", tunnel ? 443 : 80),
session_->http_auth_cache(), session_->http_auth_handler_factory(),
- session_->spdy_session_pool(), session_->quic_stream_factory(), tunnel,
- proxy_delegate));
+ session_->spdy_session_pool(), session_->quic_stream_factory(), tunnel);
}
- scoped_refptr<HttpProxySocketParams> CreateTunnelParams(
- ProxyDelegate* proxy_delegate) {
- return CreateParams(true, proxy_delegate);
+ scoped_refptr<HttpProxySocketParams> CreateTunnelParams() {
+ return CreateParams(true);
}
- scoped_refptr<HttpProxySocketParams> CreateNoTunnelParams(
- ProxyDelegate* proxy_delegate) {
- return CreateParams(false, proxy_delegate);
+ scoped_refptr<HttpProxySocketParams> CreateNoTunnelParams() {
+ return CreateParams(false);
}
- MockClientSocketFactory* socket_factory() {
- return session_deps_.socket_factory.get();
- }
+ MockTaggingClientSocketFactory* socket_factory() { return &socket_factory_; }
void Initialize(MockRead* reads, size_t reads_count,
MockWrite* writes, size_t writes_count,
@@ -234,7 +230,13 @@ class HttpProxyClientSocketPoolTest
TestNetworkQualityEstimator* estimator() { return &estimator_; }
+ MockTransportClientSocketPool* transport_socket_pool() {
+ return &transport_socket_pool_;
+ }
+ SSLClientSocketPool* ssl_socket_pool() { return &ssl_socket_pool_; }
+
private:
+ MockTaggingClientSocketFactory socket_factory_;
SpdySessionDependencies session_deps_;
TestNetworkQualityEstimator estimator_;
@@ -268,17 +270,13 @@ INSTANTIATE_TEST_CASE_P(HttpProxyType,
TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
- std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
- int rv = handle_.Init("a", CreateNoTunnelParams(proxy_delegate.get()), LOW,
+ int rv = handle_.Init("a", CreateNoTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle_.is_initialized());
ASSERT_TRUE(handle_.socket());
EXPECT_TRUE(handle_.socket()->IsConnected());
- EXPECT_FALSE(proxy_delegate->on_before_tunnel_request_called());
- EXPECT_FALSE(proxy_delegate->on_tunnel_headers_received_called());
- EXPECT_TRUE(proxy_delegate->on_tunnel_request_completed_called());
bool is_secure_proxy = GetParam() == HTTPS || GetParam() == SPDY;
histogram_tester().ExpectTotalCount(
@@ -292,7 +290,7 @@ TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) {
TEST_P(HttpProxyClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
EXPECT_EQ(
- OK, handle_.Init("a", CreateNoTunnelParams(NULL), HIGHEST,
+ OK, handle_.Init("a", CreateNoTunnelParams(), HIGHEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(HIGHEST, GetLastTransportRequestPriority());
@@ -332,7 +330,7 @@ TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) {
spdy_reads, arraysize(spdy_reads), spdy_writes,
arraysize(spdy_writes));
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -366,9 +364,7 @@ TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
"CONNECT www.google.com:443 HTTP/1.1\r\n"
"Host: www.google.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
- "Foo: " +
- proxy_host_port + "\r\n\r\n";
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n";
MockWrite writes[] = {
MockWrite(SYNCHRONOUS, 0, request.c_str()),
};
@@ -380,21 +376,13 @@ TEST_P(HttpProxyClientSocketPoolTest, HaveAuth) {
NULL, 0);
AddAuthToCache();
- std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
- int rv = handle_.Init("a", CreateTunnelParams(proxy_delegate.get()), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle_.is_initialized());
ASSERT_TRUE(handle_.socket());
EXPECT_TRUE(handle_.socket()->IsConnected());
- proxy_delegate->VerifyOnTunnelHeadersReceived(
- "www.google.com:443",
- proxy_host_port.c_str(),
- "HTTP/1.1 200 Connection Established");
- proxy_delegate->VerifyOnTunnelRequestCompleted(
- "www.google.com:443",
- proxy_host_port.c_str());
}
TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
@@ -405,9 +393,7 @@ TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
"CONNECT www.google.com:443 HTTP/1.1\r\n"
"Host: www.google.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
- "Foo: " +
- proxy_host_port + "\r\n\r\n";
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n";
MockWrite writes[] = {
MockWrite(ASYNC, 0, request.c_str()),
};
@@ -431,8 +417,7 @@ TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
arraysize(spdy_writes));
AddAuthToCache();
- std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
- int rv = handle_.Init("a", CreateTunnelParams(proxy_delegate.get()), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -443,9 +428,6 @@ TEST_P(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
EXPECT_TRUE(handle_.is_initialized());
ASSERT_TRUE(handle_.socket());
EXPECT_TRUE(handle_.socket()->IsConnected());
- proxy_delegate->VerifyOnTunnelRequestCompleted(
- "www.google.com:443",
- proxy_host_port.c_str());
}
// Make sure that HttpProxyConnectJob passes on its priority to its
@@ -470,7 +452,7 @@ TEST_P(HttpProxyClientSocketPoolTest,
EXPECT_EQ(
ERR_IO_PENDING,
- handle_.Init("a", CreateTunnelParams(NULL), MEDIUM,
+ handle_.Init("a", CreateTunnelParams(), MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(MEDIUM, GetLastTransportRequestPriority());
@@ -486,7 +468,7 @@ TEST_P(HttpProxyClientSocketPoolTest, TCPError) {
socket_factory()->AddSocketDataProvider(data_.get());
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -519,7 +501,7 @@ TEST_P(HttpProxyClientSocketPoolTest, SSLError) {
}
socket_factory()->AddSSLSocketDataProvider(ssl_data_.get());
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -551,7 +533,7 @@ TEST_P(HttpProxyClientSocketPoolTest, SslClientAuth) {
}
socket_factory()->AddSSLSocketDataProvider(ssl_data_.get());
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -594,7 +576,7 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
arraysize(spdy_writes));
AddAuthToCache();
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -634,7 +616,7 @@ TEST_P(HttpProxyClientSocketPoolTest, Tunnel1xxResponse) {
Initialize(reads, arraysize(reads), writes, arraysize(writes),
NULL, 0, NULL, 0);
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -673,7 +655,7 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupError) {
arraysize(spdy_writes));
AddAuthToCache();
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -730,7 +712,7 @@ TEST_P(HttpProxyClientSocketPoolTest, TunnelSetupRedirect) {
arraysize(spdy_writes));
AddAuthToCache();
- int rv = handle_.Init("a", CreateTunnelParams(NULL), LOW,
+ int rv = handle_.Init("a", CreateTunnelParams(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -783,104 +765,155 @@ TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolTimeout) {
// Tests the connection timeout values when the field trial parameters are
// specified.
TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithExperiment) {
- int transport_rtt_multiplier = 2;
- base::TimeDelta min_timeout = base::TimeDelta::FromSeconds(8);
- base::TimeDelta max_timeout = base::TimeDelta::FromSeconds(20);
+ // Timeout should be kMultiplier times the HTTP RTT estimate.
+ const int kMultiplier = 4;
+ const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8);
+ const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(20);
- InitAdaptiveTimeoutFieldTrialWithParams(false, transport_rtt_multiplier,
- min_timeout, max_timeout);
+ InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier,
+ kMinTimeout, kMaxTimeout);
EXPECT_LE(base::TimeDelta(), pool_->ConnectionTimeout());
- // Timeout should be |transport_rtt_multiplier| times the transport RTT
- // estimate.
- base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(7);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(rtt_estimate + rtt_estimate, pool_->ConnectionTimeout());
-
- // A change in RTT estimate should also change the connection timeout.
- rtt_estimate = base::TimeDelta::FromSeconds(8);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(rtt_estimate + rtt_estimate, pool_->ConnectionTimeout());
+ base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(4);
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ base::TimeDelta expected_connection_timeout = kMultiplier * rtt_estimate;
+ EXPECT_EQ(expected_connection_timeout, pool_->ConnectionTimeout());
- // Connection timeout should not exceed |max_timeout|.
+ // Connection timeout should not exceed kMaxTimeout.
rtt_estimate = base::TimeDelta::FromSeconds(25);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(max_timeout, pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMaxTimeout, pool_->ConnectionTimeout());
- // Connection timeout should not be less than |min_timeout|.
+ // Connection timeout should not be less than kMinTimeout.
rtt_estimate = base::TimeDelta::FromSeconds(0);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(min_timeout, pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMinTimeout, pool_->ConnectionTimeout());
}
// Tests the connection timeout values when the field trial parameters are
// specified.
TEST_P(HttpProxyClientSocketPoolTest,
ProxyPoolTimeoutWithExperimentDifferentParams) {
- int transport_rtt_multiplier = 3;
- base::TimeDelta min_timeout = base::TimeDelta::FromSeconds(2);
- base::TimeDelta max_timeout = base::TimeDelta::FromSeconds(30);
+ // Timeout should be kMultiplier times the HTTP RTT estimate.
+ const int kMultiplier = 3;
+ const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2);
+ const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30);
- InitAdaptiveTimeoutFieldTrialWithParams(false, transport_rtt_multiplier,
- min_timeout, max_timeout);
+ InitAdaptiveTimeoutFieldTrialWithParams(false, kMultiplier, kMultiplier,
+ kMinTimeout, kMaxTimeout);
EXPECT_LE(base::TimeDelta(), pool_->ConnectionTimeout());
- // Timeout should be |transport_rtt_multiplier| times the transport RTT
- // estimate.
base::TimeDelta rtt_estimate = base::TimeDelta::FromSeconds(2);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(rtt_estimate + rtt_estimate + rtt_estimate,
- pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMultiplier * rtt_estimate, pool_->ConnectionTimeout());
// A change in RTT estimate should also change the connection timeout.
rtt_estimate = base::TimeDelta::FromSeconds(7);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(rtt_estimate + rtt_estimate + rtt_estimate,
- pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMultiplier * rtt_estimate, pool_->ConnectionTimeout());
- // Connection timeout should not exceed |max_timeout|.
+ // Connection timeout should not exceed kMaxTimeout.
rtt_estimate = base::TimeDelta::FromSeconds(35);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(max_timeout, pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMaxTimeout, pool_->ConnectionTimeout());
- // Connection timeout should not be less than |min_timeout|.
+ // Connection timeout should not be less than kMinTimeout.
rtt_estimate = base::TimeDelta::FromSeconds(0);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- EXPECT_EQ(min_timeout, pool_->ConnectionTimeout());
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ EXPECT_EQ(kMinTimeout, pool_->ConnectionTimeout());
+}
+
+TEST_P(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithConnectionProperty) {
+ const int kSecureMultiplier = 3;
+ const int kNonSecureMultiplier = 5;
+ const base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(2);
+ const base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(30);
+
+ InitAdaptiveTimeoutFieldTrialWithParams(
+ false, kSecureMultiplier, kNonSecureMultiplier, kMinTimeout, kMaxTimeout);
+
+ HttpProxyClientSocketPool::HttpProxyConnectJobFactory job_factory(
+ transport_socket_pool(), ssl_socket_pool(), estimator(), nullptr);
+
+ const base::TimeDelta kRttEstimate = base::TimeDelta::FromSeconds(2);
+ estimator()->SetStartTimeNullHttpRtt(kRttEstimate);
+ // By default, connection timeout should return the timeout for secure
+ // proxies.
+ EXPECT_EQ(kSecureMultiplier * kRttEstimate, job_factory.ConnectionTimeout());
+ EXPECT_EQ(kSecureMultiplier * kRttEstimate,
+ job_factory.ConnectionTimeoutWithConnectionProperty(true));
+ EXPECT_EQ(kNonSecureMultiplier * kRttEstimate,
+ job_factory.ConnectionTimeoutWithConnectionProperty(false));
}
// Tests the connection timeout values when the field trial parameters are not
// specified.
TEST_P(HttpProxyClientSocketPoolTest,
ProxyPoolTimeoutWithExperimentDefaultParams) {
- InitAdaptiveTimeoutFieldTrialWithParams(true, 0, base::TimeDelta(),
+ InitAdaptiveTimeoutFieldTrialWithParams(true, 0, 0, base::TimeDelta(),
base::TimeDelta());
EXPECT_LE(base::TimeDelta(), pool_->ConnectionTimeout());
- // Timeout should be |transport_rtt_multiplier| times the transport RTT
+ // Timeout should be |http_rtt_multiplier| times the HTTP RTT
// estimate.
base::TimeDelta rtt_estimate = base::TimeDelta::FromMilliseconds(10);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- // Connection timeout should not be less than the transport RTT estimate.
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ // Connection timeout should not be less than the HTTP RTT estimate.
EXPECT_LE(rtt_estimate, pool_->ConnectionTimeout());
// A change in RTT estimate should also change the connection timeout.
rtt_estimate = base::TimeDelta::FromSeconds(10);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
- // Connection timeout should not be less than the transport RTT estimate.
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
+ // Connection timeout should not be less than the HTTP RTT estimate.
EXPECT_LE(rtt_estimate, pool_->ConnectionTimeout());
// Set RTT to a very large value.
rtt_estimate = base::TimeDelta::FromMinutes(60);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
EXPECT_GT(rtt_estimate, pool_->ConnectionTimeout());
// Set RTT to a very small value.
rtt_estimate = base::TimeDelta::FromSeconds(0);
- estimator()->set_start_time_null_transport_rtt(rtt_estimate);
+ estimator()->SetStartTimeNullHttpRtt(rtt_estimate);
EXPECT_LT(rtt_estimate, pool_->ConnectionTimeout());
}
// It would be nice to also test the timeouts in HttpProxyClientSocketPool.
+// Test that SocketTag passed into HttpProxyClientSocketPool is applied to
+// returned underlying TCP sockets.
+#if defined(OS_ANDROID)
+TEST_P(HttpProxyClientSocketPoolTest, Tag) {
+ Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0);
+ SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
+ SocketTag tag2(getuid(), 0x87654321);
+
+ // Verify requested socket is tagged properly.
+ int rv = handle_.Init("a", CreateNoTunnelParams(), LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), pool_.get(), NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle_.is_initialized());
+ ASSERT_TRUE(handle_.socket());
+ EXPECT_TRUE(handle_.socket()->IsConnected());
+ EXPECT_EQ(socket_factory()->GetLastProducedSocket()->tag(), tag1);
+ EXPECT_TRUE(
+ socket_factory()->GetLastProducedSocket()->tagged_before_connected());
+
+ // Verify reused socket is retagged properly.
+ StreamSocket* socket = handle_.socket();
+ handle_.Reset();
+ rv = handle_.Init("a", CreateNoTunnelParams(), LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), pool_.get(), NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle_.socket());
+ EXPECT_TRUE(handle_.socket()->IsConnected());
+ EXPECT_EQ(handle_.socket(), socket);
+ EXPECT_EQ(socket_factory()->GetLastProducedSocket()->tag(), tag2);
+ handle_.socket()->Disconnect();
+ handle_.Reset();
+}
+#endif
+
} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket_unittest.cc b/chromium/net/http/http_proxy_client_socket_unittest.cc
new file mode 100644
index 00000000000..dd35006cebe
--- /dev/null
+++ b/chromium/net/http/http_proxy_client_socket_unittest.cc
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_proxy_client_socket.h"
+
+#include "build/build_config.h"
+#include "net/base/address_list.h"
+#include "net/base/host_port_pair.h"
+#include "net/log/test_net_log.h"
+#include "net/socket/next_proto.h"
+#include "net/socket/socket_tag.h"
+#include "net/socket/socket_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(HttpProxyClientSocketTest, Tag) {
+ StaticSocketDataProvider data;
+ TestNetLog log;
+ MockTaggingStreamSocket* tagging_sock =
+ new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>(
+ new MockTCPClientSocket(AddressList(), &log, &data)));
+
+ std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+ // |connection| takes ownership of |tagging_sock|, but keep a
+ // non-owning pointer to it.
+ connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
+ HttpProxyClientSocket socket(std::move(connection), "", HostPortPair(),
+ nullptr, false, false, NextProto(), false);
+
+ EXPECT_EQ(tagging_sock->tag(), SocketTag());
+#if defined(OS_ANDROID)
+ SocketTag tag(0x12345678, 0x87654321);
+ socket.ApplySocketTag(tag);
+ EXPECT_EQ(tagging_sock->tag(), tag);
+#endif // OS_ANDROID
+}
+
+} // namespace
+
+} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.cc b/chromium/net/http/http_proxy_client_socket_wrapper.cc
index cd7a4d3db1f..4d769956cfa 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper.cc
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.cc
@@ -12,7 +12,6 @@
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/values.h"
-#include "net/base/proxy_delegate.h"
#include "net/http/http_proxy_client_socket.h"
#include "net/http/http_response_info.h"
#include "net/log/net_log_event_type.h"
@@ -20,11 +19,13 @@
#include "net/log/net_log_source_type.h"
#include "net/quic/chromium/quic_proxy_client_socket.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/spdy/chromium/spdy_proxy_client_socket.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_session_pool.h"
#include "net/spdy/chromium/spdy_stream.h"
#include "net/ssl/ssl_cert_request_info.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
@@ -32,6 +33,7 @@ namespace net {
HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
base::TimeDelta connect_timeout_duration,
base::TimeDelta proxy_negotiation_timeout_duration,
@@ -47,11 +49,11 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
bool tunnel,
- ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log)
: next_state_(STATE_NONE),
group_name_(group_name),
priority_(priority),
+ initial_socket_tag_(socket_tag),
respect_limits_(respect_limits),
connect_timeout_duration_(connect_timeout_duration),
proxy_negotiation_timeout_duration_(proxy_negotiation_timeout_duration),
@@ -65,7 +67,6 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
spdy_session_pool_(spdy_session_pool),
has_restarted_(false),
tunnel_(tunnel),
- proxy_delegate_(proxy_delegate),
using_spdy_(false),
quic_stream_request_(quic_stream_factory),
http_auth_controller_(
@@ -186,7 +187,6 @@ int HttpProxyClientSocketWrapper::Connect(const CompletionCallback& callback) {
connect_callback_ = callback;
} else {
connect_timer_.Stop();
- NotifyProxyDelegateOfCompletion(rv);
}
return rv;
@@ -291,6 +291,19 @@ int64_t HttpProxyClientSocketWrapper::GetTotalReceivedBytes() const {
return transport_socket_->GetTotalReceivedBytes();
}
+void HttpProxyClientSocketWrapper::ApplySocketTag(const SocketTag& tag) {
+ // HttpProxyClientSocketPool only tags once connected, when transport_socket_
+ // is set. Socket tagging is not supported with tunneling. Socket tagging is
+ // also not supported with proxy auth so ApplySocketTag() won't be called with
+ // a specific (non-default) tag when transport_socket_ is cleared by
+ // RestartWithAuth().
+ if (tunnel_ || !transport_socket_) {
+ CHECK(tag == SocketTag());
+ } else {
+ transport_socket_->ApplySocketTag(tag);
+ }
+}
+
int HttpProxyClientSocketWrapper::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
@@ -299,11 +312,13 @@ int HttpProxyClientSocketWrapper::Read(IOBuffer* buf,
return ERR_SOCKET_NOT_CONNECTED;
}
-int HttpProxyClientSocketWrapper::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int HttpProxyClientSocketWrapper::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
if (transport_socket_)
- return transport_socket_->Write(buf, buf_len, callback);
+ return transport_socket_->Write(buf, buf_len, callback, traffic_annotation);
return ERR_SOCKET_NOT_CONNECTED;
}
@@ -337,7 +352,6 @@ void HttpProxyClientSocketWrapper::OnIOComplete(int result) {
int rv = DoLoop(result);
if (rv != ERR_IO_PENDING) {
connect_timer_.Stop();
- NotifyProxyDelegateOfCompletion(rv);
// May delete |this|.
base::ResetAndReturn(&connect_callback_).Run(rv);
}
@@ -427,7 +441,8 @@ int HttpProxyClientSocketWrapper::DoTransportConnect() {
next_state_ = STATE_TCP_CONNECT_COMPLETE;
transport_socket_handle_.reset(new ClientSocketHandle());
return transport_socket_handle_->Init(
- group_name_, transport_params_, priority_, respect_limits_,
+ group_name_, transport_params_, priority_, initial_socket_tag_,
+ respect_limits_,
base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
base::Unretained(this)),
transport_pool_, net_log_);
@@ -466,7 +481,7 @@ int HttpProxyClientSocketWrapper::DoSSLConnect() {
next_state_ = STATE_SSL_CONNECT_COMPLETE;
transport_socket_handle_.reset(new ClientSocketHandle());
return transport_socket_handle_->Init(
- group_name_, ssl_params_, priority_, respect_limits_,
+ group_name_, ssl_params_, priority_, initial_socket_tag_, respect_limits_,
base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
base::Unretained(this)),
ssl_pool_, net_log_);
@@ -548,9 +563,8 @@ int HttpProxyClientSocketWrapper::DoHttpProxyConnect() {
// Add a HttpProxy connection on top of the tcp socket.
transport_socket_.reset(new HttpProxyClientSocket(
- transport_socket_handle_.release(), user_agent_, endpoint_,
- GetDestination().host_port_pair(), http_auth_controller_.get(), tunnel_,
- using_spdy_, negotiated_protocol_, proxy_delegate_,
+ std::move(transport_socket_handle_), user_agent_, endpoint_,
+ http_auth_controller_.get(), tunnel_, using_spdy_, negotiated_protocol_,
ssl_params_.get() != nullptr));
return transport_socket_->Connect(base::Bind(
&HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
@@ -703,14 +717,6 @@ int HttpProxyClientSocketWrapper::DoRestartWithAuthComplete(int result) {
return result;
}
-void HttpProxyClientSocketWrapper::NotifyProxyDelegateOfCompletion(int result) {
- if (!proxy_delegate_)
- return;
-
- const HostPortPair& proxy_server = GetDestination().host_port_pair();
- proxy_delegate_->OnTunnelConnectCompleted(endpoint_, proxy_server, result);
-}
-
void HttpProxyClientSocketWrapper::SetConnectTimer(base::TimeDelta delay) {
connect_timer_.Stop();
connect_timer_.Start(FROM_HERE, delay, this,
@@ -734,8 +740,6 @@ void HttpProxyClientSocketWrapper::ConnectTimeout() {
}
}
- NotifyProxyDelegateOfCompletion(ERR_CONNECTION_TIMED_OUT);
-
CompletionCallback callback = connect_callback_;
Disconnect();
callback.Run(ERR_CONNECTION_TIMED_OUT);
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.h b/chromium/net/http/http_proxy_client_socket_wrapper.h
index 26974540839..66774cbb448 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper.h
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.h
@@ -26,6 +26,7 @@
#include "net/socket/ssl_client_socket_pool.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/chromium/spdy_session.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -35,7 +36,6 @@ class HttpAuthCache;
class HttpResponseInfo;
class HttpStream;
class IOBuffer;
-class ProxyDelegate;
class SpdySessionPool;
class SSLClientSocketPool;
class TransportClientSocketPool;
@@ -57,6 +57,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
HttpProxyClientSocketWrapper(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
base::TimeDelta connect_timeout_duration,
base::TimeDelta proxy_negotiation_timeout_duration,
@@ -72,7 +73,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
bool tunnel,
- ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log);
// On destruction Disconnect() is called.
@@ -108,6 +108,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
void ClearConnectionAttempts() override;
void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -115,7 +116,8 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
@@ -169,8 +171,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
int DoRestartWithAuth();
int DoRestartWithAuthComplete(int result);
- void NotifyProxyDelegateOfCompletion(int result);
-
void SetConnectTimer(base::TimeDelta duration);
void ConnectTimeout();
@@ -180,6 +180,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
const std::string group_name_;
RequestPriority priority_;
+ const SocketTag initial_socket_tag_;
ClientSocketPool::RespectLimits respect_limits_;
const base::TimeDelta connect_timeout_duration_;
const base::TimeDelta proxy_negotiation_timeout_duration_;
@@ -197,7 +198,6 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
bool has_restarted_;
const bool tunnel_;
- ProxyDelegate* const proxy_delegate_;
bool using_spdy_;
NextProto negotiated_protocol_;
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc b/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
index 63398086c1c..9d5e034bf1e 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -7,8 +7,8 @@
#include <cstdio>
#include <memory>
-#include "net/cert/cert_verifier.h"
-#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cert/do_nothing_ct_verifier.h"
+#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_cache.h"
#include "net/http/http_auth_handler_factory.h"
@@ -21,6 +21,7 @@
#include "net/quic/core/quic_versions.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
@@ -58,7 +59,7 @@ class MockSSLConfigService : public SSLConfigService {
namespace test {
class HttpProxyClientSocketWrapperTest
- : public ::testing::TestWithParam<QuicTransportVersion> {
+ : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
protected:
static const bool kFin = true;
static const bool kIncludeVersion = true;
@@ -68,22 +69,25 @@ class HttpProxyClientSocketWrapperTest
: proxy_host_port_(kProxyHost, kProxyPort),
endpoint_host_port_(kOriginHost, kOriginPort),
ssl_config_service_(new MockSSLConfigService()),
- cert_verifier_(CertVerifier::CreateDefault()),
+ cert_verifier_(new MockCertVerifier()),
channel_id_service_(
new ChannelIDService(new DefaultChannelIDStore(nullptr))),
- cert_transparency_verifier_(new MultiLogCTVerifier()),
+ cert_transparency_verifier_(new DoNothingCTVerifier()),
random_generator_(0),
- quic_version_(GetParam()),
+ quic_version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
client_maker_(quic_version_,
0,
&clock_,
kProxyHost,
- Perspective::IS_CLIENT),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
server_maker_(quic_version_,
0,
&clock_,
kProxyHost,
- Perspective::IS_SERVER),
+ Perspective::IS_SERVER,
+ false),
header_stream_offset_(0),
response_offset_(0),
store_server_configs_in_properties_(false),
@@ -125,9 +129,11 @@ class HttpProxyClientSocketWrapperTest
/*connect_using_default_network=*/true,
migrate_sessions_on_network_change_, migrate_sessions_early_,
migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
allow_server_migration_, race_cert_verification_, estimate_initial_rtt_,
- connection_options_, client_connection_options_,
- /*enable_token_binding=*/false));
+ client_headers_include_h2_stream_dependency_, connection_options_,
+ client_connection_options_, /*enable_token_binding=*/false));
}
void PopulateConnectRequestIR(SpdyHeaderBlock* block) {
@@ -149,7 +155,7 @@ class HttpProxyClientSocketWrapperTest
return client_maker_.MakeRequestHeadersPacket(
packet_number, kClientDataStreamId1, kIncludeVersion, !kFin,
ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- std::move(block), nullptr, &header_stream_offset_);
+ std::move(block), 0, nullptr, &header_stream_offset_);
}
std::unique_ptr<QuicReceivedPacket> ConstructServerConnectReplyPacket(
@@ -197,15 +203,16 @@ class HttpProxyClientSocketWrapperTest
scoped_refptr<SSLConfigService> ssl_config_service_;
MockClientSocketFactory socket_factory_;
HttpServerPropertiesImpl http_server_properties_;
- std::unique_ptr<CertVerifier> cert_verifier_;
+ std::unique_ptr<MockCertVerifier> cert_verifier_;
CTPolicyEnforcer ct_policy_enforcer_;
std::unique_ptr<ChannelIDService> channel_id_service_;
TransportSecurityState transport_security_state_;
- std::unique_ptr<CTVerifier> cert_transparency_verifier_;
+ std::unique_ptr<DoNothingCTVerifier> cert_transparency_verifier_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
MockRandom random_generator_;
- QuicTransportVersion quic_version_;
+ const QuicTransportVersion quic_version_;
+ const bool client_headers_include_h2_stream_dependency_;
QuicTestPacketMaker client_maker_;
QuicTestPacketMaker server_maker_;
QuicStreamOffset header_stream_offset_;
@@ -260,6 +267,7 @@ TEST_P(HttpProxyClientSocketWrapperTest, QuicProxy) {
client_socket_wrapper_.reset(new HttpProxyClientSocketWrapper(
/*group_name=*/std::string(), /*requiest_priority=*/DEFAULT_PRIORITY,
+ /*socket_tag=*/SocketTag(),
/*respect_limits=*/ClientSocketPool::RespectLimits::DISABLED,
/*connect_timeout_duration=*/base::TimeDelta::FromHours(1),
/*proxy_negotiation_timeout_duration=*/base::TimeDelta::FromHours(1),
@@ -267,7 +275,7 @@ TEST_P(HttpProxyClientSocketWrapperTest, QuicProxy) {
/*transport_params=*/nullptr, ssl_params, quic_version_, kUserAgent,
endpoint_host_port_, &http_auth_cache_, http_auth_handler_factory_.get(),
/*spdy_session_pool=*/nullptr, quic_stream_factory_.get(),
- /*tunnel=*/true, /*proxy_delegate=*/nullptr, net_log_));
+ /*tunnel=*/true, net_log_));
TestCompletionCallback callback;
client_socket_wrapper_->Connect(callback.callback());
@@ -279,9 +287,11 @@ TEST_P(HttpProxyClientSocketWrapperTest, QuicProxy) {
EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
}
-INSTANTIATE_TEST_CASE_P(Version,
- HttpProxyClientSocketWrapperTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ HttpProxyClientSocketWrapperTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
}; // namespace test
}; // namespace net
diff --git a/chromium/net/http/http_request_info.h b/chromium/net/http/http_request_info.h
index ceca265be3b..419227ca2a4 100644
--- a/chromium/net/http/http_request_info.h
+++ b/chromium/net/http/http_request_info.h
@@ -10,6 +10,7 @@
#include "net/base/net_export.h"
#include "net/base/privacy_mode.h"
#include "net/http/http_request_headers.h"
+#include "net/socket/socket_tag.h"
#include "url/gurl.h"
namespace net {
@@ -56,6 +57,9 @@ struct NET_EXPORT HttpRequestInfo {
// If present, the host of the referrer whose TokenBindingID should be
// included in a referred TokenBinding.
std::string token_binding_referrer;
+
+ // Tag applied to all sockets used to service request.
+ SocketTag socket_tag;
};
} // namespace net
diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc
index 9c5dfa89a2d..c3a0fafacdb 100644
--- a/chromium/net/http/http_response_body_drainer_unittest.cc
+++ b/chromium/net/http/http_response_body_drainer_unittest.cc
@@ -88,6 +88,7 @@ class MockHttpStream : public HttpStream {
// HttpStream implementation.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override {
diff --git a/chromium/net/http/http_security_headers_unittest.cc b/chromium/net/http/http_security_headers_unittest.cc
index 1171e333269..8ca4ccab489 100644
--- a/chromium/net/http/http_security_headers_unittest.cc
+++ b/chromium/net/http/http_security_headers_unittest.cc
@@ -37,12 +37,12 @@ std::string GetTestPinImpl(uint8_t label, HashValueTag tag, bool quoted) {
reinterpret_cast<char*>(hash_value.data()), hash_value.size()), &base64);
std::string ret;
- switch (hash_value.tag) {
+ switch (hash_value.tag()) {
case HASH_VALUE_SHA256:
ret = "pin-sha256=";
break;
default:
- NOTREACHED() << "Unknown HashValueTag " << hash_value.tag;
+ NOTREACHED() << "Unknown HashValueTag " << hash_value.tag();
return std::string("ERROR");
}
if (quoted)
diff --git a/chromium/net/http/http_server_properties.h b/chromium/net/http/http_server_properties.h
index b8efe93258d..22f0a5db0f5 100644
--- a/chromium/net/http/http_server_properties.h
+++ b/chromium/net/http/http_server_properties.h
@@ -13,6 +13,7 @@
#include <tuple>
#include <vector>
+#include "base/callback.h"
#include "base/containers/mru_cache.h"
#include "base/macros.h"
#include "base/time/time.h"
@@ -313,8 +314,10 @@ class NET_EXPORT HttpServerProperties {
HttpServerProperties() {}
virtual ~HttpServerProperties() {}
- // Deletes all data.
- virtual void Clear() = 0;
+ // Deletes all data. If |callback| is non-null, flushes data to disk
+ // and invokes the callback asynchronously once changes have been written to
+ // disk.
+ virtual void Clear(base::OnceClosure callback) = 0;
// Returns true if |server| supports a network protocol which honors
// request prioritization.
diff --git a/chromium/net/http/http_server_properties_impl.cc b/chromium/net/http/http_server_properties_impl.cc
index 37248e625b1..ccd60cb109a 100644
--- a/chromium/net/http/http_server_properties_impl.cc
+++ b/chromium/net/http/http_server_properties_impl.cc
@@ -21,7 +21,9 @@
namespace net {
HttpServerPropertiesImpl::HttpServerPropertiesImpl(base::TickClock* clock)
- : broken_alternative_services_(this, clock ? clock : &default_clock_),
+ : broken_alternative_services_(
+ this,
+ clock ? clock : base::DefaultTickClock::GetInstance()),
quic_server_info_map_(kDefaultMaxQuicServerEntries),
max_server_configs_stored_in_properties_(kDefaultMaxQuicServerEntries) {
canonical_suffixes_.push_back(".ggpht.com");
@@ -175,7 +177,7 @@ HttpServerPropertiesImpl::recently_broken_alternative_services() const {
return broken_alternative_services_.recently_broken_alternative_services();
}
-void HttpServerPropertiesImpl::Clear() {
+void HttpServerPropertiesImpl::Clear(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
spdy_servers_map_.Clear();
alternative_service_map_.Clear();
@@ -185,6 +187,11 @@ void HttpServerPropertiesImpl::Clear() {
server_network_stats_map_.Clear();
quic_server_info_map_.Clear();
canonical_server_info_map_.clear();
+
+ if (!callback.is_null()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ std::move(callback));
+ }
}
bool HttpServerPropertiesImpl::SupportsRequestPriority(
diff --git a/chromium/net/http/http_server_properties_impl.h b/chromium/net/http/http_server_properties_impl.h
index dbb0ffdd096..7967e86adc9 100644
--- a/chromium/net/http/http_server_properties_impl.h
+++ b/chromium/net/http/http_server_properties_impl.h
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
@@ -86,7 +87,7 @@ class NET_EXPORT HttpServerPropertiesImpl
// HttpServerProperties methods:
// -----------------------------
- void Clear() override;
+ void Clear(base::OnceClosure callback) override;
bool SupportsRequestPriority(const url::SchemeHostPort& server) override;
bool GetSupportsSpdy(const url::SchemeHostPort& server) override;
void SetSupportsSpdy(const url::SchemeHostPort& server,
@@ -176,8 +177,6 @@ class NET_EXPORT HttpServerPropertiesImpl
// have an entry associated with |server|, the method will add one.
void UpdateCanonicalServerInfoMap(const QuicServerId& server);
- base::DefaultTickClock default_clock_;
-
SpdyServersMap spdy_servers_map_;
Http11ServerHostPortSet http11_servers_;
diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc
index 32f80acf5c9..c3b04f60ae3 100644
--- a/chromium/net/http/http_server_properties_impl_unittest.cc
+++ b/chromium/net/http/http_server_properties_impl_unittest.cc
@@ -280,9 +280,21 @@ TEST_F(SpdyServerPropertiesTest, Clear) {
EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google));
EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_mail));
- impl_.Clear();
+ base::RunLoop run_loop;
+ bool callback_invoked_ = false;
+ impl_.Clear(base::BindOnce(
+ [](bool* callback_invoked, base::OnceClosure quit_closure) {
+ *callback_invoked = true;
+ std::move(quit_closure).Run();
+ },
+ &callback_invoked_, run_loop.QuitClosure()));
EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_google));
EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail));
+
+ // Callback should be run asynchronously.
+ EXPECT_FALSE(callback_invoked_);
+ run_loop.Run();
+ EXPECT_TRUE(callback_invoked_);
}
TEST_F(SpdyServerPropertiesTest, MRUOfSpdyServersMap) {
@@ -329,7 +341,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
EXPECT_EQ(alternative_service,
alternative_service_info_vector[0].alternative_service());
- impl_.Clear();
+ impl_.Clear(base::OnceClosure());
EXPECT_FALSE(HasAlternativeService(test_server));
}
@@ -933,7 +945,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
"bar.c.youtube.com", 1234);
SetAlternativeService(canonical_server, canonical_alternative_service);
- impl_.Clear();
+ impl_.Clear(base::OnceClosure());
EXPECT_FALSE(HasAlternativeService(test_server));
}
@@ -1093,7 +1105,7 @@ TEST_F(SupportsQuicServerPropertiesTest, SetSupportsQuic) {
EXPECT_TRUE(impl_.GetSupportsQuic(&address));
EXPECT_EQ(actual_address, address);
- impl_.Clear();
+ impl_.Clear(base::OnceClosure());
EXPECT_FALSE(impl_.GetSupportsQuic(&address));
}
@@ -1186,7 +1198,7 @@ TEST_F(ServerNetworkStatsServerPropertiesTest, SetServerNetworkStats) {
// Https server should have nothing set for server network stats.
EXPECT_EQ(NULL, impl_.GetServerNetworkStats(foo_https_server));
- impl_.Clear();
+ impl_.Clear(base::OnceClosure());
EXPECT_EQ(NULL, impl_.GetServerNetworkStats(foo_http_server));
EXPECT_EQ(NULL, impl_.GetServerNetworkStats(foo_https_server));
}
@@ -1305,7 +1317,7 @@ TEST_F(QuicServerInfoServerPropertiesTest, SetQuicServerInfo) {
EXPECT_EQ(1u, impl_.quic_server_info_map().size());
EXPECT_EQ(quic_server_info1, *(impl_.GetQuicServerInfo(quic_server_id)));
- impl_.Clear();
+ impl_.Clear(base::OnceClosure());
EXPECT_EQ(0u, impl_.quic_server_info_map().size());
EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(quic_server_id));
}
diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc
index 389487143e3..af84c1d48ba 100644
--- a/chromium/net/http/http_server_properties_manager.cc
+++ b/chromium/net/http/http_server_properties_manager.cc
@@ -86,6 +86,16 @@ struct ServerPref {
ServerNetworkStats server_network_stats;
};
+QuicServerId QuicServerIdFromString(const std::string& str) {
+ GURL url(str);
+ if (!url.is_valid()) {
+ return QuicServerId();
+ }
+ return QuicServerId(HostPortPair::FromURL(url), url.path_piece() == "/private"
+ ? PRIVACY_MODE_ENABLED
+ : PRIVACY_MODE_DISABLED);
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -98,7 +108,7 @@ HttpServerPropertiesManager::HttpServerPropertiesManager(
NetLog* net_log,
base::TickClock* clock)
: pref_delegate_(std::move(pref_delegate)),
- clock_(clock ? clock : &default_clock_),
+ clock_(clock ? clock : base::DefaultTickClock::GetInstance()),
net_log_(
NetLogWithSource::Make(net_log,
NetLogSourceType::HTTP_SERVER_PROPERTIES)) {
@@ -106,9 +116,9 @@ HttpServerPropertiesManager::HttpServerPropertiesManager(
DCHECK(pref_delegate_);
DCHECK(clock_);
- pref_delegate_->StartListeningForUpdates(
- base::Bind(&HttpServerPropertiesManager::OnHttpServerPropertiesChanged,
- base::Unretained(this)));
+ pref_delegate_->StartListeningForUpdates(base::BindRepeating(
+ &HttpServerPropertiesManager::OnHttpServerPropertiesChanged,
+ base::Unretained(this)));
net_log_.BeginEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_INITIALIZATION);
http_server_properties_impl_.reset(new HttpServerPropertiesImpl(clock_));
@@ -117,7 +127,7 @@ HttpServerPropertiesManager::HttpServerPropertiesManager(
HttpServerPropertiesManager::~HttpServerPropertiesManager() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Flush settings on destruction.
- UpdatePrefsFromCache();
+ UpdatePrefsFromCache(base::OnceClosure());
}
// static
@@ -131,11 +141,11 @@ void HttpServerPropertiesManager::SetVersion(
http_server_properties_dict->SetInteger(kVersionKey, version_number);
}
-void HttpServerPropertiesManager::Clear() {
+void HttpServerPropertiesManager::Clear(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- http_server_properties_impl_->Clear();
- UpdatePrefsFromCache();
+ http_server_properties_impl_->Clear(base::OnceClosure());
+ UpdatePrefsFromCache(std::move(callback));
}
bool HttpServerPropertiesManager::SupportsRequestPriority(
@@ -773,7 +783,6 @@ bool HttpServerPropertiesManager::ParseAlternativeServiceInfoDictOfServer(
alternative_service_info->set_alternative_service(alternative_service);
// Expiration is optional, defaults to one day.
- base::Time expiration;
if (!dict.HasKey(kExpirationKey)) {
alternative_service_info->set_expiration(base::Time::Now() +
base::TimeDelta::FromDays(1));
@@ -928,9 +937,8 @@ bool HttpServerPropertiesManager::AddToQuicServerInfoMap(
it.Advance()) {
// Get quic_server_id.
const std::string& quic_server_id_str = it.key();
- QuicServerId quic_server_id;
- QuicHostnameUtils::StringToQuicServerId(quic_server_id_str,
- &quic_server_id);
+
+ QuicServerId quic_server_id = QuicServerIdFromString(quic_server_id_str);
if (quic_server_id.host().empty()) {
DVLOG(1) << "Malformed http_server_properties for quic server: "
<< quic_server_id_str;
@@ -969,15 +977,17 @@ void HttpServerPropertiesManager::ScheduleUpdatePrefs(Location location) {
return;
network_prefs_update_timer_.Start(
- FROM_HERE, kUpdatePrefsDelay, this,
- &HttpServerPropertiesManager::UpdatePrefsFromCache);
+ FROM_HERE, kUpdatePrefsDelay,
+ base::Bind(&HttpServerPropertiesManager::UpdatePrefsFromCache,
+ base::Unretained(this), base::Passed(base::OnceClosure())));
// TODO(rtenneti): Delete the following histogram after collecting some data.
UMA_HISTOGRAM_ENUMERATION("Net.HttpServerProperties.UpdatePrefs", location,
HttpServerPropertiesManager::NUM_LOCATIONS);
}
-void HttpServerPropertiesManager::UpdatePrefsFromCache() {
+void HttpServerPropertiesManager::UpdatePrefsFromCache(
+ base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
typedef base::MRUCache<url::SchemeHostPort, ServerPref> ServerPrefMap;
@@ -1105,7 +1115,8 @@ void HttpServerPropertiesManager::UpdatePrefsFromCache() {
&http_server_properties_dict);
setting_prefs_ = true;
- pref_delegate_->SetServerProperties(http_server_properties_dict);
+ pref_delegate_->SetServerProperties(http_server_properties_dict,
+ std::move(callback));
setting_prefs_ = false;
net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS,
diff --git a/chromium/net/http/http_server_properties_manager.h b/chromium/net/http/http_server_properties_manager.h
index b77b9057c5d..5f346262100 100644
--- a/chromium/net/http/http_server_properties_manager.h
+++ b/chromium/net/http/http_server_properties_manager.h
@@ -11,6 +11,7 @@
#include <string>
#include <vector>
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -51,13 +52,17 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
// Returns nullptr if the pref system has no data for the server properties.
virtual const base::DictionaryValue* GetServerProperties() const = 0;
- // Sets the server properties to the given value.
- virtual void SetServerProperties(const base::DictionaryValue& value) = 0;
+ // Sets the server properties to the given value. If |callback| is
+ // non-empty, flushes data to persistent storage and invokes |callback|
+ // asynchronously when complete.
+ virtual void SetServerProperties(const base::DictionaryValue& value,
+ base::OnceClosure callback) = 0;
// Starts listening for external storage changes. There will only be one
// callback active at a time. The first time the |callback| is invoked is
// expected to mean the initial pref store values have been loaded.
- virtual void StartListeningForUpdates(const base::Closure& callback) = 0;
+ virtual void StartListeningForUpdates(
+ const base::RepeatingClosure& callback) = 0;
};
// Create an instance of the HttpServerPropertiesManager.
@@ -83,7 +88,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
// HttpServerProperties methods:
// ----------------------------------
- void Clear() override;
+ void Clear(base::OnceClosure callback) override;
bool SupportsRequestPriority(const url::SchemeHostPort& server) override;
bool GetSupportsSpdy(const url::SchemeHostPort& server) override;
void SetSupportsSpdy(const url::SchemeHostPort& server,
@@ -182,8 +187,9 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
void ScheduleUpdatePrefs(Location location);
// Update prefs::kHttpServerProperties in preferences with the cached data
- // from |http_server_properties_impl_|.
- void UpdatePrefsFromCache();
+ // from |http_server_properties_impl_|. Invokes |callback| when changes have
+ // been committed, if non-null.
+ void UpdatePrefsFromCache(base::OnceClosure callback);
private:
FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest,
@@ -253,8 +259,6 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
recently_broken_alternative_services,
base::DictionaryValue* http_server_properties_dict);
- base::DefaultTickClock default_clock_;
-
// Used to post cache update tasks.
base::OneShotTimer pref_cache_update_timer_;
diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc
index e5eea969abc..20e835cf060 100644
--- a/chromium/net/http/http_server_properties_manager_unittest.cc
+++ b/chromium/net/http/http_server_properties_manager_unittest.cc
@@ -46,7 +46,8 @@ class MockPrefDelegate : public net::HttpServerPropertiesManager::PrefDelegate {
const base::DictionaryValue* GetServerProperties() const override {
return &prefs_;
}
- void SetServerProperties(const base::DictionaryValue& value) override {
+ void SetServerProperties(const base::DictionaryValue& value,
+ base::OnceClosure callback) override {
prefs_.Clear();
prefs_.MergeDictionary(&value);
++num_pref_updates_;
@@ -54,6 +55,7 @@ class MockPrefDelegate : public net::HttpServerPropertiesManager::PrefDelegate {
prefs_changed_callback_.Run();
if (!extra_prefs_changed_callback_.is_null())
extra_prefs_changed_callback_.Run();
+ set_properties_callback_ = std::move(callback);
}
void StartListeningForUpdates(const base::Closure& callback) override {
CHECK(prefs_changed_callback_.is_null());
@@ -80,12 +82,20 @@ class MockPrefDelegate : public net::HttpServerPropertiesManager::PrefDelegate {
extra_prefs_changed_callback_ = callback;
}
+ // Returns the base::OnceCallback, if any, passed to the last call to
+ // SetServerProperties().
+ base::OnceClosure GetSetPropertiesCallback() {
+ return std::move(set_properties_callback_);
+ }
+
private:
base::DictionaryValue prefs_;
base::Closure prefs_changed_callback_;
base::Closure extra_prefs_changed_callback_;
int num_pref_updates_ = 0;
+ base::OnceClosure set_properties_callback_;
+
DISALLOW_COPY_AND_ASSIGN(MockPrefDelegate);
};
@@ -104,10 +114,11 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
advertised_versions_ = HttpNetworkSession::Params().quic_supported_versions;
pref_delegate_ = new MockPrefDelegate;
- net_test_task_runner_clock_ = test_task_runner_->GetMockTickClock();
+ clock_ = test_task_runner_->GetMockTickClock();
+ net_test_task_runner_clock_ = clock_.get();
http_server_props_manager_ = std::make_unique<HttpServerPropertiesManager>(
base::WrapUnique(pref_delegate_), /*net_log=*/nullptr,
- net_test_task_runner_clock_.get());
+ net_test_task_runner_clock_);
EXPECT_FALSE(http_server_props_manager_->IsInitialized());
pref_delegate_->SetPrefs(base::DictionaryValue());
@@ -140,7 +151,11 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
// Overrides the main thread's message loop with a mock tick clock.
base::ScopedMockTimeMessageLoopTaskRunner test_task_runner_;
- std::unique_ptr<base::TickClock> net_test_task_runner_clock_;
+ // TODO(tzik): Remove |clock_| after updating GetMockTickClock to own the
+ // instance.
+ std::unique_ptr<base::TickClock> clock_;
+
+ base::TickClock* net_test_task_runner_clock_;
private:
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
@@ -802,8 +817,14 @@ TEST_P(HttpServerPropertiesManagerTest, Clear) {
// Clear http server data, which should instantly update prefs.
EXPECT_EQ(0, pref_delegate_->GetAndClearNumPrefUpdates());
- http_server_props_manager_->Clear();
+ bool callback_invoked_ = false;
+ http_server_props_manager_->Clear(
+ base::BindOnce([](bool* callback_invoked) { *callback_invoked = true; },
+ &callback_invoked_));
EXPECT_EQ(1, pref_delegate_->GetAndClearNumPrefUpdates());
+ EXPECT_FALSE(callback_invoked_);
+ std::move(pref_delegate_->GetSetPropertiesCallback()).Run();
+ EXPECT_TRUE(callback_invoked_);
EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
broken_alternative_service));
diff --git a/chromium/net/http/http_stream.h b/chromium/net/http/http_stream.h
index 1763722ab02..35146de3c60 100644
--- a/chromium/net/http/http_stream.h
+++ b/chromium/net/http/http_stream.h
@@ -51,9 +51,12 @@ class NET_EXPORT_PRIVATE HttpStream {
// Initialize stream. Must be called before calling SendRequest().
// The consumer should ensure that request_info points to a valid value till
// final response headers are received; after that point, the HttpStream
- // will not access |*request_info| and it may be deleted.
+ // will not access |*request_info| and it may be deleted. If |can_send_early|
+ // is true, this stream may send data early without confirming the handshake
+ // if this is a resumption of a previously established connection.
// Returns a net error code, possibly ERR_IO_PENDING.
virtual int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) = 0;
diff --git a/chromium/net/http/http_stream_factory_impl.cc b/chromium/net/http/http_stream_factory_impl.cc
index caaaa315110..ffc73e280a6 100644
--- a/chromium/net/http/http_stream_factory_impl.cc
+++ b/chromium/net/http/http_stream_factory_impl.cc
@@ -31,17 +31,10 @@
namespace net {
-HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session,
- bool for_websockets)
- : session_(session),
- job_factory_(new JobFactory()),
- for_websockets_(for_websockets),
- last_logged_job_controller_count_(0) {}
-
-HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {
- UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfJobControllerAtShutDown",
- job_controller_set_.size());
-}
+HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session)
+ : session_(session), job_factory_(new JobFactory()) {}
+
+HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {}
std::unique_ptr<HttpStreamRequest> HttpStreamFactoryImpl::RequestStream(
const HttpRequestInfo& request_info,
@@ -52,11 +45,10 @@ std::unique_ptr<HttpStreamRequest> HttpStreamFactoryImpl::RequestStream(
bool enable_ip_based_pooling,
bool enable_alternative_services,
const NetLogWithSource& net_log) {
- DCHECK(!for_websockets_);
return RequestStreamInternal(
request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- nullptr, HttpStreamRequest::HTTP_STREAM, enable_ip_based_pooling,
- enable_alternative_services, net_log);
+ nullptr, HttpStreamRequest::HTTP_STREAM, false /* is_websocket */,
+ enable_ip_based_pooling, enable_alternative_services, net_log);
}
std::unique_ptr<HttpStreamRequest>
@@ -70,12 +62,11 @@ HttpStreamFactoryImpl::RequestWebSocketHandshakeStream(
bool enable_ip_based_pooling,
bool enable_alternative_services,
const NetLogWithSource& net_log) {
- DCHECK(for_websockets_);
DCHECK(create_helper);
return RequestStreamInternal(
request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- create_helper, HttpStreamRequest::HTTP_STREAM, enable_ip_based_pooling,
- enable_alternative_services, net_log);
+ create_helper, HttpStreamRequest::HTTP_STREAM, true /* is_websocket */,
+ enable_ip_based_pooling, enable_alternative_services, net_log);
}
std::unique_ptr<HttpStreamRequest>
@@ -88,12 +79,12 @@ HttpStreamFactoryImpl::RequestBidirectionalStreamImpl(
bool enable_ip_based_pooling,
bool enable_alternative_services,
const NetLogWithSource& net_log) {
- DCHECK(!for_websockets_);
DCHECK(request_info.url.SchemeIs(url::kHttpsScheme));
return RequestStreamInternal(
request_info, priority, server_ssl_config, proxy_ssl_config, delegate,
- nullptr, HttpStreamRequest::BIDIRECTIONAL_STREAM, enable_ip_based_pooling,
+ nullptr, HttpStreamRequest::BIDIRECTIONAL_STREAM,
+ false /* is_websocket */, enable_ip_based_pooling,
enable_alternative_services, net_log);
}
@@ -106,14 +97,13 @@ std::unique_ptr<HttpStreamRequest> HttpStreamFactoryImpl::RequestStreamInternal(
WebSocketHandshakeStreamBase::CreateHelper*
websocket_handshake_stream_create_helper,
HttpStreamRequest::StreamType stream_type,
+ bool is_websocket,
bool enable_ip_based_pooling,
bool enable_alternative_services,
const NetLogWithSource& net_log) {
- AddJobControllerCountToHistograms();
-
auto job_controller = std::make_unique<JobController>(
this, delegate, session_, job_factory_.get(), request_info,
- /* is_preconnect = */ false, enable_ip_based_pooling,
+ /* is_preconnect = */ false, is_websocket, enable_ip_based_pooling,
enable_alternative_services, server_ssl_config, proxy_ssl_config);
JobController* job_controller_raw_ptr = job_controller.get();
job_controller_set_.insert(std::move(job_controller));
@@ -127,8 +117,6 @@ void HttpStreamFactoryImpl::PreconnectStreams(
const HttpRequestInfo& request_info) {
DCHECK(request_info.url.is_valid());
- AddJobControllerCountToHistograms();
-
SSLConfig server_ssl_config;
SSLConfig proxy_ssl_config;
session_->GetSSLConfig(request_info, &server_ssl_config, &proxy_ssl_config);
@@ -136,11 +124,10 @@ void HttpStreamFactoryImpl::PreconnectStreams(
server_ssl_config.verify_ev_cert = true;
proxy_ssl_config.verify_ev_cert = true;
- DCHECK(!for_websockets_);
-
auto job_controller = std::make_unique<JobController>(
this, nullptr, session_, job_factory_.get(), request_info,
/* is_preconnect = */ true,
+ /* is_websocket = */ false,
/* enable_ip_based_pooling = */ true,
/* enable_alternative_services = */ true, server_ssl_config,
proxy_ssl_config);
@@ -244,45 +231,6 @@ bool HttpStreamFactoryImpl::ProxyServerSupportsPriorities(
scheme_host_port);
}
-void HttpStreamFactoryImpl::AddJobControllerCountToHistograms() {
- // Only log the count of JobControllers when the count is hitting one of the
- // boundaries for the first time which is a multiple of 1000: 1000, 2000,
- // 3000, etc.
- if (job_controller_set_.size() % 1000 != 0 ||
- job_controller_set_.size() <= last_logged_job_controller_count_) {
- return;
- }
- last_logged_job_controller_count_ = job_controller_set_.size();
-
- UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfJobController",
- job_controller_set_.size());
-
- size_t num_controllers_with_request = 0;
- size_t num_controllers_for_preconnect = 0;
- for (const auto& job_controller : job_controller_set_) {
- // Additionally log the states of the jobs.
- job_controller->LogHistograms();
- // For a preconnect controller, it should have exactly the main job.
- if (job_controller->is_preconnect()) {
- num_controllers_for_preconnect++;
- continue;
- }
- // For non-preconnects.
- if (job_controller->HasPendingRequest())
- num_controllers_with_request++;
- }
- UMA_HISTOGRAM_COUNTS_1M(
- "Net.JobControllerSet.CountOfJobController.Preconnect",
- num_controllers_for_preconnect);
- UMA_HISTOGRAM_COUNTS_1M(
- "Net.JobControllerSet.CountOfJobController.NonPreconnect.PendingRequest",
- num_controllers_with_request);
- UMA_HISTOGRAM_COUNTS_1M(
- "Net.JobControllerSet.CountOfJobController.NonPreconnect.RequestGone",
- job_controller_set_.size() - num_controllers_for_preconnect -
- num_controllers_with_request);
-}
-
void HttpStreamFactoryImpl::DumpMemoryStats(
base::trace_event::ProcessMemoryDump* pmd,
const std::string& parent_absolute_name) const {
diff --git a/chromium/net/http/http_stream_factory_impl.h b/chromium/net/http/http_stream_factory_impl.h
index 058d702a440..30480ed5347 100644
--- a/chromium/net/http/http_stream_factory_impl.h
+++ b/chromium/net/http/http_stream_factory_impl.h
@@ -36,10 +36,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
class NET_EXPORT_PRIVATE JobController;
class NET_EXPORT_PRIVATE JobFactory;
class NET_EXPORT_PRIVATE Request;
- // RequestStream may only be called if |for_websockets| is false.
- // RequestWebSocketHandshakeStream may only be called if |for_websockets|
- // is true.
- HttpStreamFactoryImpl(HttpNetworkSession* session, bool for_websockets);
+ HttpStreamFactoryImpl(HttpNetworkSession* session);
~HttpStreamFactoryImpl() override;
// HttpStreamFactory interface
@@ -126,6 +123,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
HttpStreamRequest::Delegate* delegate,
WebSocketHandshakeStreamBase::CreateHelper* create_helper,
HttpStreamRequest::StreamType stream_type,
+ bool is_websocket,
bool enable_ip_based_pooling,
bool enable_alternative_services,
const NetLogWithSource& net_log);
@@ -157,11 +155,6 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
// priorities.
bool ProxyServerSupportsPriorities(const ProxyInfo& proxy_info) const;
- // Adds the count of JobControllers that are not completed to UMA histogram if
- // the count is a multiple of 100: 100, 200, 400, etc. Break down
- // JobControllers count based on the type of JobController.
- void AddJobControllerCountToHistograms();
-
HttpNetworkSession* const session_;
// All Requests/Preconnects are assigned with a JobController to manage
@@ -178,11 +171,6 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
// preconnects should be skipped.
std::set<PreconnectingProxyServer> preconnecting_proxy_servers_;
- const bool for_websockets_;
-
- // The count of JobControllers that was most recently logged to histograms.
- size_t last_logged_job_controller_count_;
-
DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImpl);
};
diff --git a/chromium/net/http/http_stream_factory_impl_job.cc b/chromium/net/http/http_stream_factory_impl_job.cc
index 8b1a2a49a23..0a5801a0835 100644
--- a/chromium/net/http/http_stream_factory_impl_job.cc
+++ b/chromium/net/http/http_stream_factory_impl_job.cc
@@ -165,6 +165,7 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate,
NextProto alternative_protocol,
QuicTransportVersion quic_version,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log)
: request_info_(request_info),
@@ -177,11 +178,11 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate,
io_callback_(base::Bind(&Job::OnIOComplete, base::Unretained(this))),
connection_(new ClientSocketHandle),
session_(session),
- state_(STATE_NONE),
next_state_(STATE_NONE),
destination_(destination),
origin_url_(origin_url),
alternative_proxy_server_(alternative_proxy_server),
+ is_websocket_(is_websocket),
enable_ip_based_pooling_(enable_ip_based_pooling),
delegate_(delegate),
job_type_(job_type),
@@ -195,11 +196,13 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate,
using_spdy_(false),
should_reconsider_proxy_(false),
quic_request_(session_->quic_stream_factory()),
+ expect_on_quic_host_resolution_(false),
using_existing_quic_session_(false),
establishing_tunnel_(false),
was_alpn_negotiated_(false),
negotiated_protocol_(kProtoUnknown),
num_streams_(0),
+ pushed_stream_id_(kNoPushedStreamFound),
spdy_session_direct_(
!(proxy_info.is_https() && origin_url_.SchemeIs(url::kHttpScheme))),
spdy_session_key_(using_quic_
@@ -244,6 +247,9 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate,
if (using_quic_) {
DCHECK(session_->IsQuicEnabled());
}
+ if (job_type_ == PRECONNECT || is_websocket_) {
+ DCHECK(request_info_.socket_tag == SocketTag());
+ }
}
HttpStreamFactoryImpl::Job::~Job() {
@@ -367,20 +373,6 @@ const ProxyInfo& HttpStreamFactoryImpl::Job::proxy_info() const {
return proxy_info_;
}
-void HttpStreamFactoryImpl::Job::LogHistograms() const {
- if (job_type_ == MAIN) {
- UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.NextState",
- next_state_, STATE_MAX);
- UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.State", state_,
- STATE_MAX);
- } else if (job_type_ == ALTERNATIVE) {
- UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.NextState",
- next_state_, STATE_MAX);
- UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.State", state_,
- STATE_MAX);
- }
-}
-
void HttpStreamFactoryImpl::Job::GetSSLInfo(SSLInfo* ssl_info) {
DCHECK(using_ssl_);
DCHECK(!establishing_tunnel_);
@@ -433,12 +425,12 @@ bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const {
}
// We need to make sure that if a spdy session was created for
- // https://somehost/ that we don't use that session for http://somehost:443/.
+ // https://somehost/ then we do not use that session for http://somehost:443/.
// The only time we can use an existing session is if the request URL is
- // https (the normal case) or if we're connection to a SPDY proxy.
+ // https (the normal case) or if we are connecting to a SPDY proxy.
// https://crbug.com/133176
- // TODO(ricea): Add "wss" back to this list when SPDY WebSocket support is
- // working.
+ // TODO(bnc): Add kWssScheme back to this list when WebSockets over HTTP/2 is
+ // implemented. https://crbug.com/801564.
return origin_url_.SchemeIs(url::kHttpsScheme) ||
proxy_info_.proxy_server().is_https();
}
@@ -446,7 +438,7 @@ bool HttpStreamFactoryImpl::Job::CanUseExistingSpdySession() const {
void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
DCHECK(stream_.get());
DCHECK_NE(job_type_, PRECONNECT);
- DCHECK(!delegate_->for_websockets());
+ DCHECK(!is_websocket_);
MaybeCopyConnectionAttemptsFromSocketOrHandle();
@@ -457,7 +449,7 @@ void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() {
DCHECK(websocket_stream_);
DCHECK_NE(job_type_, PRECONNECT);
- DCHECK(delegate_->for_websockets());
+ DCHECK(is_websocket_);
MaybeCopyConnectionAttemptsFromSocketOrHandle();
@@ -657,7 +649,7 @@ void HttpStreamFactoryImpl::Job::RunLoop(int result) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&Job::OnNewSpdySessionReadyCallback,
ptr_factory_.GetWeakPtr()));
- } else if (delegate_->for_websockets()) {
+ } else if (is_websocket_) {
DCHECK(websocket_stream_);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback,
@@ -694,8 +686,6 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) {
int rv = result;
do {
State state = next_state_;
- // Added to investigate crbug.com/711721.
- state_ = state;
next_state_ = STATE_NONE;
switch (state) {
case STATE_START:
@@ -841,9 +831,10 @@ void HttpStreamFactoryImpl::Job::ResumeInitConnection() {
int HttpStreamFactoryImpl::Job::DoInitConnection() {
net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_INIT_CONNECTION);
int result = DoInitConnectionImpl();
- if (result != ERR_SPDY_SESSION_ALREADY_EXISTS)
+ if (result != ERR_SPDY_SESSION_ALREADY_EXISTS &&
+ !expect_on_quic_host_resolution_) {
delegate_->OnConnectionInitialized(this, result);
-
+ }
return result;
}
@@ -913,13 +904,14 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() {
net_log_, &net_error_details_, io_callback_);
if (rv == OK) {
using_existing_quic_session_ = true;
- } else {
+ } else if (rv == ERR_IO_PENDING) {
// There's no available QUIC session. Inform the delegate how long to
// delay the main job.
- if (rv == ERR_IO_PENDING) {
- delegate_->MaybeSetWaitTimeForMainJob(
- quic_request_.GetTimeDelayForWaitingJob());
- }
+ delegate_->MaybeSetWaitTimeForMainJob(
+ quic_request_.GetTimeDelayForWaitingJob());
+ expect_on_quic_host_resolution_ =
+ quic_request_.WaitForHostResolution(base::BindRepeating(
+ &Job::OnQuicHostResolution, base::Unretained(this)));
}
return rv;
}
@@ -928,9 +920,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() {
// connection this request can pool to. If so, then go straight to using
// that.
if (CanUseExistingSpdySession()) {
- existing_spdy_session_ =
- session_->spdy_session_pool()->push_promise_index()->Find(
- spdy_session_key_, origin_url_);
+ session_->spdy_session_pool()->push_promise_index()->ClaimPushedStream(
+ spdy_session_key_, origin_url_, request_info_, &existing_spdy_session_,
+ &pushed_stream_id_);
if (!existing_spdy_session_) {
existing_spdy_session_ =
session_->spdy_session_pool()->FindAvailableSession(
@@ -961,7 +953,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() {
}
if (job_type_ == PRECONNECT) {
- DCHECK(!delegate_->for_websockets());
+ DCHECK(!is_websocket_);
+ DCHECK(request_info_.socket_tag == SocketTag());
return PreconnectSocketsForHttpRequest(
GetSocketGroup(), destination_, request_info_.extra_headers,
request_info_.load_flags, priority_, session_, proxy_info_,
@@ -977,7 +970,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() {
? base::Bind(&Job::OnHostResolution, session_->spdy_session_pool(),
spdy_session_key_, enable_ip_based_pooling_)
: OnHostResolutionCallback();
- if (delegate_->for_websockets()) {
+ if (is_websocket_) {
+ DCHECK(request_info_.socket_tag == SocketTag());
SSLConfig websocket_server_ssl_config = server_ssl_config_;
websocket_server_ssl_config.alpn_protos.clear();
return InitSocketHandleForWebSocketRequest(
@@ -992,8 +986,14 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() {
GetSocketGroup(), destination_, request_info_.extra_headers,
request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy_,
quic_version_, server_ssl_config_, proxy_ssl_config_,
- request_info_.privacy_mode, net_log_, connection_.get(),
- resolution_callback, io_callback_);
+ request_info_.privacy_mode, request_info_.socket_tag, net_log_,
+ connection_.get(), resolution_callback, io_callback_);
+}
+
+void HttpStreamFactoryImpl::Job::OnQuicHostResolution(int result) {
+ DCHECK(expect_on_quic_host_resolution_);
+ expect_on_quic_host_resolution_ = false;
+ delegate_->OnConnectionInitialized(this, result);
}
int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
@@ -1105,7 +1105,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
// Quic session is closed before stream can be created.
return ERR_CONNECTION_CLOSED;
}
- stream_.reset(new QuicHttpStream(std::move(session)));
+ stream_ = std::make_unique<QuicHttpStream>(std::move(session));
}
next_state_ = STATE_NONE;
return OK;
@@ -1146,9 +1146,9 @@ int HttpStreamFactoryImpl::Job::DoWaitingUserAction(int result) {
int HttpStreamFactoryImpl::Job::SetSpdyHttpStreamOrBidirectionalStreamImpl(
base::WeakPtr<SpdySession> session,
bool direct) {
- // TODO(ricea): Restore the code for WebSockets over SPDY once it's
- // implemented.
- if (delegate_->for_websockets())
+ // TODO(bnc): Restore the code for WebSockets over HTTP/2 once it is
+ // implemented. https://crbug.com/801564.
+ if (is_websocket_)
return ERR_NOT_IMPLEMENTED;
if (stream_type_ == HttpStreamRequest::BIDIRECTIONAL_STREAM) {
bidirectional_stream_impl_ = std::make_unique<BidirectionalStreamSpdyImpl>(
@@ -1162,8 +1162,8 @@ int HttpStreamFactoryImpl::Job::SetSpdyHttpStreamOrBidirectionalStreamImpl(
bool use_relative_url =
direct || request_info_.url.SchemeIs(url::kHttpsScheme);
- stream_ = std::make_unique<SpdyHttpStream>(session, use_relative_url,
- net_log_.source());
+ stream_ = std::make_unique<SpdyHttpStream>(
+ session, pushed_stream_id_, use_relative_url, net_log_.source());
return OK;
}
@@ -1186,7 +1186,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) &&
(request_info_.url.SchemeIs(url::kHttpScheme) ||
request_info_.url.SchemeIs(url::kFtpScheme));
- if (delegate_->for_websockets()) {
+ if (is_websocket_) {
DCHECK_NE(job_type_, PRECONNECT);
DCHECK(delegate_->websocket_handshake_stream_create_helper());
websocket_stream_ =
@@ -1205,9 +1205,9 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
// It is possible that a pushed stream has been opened by a server since last
// time Job checked above.
if (!existing_spdy_session_) {
- existing_spdy_session_ =
- session_->spdy_session_pool()->push_promise_index()->Find(
- spdy_session_key_, origin_url_);
+ session_->spdy_session_pool()->push_promise_index()->ClaimPushedStream(
+ spdy_session_key_, origin_url_, request_info_, &existing_spdy_session_,
+ &pushed_stream_id_);
// It is also possible that an HTTP/2 connection has been established since
// last time Job checked above.
if (!existing_spdy_session_) {
@@ -1472,12 +1472,13 @@ HttpStreamFactoryImpl::JobFactory::CreateMainJob(
const SSLConfig& proxy_ssl_config,
HostPortPair destination,
GURL origin_url,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
return std::make_unique<HttpStreamFactoryImpl::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, destination, origin_url,
- kProtoUnknown, QUIC_VERSION_UNSUPPORTED, ProxyServer(),
+ kProtoUnknown, QUIC_VERSION_UNSUPPORTED, ProxyServer(), is_websocket,
enable_ip_based_pooling, net_log);
}
@@ -1495,12 +1496,13 @@ HttpStreamFactoryImpl::JobFactory::CreateAltSvcJob(
GURL origin_url,
NextProto alternative_protocol,
QuicTransportVersion quic_version,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
return std::make_unique<HttpStreamFactoryImpl::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, destination, origin_url,
- alternative_protocol, quic_version, ProxyServer(),
+ alternative_protocol, quic_version, ProxyServer(), is_websocket,
enable_ip_based_pooling, net_log);
}
@@ -1517,13 +1519,14 @@ HttpStreamFactoryImpl::JobFactory::CreateAltProxyJob(
HostPortPair destination,
GURL origin_url,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
return std::make_unique<HttpStreamFactoryImpl::Job>(
delegate, job_type, session, request_info, priority, proxy_info,
server_ssl_config, proxy_ssl_config, destination, origin_url,
kProtoUnknown, QUIC_VERSION_UNSUPPORTED, alternative_proxy_server,
- enable_ip_based_pooling, net_log);
+ is_websocket, enable_ip_based_pooling, net_log);
}
} // namespace net
diff --git a/chromium/net/http/http_stream_factory_impl_job.h b/chromium/net/http/http_stream_factory_impl_job.h
index 3fdec071b95..aa87699644b 100644
--- a/chromium/net/http/http_stream_factory_impl_job.h
+++ b/chromium/net/http/http_stream_factory_impl_job.h
@@ -152,8 +152,6 @@ class HttpStreamFactoryImpl::Job {
websocket_handshake_stream_create_helper() = 0;
virtual void MaybeSetWaitTimeForMainJob(const base::TimeDelta& delay) = 0;
-
- virtual bool for_websockets() = 0;
};
// Job is owned by |delegate|, hence |delegate| is valid for the lifetime of
@@ -192,6 +190,7 @@ class HttpStreamFactoryImpl::Job {
NextProto alternative_protocol,
QuicTransportVersion quic_version,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log);
virtual ~Job();
@@ -254,10 +253,6 @@ class HttpStreamFactoryImpl::Job {
bool should_reconsider_proxy() const { return should_reconsider_proxy_; }
- // TODO(xunjieli): Added to investigate crbug.com/711721. Remove when no
- // longer needed.
- void LogHistograms() const;
-
NetErrorDetails* net_error_details() { return &net_error_details_; }
private:
@@ -318,6 +313,11 @@ class HttpStreamFactoryImpl::Job {
int StartInternal();
int DoInitConnectionImpl();
+ // If this is a QUIC alt job, then this function is called when host
+ // resolution completes. It's called with the next result after host
+ // resolution, not the result of host resolution itself.
+ void OnQuicHostResolution(int result);
+
// Each of these methods corresponds to a State value. Those with an input
// argument receive the result from the previous state. If a method returns
// ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
@@ -337,7 +337,7 @@ class HttpStreamFactoryImpl::Job {
void ResumeInitConnection();
// Creates a SpdyHttpStream or a BidirectionalStreamImpl from the given values
// and sets to |stream_| or |bidirectional_stream_impl_| respectively. Does
- // nothing if |stream_factory_| is for WebSockets.
+ // nothing if |stream_factory_| is for WebSocket.
int SetSpdyHttpStreamOrBidirectionalStreamImpl(
base::WeakPtr<SpdySession> session,
bool direct);
@@ -415,9 +415,6 @@ class HttpStreamFactoryImpl::Job {
std::unique_ptr<ClientSocketHandle> connection_;
HttpNetworkSession* const session_;
- // |state_| is only used for LogHistograms().
- State state_;
-
State next_state_;
// The server we are trying to reach, could be that of the origin or of the
@@ -432,6 +429,9 @@ class HttpStreamFactoryImpl::Job {
// request.
const ProxyServer alternative_proxy_server_;
+ // True if request is for Websocket.
+ const bool is_websocket_;
+
// Enable pooling to a SpdySession with matching IP and certificate
// even if the SpdySessionKey is different.
const bool enable_ip_based_pooling_;
@@ -464,6 +464,10 @@ class HttpStreamFactoryImpl::Job {
QuicStreamRequest quic_request_;
+ // Only valid for a QUIC job. Set when a QUIC connection is started. If true,
+ // then OnQuicHostResolution() is expected to be called in the future.
+ bool expect_on_quic_host_resolution_;
+
// True if this job used an existing QUIC session.
bool using_existing_quic_session_;
@@ -491,6 +495,12 @@ class HttpStreamFactoryImpl::Job {
// Initialized when we have an existing SpdySession.
base::WeakPtr<SpdySession> existing_spdy_session_;
+ // Once Job claims a pushed stream on a SpdySession, |pushed_stream_id_| is
+ // the ID of the claimed stream, and |existing_spdy_session_| points to that
+ // SpdySession. Otherwise |pushed_stream_id_| is set to kNoPushedStreamFound
+ // (but |existing_spdy_session_| can still be non-null).
+ SpdyStreamId pushed_stream_id_;
+
// True if not connecting to an Https proxy for an Http url.
const bool spdy_session_direct_;
@@ -527,6 +537,7 @@ class HttpStreamFactoryImpl::JobFactory {
const SSLConfig& proxy_ssl_config,
HostPortPair destination,
GURL origin_url,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log);
@@ -543,6 +554,7 @@ class HttpStreamFactoryImpl::JobFactory {
GURL origin_url,
NextProto alternative_protocol,
QuicTransportVersion quic_version,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log);
@@ -558,6 +570,7 @@ class HttpStreamFactoryImpl::JobFactory {
HostPortPair destination,
GURL origin_url,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log);
};
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller.cc b/chromium/net/http/http_stream_factory_impl_job_controller.cc
index e5631fece20..0722a6393d7 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller.cc
+++ b/chromium/net/http/http_stream_factory_impl_job_controller.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -64,6 +65,7 @@ HttpStreamFactoryImpl::JobController::JobController(
JobFactory* job_factory,
const HttpRequestInfo& request_info,
bool is_preconnect,
+ bool is_websocket,
bool enable_ip_based_pooling,
bool enable_alternative_services,
const SSLConfig& server_ssl_config,
@@ -74,6 +76,7 @@ HttpStreamFactoryImpl::JobController::JobController(
request_(nullptr),
delegate_(delegate),
is_preconnect_(is_preconnect),
+ is_websocket_(is_websocket),
enable_ip_based_pooling_(enable_ip_based_pooling),
enable_alternative_services_(enable_alternative_services),
alternative_job_net_error_(OK),
@@ -83,7 +86,7 @@ HttpStreamFactoryImpl::JobController::JobController(
bound_job_(nullptr),
can_start_alternative_proxy_job_(true),
next_state_(STATE_RESOLVE_PROXY),
- pac_request_(nullptr),
+ proxy_resolve_request_(nullptr),
io_callback_(
base::Bind(&JobController::OnIOComplete, base::Unretained(this))),
request_info_(request_info),
@@ -105,17 +108,13 @@ HttpStreamFactoryImpl::JobController::~JobController() {
main_job_.reset();
alternative_job_.reset();
bound_job_ = nullptr;
- if (pac_request_) {
+ if (proxy_resolve_request_) {
DCHECK_EQ(STATE_RESOLVE_PROXY_COMPLETE, next_state_);
- session_->proxy_service()->CancelPacRequest(pac_request_);
+ session_->proxy_service()->CancelRequest(proxy_resolve_request_);
}
net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER);
}
-bool HttpStreamFactoryImpl::JobController::for_websockets() {
- return factory_->for_websockets_;
-}
-
std::unique_ptr<HttpStreamFactoryImpl::Request>
HttpStreamFactoryImpl::JobController::Start(
HttpStreamRequest::Delegate* delegate,
@@ -160,7 +159,7 @@ void HttpStreamFactoryImpl::JobController::Preconnect(int num_streams) {
LoadState HttpStreamFactoryImpl::JobController::GetLoadState() const {
DCHECK(request_);
if (next_state_ == STATE_RESOLVE_PROXY_COMPLETE)
- return session_->proxy_service()->GetLoadState(pac_request_);
+ return session_->proxy_service()->GetLoadState(proxy_resolve_request_);
if (bound_job_)
return bound_job_->GetLoadState();
if (main_job_)
@@ -210,7 +209,7 @@ void HttpStreamFactoryImpl::JobController::OnStreamReadyOnPooledConnection(
const ProxyInfo& proxy_info,
std::unique_ptr<HttpStream> stream) {
DCHECK(request_->completed());
- DCHECK(!factory_->for_websockets_);
+ DCHECK(!is_websocket_);
DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
main_job_.reset();
@@ -227,7 +226,7 @@ void HttpStreamFactoryImpl::JobController::
const ProxyInfo& used_proxy_info,
std::unique_ptr<BidirectionalStreamImpl> stream) {
DCHECK(request_->completed());
- DCHECK(!factory_->for_websockets_);
+ DCHECK(!is_websocket_);
DCHECK_EQ(HttpStreamRequest::BIDIRECTIONAL_STREAM, request_->stream_type());
main_job_.reset();
@@ -257,7 +256,7 @@ void HttpStreamFactoryImpl::JobController::OnStreamReady(
if (!request_)
return;
- DCHECK(!factory_->for_websockets_);
+ DCHECK(!is_websocket_);
DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
OnJobSucceeded(job);
DCHECK(request_->completed());
@@ -285,7 +284,7 @@ void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady(
std::unique_ptr<BidirectionalStreamImpl> stream =
job->ReleaseBidirectionalStream();
DCHECK(stream);
- DCHECK(!factory_->for_websockets_);
+ DCHECK(!is_websocket_);
DCHECK_EQ(HttpStreamRequest::BIDIRECTIONAL_STREAM, request_->stream_type());
OnJobSucceeded(job);
@@ -305,7 +304,7 @@ void HttpStreamFactoryImpl::JobController::OnWebSocketHandshakeStreamReady(
if (!request_)
return;
- DCHECK(factory_->for_websockets_);
+ DCHECK(is_websocket_);
DCHECK_EQ(HttpStreamRequest::HTTP_STREAM, request_->stream_type());
DCHECK(stream);
@@ -494,9 +493,9 @@ void HttpStreamFactoryImpl::JobController::OnNewSpdySessionReady(
MarkRequestComplete(was_alpn_negotiated, negotiated_protocol, using_spdy);
- if (for_websockets()) {
- // TODO(ricea): Re-instate this code when WebSockets over SPDY is
- // implemented.
+ if (is_websocket_) {
+ // TODO(bnc): Re-instate this code when WebSockets over HTTP/2 is
+ // implemented. https://crbug.com/801564.
NOTREACHED();
} else if (job->stream_type() == HttpStreamRequest::BIDIRECTIONAL_STREAM) {
std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl =
@@ -680,13 +679,6 @@ bool HttpStreamFactoryImpl::JobController::HasPendingAltJob() const {
return alternative_job_.get() != nullptr;
}
-void HttpStreamFactoryImpl::JobController::LogHistograms() const {
- if (main_job_)
- main_job_->LogHistograms();
- if (alternative_job_)
- alternative_job_->LogHistograms();
-}
-
size_t HttpStreamFactoryImpl::JobController::EstimateMemoryUsage() const {
return base::trace_event::EstimateMemoryUsage(main_job_) +
base::trace_event::EstimateMemoryUsage(alternative_job_);
@@ -745,7 +737,7 @@ int HttpStreamFactoryImpl::JobController::DoLoop(int rv) {
}
int HttpStreamFactoryImpl::JobController::DoResolveProxy() {
- DCHECK(!pac_request_);
+ DCHECK(!proxy_resolve_request_);
DCHECK(session_);
next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
@@ -760,13 +752,13 @@ int HttpStreamFactoryImpl::JobController::DoResolveProxy() {
return session_->proxy_service()->ResolveProxy(
origin_url, request_info_.method, &proxy_info_, io_callback_,
- &pac_request_, session_->context().proxy_delegate, net_log_);
+ &proxy_resolve_request_, session_->context().proxy_delegate, net_log_);
}
int HttpStreamFactoryImpl::JobController::DoResolveProxyComplete(int rv) {
DCHECK_NE(ERR_IO_PENDING, rv);
- pac_request_ = nullptr;
+ proxy_resolve_request_ = nullptr;
net_log_.AddEvent(
NetLogEventType::HTTP_STREAM_JOB_CONTROLLER_PROXY_SERVER_RESOLVED,
base::Bind(
@@ -824,12 +816,12 @@ int HttpStreamFactoryImpl::JobController::DoCreateJobs() {
this, PRECONNECT, session_, request_info_, IDLE, proxy_info_,
server_ssl_config_, proxy_ssl_config_, alternative_destination,
origin_url, alternative_service_info_.protocol(), quic_version,
- enable_ip_based_pooling_, session_->net_log());
+ is_websocket_, enable_ip_based_pooling_, session_->net_log());
} else {
main_job_ = job_factory_->CreateMainJob(
this, PRECONNECT, session_, request_info_, IDLE, proxy_info_,
server_ssl_config_, proxy_ssl_config_, destination, origin_url,
- enable_ip_based_pooling_, session_->net_log());
+ is_websocket_, enable_ip_based_pooling_, session_->net_log());
}
main_job_->Preconnect(num_streams_);
return OK;
@@ -837,7 +829,7 @@ int HttpStreamFactoryImpl::JobController::DoCreateJobs() {
main_job_ = job_factory_->CreateMainJob(
this, MAIN, session_, request_info_, priority_, proxy_info_,
server_ssl_config_, proxy_ssl_config_, destination, origin_url,
- enable_ip_based_pooling_, net_log_.net_log());
+ is_websocket_, enable_ip_based_pooling_, net_log_.net_log());
// Alternative Service can only be set for HTTPS requests while Alternative
// Proxy is set for HTTP requests.
if (alternative_service_info_.protocol() != kProtoUnknown) {
@@ -855,7 +847,7 @@ int HttpStreamFactoryImpl::JobController::DoCreateJobs() {
this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_,
server_ssl_config_, proxy_ssl_config_, alternative_destination,
origin_url, alternative_service_info_.protocol(), quic_version,
- enable_ip_based_pooling_, net_log_.net_log());
+ is_websocket_, enable_ip_based_pooling_, net_log_.net_log());
main_job_is_blocked_ = true;
alternative_job_->Start(request_->stream_type());
@@ -870,7 +862,7 @@ int HttpStreamFactoryImpl::JobController::DoCreateJobs() {
alternative_job_ = job_factory_->CreateAltProxyJob(
this, ALTERNATIVE, session_, request_info_, priority_,
alternative_proxy_info, server_ssl_config_, proxy_ssl_config_,
- destination, origin_url, alternative_proxy_server,
+ destination, origin_url, alternative_proxy_server, is_websocket_,
enable_ip_based_pooling_, net_log_.net_log());
can_start_alternative_proxy_job_ = false;
@@ -921,7 +913,7 @@ void HttpStreamFactoryImpl::JobController::OrphanUnboundJob() {
RemoveRequestFromSpdySessionRequestMap();
if (bound_job_->job_type() == MAIN && alternative_job_) {
- DCHECK(!for_websockets());
+ DCHECK(!is_websocket_);
// Allow |alternative_job_| to run to completion, rather than resetting it
// to check if there is any broken alternative service to report.
// OnOrphanedJobComplete() will clean up |this| when the job completes.
@@ -998,7 +990,7 @@ void HttpStreamFactoryImpl::JobController::ReportBrokenAlternativeService() {
int error_to_report = alternative_job_net_error_;
alternative_job_net_error_ = OK;
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.AlternateServiceFailed", -error_to_report);
+ base::UmaHistogramSparse("Net.AlternateServiceFailed", -error_to_report);
if (error_to_report == ERR_NETWORK_CHANGED ||
error_to_report == ERR_INTERNET_DISCONNECTED) {
@@ -1228,12 +1220,7 @@ bool HttpStreamFactoryImpl::JobController::
return false;
}
- ProxyDelegate* proxy_delegate = session_->context().proxy_delegate;
- if (!proxy_delegate)
- return false;
- proxy_delegate->GetAlternativeProxy(url, proxy_info.proxy_server(),
- alternative_proxy_server);
-
+ *alternative_proxy_server = proxy_info.alternative_proxy();
if (!alternative_proxy_server->is_valid())
return false;
@@ -1286,7 +1273,7 @@ int HttpStreamFactoryImpl::JobController::ReconsiderProxyAfterError(Job* job,
int error) {
// ReconsiderProxyAfterError() should only be called when the last job fails.
DCHECK(!(alternative_job_ && main_job_));
- DCHECK(!pac_request_);
+ DCHECK(!proxy_resolve_request_);
DCHECK(session_);
if (!job->should_reconsider_proxy())
@@ -1311,7 +1298,7 @@ int HttpStreamFactoryImpl::JobController::ReconsiderProxyAfterError(Job* job,
int rv = session_->proxy_service()->ReconsiderProxyAfterError(
origin_url, request_info_.method, error, &proxy_info_, io_callback_,
- &pac_request_, session_->context().proxy_delegate, net_log_);
+ &proxy_resolve_request_, session_->context().proxy_delegate, net_log_);
if (rv == OK || rv == ERR_IO_PENDING) {
if (!job->using_quic())
RemoveRequestFromSpdySessionRequestMap();
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller.h b/chromium/net/http/http_stream_factory_impl_job_controller.h
index ddd4dc07c9c..48d5cc65e76 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller.h
+++ b/chromium/net/http/http_stream_factory_impl_job_controller.h
@@ -35,6 +35,7 @@ class HttpStreamFactoryImpl::JobController
JobFactory* job_factory,
const HttpRequestInfo& request_info,
bool is_preconnect,
+ bool is_websocket,
bool enable_ip_based_pooling,
bool enable_alternative_services,
const SSLConfig& server_ssl_config,
@@ -42,8 +43,6 @@ class HttpStreamFactoryImpl::JobController
~JobController() override;
- bool for_websockets() override;
-
// Used in tests only for verification purpose.
const Job* main_job() const { return main_job_.get(); }
const Job* alternative_job() const { return alternative_job_.get(); }
@@ -192,10 +191,6 @@ class HttpStreamFactoryImpl::JobController
// Returns true if |this| has a pending alternative job that is not completed.
bool HasPendingAltJob() const;
- // TODO(xunjieli): Added to investigate crbug.com/711721. Remove when no
- // longer needed.
- void LogHistograms() const;
-
// Returns the estimated memory usage in bytes.
size_t EstimateMemoryUsage() const;
@@ -331,6 +326,9 @@ class HttpStreamFactoryImpl::JobController
// True if this JobController is used to preconnect streams.
const bool is_preconnect_;
+ // True if request is for Websocket.
+ const bool is_websocket_;
+
// Enable pooling to a SpdySession with matching IP and certificate even if
// the SpdySessionKey is different.
const bool enable_ip_based_pooling_;
@@ -373,7 +371,7 @@ class HttpStreamFactoryImpl::JobController
bool can_start_alternative_proxy_job_;
State next_state_;
- ProxyService::PacRequest* pac_request_;
+ ProxyService::Request* proxy_resolve_request_;
CompletionCallback io_callback_;
const HttpRequestInfo request_info_;
ProxyInfo proxy_info_;
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
index df7a00d97b1..48bfe8c0b56 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -15,6 +15,7 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_mock_time_message_loop_task_runner.h"
#include "base/test/scoped_task_environment.h"
+#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/platform_thread.h"
#include "net/base/test_proxy_delegate.h"
#include "net/dns/mock_host_resolver.h"
@@ -244,8 +245,9 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
if (create_job_controller_) {
job_controller_ = new HttpStreamFactoryImpl::JobController(
factory_, &request_delegate_, session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
}
}
@@ -303,8 +305,12 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
MockClock clock_;
MockRandom random_generator_{0};
QuicTestPacketMaker client_maker_{
- HttpNetworkSession::Params().quic_supported_versions[0], 0, &clock_,
- kServerHostname, Perspective::IS_CLIENT};
+ HttpNetworkSession::Params().quic_supported_versions[0],
+ 0,
+ &clock_,
+ kServerHostname,
+ Perspective::IS_CLIENT,
+ false};
protected:
BoundTestNetLog net_log_;
@@ -433,8 +439,9 @@ class JobControllerReconsiderProxyAfterErrorTest
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, &request_delegate_, session_.get(), &default_job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
return job_controller->Start(&request_delegate_, nullptr, net_log_.bound(),
HttpStreamRequest::HTTP_STREAM,
@@ -546,18 +553,6 @@ TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) {
// as invalid so that it is not used for subsequent requests.
EXPECT_FALSE(
test_proxy_delegate_raw->alternative_proxy_server().is_valid());
-
- if (set_alternative_proxy_server) {
- // GetAlternativeProxy should be called only once for the first
- // request.
- EXPECT_EQ(1,
- test_proxy_delegate_raw->get_alternative_proxy_invocations());
- } else {
- // Alternative proxy server job is never started. So, ProxyDelegate is
- // queried once per request.
- EXPECT_EQ(2,
- test_proxy_delegate_raw->get_alternative_proxy_invocations());
- }
}
EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
}
@@ -1375,12 +1370,18 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
- base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
- auto failing_resolver = std::make_unique<MockHostResolver>();
- failing_resolver->set_ondemand_mode(true);
- failing_resolver->rules()->AddSimulatedFailure("*google.com");
- session_deps_.host_resolver = std::move(failing_resolver);
+// Verifies that the main job is not resumed until after the alt job completes
+// host resolution.
+TEST_F(HttpStreamFactoryImplJobControllerTest, HostResolutionHang) {
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner(
+ new base::TestMockTimeTaskRunner());
+ base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context(
+ test_task_runner.get());
+
+ auto hanging_resolver = std::make_unique<MockHostResolver>();
+ hanging_resolver->set_ondemand_mode(true);
+ hanging_resolver->set_synchronous_mode(false);
+ session_deps_.host_resolver = std::move(hanging_resolver);
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -1388,6 +1389,13 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
Initialize(request_info);
+ // handshake will fail asynchronously after mock data is unpaused.
+ MockQuicData quic_data;
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ quic_data.AddRead(ASYNC, ERR_FAILED);
+ quic_data.AddWrite(ASYNC, ERR_FAILED);
+ quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
+
// Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
quic_stream_factory->set_require_confirmation(false);
@@ -1400,35 +1408,116 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
SetAlternativeService(request_info, alternative_service);
+ // This prevents handshake from immediately succeeding.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+
request_ =
job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
- EXPECT_TRUE(job_controller_->main_job()->is_waiting());
+ EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
- // The alternative job stalls as host resolution hangs when creating the QUIC
- // request and controller should resume the main job after delay.
+ // Since the alt job has not finished host resolution, there should be no
+ // delayed task posted to resume the main job.
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(50));
+ EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
+
+ // Allow alt job host resolution to complete.
+ session_deps_.host_resolver->ResolveAllPending();
+
+ // Task to resume main job in 15 microseconds should be posted.
EXPECT_TRUE(test_task_runner->HasPendingTask());
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(14));
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
- test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
- EXPECT_FALSE(test_task_runner->HasPendingTask());
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(1));
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
+ EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
+ EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
- // |alternative_job| fails but should not report status to Request.
+ // Unpause mock quic data.
+ // Will cause |alternative_job| to fail, but its failure should not be
+ // reported to Request.
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(0);
-
- EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
// OnStreamFailed will post a task to resume the main job immediately but
// won't call Resume() on the main job since it's been resumed already.
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
- // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can
- // be cleaned up.
- session_deps_.host_resolver->ResolveAllPending();
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
+ quic_data.GetSequencedSocketData()->Resume();
+ test_task_runner->FastForwardUntilNoTasksRemain();
+ // Alt job should be cleaned up
+ EXPECT_FALSE(job_controller_->alternative_job());
+}
+
+TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner(
+ new base::TestMockTimeTaskRunner());
+ base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context(
+ test_task_runner.get());
+
+ auto immediate_resolver = std::make_unique<MockHostResolver>();
+ immediate_resolver->set_synchronous_mode(true);
+ session_deps_.host_resolver = std::move(immediate_resolver);
+
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.google.com");
+
+ Initialize(request_info);
+
+ // Handshake will fail asynchronously after mock data is unpaused.
+ MockQuicData quic_data;
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ quic_data.AddRead(ASYNC, ERR_FAILED);
+ quic_data.AddWrite(ASYNC, ERR_FAILED);
+ quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
+
+ // Enable delayed TCP and set time delay for waiting job.
+ QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
+ quic_stream_factory->set_require_confirmation(false);
+ ServerNetworkStats stats1;
+ stats1.srtt = base::TimeDelta::FromMicroseconds(10);
+ session_->http_server_properties()->SetServerNetworkStats(
+ url::SchemeHostPort(GURL("https://www.google.com")), stats1);
+
+ url::SchemeHostPort server(request_info.url);
+ AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
+ SetAlternativeService(request_info, alternative_service);
+
+ // This prevents handshake from immediately succeeding.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+
+ request_ =
+ job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
+ HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting());
+ // Main job is not blocked but hasn't resumed yet; it should resume in 15us.
+ EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
+ EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
+
+ // Task to resume main job in 15us should be posted.
+ EXPECT_TRUE(test_task_runner->HasPendingTask());
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(14));
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(1));
+
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+ EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
+
+ // Unpause mock quic data and run all remaining tasks. Alt-job should fail
+ // and be cleaned up.
+ quic_data.GetSequencedSocketData()->Resume();
test_task_runner->FastForwardUntilNoTasksRemain();
EXPECT_FALSE(job_controller_->alternative_job());
}
@@ -1510,8 +1599,7 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobLaterCanceled) {
// Reset task environment back to the default type.
// TODO(xunjieli): Remove this temporary workaround once crbug.com/791831 is
// fixed.
- NetTestSuite::SetScopedTaskEnvironment(
- base::test::ScopedTaskEnvironment::MainThreadType::IO);
+ NetTestSuite::ResetScopedTaskEnvironment();
}
// Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if
@@ -1519,15 +1607,17 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobLaterCanceled) {
// which would potentially delay the main job for a extremely long time in
// delayed tcp case.
TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) {
- // Overrides the main thread's message loop with a mock tick clock so that we
- // could verify the main job is resumed with appropriate delay.
- base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner(
+ new base::TestMockTimeTaskRunner());
+ base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context(
+ test_task_runner.get());
+
// The max delay time should be in sync with .cc file.
base::TimeDelta kMaxDelayTimeForMainJob = base::TimeDelta::FromSeconds(3);
- auto failing_resolver = std::make_unique<MockHostResolver>();
- failing_resolver->set_ondemand_mode(true);
- failing_resolver->rules()->AddSimulatedFailure("*google.com");
- session_deps_.host_resolver = std::move(failing_resolver);
+
+ auto immediate_resolver = std::make_unique<MockHostResolver>();
+ immediate_resolver->set_synchronous_mode(true);
+ session_deps_.host_resolver = std::move(immediate_resolver);
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -1535,7 +1625,14 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) {
Initialize(request_info);
- // Enable delayed TCP and set a extremely large time delay for waiting job.
+ // handshake will fail asynchronously after mock data is unpaused.
+ MockQuicData quic_data;
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ quic_data.AddRead(ASYNC, ERR_FAILED);
+ quic_data.AddWrite(ASYNC, ERR_FAILED);
+ quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
+
+ // Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
quic_stream_factory->set_require_confirmation(false);
ServerNetworkStats stats1;
@@ -1543,47 +1640,53 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) {
session_->http_server_properties()->SetServerNetworkStats(
url::SchemeHostPort(GURL("https://www.google.com")), stats1);
- // Set a SPDY alternative service for the server.
url::SchemeHostPort server(request_info.url);
AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
SetAlternativeService(request_info, alternative_service);
+ // This prevents handshake from immediately succeeding.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+
request_ =
job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
- EXPECT_TRUE(job_controller_->main_job()->is_waiting());
+ // Main job is not blocked but hasn't resumed yet; it should resume in 3s.
+ EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
+ EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
- // The alternative job stalls as host resolution hangs when creating the QUIC
- // request and controller should resume the main job after delay.
+ // Task to resume main job in 3 seconds should be posted.
EXPECT_TRUE(test_task_runner->HasPendingTask());
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
-
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(kMaxDelayTimeForMainJob -
+ base::TimeDelta::FromMicroseconds(1));
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
- // Move forward the task runner with kMaxDelayTimeForMainJob and verify the
- // main job is resumed.
- test_task_runner->FastForwardBy(kMaxDelayTimeForMainJob);
- EXPECT_FALSE(test_task_runner->HasPendingTask());
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(1));
- // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can
- // be cleaned up.
- session_deps_.host_resolver->ResolveAllPending();
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+ EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
+
+ // Unpause mock quic data and run all remaining tasks. Alt-job should fail
+ // and be cleaned up.
+ quic_data.GetSequencedSocketData()->Resume();
test_task_runner->FastForwardUntilNoTasksRemain();
EXPECT_FALSE(job_controller_->alternative_job());
}
TEST_F(HttpStreamFactoryImplJobControllerTest,
ResumeMainJobImmediatelyOnStreamFailed) {
- // Overrides the main thread's message loop with a mock tick clock so that we
- // could verify the main job is resumed with appropriate delay.
- base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner(
+ new base::TestMockTimeTaskRunner());
+ base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context(
+ test_task_runner.get());
- auto failing_resolver = std::make_unique<MockHostResolver>();
- failing_resolver->set_ondemand_mode(true);
- failing_resolver->rules()->AddSimulatedFailure("*google.com");
- session_deps_.host_resolver = std::move(failing_resolver);
+ auto immediate_resolver = std::make_unique<MockHostResolver>();
+ immediate_resolver->set_synchronous_mode(true);
+ session_deps_.host_resolver = std::move(immediate_resolver);
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -1591,6 +1694,13 @@ TEST_F(HttpStreamFactoryImplJobControllerTest,
Initialize(request_info);
+ // handshake will fail asynchronously after mock data is unpaused.
+ MockQuicData quic_data;
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ quic_data.AddRead(ASYNC, ERR_FAILED);
+ quic_data.AddWrite(ASYNC, ERR_FAILED);
+ quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
+
// Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
quic_stream_factory->set_require_confirmation(false);
@@ -1599,44 +1709,48 @@ TEST_F(HttpStreamFactoryImplJobControllerTest,
session_->http_server_properties()->SetServerNetworkStats(
url::SchemeHostPort(GURL("https://www.google.com")), stats1);
- // Set a SPDY alternative service for the server.
url::SchemeHostPort server(request_info.url);
AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
SetAlternativeService(request_info, alternative_service);
- // The alternative job stalls as host resolution hangs when creating the QUIC
- // request and controller should resume the main job with delay.
- // OnStreamFailed should resume the main job immediately.
+ // This prevents handshake from immediately succeeding.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+
request_ =
job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
- EXPECT_TRUE(job_controller_->main_job()->is_waiting());
+ // Main job is not blocked but hasn't resumed yet; it's scheduled to resume
+ // in 15us.
+ EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
+ EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
+ // Task to resume main job in 15us should be posted.
EXPECT_TRUE(test_task_runner->HasPendingTask());
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
- // |alternative_job| fails but should not report status to Request.
- EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(0);
- // Now unblock Resolver to fail the alternate job.
- session_deps_.host_resolver->ResolveAllPending();
- EXPECT_EQ(2u, test_task_runner->GetPendingTaskCount());
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(1));
- // Verify the main job will be resumed immediately.
+ // Now unpause the mock quic data to fail the alt job. This should immediately
+ // resume the main job.
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
- // Execute tasks that have no remaining delay. Tasks with nonzero delay will
- // remain queued.
- test_task_runner->RunUntilIdle();
+ quic_data.GetSequencedSocketData()->Resume();
+ test_task_runner->FastForwardBy(base::TimeDelta());
+
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_FALSE(job_controller_->alternative_job());
+ EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
// Verify there is another task to resume main job with delay but should
// not call Resume() on the main job as main job has been resumed.
EXPECT_TRUE(test_task_runner->HasPendingTask());
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
- EXPECT_FALSE(test_task_runner->HasPendingTask());
- EXPECT_FALSE(job_controller_->alternative_job());
+
+ test_task_runner->FastForwardUntilNoTasksRemain();
}
// Verifies that the alternative proxy server job is not created if the URL
@@ -1660,7 +1774,6 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) {
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
}
// Verifies that the alternative proxy server job is not created if the main job
@@ -1685,31 +1798,37 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) {
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
base::RunLoop().RunUntilIdle();
-
- EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
}
// Verifies that the main job is resumed properly after a delay when the
// alternative proxy server job hangs.
TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) {
- // Overrides the main thread's message loop with a mock tick clock so that we
- // could verify the main job is resumed with appropriate delay.
- base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
+ scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner(
+ new base::TestMockTimeTaskRunner());
+ base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context(
+ test_task_runner.get());
- auto failing_resolver = std::make_unique<MockHostResolver>();
- failing_resolver->set_ondemand_mode(true);
- failing_resolver->rules()->AddSimulatedFailure("*myproxy.org");
- session_deps_.host_resolver = std::move(failing_resolver);
+ auto immediate_resolver = std::make_unique<MockHostResolver>();
+ immediate_resolver->set_synchronous_mode(true);
+ session_deps_.host_resolver = std::move(immediate_resolver);
UseAlternativeProxy();
HttpRequestInfo request_info;
request_info.method = "GET";
- request_info.url = GURL("http://mail.example.org/");
+ request_info.url = GURL("http://www.mail.example.org/");
+
Initialize(request_info);
EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
+ // Handshake will fail asynchronously after mock data is unpaused.
+ MockQuicData quic_data;
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ quic_data.AddRead(ASYNC, ERR_FAILED);
+ quic_data.AddWrite(ASYNC, ERR_FAILED);
+ quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
+
// Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
quic_stream_factory->set_require_confirmation(false);
@@ -1718,32 +1837,39 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) {
session_->http_server_properties()->SetServerNetworkStats(
url::SchemeHostPort(GURL("https://myproxy.org")), stats1);
+ url::SchemeHostPort server(request_info.url);
+ AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
+ SetAlternativeService(request_info, alternative_service);
+
+ // This prevents handshake from immediately succeeding.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+
request_ =
job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+
EXPECT_TRUE(job_controller_->main_job());
- EXPECT_TRUE(job_controller_->main_job()->is_waiting());
EXPECT_TRUE(job_controller_->alternative_job());
- // The main job is unblocked but is resumed one message loop iteration later.
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting());
+ // Main job is not blocked but hasn't resumed yet; it should resume in 15us.
EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
- // Move forward the delay and verify the main job is resumed.
+ // Task to resume main job in 15us should be posted.
+ EXPECT_TRUE(test_task_runner->HasPendingTask());
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(14));
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
- test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
- EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
- EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
+ test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(1));
- test_task_runner->RunUntilIdle();
- EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid());
- EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
- EXPECT_FALSE(test_task_runner->HasPendingTask());
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+ EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
- // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can
- // be cleaned up.
- session_deps_.host_resolver->ResolveAllPending();
- EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
+ // Unpause mock quic data and run all remaining tasks. Alt-job should fail
+ // and be cleaned up.
+ quic_data.GetSequencedSocketData()->Resume();
test_task_runner->FastForwardUntilNoTasksRemain();
EXPECT_FALSE(job_controller_->alternative_job());
}
@@ -1789,7 +1915,6 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) {
// The alternative proxy server should be marked as bad.
EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid());
- EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
request_.reset();
EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
}
@@ -1836,7 +1961,6 @@ TEST_F(HttpStreamFactoryImplJobControllerTest,
// The alternative proxy server should not be marked as bad.
EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid());
- EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
request_.reset();
EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
}
@@ -1987,8 +2111,9 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequests) {
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, request_delegates[i].get(), session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
auto request = job_controller->Start(
request_delegates[i].get(), nullptr, net_log_.bound(),
@@ -2060,8 +2185,9 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) {
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, request_delegates[i].get(), session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
auto request = job_controller->Start(
request_delegates[i].get(), nullptr, net_log_.bound(),
@@ -2132,8 +2258,9 @@ TEST_F(JobControllerLimitMultipleH2Requests,
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, request_delegates[i].get(), session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
auto request = job_controller->Start(
request_delegates[i].get(), nullptr, net_log_.bound(),
@@ -2185,8 +2312,9 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultiplePreconnects) {
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, request_delegates[i].get(), session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
job_controller->Preconnect(1);
EXPECT_TRUE(job_controller->main_job());
@@ -2231,8 +2359,9 @@ TEST_F(JobControllerLimitMultipleH2Requests, H1NegotiatedForFirstRequest) {
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, request_delegates[i].get(), session_.get(), &job_factory_,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
auto request = job_controller->Start(
request_delegates[i].get(), nullptr, net_log_.bound(),
@@ -2291,8 +2420,9 @@ TEST_F(JobControllerLimitMultipleH2Requests, QuicJobNotThrottled) {
HttpStreamFactoryImpl::JobController* job_controller =
new HttpStreamFactoryImpl::JobController(
factory_, &request_delegate_, session_.get(), &default_job_factory,
- request_info, is_preconnect_, enable_ip_based_pooling_,
- enable_alternative_services_, SSLConfig(), SSLConfig());
+ request_info, is_preconnect_, false /* is_websocket */,
+ enable_ip_based_pooling_, enable_alternative_services_, SSLConfig(),
+ SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
request_ =
job_controller->Start(&request_delegate_, nullptr, net_log_.bound(),
@@ -2385,6 +2515,7 @@ class HttpStreamFactoryImplJobControllerPreconnectTest
job_controller_ = new HttpStreamFactoryImpl::JobController(
factory_, &request_delegate_, session_.get(), &job_factory_,
request_info_, /* is_preconnect = */ true,
+ /* is_websocket = */ false,
/* enable_ip_based_pooling = */ true,
/* enable_alternative_services = */ true, SSLConfig(), SSLConfig());
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
diff --git a/chromium/net/http/http_stream_factory_impl_request_unittest.cc b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
index 612b136d851..7e965679077 100644
--- a/chromium/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
@@ -42,6 +42,7 @@ TEST_F(HttpStreamFactoryImplRequestTest, SetPriority) {
auto job_controller = std::make_unique<HttpStreamFactoryImpl::JobController>(
factory, &request_delegate, session.get(), &job_factory, request_info,
/* is_preconnect = */ false,
+ /* is_websocket = */ false,
/* enable_ip_based_pooling = */ true,
/* enable_alternative_services = */ true, SSLConfig(), SSLConfig());
HttpStreamFactoryImpl::JobController* job_controller_raw_ptr =
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc
index b6a1a482d5e..b7ff5492b8c 100644
--- a/chromium/net/http/http_stream_factory_impl_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_unittest.cc
@@ -50,6 +50,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/mock_client_socket_pool_manager.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_session_pool.h"
@@ -99,6 +100,7 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
// HttpStream methods
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override {
@@ -157,7 +159,7 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
public:
explicit MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session)
- : HttpStreamFactoryImpl(session, false),
+ : HttpStreamFactoryImpl(session),
preconnect_done_(false),
waiting_for_preconnect_(false) {}
@@ -388,6 +390,7 @@ class CapturePreconnectsSocketPool : public ParentPool {
int RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -1021,16 +1024,6 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyMarkedAsBad) {
// If alternative proxy server was specified, it should have been marked
// as invalid so that it is not used for subsequent requests.
EXPECT_FALSE(test_proxy_delegate.alternative_proxy_server().is_valid());
-
- if (set_alternative_proxy_server) {
- // GetAlternativeProxy should be called only once for the first
- // request.
- EXPECT_EQ(1, test_proxy_delegate.get_alternative_proxy_invocations());
- } else {
- // Alternative proxy server job is never started. So, ProxyDelegate is
- // queried once per request.
- EXPECT_EQ(2, test_proxy_delegate.get_alternative_proxy_invocations());
- }
}
}
}
@@ -1126,10 +1119,6 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyNotMarkedAsBad) {
// Alternative proxy server should be marked as invalid so that it is
// not used for subsequent requests.
EXPECT_FALSE(test_proxy_delegate.alternative_proxy_server().is_quic());
-
- // GetAlternativeProxy should be called only once per request.
- EXPECT_EQ(static_cast<int>(i + 1),
- test_proxy_delegate.get_alternative_proxy_invocations());
}
}
}
@@ -1818,12 +1807,11 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
StreamRequestWaiter waiter;
WebSocketStreamCreateHelper create_helper;
std::unique_ptr<HttpStreamRequest> request(
- session->http_stream_factory_for_websocket()
- ->RequestWebSocketHandshakeStream(
- request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
- &create_helper,
- /* enable_ip_based_pooling = */ true,
- /* enable_alternative_services = */ true, NetLogWithSource()));
+ session->http_stream_factory()->RequestWebSocketHandshakeStream(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ &create_helper,
+ /* enable_ip_based_pooling = */ true,
+ /* enable_alternative_services = */ true, NetLogWithSource()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(nullptr == waiter.stream());
@@ -1863,12 +1851,11 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
StreamRequestWaiter waiter;
WebSocketStreamCreateHelper create_helper;
std::unique_ptr<HttpStreamRequest> request(
- session->http_stream_factory_for_websocket()
- ->RequestWebSocketHandshakeStream(
- request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
- &create_helper,
- /* enable_ip_based_pooling = */ true,
- /* enable_alternative_services = */ true, NetLogWithSource()));
+ session->http_stream_factory()->RequestWebSocketHandshakeStream(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ &create_helper,
+ /* enable_ip_based_pooling = */ true,
+ /* enable_alternative_services = */ true, NetLogWithSource()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(nullptr == waiter.stream());
@@ -1906,12 +1893,11 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
StreamRequestWaiter waiter;
WebSocketStreamCreateHelper create_helper;
std::unique_ptr<HttpStreamRequest> request(
- session->http_stream_factory_for_websocket()
- ->RequestWebSocketHandshakeStream(
- request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
- &create_helper,
- /* enable_ip_based_pooling = */ true,
- /* enable_alternative_services = */ true, NetLogWithSource()));
+ session->http_stream_factory()->RequestWebSocketHandshakeStream(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ &create_helper,
+ /* enable_ip_based_pooling = */ true,
+ /* enable_alternative_services = */ true, NetLogWithSource()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(nullptr == waiter.stream());
@@ -2081,7 +2067,7 @@ TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) {
ssl_config, PRIVACY_MODE_DISABLED, 0, false));
std::string group_name = "ssl/" + host_port_pair.ToString();
int rv = connection->Init(
- group_name, ssl_params, MEDIUM,
+ group_name, ssl_params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
NetLogWithSource());
@@ -2236,20 +2222,25 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) {
class HttpStreamFactoryBidirectionalQuicTest
: public ::testing::Test,
- public ::testing::WithParamInterface<QuicTransportVersion> {
+ public ::testing::WithParamInterface<
+ std::tuple<QuicTransportVersion, bool>> {
protected:
HttpStreamFactoryBidirectionalQuicTest()
: default_url_(kDefaultUrl),
- client_packet_maker_(GetParam(),
+ version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ client_packet_maker_(version_,
0,
&clock_,
"www.example.org",
- Perspective::IS_CLIENT),
- server_packet_maker_(GetParam(),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
+ server_packet_maker_(version_,
0,
&clock_,
"www.example.org",
- Perspective::IS_SERVER),
+ Perspective::IS_SERVER,
+ false),
random_generator_(0),
proxy_service_(ProxyService::CreateDirect()),
ssl_config_service_(new SSLConfigServiceDefaults) {
@@ -2267,7 +2258,9 @@ class HttpStreamFactoryBidirectionalQuicTest
void Initialize() {
params_.enable_quic = true;
params_.quic_supported_versions =
- test::SupportedTransportVersions(GetParam());
+ test::SupportedTransportVersions(version_);
+ params_.quic_headers_include_h2_stream_dependency =
+ client_headers_include_h2_stream_dependency_;
HttpNetworkSession::Context session_context;
session_context.http_server_properties = &http_server_properties_;
@@ -2320,10 +2313,12 @@ class HttpStreamFactoryBidirectionalQuicTest
const GURL default_url_;
QuicStreamId GetNthClientInitiatedStreamId(int n) {
- return test::GetNthClientInitiatedStreamId(GetParam(), n);
+ return test::GetNthClientInitiatedStreamId(version_, n);
}
private:
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
MockClock clock_;
test::QuicTestPacketMaker client_packet_maker_;
test::QuicTestPacketMaker server_packet_maker_;
@@ -2343,9 +2338,11 @@ class HttpStreamFactoryBidirectionalQuicTest
HttpNetworkSession::Params params_;
};
-INSTANTIATE_TEST_CASE_P(Version,
- HttpStreamFactoryBidirectionalQuicTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ HttpStreamFactoryBidirectionalQuicTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
TEST_P(HttpStreamFactoryBidirectionalQuicTest,
RequestBidirectionalStreamImplQuicAlternative) {
@@ -2360,7 +2357,8 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
2, GetNthClientInitiatedStreamId(0), /*should_include_version=*/true,
/*fin=*/true, priority,
client_packet_maker().GetRequestHeaders("GET", "https", "/"),
- &spdy_headers_frame_length, &header_stream_offset));
+ /*parent_stream_id=*/0, &spdy_headers_frame_length,
+ &header_stream_offset));
size_t spdy_response_headers_frame_length;
mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
1, GetNthClientInitiatedStreamId(0), /*should_include_version=*/false,
@@ -2486,7 +2484,8 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
2, GetNthClientInitiatedStreamId(0), /*should_include_version=*/true,
/*fin=*/true, priority,
client_packet_maker().GetRequestHeaders("GET", "https", "/"),
- &spdy_headers_frame_length, &header_stream_offset));
+ /*parent_stream_id=*/0, &spdy_headers_frame_length,
+ &header_stream_offset));
size_t spdy_response_headers_frame_length;
mock_quic_data.AddRead(server_packet_maker().MakeResponseHeadersPacket(
1, GetNthClientInitiatedStreamId(0), /*should_include_version=*/false,
diff --git a/chromium/net/http/http_stream_factory_test_util.cc b/chromium/net/http/http_stream_factory_test_util.cc
index 264030e342c..b3c0fae11e6 100644
--- a/chromium/net/http/http_stream_factory_test_util.cc
+++ b/chromium/net/http/http_stream_factory_test_util.cc
@@ -29,6 +29,7 @@ MockHttpStreamFactoryImplJob::MockHttpStreamFactoryImplJob(
NextProto alternative_protocol,
QuicTransportVersion quic_version,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log)
: HttpStreamFactoryImpl::Job(delegate,
@@ -44,6 +45,7 @@ MockHttpStreamFactoryImplJob::MockHttpStreamFactoryImplJob(
alternative_protocol,
quic_version,
alternative_proxy_server,
+ is_websocket,
enable_ip_based_pooling,
net_log) {
DCHECK(!is_waiting());
@@ -69,6 +71,7 @@ std::unique_ptr<HttpStreamFactoryImpl::Job> TestJobFactory::CreateMainJob(
const SSLConfig& proxy_ssl_config,
HostPortPair destination,
GURL origin_url,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
if (override_main_job_url_)
@@ -77,8 +80,8 @@ std::unique_ptr<HttpStreamFactoryImpl::Job> TestJobFactory::CreateMainJob(
auto main_job = std::make_unique<MockHttpStreamFactoryImplJob>(
delegate, job_type, session, request_info, priority, proxy_info,
SSLConfig(), SSLConfig(), destination, origin_url, kProtoUnknown,
- QUIC_VERSION_UNSUPPORTED, ProxyServer(), enable_ip_based_pooling,
- net_log);
+ QUIC_VERSION_UNSUPPORTED, ProxyServer(), is_websocket,
+ enable_ip_based_pooling, net_log);
// Keep raw pointer to Job but pass ownership.
main_job_ = main_job.get();
@@ -99,12 +102,14 @@ std::unique_ptr<HttpStreamFactoryImpl::Job> TestJobFactory::CreateAltSvcJob(
GURL origin_url,
NextProto alternative_protocol,
QuicTransportVersion quic_version,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
auto alternative_job = std::make_unique<MockHttpStreamFactoryImplJob>(
delegate, job_type, session, request_info, priority, proxy_info,
SSLConfig(), SSLConfig(), destination, origin_url, alternative_protocol,
- quic_version, ProxyServer(), enable_ip_based_pooling, net_log);
+ quic_version, ProxyServer(), is_websocket, enable_ip_based_pooling,
+ net_log);
// Keep raw pointer to Job but pass ownership.
alternative_job_ = alternative_job.get();
@@ -124,12 +129,13 @@ std::unique_ptr<HttpStreamFactoryImpl::Job> TestJobFactory::CreateAltProxyJob(
HostPortPair destination,
GURL origin_url,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) {
auto alternative_job = std::make_unique<MockHttpStreamFactoryImplJob>(
delegate, job_type, session, request_info, priority, proxy_info,
SSLConfig(), SSLConfig(), destination, origin_url, kProtoUnknown,
- QUIC_VERSION_UNSUPPORTED, alternative_proxy_server,
+ QUIC_VERSION_UNSUPPORTED, alternative_proxy_server, is_websocket,
enable_ip_based_pooling, net_log);
// Keep raw pointer to Job but pass ownership.
diff --git a/chromium/net/http/http_stream_factory_test_util.h b/chromium/net/http/http_stream_factory_test_util.h
index 238cc508744..b22d53a7a59 100644
--- a/chromium/net/http/http_stream_factory_test_util.h
+++ b/chromium/net/http/http_stream_factory_test_util.h
@@ -120,6 +120,7 @@ class MockHttpStreamFactoryImplJob : public HttpStreamFactoryImpl::Job {
NextProto alternative_protocol,
QuicTransportVersion quic_version,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log);
@@ -147,6 +148,7 @@ class TestJobFactory : public HttpStreamFactoryImpl::JobFactory {
const SSLConfig& proxy_ssl_config,
HostPortPair destination,
GURL origin_url,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) override;
@@ -163,6 +165,7 @@ class TestJobFactory : public HttpStreamFactoryImpl::JobFactory {
GURL origin_url,
NextProto alternative_protocol,
QuicTransportVersion quic_version,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) override;
@@ -178,6 +181,7 @@ class TestJobFactory : public HttpStreamFactoryImpl::JobFactory {
HostPortPair destination,
GURL origin_url,
const ProxyServer& alternative_proxy_server,
+ bool is_websocket,
bool enable_ip_based_pooling,
NetLog* net_log) override;
diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc
index ced3da36322..b192b80ce9e 100644
--- a/chromium/net/http/http_stream_parser.cc
+++ b/chromium/net/http/http_stream_parser.cc
@@ -207,16 +207,20 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
sent_last_chunk_(false),
upload_error_(OK),
weak_ptr_factory_(this) {
+ CHECK(connection_) << "ClientSocketHandle passed to HttpStreamParser must "
+ "not be NULL. See crbug.com/790776";
io_callback_ = base::Bind(&HttpStreamParser::OnIOComplete,
weak_ptr_factory_.GetWeakPtr());
}
HttpStreamParser::~HttpStreamParser() = default;
-int HttpStreamParser::SendRequest(const std::string& request_line,
- const HttpRequestHeaders& headers,
- HttpResponseInfo* response,
- const CompletionCallback& callback) {
+int HttpStreamParser::SendRequest(
+ const std::string& request_line,
+ const HttpRequestHeaders& headers,
+ const NetworkTrafficAnnotationTag& traffic_annotation,
+ HttpResponseInfo* response,
+ const CompletionCallback& callback) {
DCHECK_EQ(STATE_NONE, io_state_);
DCHECK(callback_.is_null());
DCHECK(!callback.is_null());
@@ -228,6 +232,7 @@ int HttpStreamParser::SendRequest(const std::string& request_line,
DVLOG(1) << __func__ << "() request_line = \"" << request_line << "\""
<< " headers = \"" << headers.ToString() << "\"";
+ traffic_annotation_ = MutableNetworkTrafficAnnotationTag(traffic_annotation);
response_ = response;
// Put the peer's IP address and port into the response.
@@ -455,8 +460,9 @@ int HttpStreamParser::DoSendHeaders() {
response_->request_time = base::Time::Now();
io_state_ = STATE_SEND_HEADERS_COMPLETE;
- return connection_->socket()
- ->Write(request_headers_.get(), bytes_remaining, io_callback_);
+ return connection_->socket()->Write(
+ request_headers_.get(), bytes_remaining, io_callback_,
+ NetworkTrafficAnnotationTag(traffic_annotation_));
}
int HttpStreamParser::DoSendHeadersComplete(int result) {
@@ -503,10 +509,9 @@ int HttpStreamParser::DoSendHeadersComplete(int result) {
int HttpStreamParser::DoSendBody() {
if (request_body_send_buf_->BytesRemaining() > 0) {
io_state_ = STATE_SEND_BODY_COMPLETE;
- return connection_->socket()
- ->Write(request_body_send_buf_.get(),
- request_body_send_buf_->BytesRemaining(),
- io_callback_);
+ return connection_->socket()->Write(
+ request_body_send_buf_.get(), request_body_send_buf_->BytesRemaining(),
+ io_callback_, NetworkTrafficAnnotationTag(traffic_annotation_));
}
if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) {
diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h
index 6a0248202c2..56f5dae8775 100644
--- a/chromium/net/http/http_stream_parser.h
+++ b/chromium/net/http/http_stream_parser.h
@@ -21,6 +21,7 @@
#include "net/base/net_export.h"
#include "net/log/net_log_with_source.h"
#include "net/ssl/token_binding.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -61,6 +62,7 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// some additional functionality
int SendRequest(const std::string& request_line,
const HttpRequestHeaders& headers,
+ const NetworkTrafficAnnotationTag& traffic_annotation,
HttpResponseInfo* response,
const CompletionCallback& callback);
@@ -284,6 +286,8 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// Error received when uploading the body, if any.
int upload_error_;
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
base::WeakPtrFactory<HttpStreamParser> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(HttpStreamParser);
diff --git a/chromium/net/http/http_stream_parser_fuzzer.cc b/chromium/net/http/http_stream_parser_fuzzer.cc
index f31d0edeacc..cb509f33d5d 100644
--- a/chromium/net/http/http_stream_parser_fuzzer.cc
+++ b/chromium/net/http/http_stream_parser_fuzzer.cc
@@ -25,6 +25,7 @@
#include "net/log/test_net_log.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/fuzzed_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "url/gurl.h"
// Fuzzer for HttpStreamParser.
@@ -52,9 +53,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bound_test_net_log.bound());
net::HttpResponseInfo response_info;
- int result =
- parser.SendRequest("GET / HTTP/1.1\r\n", net::HttpRequestHeaders(),
- &response_info, callback.callback());
+ int result = parser.SendRequest(
+ "GET / HTTP/1.1\r\n", net::HttpRequestHeaders(),
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info, callback.callback());
result = callback.GetResult(result);
if (net::OK != result)
return 0;
diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc
index 0ad717f10b1..7b6de3d8b1e 100644
--- a/chromium/net/http/http_stream_parser_unittest.cc
+++ b/chromium/net/http/http_stream_parser_unittest.cc
@@ -32,6 +32,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -138,7 +139,8 @@ TEST(HttpStreamParser, DataReadErrorSynchronous) {
HttpResponseInfo response;
TestCompletionCallback callback;
- int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback());
EXPECT_THAT(callback.GetResult(result), IsError(ERR_FAILED));
@@ -179,7 +181,8 @@ TEST(HttpStreamParser, DataReadErrorAsynchronous) {
HttpResponseInfo response;
TestCompletionCallback callback;
- int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ int result = parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback());
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
@@ -255,7 +258,8 @@ TEST(HttpStreamParser, InitAsynchronousUploadDataStream) {
HttpResponseInfo response;
TestCompletionCallback callback1;
- int result1 = parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ int result1 = parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback1.callback());
EXPECT_EQ(ERR_IO_PENDING, result1);
base::RunLoop().RunUntilIdle();
@@ -438,7 +442,8 @@ TEST(HttpStreamParser, SentBytesNoHeaders) {
HttpResponseInfo response;
TestCompletionCallback callback;
EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", HttpRequestHeaders(),
- &response, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
+ callback.callback()));
EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
}
@@ -469,7 +474,8 @@ TEST(HttpStreamParser, SentBytesWithHeaders) {
HttpResponseInfo response;
TestCompletionCallback callback;
- EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback()));
EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
@@ -501,7 +507,8 @@ TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) {
HttpResponseInfo response;
TestCompletionCallback callback;
- EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback()));
EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
@@ -533,7 +540,8 @@ TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) {
HttpResponseInfo response;
TestCompletionCallback callback;
EXPECT_EQ(ERR_CONNECTION_RESET,
- parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ parser.SendRequest("GET / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback()));
EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
@@ -572,7 +580,8 @@ TEST(HttpStreamParser, SentBytesPost) {
HttpResponseInfo response;
TestCompletionCallback callback;
- EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response,
callback.callback()));
EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
@@ -616,6 +625,7 @@ TEST(HttpStreamParser, SentBytesChunkedPostError) {
HttpResponseInfo response;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS,
&response, callback.callback()));
base::RunLoop().RunUntilIdle();
@@ -685,7 +695,8 @@ TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) {
// complete asynchronously.
ASSERT_EQ(ERR_IO_PENDING,
parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
// Complete the initial request write. Callback should not have been invoked.
base::RunLoop().RunUntilIdle();
@@ -765,7 +776,8 @@ TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) {
// complete asynchronously.
ASSERT_EQ(ERR_IO_PENDING,
parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
ASSERT_THAT(callback.WaitForResult(), IsOk());
// Attempt to read the response status and the response headers.
@@ -845,7 +857,8 @@ TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) {
// complete asynchronously.
ASSERT_EQ(ERR_IO_PENDING,
parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
ASSERT_FALSE(callback.have_result());
// Sending the request and the first chunk completes.
@@ -929,7 +942,8 @@ TEST(HttpStreamParser, AsyncEmptyChunkedUpload) {
// complete asynchronously.
ASSERT_EQ(ERR_IO_PENDING,
parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
// Now append the terminal 0-byte "chunk".
upload_stream.AppendData(nullptr, 0, true);
@@ -1004,7 +1018,8 @@ TEST(HttpStreamParser, SyncEmptyChunkedUpload) {
// complete asynchronously.
ASSERT_EQ(ERR_IO_PENDING,
parser.SendRequest("GET /one.html HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
// Complete writing the request headers and body.
ASSERT_THAT(callback.WaitForResult(), IsOk());
@@ -1101,6 +1116,7 @@ TEST(HttpStreamParser, TruncatedHeaders) {
HttpResponseInfo response_info;
TestCompletionCallback callback;
ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS,
&response_info, callback.callback()));
int rv = parser.ReadResponseHeaders(callback.callback());
@@ -1158,7 +1174,8 @@ TEST(HttpStreamParser, Websocket101Response) {
HttpResponseInfo response_info;
TestCompletionCallback callback;
ASSERT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", request_headers,
- &response_info, callback.callback()));
+ TRAFFIC_ANNOTATION_FOR_TESTS, &response_info,
+ callback.callback()));
EXPECT_THAT(parser.ReadResponseHeaders(callback.callback()), IsOk());
ASSERT_TRUE(response_info.headers.get());
@@ -1236,6 +1253,7 @@ class SimpleGetRunner {
TestCompletionCallback callback;
ASSERT_EQ(OK, parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_,
+ TRAFFIC_ANNOTATION_FOR_TESTS,
&response_info_, callback.callback()));
}
@@ -1673,8 +1691,10 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
std::unique_ptr<HttpRequestHeaders> request_headers(new HttpRequestHeaders());
std::unique_ptr<HttpResponseInfo> response_info(new HttpResponseInfo());
TestCompletionCallback callback;
- ASSERT_EQ(OK, parser.SendRequest("GET /foo.html HTTP/1.1\r\n",
- *request_headers, response_info.get(), callback.callback()));
+ ASSERT_EQ(
+ OK, parser.SendRequest("GET /foo.html HTTP/1.1\r\n", *request_headers,
+ TRAFFIC_ANNOTATION_FOR_TESTS, response_info.get(),
+ callback.callback()));
ASSERT_THAT(parser.ReadResponseHeaders(callback.callback()), IsOk());
// If the object that owns the HttpStreamParser is deleted, it takes the
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.cc b/chromium/net/http/proxy_connect_redirect_http_stream.cc
index 2fc8eb8b0a3..699d71aad59 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.cc
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.cc
@@ -22,6 +22,7 @@ ProxyConnectRedirectHttpStream::~ProxyConnectRedirectHttpStream() = default;
int ProxyConnectRedirectHttpStream::InitializeStream(
const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) {
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.h b/chromium/net/http/proxy_connect_redirect_http_stream.h
index 5df1ffa25e6..285a9b4e8d4 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.h
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.h
@@ -29,6 +29,7 @@ class ProxyConnectRedirectHttpStream : public HttpStream {
// marked one.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override;
diff --git a/chromium/net/http/transport_security_persister_unittest.cc b/chromium/net/http/transport_security_persister_unittest.cc
index 3ad29887f51..f18c4ae7a01 100644
--- a/chromium/net/http/transport_security_persister_unittest.cc
+++ b/chromium/net/http/transport_security_persister_unittest.cc
@@ -283,7 +283,7 @@ TEST_F(TransportSecurityPersisterTest, PublicKeyPins) {
TransportSecurityState::PKPState new_pkp_state;
EXPECT_TRUE(state_.GetDynamicPKPState(kTestDomain, &new_pkp_state));
EXPECT_EQ(1u, new_pkp_state.spki_hashes.size());
- EXPECT_EQ(sha256.tag, new_pkp_state.spki_hashes[0].tag);
+ EXPECT_EQ(sha256.tag(), new_pkp_state.spki_hashes[0].tag());
EXPECT_EQ(0, memcmp(new_pkp_state.spki_hashes[0].data(), sha256.data(),
sha256.size()));
EXPECT_EQ(report_uri, new_pkp_state.report_uri);
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index a433afd0217..6eaa321ef4b 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -12,8 +12,8 @@
#include "base/build_time.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -72,8 +72,7 @@ bool IsDynamicExpectCTEnabled() {
void RecordUMAForHPKPReportFailure(const GURL& report_uri,
int net_error,
int http_response_code) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.PublicKeyPinReportSendingFailure2",
- -net_error);
+ base::UmaHistogramSparse("Net.PublicKeyPinReportSendingFailure2", -net_error);
}
std::string TimeToISO8601(const base::Time& t) {
@@ -143,7 +142,7 @@ bool GetHPKPReport(const HostPortPair& host_port_pair,
for (const auto& hash_value : pkp_state.spki_hashes) {
std::string known_pin;
- switch (hash_value.tag) {
+ switch (hash_value.tag()) {
case HASH_VALUE_SHA256:
known_pin += "pin-sha256=";
break;
@@ -901,6 +900,9 @@ TransportSecurityState::CheckCTRequirements(
ExpectCTState state;
if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
GetDynamicExpectCTState(hostname, &state)) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup",
+ policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX);
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,
@@ -947,9 +949,12 @@ TransportSecurityState::CheckCTRequirements(
const base::Time epoch = base::Time::UnixEpoch();
const CTRequiredPolicies& ct_required_policies = GetCTRequiredPolicies();
+
+ bool found = false;
for (const auto& restricted_ca : ct_required_policies) {
- if (epoch + restricted_ca.effective_date >
- validated_certificate_chain->valid_start()) {
+ if (!restricted_ca.effective_date.is_zero() &&
+ (epoch + restricted_ca.effective_date >
+ validated_certificate_chain->valid_start())) {
// The candidate cert is not subject to the CT policy, because it
// was issued before the effective CT date.
continue;
@@ -964,15 +969,21 @@ TransportSecurityState::CheckCTRequirements(
// Found a match, indicating this certificate is potentially
// restricted. Determine if any of the hashes are on the exclusion
// list as exempt from the CT requirement.
- if (IsAnySHA256HashInSortedArray(public_key_hashes,
+ if (restricted_ca.exceptions &&
+ IsAnySHA256HashInSortedArray(public_key_hashes,
restricted_ca.exceptions,
restricted_ca.exceptions_length)) {
// Found an excluded sub-CA; CT is not required.
- return default_response;
+ continue;
}
- // No exception found. This certificate must conform to the CT policy.
- return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
+
+ // No exception found. This certificate must conform to the CT policy. The
+ // compliance state is treated as additive - it must comply with all
+ // stated policies.
+ found = true;
}
+ if (found)
+ return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
return default_response;
}
@@ -1507,6 +1518,9 @@ void TransportSecurityState::ProcessExpectCTHeader(
// public root or did not comply with CT policy.
if (!ssl_info.is_issued_by_known_root)
return;
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.ExpectCTHeader.PolicyComplianceOnHeaderProcessing",
+ ssl_info.ct_policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX);
if (ssl_info.ct_policy_compliance !=
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) {
// If an Expect-CT header is observed over a non-compliant connection, the
diff --git a/chromium/net/http/transport_security_state_ct_policies.inc b/chromium/net/http/transport_security_state_ct_policies.inc
index d01cbd2ad7b..f7ea8e51ef5 100644
--- a/chromium/net/http/transport_security_state_ct_policies.inc
+++ b/chromium/net/http/transport_security_state_ct_policies.inc
@@ -20,7 +20,8 @@ struct CTRequiredPolicy {
size_t roots_length;
// The date at which enforcement should begin, relative to the Unix
- // Epoch.
+ // Epoch. If equivalent to zero (base::TimeDelta()), then it is enforced
+ // for all certificates.
base::TimeDelta effective_date;
// However, if a certificate ALSO chains to or through one of
@@ -33,7 +34,7 @@ struct CTRequiredPolicy {
size_t exceptions_length;
};
-typedef CTRequiredPolicy CTRequiredPolicies[1];
+typedef CTRequiredPolicy CTRequiredPolicies[2];
const CTRequiredPolicies& GetCTRequiredPolicies() {
static const CTRequiredPolicy kCTRequiredPolicies[] = {
@@ -41,8 +42,12 @@ const CTRequiredPolicies& GetCTRequiredPolicies() {
{
kSymantecRoots, kSymantecRootsLength,
// 1 June 2016, 00:00:00 GMT.
- base::TimeDelta::FromSeconds(1464739200), kSymantecExceptions,
- kSymantecExceptionsLength,
+ base::TimeDelta::FromSeconds(1464739200),
+ kSymantecExceptions, kSymantecExceptionsLength,
+ },
+ {
+ kSymantecManagedCAs, kSymantecManagedCAsLength,
+ base::TimeDelta(), nullptr, 0
},
};
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 0e18132ed4e..5a6fea71063 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -275,15 +275,15 @@
"expect_staple_report_uri": "https://report.badssl.com/expect-staple"
},
- // eTLDs
- // At the moment, this only includes Google-owned gTLDs,
- // but other gTLDs and eTLDs are welcome to preload if they are interested.
- { "name": "google", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true, "pins": "google" },
+ // gTLDs and eTLDs are welcome to preload if they are interested.
+ { "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
+ { "name": "bank", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
+ { "name": "chrome", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "dev", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "foo", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
+ { "name": "google", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true, "pins": "google" },
+ { "name": "insurance", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "page", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
- { "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
- { "name": "chrome", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
// Google domains using Expect-CT.
{
@@ -364,6 +364,7 @@
{ "name": "groups.google.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "gvt2.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "gvt3.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
+ { "name": "developer.android.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "market.android.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "translate.googleapis.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "withgoogle.com", "policy": "google", "mode": "force-https", "include_subdomains": true, "pins": "google" },
@@ -639,6 +640,7 @@
{ "name": "googleweblight.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "google.ws", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "gstatic.com", "policy": "google", "include_subdomains": true, "pins": "google" },
+ { "name": "gvt1.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "static.googleadsserving.cn", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "urchin.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{
@@ -650,9 +652,6 @@
{ "name": "youtu.be", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "youtube-nocookie.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "ytimg.com", "policy": "google", "include_subdomains": true, "pins": "google" },
- // Exclude the learn.doubleclick.net subdomain because it uses a different
- // CA.
- { "name": "learn.doubleclick.net", "policy": "google", "include_subdomains": true },
// Enforce HSTS and public key pins for Yahoo domains.
{ "name": "at.search.yahoo.com", "policy": "custom", "mode": "force-https", "include_subdomains": false, "pins": "yahoo" },
@@ -2049,7 +2048,6 @@
{ "name": "leonklingele.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "madars.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "magneticanvil.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mimeit.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mobilcom-debitel-empfehlen.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "morethanadream.lv", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "narodniki.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3341,7 +3339,6 @@
{ "name": "endlesshorizon.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "entrepreneur.or.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eol34.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "eroticen.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eucl3d.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "firmapi.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "freeweibo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -3772,7 +3769,6 @@
{ "name": "sifls.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "smkn1lengkong.sch.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ssldecoder.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "startupsort.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sx3.no", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tech-seminar.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tncnanet.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5311,7 +5307,6 @@
{ "name": "jonathancarter.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jonfor.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jorgemesa.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "josephrees.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "joyofcookingandbaking.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kachlikova2.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kanotijd.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5416,7 +5411,6 @@
{ "name": "ronwo.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rootwpn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "russmarshall.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rww.name", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saltercane.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saveyour.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "scienceathome.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6944,7 +6938,6 @@
{ "name": "tsumi.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tty.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tuvalie.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tuxcall.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ty2u.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "uat-activesg.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ukrgadget.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -7359,7 +7352,6 @@
{ "name": "kleinerarchitekturfuehrer.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "klicktojob.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kmkz.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kojima-life.co.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kolmann.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "krasota.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "krmela.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -7706,7 +7698,6 @@
{ "name": "xn--3lqp21gwna.xn--fiqs8s", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--3lqt7ir4md4tzwa.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--3lqt7ir4md4tzwa.xn--fiqs8s", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "xn--jobbrse-d1a.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--qckss0j.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xqin.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xuri.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -8454,7 +8445,6 @@
{ "name": "polypet.com.sg", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "posylka.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ppro.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "prezola.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pro-link.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "projectarmy.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "punknews.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -9377,7 +9367,6 @@
{ "name": "dentallaborgeraeteservice.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dentystabirmingham.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "derchris.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "deregowski.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "desiccantpackets.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "designgears.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "designthinking.or.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10078,7 +10067,6 @@
{ "name": "lanbyte.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "langbein.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lansinoh.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "laposte.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lasnaves.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "latinphone.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lauftreff-himmelgeist.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11233,7 +11221,6 @@
{ "name": "waylaydesign.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wdt.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wealthcentral.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "wealthfactory.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wealthreport.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wear2work.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wearandcare.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12343,7 +12330,6 @@
{ "name": "svatba-frantovi.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sumoatm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tails.com.ar", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tabelfirme.ro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sv-turm-hohenlimburg.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "taravancil.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tangibilizing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -15814,7 +15800,6 @@
{ "name": "itilo.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jamessmith.me.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "justmy.website", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "johnmcgovern.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "karmaassurance.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jiyuu-ni.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "joe-pagan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -16034,7 +16019,6 @@
{ "name": "magnets.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mfxbe.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "miegl.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "lmkts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "logicio.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "lwl12.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mockmyapp.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -17651,7 +17635,6 @@
{ "name": "mariehane.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mdma.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "matthewkenny.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "meledia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "marksouthall.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kinniyaonlus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "martins.im", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18243,7 +18226,6 @@
{ "name": "xn--yoamomisuasbcn-ynb.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yuzu.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zlc1994.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "xuwei.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "woufbox.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zenycosta.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "worldsbeststory.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -18601,7 +18583,6 @@
{ "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 },
- { "name": "businesshub.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "c3vo.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "card-toka.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "achterstieg.dedyn.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -19920,7 +19901,6 @@
{ "name": "politik-bei-uns.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pm13-media.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "principia-journal.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "pornbase.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "practicepanther.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pozytywnyplan.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "personalizedtouch.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -22550,7 +22530,6 @@
{ "name": "planktonholland.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "premiership-predictors.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pikeitservices.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "pnyxnet.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pottshome.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "philia-sa.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "proxybay.eu.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25760,7 +25739,6 @@
{ "name": "fitea.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fivestepfunnels.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fixmyalarmpanel.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "fixvoltage.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "fktpm.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flairbros.at", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "flaretechnologies.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26440,7 +26418,6 @@
{ "name": "kineto.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kingclass.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kingdomcrc.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kingopen.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kintoandar.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "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 },
@@ -26880,7 +26857,6 @@
{ "name": "mplanetphl.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mpy.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mr-anderson.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "mrhack.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mrx.one", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mscenter.cf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "mshemailmarketer.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27879,7 +27855,6 @@
{ "name": "sugarcitycon.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "suiranfes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sumguy.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sungo.wtf", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sunsmartresorts.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "supa.sexy", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "supercalorias.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -28050,7 +28025,6 @@
{ "name": "tiste.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "titusetcompagnies.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tjandpals.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tjullrich.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tkacz.pro", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tkts.cl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tkusano.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31212,7 +31186,6 @@
{ "name": "pokemontabletopadventures.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "portalcarriers.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pixelfou.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "popcultureshack.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "plut.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "plaque-funeraire.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "phdwuda.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31279,7 +31252,6 @@
{ "name": "privacynow.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "promods.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "privacyscore.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "polkam.go.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "propepper.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "prodinger.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "plantastique.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32000,7 +31972,6 @@
{ "name": "thisoldearth.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tommic.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "top-opakowania.pl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "truehealthreport.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tavolaquadrada.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "topeng-emas.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "treinonerd.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34317,7 +34288,6 @@
{ "name": "sonoecoracao.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sobelift.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "staxflax.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "studentshare.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "stephsolis.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "steinbergmedia.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "soldout-app.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34916,7 +34886,6 @@
{ "name": "ripmixmake.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "00001.am", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pascalmathis.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "zqwqz.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "scrumbleship.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sidpod.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "saintaardvarkthecarpeted.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -35075,7 +35044,6 @@
{ "name": "globalprojetores.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "great.nagoya", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grouphomes.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gym-old.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "halitopuroprodutos.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hanys.xyz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "haogoodair.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -36586,7 +36554,6 @@
{ "name": "dnfc.rocks", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dockerm.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "documaniatv.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "doesnotscale.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "domengrad.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "domian.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dominik-schlueter.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -37337,7 +37304,6 @@
{ "name": "owl-stat.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "owlishmedia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paazmaya.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "pagalworld.la", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "painlessproperty.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paktolos.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pantallasled.com.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -37466,7 +37432,6 @@
{ "name": "ref1oct.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "refficience.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "refreshliving.us", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "reimu.ink", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reismil.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reneleu.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "replicaswiss.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -37810,10 +37775,6 @@
{ "name": "votercircle.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "voyagesdetective.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vozami.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vpls.co.th", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vpls.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vpls.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "vplssolutions.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vranjske.co.rs", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vsamsonov.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "vuzi.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -39550,7 +39511,6 @@
{ "name": "m.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ma-musique.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "maaya.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "machineryhouse.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "maciespartyhire.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mactools.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "madbouncycastles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -40213,7 +40173,6 @@
{ "name": "mncr.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "monolithindustries.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "mystatus24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "nil2.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ortho-graz.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "os24.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oyesunn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41107,7 +41066,6 @@
{ "name": "docs.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dokan-e.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dolci-delizie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "dongkexue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dont.watch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dotjs.party", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dragonsunited.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41492,7 +41450,6 @@
{ "name": "urcentral.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vaindil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vales.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "vampyrium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vapecom-shop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "vectro.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "venninvestorplatform.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41542,7 +41499,6 @@
{ "name": "xchating.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xdavidhu.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xfce.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "xiaowutou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xingiahanvisa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xlboo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--mgbmmp7eub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41557,6 +41513,2676 @@
{ "name": "zhima.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zivagold.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zlcp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "100pounds.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123termpapers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2333666.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3queens.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3queens.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3vlnaeet.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5000yz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "506pay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "6lo.zgora.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aaron.xin", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ac.milan.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "accessoripersmartphone.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acemypaper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acordes.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "activeworld.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adorade.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "africanimpact.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agoodmind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agoravox.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agoravox.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agoravox.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agr.asia", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ahoy.travel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aigenpul.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "albertify.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aliaswp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alttrackr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amalfirock.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amato.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amministratorecondominio.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andronika.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anhaffen.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antama.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthro.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anynode.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aomonk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apio.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aporia.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aquabar.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "areallyneatwebsite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artea.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteaga.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asiesvenezuela.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "assadrivesloirecher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "assistenzamicroonde.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ateliers-veronese-nantes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atheoryofchange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aulaschrank.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aurosa.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "auskunftsbegehren.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autoscuola.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autosearch.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avalon-studios.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avova.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "babyphototime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balconnr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balconsverdun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bankofrealty.review", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baobeiglass.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baustils.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bcradio.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beautybear.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bennygommers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bgr34.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bilsho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bipyo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bleep.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blm.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluefinger.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bngs.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bologna-disinfestazioni.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bonprix.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bookingapp.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bouk.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brainwork.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brammingfys.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bran.soy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brandweertrainingen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bravehearts.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bridgevest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brokervalues.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsdunix.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buy-thing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calafont.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calidoinvierno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calypso-tour.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canerkorkmaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canmipai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cash-4x4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "catuniverse.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "causae.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cazaviajes.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chapiteauxduleman.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chasing-coins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chcsct.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheapestgamecards.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheapestgamecards.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheapestgamecards.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheapestgamecards.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheapestgamecards.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "childvisitationassistance.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "class.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "claster.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clearance365.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "climaencusco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "code-judge.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "colorlifesupport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comphare.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crag.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crowdliminal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crypto-armory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "curvissa.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cutephil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cy.technology", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danielsteiner.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danna-salary.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daravk.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dcards.in.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deai-life.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dealapp.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "degoulet.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delitto.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "derattizzazione.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "derattizzazioni.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "derattizzazioni.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detekenmuze.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detoxetmoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detuinmuze.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "developyourelement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dierabenmutti.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalbox.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalwasteland.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "direct2uk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dirtygeek.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestando.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazione.brescia.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "distribuidoracristal.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doctafit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dorth.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doypacky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dpisecuretests.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dragonprogrammer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dukefox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e9a.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "economias.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edholm.pub", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edsh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edv-bv.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eff-bee-eye.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "egarden.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricalagoura.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elguadia.faith", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elitesensual.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elucron.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "empower.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enpalmademallorca.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epiteugma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eppelblei.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eppelpress.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eroticforce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eru.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esailinggear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "escortshotsexy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "espressivo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exteriorservices.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faidanoi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faithindemocracy.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "falcibiosystems.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "falcoz.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fatowltees.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fburl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ferret.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "find-mba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finflix.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fioulmarket.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowersbylegacy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fm992.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foreversummertime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "framedpaws.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freelanceshipping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freemans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freeshkre.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "friederes.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fsk.fo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funarena.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funinbeds.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gambitboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ganztagplus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gastoudererenda.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gatomix.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gazflynn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gcbit.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekshirts.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekz.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geloofindemocratie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gensenwedding.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geocommunicator.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getcleartouch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getticker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "giardinaggio.napoli.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gifts365.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "giochiecodici.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gitesdeshautescourennes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "global-village.koeln", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goodyearsotn.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goubi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gpio.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grandjunctionbrewing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grattan.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grayowlworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grendel.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grinnellplans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grootinadvies.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "groupe-neurologique-nord.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guhei.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guillaume-briand.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ha6.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haccp.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "handynummer.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haqaza.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "harilova.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hearty.taipei", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hightimes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hilhorst-uitvaartverzorging.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hiresteve.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homebasedsalons.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homoglyph.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hr98.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hub385.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.co.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.com.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebeeshop.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hypothyroidmom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ibwc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idolshop.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igd.chat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "igk.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ik-life.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imaginetricks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imgup.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inanyevent.london", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infomegastore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infomisto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infotolium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "institutmaupertuis.hopto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "investcountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "irstaxforumsonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaackabel.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaackabel.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaackabel.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaackabel.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaackabel.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "it-shamans.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itad.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jakpremyslet.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "janschaumann.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jdncr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeuxetcodes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jinanshen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jkest.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joliettech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jonathanschle.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joshlovephotography.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juegosycodigos.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jugh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juliedecubber.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jumboquid.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaleidoscope.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kansaiyamamoto.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "katalogakci.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kcore.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keakon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keldan.fo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kevlar.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "khasiatmanfaat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kisiselveri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "klimaloven.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kniwweler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koreaboo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "krautomat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kruisselbrink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laassari.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "labcoat.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "landinfo.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lascana.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lebarbatruc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ledeguisement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemonop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lenguajedeprogramacion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lib64.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifescience-japan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linostassi.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livecards.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livecards.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livecards.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livekarten.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livekarten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lixtick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "llm-guide.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loeildansledoigt.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logicchen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lolnames.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lon-so.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lookagain.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lookbetweenthelines.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "losebellyfat.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lostandcash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lsvih.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lucassoler.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luckyfrog.hk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lukestebbing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lunis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lunorian.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lusynth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lv5.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lyoness.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magnificentdata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maispa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maplenorth.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marlonlosurdopictures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcfedries.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medcrowd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meddigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "media-access.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meiqia.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meiqia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mes-finances.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mia.ac", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "micromata.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mijn-financien.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mindwork.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minei.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minerstat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minor.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modaperuimport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mojeco2.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mondedesnovels.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monotsuku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moodifiers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mosaicadvisors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moskeedieren.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "motezazer.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "movie-infos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muffet.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multibase.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myhatsuden.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mymommyworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n-design.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "na.hn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "namazvakitleri.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nani.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natchmatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nationalcprfoundation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "natlec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naturalkitchen.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncc-qualityandsafety.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "needle.net.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "needle.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neko.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nerfroute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nerpa-club.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netnik.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neutralvehicle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nightmoose.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ninebytes.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ninfora.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noovell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "northern-lakes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nunnun.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nutrifyyourself.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyanco.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "occmon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oducs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offbyinfinity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "office-morimoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omoteura.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "one-resource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onepointzero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "organisatieteam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "origamika.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oscarmashauri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "overstemmen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parkwayminyan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paulward.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pbqs.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pcmkrembangan.or.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pcrypt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pedicurean.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perrone.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petlife.vet", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "philippe-mignotte.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "photolium.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pianetatatuaggi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pidginhost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pirateproxy.ist", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pixelution.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plumbingbenoni.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pmarques.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ponzi.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pottersheartministry.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prakhar.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "primotiles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "primotilesandbathrooms.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "privacyforjournalists.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "progeon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proggersession.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "projectforge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "purplebricksplc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pyjiaoyi.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qimiao.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quarryhillrentals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quatrefoiscent.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quehacerencusco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "r-ay.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ravenger.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raw-diets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rcmlinx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rechtenliteratuurleiden.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remejeanne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rentacaramerica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "retrowave.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reverse.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rittau.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rittau.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ritzlux.com.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rixter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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": "ruri.io", "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 },
+ { "name": "sana-store.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sana-store.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sandyrobsonhypnotherapy.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sanilodge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sbsnursery.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sci-internet.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scp500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "searchgov.gov.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sebastiaandouma.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "selectel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shawnstarrcustomhomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shieldcomputer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shutter-shower.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "siciliadisinfestazioni.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sinsojb.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skyquid.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slides.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solonotizie24.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soohealthy.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soopure.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sorellecollection.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spilogkoder.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportparks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportparks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "squadlinx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssuiteoffice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssuitesoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stackhub.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "standardequipment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stanthonymaryclaret.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stevenz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stimmgabel.lu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuarts.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stucydee.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "studionowystyl.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suluvir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "superbdistribute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supersec.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suseasky.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sveinerik.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swattransport.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swimwear365.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tabledusud.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tabledusud.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taichi-jade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tailandfur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techview.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techviewforum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tejarat98.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thebit.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theoverfly.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thestyle.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thewebdexter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thinkmarketing.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thoroquel.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tintenprofi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "todocracy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "todoscomciro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tolle-wolke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tommy-bordas.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomravinmd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toxicboot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tracfinancialservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tracinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trickedguys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tronflix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trunk-show.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tune-web.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uel-thompson-okanagan.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unblocked.vc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unsacsurledos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "utahfireinfo.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vagaerg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vagaerg.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vampyrium.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "varcare.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "velonustraduction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vendserve.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vernonatvclub.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vik.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "violet-letter.delivery", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vize.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vliegensvlug.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vvdbronckhorst.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vww-8522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "w10club.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "walravensax.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdesignerinwarwickshire.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdesignssussex.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wellsplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whatsahoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whoimg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "willywangstory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "witt-international.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wiz.farm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wlog.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldchess.london", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldnettps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wot-tudasbazis.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wvw-8522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xdty.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xeedbeam.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xjpvictor.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--dragni-g1a.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--o77hka.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--r77hya.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yamashita-clinic.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ybin.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yogabhawnamission.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "youcaitian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "young-sheldon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yurinet.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "z-coder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zenics.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zoomseoservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00100010.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00120012.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00130013.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00140014.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00150015.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00160016.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00180018.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00190019.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00330033.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00440044.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00550055.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00660066.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00770077.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00880088.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "00990099.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "110110110.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "112112112.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "113113113.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "118118118.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481481.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481481.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481482.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481482.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481483.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481483.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481485.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481485.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481486.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1481486.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "168bet9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "168bo9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "168bo9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "168esb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "174343.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1day1ac.red", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2333blog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "233boy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "24hourscienceprojects.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2fl.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2li.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "304squadron.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3839.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "404.guide", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "439050.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4flex.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5214889.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5214889.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "52b9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "52b9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5310899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5310899.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "53ningen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "546802.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "598598598.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "788da.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7bwin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "81uc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8888esb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8901178.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8901178.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8910899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8910899.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8917168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8917168.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8917818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8917818.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8951889.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8951889.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8992088.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8992088.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9617818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9617818.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9696178.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9696178.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9bingo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a-1basements.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aa6688.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abckam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aboutyou.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abstractbarista.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abstractbarista.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "accredit.ly", "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": "actom.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adamcoffee.net", "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 },
+ { "name": "adminwerk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "advancyte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agelesscitizen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agelesscitizens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agoravm.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agouraelectrician.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ai1989.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aimerworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aimrom.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akcounselingservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alainodea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alcoholapi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexsinnott.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alextjam.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alibababee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allenosgood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allenscaravans.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allgrass.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allgrass.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allgreenturf.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allincoin.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alljamin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allpropertyservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allseasons-cleaning.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allsync.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allsync.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alpinechaletrental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alpinetrek.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alpiniste.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altaplana.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altitudemoversdenver.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altruistgroup.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alwaysonssl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alzonaprinting.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 },
+ { "name": "america.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ameriikanpoijat.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amielucha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amitpatra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ammanagingdirectors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amosng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andariegocusco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andys-place.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ankya9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ansermfg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antennisti.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthony.codes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antyblokada.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apache-portal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apination.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appformacpc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apps4all.sytes.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "archivero.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arcridge.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "areqgaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arimarie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arlingtonwine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "armedpoet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aromacos.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artboja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteaga.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteaga.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteaga.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteaga.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artecat.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artisansoftaste.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artmarketingnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ashlocklawgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asspinter.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "astal.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atac.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ateamsport.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atedificacion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atelierdeloulou.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atheist-refugees.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "attac.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "audividi.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "augix.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aupasdecourses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aurelienaltarriba.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "auroware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "austinuniversityhouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "australianarmedforces.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "australianimmigrationadvisors.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autocrypt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autopapo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autostock.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autres-talents.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "av0ndale.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avanet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avatarrecruit.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avexon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avia-krasnoyarsk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avia-ufa.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aviapoisk.kz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avietech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awxg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ayon.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b0618.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b0618.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b0868.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b0868.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1236.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1758.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1758.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1768.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1768.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1788.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1788.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b1rd.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b2486.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b2486.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5189.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5189.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5289.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5289.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5989.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b5989.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b61688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b8591.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b8591.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b8979.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b8979.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9018.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9108.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9108.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9110.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9112.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9112.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b911gt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b911gt.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b91688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b91688.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b91688.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b91688.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9175.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9175.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9258.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9258.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9318.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9318.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9418.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9418.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9428.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9428.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9453.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9453.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9468.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9468.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9488.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9488.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9498.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9498.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9518.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9518.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9518.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9518.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9520.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9528.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9528.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9538.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9538.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9568.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9586.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9588.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b95888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9589.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9598.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9598.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9658.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9658.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b96899.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9758.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9758.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9818.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9818.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9858.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9858.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9880.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9883.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9884.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9885.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9886.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9887.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b98886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9889.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9920.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9930.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9948.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9948.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99520.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9960.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9970.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9980.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99881.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99882.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99883.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99885.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b99886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9best.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9best.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9king.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9king.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9king.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9winner.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9winner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b9winner.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bachata.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baka-gamer.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ballinarsl.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bamboorelay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banduhn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banknet.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bao-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bao-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baodan666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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": "bat909.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bat9vip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bat9vip.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "batvip9.net", "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.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bbswin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bbxin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bbxin9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bcdonadio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bcdonadio.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bcodeur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9418.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9418.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9418.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9418.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9458.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9458.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9458.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9458.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be958.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be958.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be958.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be958.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be9966.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bealpha.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bebout.domains", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beerview.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bellthrogh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bellthrough.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benevisim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benjii.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benriya.shiga.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benzi.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "berodes.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bessettenotaire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestattorney.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestbatteriesonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestesb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestinductioncooktop.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestoffert.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet-99.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet-99.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet168wy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet168wy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet909.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet990.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bet9bet9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betgo9.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betterjapanese.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betwin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betwin9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beylikduzum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beylikduzuvaillant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bh.sb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bicecontracting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bihub.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biletyplus.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biletyplus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biletyplus.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biletyplus.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bill-nye-the.science", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "binbin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "binbin9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bingo9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "binkanhada.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biocheminee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "birgitandmerlin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bistrotdelagare.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcoinwalletscript.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitenose.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitenose.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitgrapes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitxel.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bjl5689.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bjl5689.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bkhayes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackislegroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackscreen.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blazing.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bling9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bling999.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bling999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bling999.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blip.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blobfolio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockshopauto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blok56.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bludnykoren.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blueblou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluecardlottery.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluedeck.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blunderify.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluproducts.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bmriv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo1689.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo1689.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9club.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9club.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9club.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9fun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9fun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9game.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9game.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bo9king.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boards.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bodypainting.waw.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bolgarnyelv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bondingwithbaby.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "booksearch.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bopiweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bordes.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boredhackers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boundarybrighton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bovenwebdesign.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bozit.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bramburek.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bramstaps.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "breatheav.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "breatheproduction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "briandwells.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brownihc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brztec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsa157.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsd-box.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsdes.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bserved.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "budget.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bulario.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "burtplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buryit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "busybee360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buybike.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buycarpet.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buycook.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyhealth.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyjewel.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyplussize.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyprofessional.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buywine.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buywood.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bx-web.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bytema.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bytema.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bythen.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bywin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caarecord.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cadams.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cadra.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calcedge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "campingskyhooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canglong.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canker.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canterbury.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "captainark.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "car-rental24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carlscatering.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carolinaclimatecontrolsc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.com.ve", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.ec", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartadeviajes.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casacameo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caseplus-daem.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cashsector.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casino-trio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caspar.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cayounglab.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdbtech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdsdigital.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centralebigmat.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cerberusinformatica.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cercevelet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "certifiednurses.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cfpa-formation.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "changes.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chaosriftgames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chasse-et-plaisir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chd-expert.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "checkspf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cheladmin.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chemicalcrux.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chemiphys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cherie-belle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cherylsoleway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chiboard.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chikazawa.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chinwag.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chloca.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chrisaitch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christopherkennelly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chriswald.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cidersus.com.ec", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "circulatedigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "civicunicorn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "civicunicorn.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckenelley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckenelly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckenely.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckenneley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckennelley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckennely.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "claritysrv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clash.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "classroomcountdown.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clazzrooms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cleansewellness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clearbreezesecuritydoors.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clicksaveandprint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clinicminds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clnc.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clorophilla.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "club-duomo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clubcall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clubiconkenosha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmdtelecom.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmrss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocktail-shaken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocubes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cokebar.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coldstreamcreekfarm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "collectorknives.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coltonrb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comidasperuanas.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "commco.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comoeliminarlaspapulasperladasenelglande.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comosatisfaceraunhombreenlacamaydejarloloco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "compeat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "compusolve.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "concertsenboite.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "contentdesign.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "convergencela.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cookeatup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coolprylar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corintech.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corporateclash.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corpsepaint.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corrbee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cosmechic.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "couscous.recipes", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creatieven.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creativeconceptsvernon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creato.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creatujoya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "creditreporttips.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cribcore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crimevictims.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cronologie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crose.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crypteianetworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptolinc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csehnyelv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csgoswap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ctcue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cubix.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cueca.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cumplegenial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cupcakesandcrinoline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cupcao.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cybercrew.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberseguranca.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyelint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cygnaltech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "czfa.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d-msg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dabuttonfactory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "damienpontifex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daminiphysio.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "darknetlive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "datacave.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daverandom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "davidbranco.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "davidbrito.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deanisa.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "decaffeinated.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "decs.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dedg3.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deeps.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deeps.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dekonix.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delfino.cr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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 },
+ { "name": "digitalcitizen.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalcitizen.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalfishfun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dildoexperten.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "direct-sel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "directspa.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dischempharmacie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazioni.venezia.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "distiduffer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dj-leszwolle.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "djcursuszwolle.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "djursland-psykologen.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dnscrawler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doc-justice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doesburg-comp.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dogcontrol.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domen-reg.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dominique-haas.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domquixoteepi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dongxuwang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dotshule.ug", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doubleaste.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "downrightcute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dp.cx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dreadd.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dreax.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dreischneidiger.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drillingsupplystore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drmtransit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dronnet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drugs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drvr.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dsmjs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dsouzamusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dsrw.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dubai-company.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dunklau.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "duoquadragintien.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "durfteparticiperen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dusnan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dustplanet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dzytdl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-tech-solution.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-techsolution.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-techsolutions.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-vo-linka.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e1488.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e4metech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e52888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e52888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e53888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e53888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e59888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e59888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eagle.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eaglemessaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eastsidecottages.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "easycontentplan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebene-bpo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebizarts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecodedi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eddokloosterman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edehsa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edincmovie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edservicing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edxn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "egrp365.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ekati.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ekb-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ekyu.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electric-vault.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricalagourahills.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricalcalabasas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricalcamarillo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricalconejovalley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eleicoes2018.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elektronickakancelar.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eleonorengland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eline168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elviraszabo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elvispresley.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elwix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elysiria.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "empyrean-advisors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emvoiceapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "en4u.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enderbycamping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "endoftenancycleaninglondon.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enginx.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ensemble-vos-idees.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "entheorie.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enviatufoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epa.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ephesusbreeze.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epreskripce.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "equinetherapy.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eroimatome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eroma.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erwinpaal.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "es888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "es8888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "es888999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "es999.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "es9999.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb-top.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb-top.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb111.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb116.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1314.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1668.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb168168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb168168.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb168168.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb168168.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1688.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1688.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1688.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1688.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb16888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1711.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1711.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1788.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1788.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1788.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb1788.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb17888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb2013.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb2013.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb2099.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb2099.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb222.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb258.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb325.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb325.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb333.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb336.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb369.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb518.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb553.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb555.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb555.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb556.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb5889.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb5889.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb6.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb666.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb66666.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb677.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb688.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb68888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb775.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb777.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb888.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb8886.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb9527.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb9588.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb9588.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb9588.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb9588.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb999.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb999.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb999.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esb999.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esba11.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esba11.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esba11.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esba11.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esba11.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.bz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball518.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball518.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball518.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball518.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esball888.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esballs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbbon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbbon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbfun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbfun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbgood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbin.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbjon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbjon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbm4.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esbm5.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esmoney.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esmoney.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etech-solution.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etech-solution.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etech-solutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etechsolution.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ethandelany.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eurolocarno.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "europeantimberconnectors.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "europeos.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "euroskano.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eurousa.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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 },
+ { "name": "exatmiseis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exchaser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exploringenderby.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extreme.co.th", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eyona.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f2h.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "f3nws.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facekungfu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "factcool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faerb.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fanboi.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faradome.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "farmaciamedicom.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fastvistorias.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faui2k17.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fbiic.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fbtholdings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fedemo.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "federatedbank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fedpartnership.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feeriedesign-event.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feetpa.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "felger-times.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feng-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feng-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feudaltactics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feuerwehr-mehring.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ffiec.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fibo-forex.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "filanthropystar.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finchnest.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fingerscrossed.style", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fintry.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "firefly-iii.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fireworkcoaching.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fitfitup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fiveboosts.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fixvoltage.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flamero.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flangaapis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fleurenplume.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flextribly.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fliino.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fliino.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fliino.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fliino.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flipbell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flirtycourts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flmortgagebank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "florenceapp.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "floro.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowinvoice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flugsportvereinigungcelle.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fluhrers.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fluitbeurt.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fmussatmd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "focuspointtechnologies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forbid.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "force-des-maths.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fordlibrarymuseum.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forecastcity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forfunssake.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forpc.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fotonjan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fowlsmurf.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "francescoservida.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frankenhost.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frankslaughterinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frederikvig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freelancecollab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freepnglogos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frejasdal.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frosthall.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frugal-millennial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fs-community.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fu-li88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fu-li88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fullhost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "futurehack.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fwest98.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaff-rig.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "galle.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gamecdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ganaenergia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ganasoku.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaudeamus-folklor.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gavinsblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gayukai.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gazachallenge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "generalinsuranceservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "generationsweldom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geojs.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "georgewbushlibrary.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getenergized2018.kpn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getpagespeed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getteamninja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gfms.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gfw.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghid-pitesti.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "giethoorn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gigime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ginza-luce.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gites-alizea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gkvsc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glaciernursery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gladystudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "globalgovernancewatch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "god-esb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "godbo9.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "godbo9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "godbo9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "godesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goedkopeonesies.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goetic.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goozp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goquiq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gorgias.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gorognyelv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gotrail.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gowin9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gowin9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grahamcluley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gram.tips", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grandcafetwist.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gratiswifivoorjegasten.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greatagain.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greenitpark.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grengine.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grexx.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grexx.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grifomarchetti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grimstveit.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "groenewoud.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gruenderwoche-dresden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grumpygamers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guiacidade.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guideline.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guidelines.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guishem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gumannp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gumballs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guoliang.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gutschein-spezialist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "h1z1swap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ha-kunamatata.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "habbixed.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "habitat-domotique.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "habview.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haccp.bergamo.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hakase.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hamon.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hanoibuffet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hansbijster.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haptemic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "has-no-email-set.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hasecuritysolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hashimoto-jimusho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hayleishop.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hdnastudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healey.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "health.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthfinder.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthypeople.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hearty.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hearty.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hebocon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heijdel.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heinemann.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heinemeier.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heistheguy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "helpfute.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "helpverif.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "helpwithmybank.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "henkboelman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hermann.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herrenmuehle-wein.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heute.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heyjournal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hf-tekst.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hf51.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hibari.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hideout.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hightechgadgets.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hipnoseinstitute.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hireprofs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hitokoto-mania.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hiyobi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hl8999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hnyp.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoaas.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hochzeitsgezwitscher.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hodnos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homepage.shiga.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homyremedies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "honeycreeper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoorr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hope-line-earth.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "horizonmoto.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "horvatnyelvkonyv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hotesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hotesb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "housekeeperlondon.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "howgoodwasmysex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hstspreload.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hua-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hua-li88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hua-li88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "huangting.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hubrecht.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hui-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hui-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "huislijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humboldtmfg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hunstoncanoeclub.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "huntexpired.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyperactive.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hztgzz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i-scream.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i5y.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iainsimms.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iainsimms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iane-ccs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ich-hab-die-schnauze-voll-von-der-suche-nach-ner-kurzen-domain.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icnsoft.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ideapaisajistas.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ideasenfoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idered.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idesignstudio.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idrissi.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iha6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ikkbb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ikkev.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imeid.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "immaternity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imponet.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imprenta-es.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inetsoftware.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infinite.hosting", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infruction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ing89.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ing89.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ingatlanneked.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ingi.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inmoodforsex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inspirationconcepts.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "instamojo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intergenx.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intergenx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intergenx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intergenx.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "interiery-waters.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "interiorprofesional.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "interspot.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invitethemhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invuelto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iodine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iplayradio.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ironhide.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaaczais.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iskkk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "istheinternetonfire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "it-maker.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iwch.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iworos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iyassu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "izzys.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "j0bs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jakob-server.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamalfi.bio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "janhermann.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jape.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jastrow.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "javiermixdjs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaysenjohnson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jci.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jdgonzalez95.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jedayoshi.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeepeg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jenniferchan.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jetapi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jetbrains.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jexler.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jfsa.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jiid.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jing-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jing-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jiosongs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jldp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jlot.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobers.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jobers.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joblab.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joel.coffee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joeyhoer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johannes-bugenhagen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johanneskonrad.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johego.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jonespayne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jonincharacter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jonlu.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joonatoona.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jose-alexand.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "joshuadmiller.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "journalof.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jselby.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "judge2020.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "judge2020.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juliohernandezgt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jungundwild-design.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juridiqueo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justiceo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justinrudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jzachpearson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "k38.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "k4r.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaeru-seitai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kai.cool", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kakuto.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kalamos-psychiatrie.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaleidoskop-freiburg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kalwestelectric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kamppailusali.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kana-mono.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanag.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanr.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanzakiranko.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kanzlei-myca.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaotik4266.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kargl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keematdekho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kescher.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kfirba.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kidsareatrip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kin.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinderjugendfreizeitverein.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kirwandigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kissesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kissesb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kivitelezesbiztositas.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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 },
+ { "name": "konventa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kopio.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kopjethee.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koppelvlak.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "korben.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kostal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kotly-marten.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kouten-jp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koval.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kowalstwo.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kpforme.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kraftzeiten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kraken.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "krasnodar-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "krausen.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kreditkarte-fuer-backpacker.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kryptomodkingz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kupinska.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuroinu.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kwench.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kyprexxo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "la-compagnie-des-elfes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laatjeniethackmaken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laboutiquedejuliette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "labrat.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lachosetypo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ladyanna.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lafcheta.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lagit.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lalalab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lalunecreative.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lamaisondelatransformationculturelle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lamereabizix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "langstreckensaufen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lanternhealth.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lassesworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lassesworld.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "launchpadder2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lauraofrank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lauriemilne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laut.digital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "law.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lc-cs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lcrmscp.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "le-drive-de-just-vet.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leaderoftheresistance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leaderoftheresistance.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leadquest.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "learnforestry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lecoinchocolat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ledlampor365.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "legaleus.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lengyelnyelvoktatas.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lengyelul.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leodraxler.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leonauto.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lesaffre.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lesh.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letempsdunefleur.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leviaan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lhajn.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lian-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lian-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liang-li88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liang-li88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "librarytools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "libre-service.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lichttechnik-tumler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lieblingsholz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lieuu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifeinsurances.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifeinsurances24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "light-up.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "limbo.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "limn.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lincnaarzorg.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linux.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linuxincluded.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liquimoly.market", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "littlegreece.ae", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liufengyu.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livelifewithintent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "localdata.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "locomotive.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojadarenda.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojavirtualfc.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loket.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loli.ski", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "losangelestown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovebo9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovebo9.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovingpenguin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lswim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ltaake.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lucaslarson.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ludum.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luedeke-bremen.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lufu.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lui.pink", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lxd.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lycly.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lyscnd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mackiehouse.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maddreefer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madridartcollection.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maelstrom-fury.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mahraartisan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maisonpaulmier.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "makemyvape.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "makeurbiz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "malone.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mamaasia.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mamafit.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mamuko.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manageathome.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mantabiofuel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcelinofranchini.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcelinofranchini.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcelinofranchini.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcelinofranchini.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marco-goltz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marjoriecarvalho.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mark-armstrong-gaming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketingco.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketingromania.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marklauman.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marpa-wohnen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marshyplay.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "martijnhielema.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marustat.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "math.hamburg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matrixim.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattari-app.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattmcshane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mauricedb.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxpl0it.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mchan.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcpaoffice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "md-clinica.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mdlayher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediarocks.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medinside.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medinside.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medinsider.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medinsider.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medschat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medvet.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "melopie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "memo.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mendozagenevieve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mennace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "menntagatt.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "metro-web.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meujeitodigital.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meyash.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mfen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mfxer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "miaonagemi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "michal-s.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "micomi.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "midkam.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikewritesstuff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikhirev.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "min.kiwi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minehattan.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minerva2015.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ministeriumfuerinternet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minu.link", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mirabalphoto.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mirrorsedgearchive.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mirrorsedgearchive.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mitigationcommission.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mixer.cash", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mjscustomcreations.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlmjam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mlpvector.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mms.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobilebingoclub.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobilecasinoclub.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobilemalin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobimalin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobmp4.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobmp4.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobmp4.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mockerel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modding-forum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modelclub-draveil.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moebel-vergleichen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moisesbarrio.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "momfulfilled.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "momy-genealogie.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mon-mobile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monalyse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monicabeckstrom.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monodukuri.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monodzukuri.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monozukuri.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moodforsex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moolah.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moonbot.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moreal.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morepopcorn.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "motowilliams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "movienized.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mozartgroup.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrbuckykat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrknee.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrparker.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mufibot.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mushman.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mustafaturhan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myabcm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mycareersfuture.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myessaygeek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mygreatlakes.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mymarketingcourses.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mypaperdone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myref.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysexydate24.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysongbird.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mytun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n64chan.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nakada4610.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nameme.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "namskra.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naomi.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nataniel-perissier.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nationalbank.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nationalbanknet.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nay.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nba669.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nba686.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nbad.al", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nc-beautypro.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nc-formation.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nc-network.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "necio.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neilfarrington.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nekox.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neocyd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "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 },
+ { "name": "net-masters.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nethask.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netsparker.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nettamente.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neurolab.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "news4c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ngc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nhsuites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nicholaswilliams.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nickscomputers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nightsi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nikkasystems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nimidam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ninepints.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nirjonmela.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noelblog.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noise.agency", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noisetor.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nolimits.net.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nomenclator.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nordlichter-brv.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "norichanmama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "normanschwaneberg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "northokanaganbookkeeping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "novgorod-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "novosibavia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nsa.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nsapwn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nutriciametabolics-shop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nutrishop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "o8b.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oclausen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "octo.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "octohost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ohohrazi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oisd.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "olgui.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oliveoil.bot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oliverclausen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oliviervaillancourt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ollies.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onahonavi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ondcp.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oneidentity.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onetly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oni.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "online-calculator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "online-stopwatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "online.net.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onlyesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onlyesb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onsgenoegen-waz.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onspring.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opalesurfcasting.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "openclima.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opentuition.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "operationforever.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oppag.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "optm.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orbitdefence.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oregonmu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orum.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osla.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osmre.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "otus-magnum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ouowo.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pablo.scot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pablo.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.nom.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.science", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pabloarteaga.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pacifique-web.nc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "packshot-creator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "padron.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagalworld.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagalworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagalworld.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pagalworld.la", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paincareehr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paket.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "palawan.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "palazzotalamo.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pangci.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "papapa-members.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "papotage.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paradependentesquimicos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parisderriere.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pasearch.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "passvanille-reservation.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "patentados.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "patika-biztositas.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paulmeier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pay.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pb.ax", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pcdocjim.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peaceispossible.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pearlcohen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peddy.dyndns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pedro.com.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pelotonimports.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "penguinprotocols.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "penispumpen.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pepper.dog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perm-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "permajackofstlouis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petit-archer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pflan.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pflegesalon-siebke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pi-net.dedyn.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pierreprinetti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pimpmypaper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pinklittlenotebook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pixiv.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pixloc.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plagiarismcheck.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planer.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planetanim.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plannedlink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planujemywesele.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plasticsurgerynola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "playreal.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plerion.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pm25.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pmgnet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pneu01.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pneu74.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pocakdrops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pocakking.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pocitacezababku.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pocket-lint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pohlmann.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pointworksacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "policereferencecheck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pomfeed.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pomozmruczkom.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poolspondsandwaterscapes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "popcultureshack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "port.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "posijson.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powerserg.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powersergholdings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powertothebuilder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pozlife.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "praktijkdevecht.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pritchett.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "privatecapsecurity.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pro-esb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pro-esb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prodware.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proesb.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "projectl1b1t1na.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "promotioncentre.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "proteogenix-products.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "protocol.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prylarprylar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psdsuc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pthsec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "publicinquiry.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pulpproject.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "punchunique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "purplehippie.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "putman-it.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "puzzlage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pvda.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pvpctutorials.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pycycle.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pzsearch.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qc.immo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qclt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qruiser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quanwuji.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quartix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quartzclinical.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quilmo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quimsertek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qwdqwd.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qwq.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "r1ch.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radartatska.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radartek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radiorsvp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rammstein-portugal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rangsmo.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ranyeh.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raphrfg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rapidemobile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rapidflow.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raucris.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raviparekh.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raystark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raywin168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raywin168.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raywin88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "recipex.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "red-trigger.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "red2fred2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redactieco.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regency-fire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regency-fire.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regisearch.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "registerra.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renewmedispa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "resfriatech.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reviewninja.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "richamorindonesia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ricky.capital", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ristrutturazioneappartamento.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rizalpalawan.gov.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rlnunez.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "robertnemec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "robertocasares.no-ip.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roboth.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rodarion.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roelbazuin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roligprylar.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rollercoasteritalia.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rollingbarge.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rook-playz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roopakv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rootkea.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ropd.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roseparkhouse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rosetiger.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rostov-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ruaneattorneys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ruobr.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rushyo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rwx.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s-n-unso.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s-s-paint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s3cases.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "s44.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sabtunes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saintw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sajamstudija.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salon1.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samanthasicecream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samara-avia.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sandiegotown.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sapphireblue.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sarahplusdrei.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sasrobotics.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sativatunja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saxeandthecity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sbrouwer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schollbox.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schwerkraftlabor.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scib.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scicomm.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scijinks.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scrapmalin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "screenmachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sdxcentral.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sean-wright.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "season.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sebastianpedersen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sebasveeke.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sec.red", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sec455.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sec530.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sec555.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "secureim.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seehimnaked.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seehimnude.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seehisnudes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seobutler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sergiozygmunt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servida.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "setenforce.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sevenicealimentos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sexdocka.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharelovenotsecrets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shaunandamyswedding.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shico.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shiga1.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shihadwiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouttag.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shteiman.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shura.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "silerfamily.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sim-minaoshi.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simhaf.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simplyregister.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sinclairinat0r.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sinn.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sipsik.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sjaakgilsingfashion.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skanword.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skedda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skepneklaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skiddle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skippy.dog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sknclinics.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skolagatt.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skyderby.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slashcrypto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sleepstar.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "slonep.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smadav.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smalle-voet.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smartcpa.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smilingmiao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smx.net.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "socialtrends.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "societe-chablaisienne-de-revetements.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "societe-chablaisienne-de-revetements.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sodadigital.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "softart.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sokouchousa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solvingproblems.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sommefeldt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sompani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sonicdoe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sorenam.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sortesim.com.br", "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 },
+ { "name": "spcx.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "specialtyalloys.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "speechdrop.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "speedof.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "speedway.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spellchecker.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spindrift.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "splintermail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spoluck.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sponsormatch.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spookyinternet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spot-lumiere-led.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spotrebitelskecentrum.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sr-33.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssbgportal.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssc8689.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssc8689.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssdservers.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssready.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "staktrace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "startle.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stdev.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steamhours.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stemapp.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steuerberater-essen-steele.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stevemonteyne.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stickeramoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stiffordacademy.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stouter.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "striata.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuudium.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "subrosr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "succesprojekter.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sudo.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sunfulong.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sunriseafricarelief.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "super-demarche.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supperclub.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "surfocal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suroil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swallsoft.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swallsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swap.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sweep.cards", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sweet-orr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sweets-mimatsu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swisstechtalks.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swordfighting.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sym01.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "symetria.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "systemadmin.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "systemd.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "szerbnyelvkonyv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "szlovaknyelv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "szlovennyelv.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tacklinglife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tadluedtke.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tai-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tai-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "takebackyourstate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "takebackyourstate.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "takebackyourstate.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tangsisi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taniafitness.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taniafitness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tanie-uslugi-ksiegowe.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tariff.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tass.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tbys.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tchaka.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teambodyproject.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teamninjaapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techdroid.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techformator.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "technosuport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tecnologiasurbanas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telefonogratuito.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telfordwhitehouse.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tematicas.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tennisapp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenpo-iku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenzer.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "termax.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terra.fitness", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tfreeman.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theadultswiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theconcordbridge.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theemasphere.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thefasterweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thefengshuioffice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thegemriverside.com.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thehiddenbay.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theplaidpoodle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesaurus.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesignacademy.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesmallbusinesswebsiteguy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thewarrencenter.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thewoolroom.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thinegen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thisdot.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thomas.love", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thriveweb.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tigit.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiglitub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timetech.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timothybjacobs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tinlc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tiny.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "titanpointe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tju.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "to2mbn.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tobias-kleinmann.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tobyx.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "todacarreira.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toekomstperspectief.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tokinoha.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tokky.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomaspatera.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomlowenthal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomosm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toolkits.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toothdoc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "top-esb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topbilan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topesb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topicdesk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toponlinecasinosites.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topwindowcleaners.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torngalaxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torte.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "totodil.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "totolabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "touchweb.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "touhou.fm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tourtrektrip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tovp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toyota-kinenkan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trackingstream.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trade-arcade.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "travel1x1.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "travellovers.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "treaslockbox.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "treetopsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tribly.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "troomcafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trouver-son-chemin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "troykelly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trustednetworks.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tryfm.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trygarciniaslimdiet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ttyystudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "turnaroundforum.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tutorme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tuwaner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tuza.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tv-programme.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tv-programme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "txbi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uahs.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uhlhosting.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ultimate-uk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ultrasite.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "umbriel.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unblock-zh.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unccelearn.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unefleur.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unidevgroup.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unifiednetwork.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uno.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "upperroommission.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "urbanmic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "urth.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usbr.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "utcast-mate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "utgifter.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valudo.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vanderbiltcisa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vantagepointpreneed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vasilikieleftheriou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vats.im", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vatsim-uk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vatsim.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vaughanrisher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vcps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vega-motor.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vegalengd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vegguide.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "veit.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ventilateurs-plafond.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "veraandsteve.date", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verbier-lechable.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vernonfigureskatingclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "very-kids.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vidadu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vidb.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "videoload.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "videospornogratis.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villamariaamalfi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vinogradovka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vintagebandfestival.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vintagesouthernpicks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipesball.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipesball.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipesball.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vipesball.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visit-montenegro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vizija-nepremicnine.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vjhfoundation.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vmstan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volbyzive.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vrijgezellenfeestzwolle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vucdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vynedmusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "w50.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "w84.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wai-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waka168.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waka168.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waka88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wakfu.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wakiminblog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waltzmanplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "walvi.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wannaridecostarica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "warcraftjournal.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wasatchcrest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waylee.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "web-demarche.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdesignlabor.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webev.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "websitesabq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webwednesday.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weiltoast.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weld.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wen-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wen-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "werkenvoorphiladelphia.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wezl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whistler-transfers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whitehousedrugpolicy.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whoasome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whocybered.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "willowtree.school", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wisak.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "woktoss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "woodcoin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "woonboulevardvolendam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worf.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "workissime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "workshopszwolle.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "workshopzwolle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "worldcareers.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpformation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wphelpwithhomework.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "writemyessay.today", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wrmea.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wuxiaohen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wybar.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wzfetish.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xanadu-taxi.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xilegames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xin-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xin-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xing-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xinghuokeji.xin", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--lnakuten-9za.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--n8jubz39q0g0afpa985c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--pckqk6xk43lunk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--zr9h.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--zr9h.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--zr9h.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--zr9h.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xnu.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xsec.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xuan-li88.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xuan-li88.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xxxlbox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yacineboumaza.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yakaz.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yannick.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yao-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yao-in.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ybscareers.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yenibilgi.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yetishirt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yimgo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yocchan1513.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yoga-alliance-teacher-training.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yongbin.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yourfriendlytech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ysx.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubico.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubikey.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuema.net.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yummylooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yurisviridov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yusu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yutang.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yvetteerasmus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yzcloud.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "z-latko.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zacharyschneider.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zachschneider.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaem.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaghyr.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zalohovaniburian.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zargescases.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zekesnider.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zeroseteatacado.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zgan.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhiwei.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhuweiyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zitseng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zorki.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zrnieckapresny.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zuan-in.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zyciedogorynogami.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zyrillezuno.com", "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,
@@ -41627,6 +44253,8 @@
{ "name": "mitm-software.badssl.com", "policy": "custom", "mode": "force-https", "include_subdomains": true },
{ "name": "www.hyatt.com", "policy": "custom", "mode": "force-https", "include_subdomains": true },
{ "name": "connect.facebook.net", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ { "name": "bing.com", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ { "name": "fan.gov", "policy": "custom", "mode": "force-https", "include_subdomains": true },
// No subdomains
{ "name": "wordpress.com", "policy": "custom", "mode": "force-https", "include_subdomains": false },
{ "name": "www.wordpress.com", "policy": "custom", "mode": "force-https", "include_subdomains": false },
@@ -41635,11 +44263,12 @@
{ "name": "swehack.org", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "swehackCom" },
{ "name": "ncsccs.com", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "ncsccs" },
{ "name": "themathematician.uk", "policy": "custom", "mode": "force-https", "include_subdomains": true, "pins": "ncsccs" },
- // TODO(lgarron): hstspreload.org can't scan IPv6-only sites due to Google
+ // TODO(elawrence): hstspreload.org can't scan IPv6-only sites due to Google
// Cloud limitations. Move these entries to the bulk entries once they can
// be handled automatically: github.com/chromium/hstspreload.org/issues/43
// IPv6
{ "name": "ipv6only.network", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ { "name": "trinity.fr.eu.org", "policy": "custom", "mode": "force-https", "include_subdomains": true },
// Expect-CT/Expect-Staple
{
"name": "crt.sh", "policy": "custom",
@@ -41827,6 +44456,7 @@
{ "name": "safecar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "famep.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "nationalmall.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+ { "name": "mytuleap.com", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
// END OF ETLD-OWNER REQUESTED ENTRIES
// To avoid trailing comma changes from showing up in diffs, we place a
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index d7a0df28483..c1569892b3d 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -246,7 +246,7 @@ void CheckHPKPReport(
const HashValueVector& known_pins) {
std::unique_ptr<base::Value> value(base::JSONReader::Read(report));
ASSERT_TRUE(value);
- ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY));
+ ASSERT_TRUE(value->is_dict());
base::DictionaryValue* report_dict;
ASSERT_TRUE(value->GetAsDictionary(&report_dict));
@@ -311,7 +311,7 @@ void CheckSerializedExpectStapleReport(const std::string& report,
const std::string& cert_status) {
std::unique_ptr<base::Value> value(base::JSONReader::Read(report));
ASSERT_TRUE(value);
- ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY));
+ ASSERT_TRUE(value->is_dict());
base::DictionaryValue* report_dict;
ASSERT_TRUE(value->GetAsDictionary(&report_dict));
@@ -2220,8 +2220,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ASSERT_TRUE(cert);
HashValueVector hashes;
- hashes.push_back(HashValue(
- X509Certificate::CalculateFingerprint256(cert->os_cert_handle())));
+ hashes.push_back(
+ HashValue(X509Certificate::CalculateFingerprint256(cert->cert_buffer())));
{
TransportSecurityState state;
@@ -2357,11 +2357,11 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
ImportCertFromFile(GetTestCertsDirectory(), "post_june_2016.pem");
ASSERT_TRUE(after_cert);
- SHA256HashValue symantec_hash_value = {
+ const SHA256HashValue symantec_hash_value = {
{0xb2, 0xde, 0xf5, 0x36, 0x2a, 0xd3, 0xfa, 0xcd, 0x04, 0xbd, 0x29,
0x04, 0x7a, 0x43, 0x84, 0x4f, 0x76, 0x70, 0x34, 0xea, 0x48, 0x92,
0xf8, 0x0e, 0x56, 0xbe, 0xe6, 0x90, 0x24, 0x3e, 0x25, 0x02}};
- SHA256HashValue google_hash_value = {
+ const SHA256HashValue google_hash_value = {
{0xec, 0x72, 0x29, 0x69, 0xcb, 0x64, 0x20, 0x0a, 0xb6, 0x63, 0x8f,
0x68, 0xac, 0x53, 0x8e, 0x40, 0xab, 0xab, 0x5b, 0x19, 0xa6, 0x48,
0x56, 0x61, 0x04, 0x2a, 0x10, 0x61, 0xc4, 0x61, 0x27, 0x76}};
@@ -2473,6 +2473,93 @@ TEST_F(TransportSecurityStateTest, RequireCTForSymantec) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
}
+// Tests that Certificate Transparency is required for all of the Symantec
+// Managed CAs, regardless of when the certificate was issued.
+TEST_F(TransportSecurityStateTest, RequireCTForSymantecManagedCAs) {
+ const SHA256HashValue symantec_hash_value = {
+ {0xb2, 0xde, 0xf5, 0x36, 0x2a, 0xd3, 0xfa, 0xcd, 0x04, 0xbd, 0x29,
+ 0x04, 0x7a, 0x43, 0x84, 0x4f, 0x76, 0x70, 0x34, 0xea, 0x48, 0x92,
+ 0xf8, 0x0e, 0x56, 0xbe, 0xe6, 0x90, 0x24, 0x3e, 0x25, 0x02}};
+ const SHA256HashValue managed_hash_value = {
+ {0x7c, 0xac, 0x9a, 0x0f, 0xf3, 0x15, 0x38, 0x77, 0x50, 0xba, 0x8b,
+ 0xaf, 0xdb, 0x1c, 0x2b, 0xc2, 0x9b, 0x3f, 0x0b, 0xba, 0x16, 0x36,
+ 0x2c, 0xa9, 0x3a, 0x90, 0xf8, 0x4d, 0xa2, 0xdf, 0x5f, 0x3e}};
+
+ TransportSecurityState state;
+
+ HashValueVector hashes;
+ hashes.push_back(HashValue(symantec_hash_value));
+ hashes.push_back(HashValue(managed_hash_value));
+
+ // All certificates, both before and after the pre-existing 1 June 2016
+ // date, are expected to be compliant.
+ scoped_refptr<X509Certificate> before_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "pre_june_2016.pem");
+ ASSERT_TRUE(before_cert);
+
+ 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_ENOUGH_SCTS));
+ 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));
+ 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));
+ 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));
+
+ scoped_refptr<X509Certificate> after_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "post_june_2016.pem");
+ ASSERT_TRUE(after_cert);
+
+ 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_ENOUGH_SCTS));
+ 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));
+ 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));
+ 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));
+}
+
// Tests that dynamic Expect-CT state is cleared from ClearDynamicData().
TEST_F(TransportSecurityStateTest, DynamicExpectCTStateCleared) {
base::test::ScopedFeatureList feature_list;
@@ -3104,6 +3191,8 @@ TEST_F(TransportSecurityStateStaticTest, IsPreloaded) {
const std::string google = "google";
const std::string www_google = "www.google";
const std::string foo = "foo";
+ const std::string bank = "example.bank";
+ const std::string insurance = "sub.example.insurance";
TransportSecurityState state;
TransportSecurityState::STSState sts_state;
@@ -3115,6 +3204,10 @@ TEST_F(TransportSecurityStateStaticTest, IsPreloaded) {
EXPECT_TRUE(GetStaticDomainState(&state, google, &sts_state, &pkp_state));
EXPECT_TRUE(GetStaticDomainState(&state, www_google, &sts_state, &pkp_state));
EXPECT_TRUE(GetStaticDomainState(&state, foo, &sts_state, &pkp_state));
+ EXPECT_TRUE(GetStaticDomainState(&state, bank, &sts_state, &pkp_state));
+ EXPECT_TRUE(sts_state.include_subdomains);
+ EXPECT_TRUE(GetStaticDomainState(&state, insurance, &sts_state, &pkp_state));
+ EXPECT_TRUE(sts_state.include_subdomains);
EXPECT_FALSE(
GetStaticDomainState(&state, a_www_paypal, &sts_state, &pkp_state));
EXPECT_FALSE(
@@ -3347,6 +3440,9 @@ TEST_F(TransportSecurityStateStaticTest, Preloaded) {
EXPECT_TRUE(StaticShouldRedirect("crate.io"));
EXPECT_TRUE(StaticShouldRedirect("foo.crate.io"));
+
+ EXPECT_TRUE(StaticShouldRedirect("sub.bank"));
+ EXPECT_TRUE(StaticShouldRedirect("sub.insurance"));
}
TEST_F(TransportSecurityStateStaticTest, PreloadedPins) {
@@ -3498,7 +3594,7 @@ TEST_F(TransportSecurityStateStaticTest, OptionalHSTSCertPins) {
EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com"));
EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net"));
EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net"));
- EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net"));
+ EXPECT_TRUE(HasStaticPublicKeyPins("redirector.gvt1.com"));
EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com"));
}
diff --git a/chromium/net/http2/decoder/decode_buffer_test.cc b/chromium/net/http2/decoder/decode_buffer_test.cc
index b982d4c9aef..2f1abdd2c30 100644
--- a/chromium/net/http2/decoder/decode_buffer_test.cc
+++ b/chromium/net/http2/decoder/decode_buffer_test.cc
@@ -43,7 +43,7 @@ struct TestStruct {
class DecodeBufferTest : public ::testing::Test {
public:
- DecodeBufferTest() {}
+ DecodeBufferTest() = default;
protected:
Http2Random random_;
diff --git a/chromium/net/http2/decoder/http2_frame_decoder_listener_test_util.cc b/chromium/net/http2/decoder/http2_frame_decoder_listener_test_util.cc
index 9159b6cdc5b..74c59eebccb 100644
--- a/chromium/net/http2/decoder/http2_frame_decoder_listener_test_util.cc
+++ b/chromium/net/http2/decoder/http2_frame_decoder_listener_test_util.cc
@@ -9,8 +9,8 @@
namespace net {
-FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() {}
-FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() {}
+FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() = default;
+FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() = default;
bool FailingHttp2FrameDecoderListener::OnFrameHeader(
const Http2FrameHeader& header) {
@@ -196,7 +196,7 @@ LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener()
LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener(
Http2FrameDecoderListener* wrapped)
: wrapped_(wrapped) {}
-LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() {}
+LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() = default;
bool LoggingHttp2FrameDecoderListener::OnFrameHeader(
const Http2FrameHeader& header) {
diff --git a/chromium/net/http2/decoder/http2_frame_decoder_test.cc b/chromium/net/http2/decoder/http2_frame_decoder_test.cc
index a1d848326b9..d81c7ac98ec 100644
--- a/chromium/net/http2/decoder/http2_frame_decoder_test.cc
+++ b/chromium/net/http2/decoder/http2_frame_decoder_test.cc
@@ -196,7 +196,7 @@ class Http2FrameDecoderTest : public RandomDecoderTest {
template <size_t N>
AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N],
FrameParts expected) {
- expected.has_frame_size_error = true;
+ expected.SetHasFrameSizeError(true);
VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected));
}
@@ -260,7 +260,7 @@ TEST_F(Http2FrameDecoderTest, Priority) {
};
Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2);
FrameParts expected(header);
- expected.opt_priority = Http2PriorityFields(1, 17, true);
+ expected.SetOptPriority(Http2PriorityFields(1, 17, true));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -274,7 +274,7 @@ TEST_F(Http2FrameDecoderTest, RstStream) {
};
Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1);
FrameParts expected(header);
- expected.opt_rst_stream_error_code = Http2ErrorCode::PROTOCOL_ERROR;
+ expected.SetOptRstStreamErrorCode(Http2ErrorCode::PROTOCOL_ERROR);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -312,7 +312,7 @@ TEST_F(Http2FrameDecoderTest, PushPromiseMinimal) {
Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
Http2FrameFlag::END_HEADERS, 2);
FrameParts expected(header, "");
- expected.opt_push_promise = Http2PushPromiseFields{1};
+ expected.SetOptPushPromise(Http2PushPromiseFields{1});
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -327,7 +327,8 @@ TEST_F(Http2FrameDecoderTest, Ping) {
};
Http2FrameHeader header(8, Http2FrameType::PING, 0, 0);
FrameParts expected(header);
- expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
+ expected.SetOptPing(
+ Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -342,7 +343,8 @@ TEST_F(Http2FrameDecoderTest, PingAck) {
};
Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
FrameParts expected(header);
- expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
+ expected.SetOptPing(
+ Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -357,8 +359,8 @@ TEST_F(Http2FrameDecoderTest, GoAwayMinimal) {
};
Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1);
FrameParts expected(header);
- expected.opt_goaway =
- Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR);
+ expected.SetOptGoaway(
+ Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -372,7 +374,7 @@ TEST_F(Http2FrameDecoderTest, WindowUpdate) {
};
Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1);
FrameParts expected(header);
- expected.opt_window_update_increment = 1024;
+ expected.SetOptWindowUpdateIncrement(1024);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -398,8 +400,8 @@ TEST_F(Http2FrameDecoderTest, AltSvcMinimal) {
};
Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0);
FrameParts expected(header);
- expected.opt_altsvc_origin_length = 0;
- expected.opt_altsvc_value_length = 0;
+ expected.SetOptAltsvcOriginLength(0);
+ expected.SetOptAltsvcValueLength(0);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -458,7 +460,7 @@ TEST_F(Http2FrameDecoderTest, HeadersPriority) {
Http2FrameHeader header(5, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
2);
FrameParts expected(header);
- expected.opt_priority = Http2PriorityFields(1, 256, false);
+ expected.SetOptPriority(Http2PriorityFields(1, 256, false));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -475,9 +477,9 @@ TEST_F(Http2FrameDecoderTest, Settings) {
};
Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0);
FrameParts expected(header);
- expected.settings.push_back(Http2SettingFields(
+ expected.AppendSetting(Http2SettingFields(
Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141));
- expected.settings.push_back(
+ expected.AppendSetting(
Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -494,7 +496,7 @@ TEST_F(Http2FrameDecoderTest, PushPromisePayload) {
Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE,
Http2FrameFlag::END_HEADERS, 255);
FrameParts expected(header, "abc");
- expected.opt_push_promise = Http2PushPromiseFields{256};
+ expected.SetOptPushPromise(Http2PushPromiseFields{256});
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -510,8 +512,8 @@ TEST_F(Http2FrameDecoderTest, GoAwayOpaqueData) {
};
Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0);
FrameParts expected(header, "opaque");
- expected.opt_goaway =
- Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR);
+ expected.SetOptGoaway(
+ Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -615,7 +617,7 @@ TEST_F(Http2FrameDecoderTest, HeadersPayloadPriorityAndPadding) {
2);
size_t total_pad_length = 4; // Including the Pad Length field.
FrameParts expected(header, "abc", total_pad_length);
- expected.opt_priority = Http2PriorityFields(1, 17, true);
+ expected.SetOptPriority(Http2PriorityFields(1, 17, true));
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -635,7 +637,7 @@ TEST_F(Http2FrameDecoderTest, PushPromisePayloadAndPadding) {
1);
size_t total_pad_length = 4; // Including the Pad Length field.
FrameParts expected(header, "abc", total_pad_length);
- expected.opt_push_promise = Http2PushPromiseFields{2};
+ expected.SetOptPushPromise(Http2PushPromiseFields{2});
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
}
@@ -651,7 +653,7 @@ TEST_F(Http2FrameDecoderTest, DataMissingPadLengthField) {
};
Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::PADDED, 1);
FrameParts expected(header);
- expected.opt_missing_length = 1;
+ expected.SetOptMissingLength(1);
EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
}
@@ -667,7 +669,7 @@ TEST_F(Http2FrameDecoderTest, HeaderPaddingTooLong) {
Http2FrameHeader header(2, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
65536);
FrameParts expected(header);
- expected.opt_missing_length = 254;
+ expected.SetOptMissingLength(254);
EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
}
@@ -723,7 +725,7 @@ TEST_F(Http2FrameDecoderTest, SettingsWrongSize) {
};
Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0);
FrameParts expected(header);
- expected.settings.push_back(
+ expected.AppendSetting(
Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected));
}
@@ -835,7 +837,7 @@ TEST_F(Http2FrameDecoderTest, BeyondMaximum) {
Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
2);
FrameParts expected(header);
- expected.has_frame_size_error = true;
+ expected.SetHasFrameSizeError(true);
auto validator = [&expected, this](const DecodeBuffer& input,
DecodeStatus status) -> AssertionResult {
VERIFY_EQ(status, DecodeStatus::kDecodeError);
diff --git a/chromium/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
index 74bcd18b1fe..42b359f7d0f 100644
--- a/chromium/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
@@ -98,7 +98,7 @@ TEST_P(GoAwayOpaqueDataLengthTests, ValidLength) {
RandStreamId());
set_frame_header(header);
FrameParts expected(header, opaque_data);
- expected.opt_goaway = goaway;
+ expected.SetOptGoaway(goaway);
ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
diff --git a/chromium/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
index 75282d952b2..1889dde2eed 100644
--- a/chromium/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
@@ -126,7 +126,7 @@ TEST_P(HeadersPayloadDecoderTest, VariousHpackPayloadSizes) {
ScrubFlagsOfHeader(&frame_header);
FrameParts expected(frame_header, hpack_payload, total_pad_length_);
if (has_priority) {
- expected.opt_priority = priority;
+ expected.SetOptPriority(priority);
}
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(),
expected));
diff --git a/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
index 43be7b52d37..67033fa779f 100644
--- a/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
+++ b/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
@@ -232,11 +232,11 @@ class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest {
VERIFY_FALSE(listener_.IsInProgress());
VERIFY_EQ(1u, listener_.size());
const FrameParts* frame = listener_.frame(0);
- VERIFY_EQ(header, frame->frame_header);
- VERIFY_TRUE(frame->has_frame_size_error);
+ VERIFY_EQ(header, frame->GetFrameHeader());
+ VERIFY_TRUE(frame->GetHasFrameSizeError());
// Verify did not get OnPaddingTooLong, as we should only ever produce
// one of these two errors for a single frame.
- VERIFY_FALSE(frame->opt_missing_length);
+ VERIFY_FALSE(frame->GetOptMissingLength());
return validator(input, status);
};
VERIFY_AND_RETURN_SUCCESS(
@@ -403,11 +403,11 @@ class AbstractPaddablePayloadDecoderTest
VERIFY_FALSE(listener.IsInProgress());
VERIFY_EQ(1u, listener.size());
const FrameParts* frame = listener.frame(0);
- VERIFY_EQ(header, frame->frame_header);
- VERIFY_TRUE(frame->opt_missing_length);
- VERIFY_EQ(expected_missing_length, frame->opt_missing_length.value());
+ VERIFY_EQ(header, frame->GetFrameHeader());
+ VERIFY_TRUE(frame->GetOptMissingLength());
+ VERIFY_EQ(expected_missing_length, frame->GetOptMissingLength().value());
// Verify did not get OnFrameSizeError.
- VERIFY_FALSE(frame->has_frame_size_error);
+ VERIFY_FALSE(frame->GetHasFrameSizeError());
return ::testing::AssertionSuccess();
};
VERIFY_AND_RETURN_SUCCESS(
diff --git a/chromium/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
index 04e0b445a37..fbe5fef44ad 100644
--- a/chromium/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
@@ -85,7 +85,7 @@ TEST_F(PingPayloadDecoderTest, Ping) {
RandFlags() & ~Http2FrameFlag::ACK, RandStreamId());
set_frame_header(header);
FrameParts expected(header);
- expected.opt_ping = fields;
+ expected.SetOptPing(fields);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
@@ -100,7 +100,7 @@ TEST_F(PingPayloadDecoderTest, PingAck) {
RandFlags() | Http2FrameFlag::ACK, RandStreamId());
set_frame_header(header);
FrameParts expected(header);
- expected.opt_ping = fields;
+ expected.SetOptPing(fields);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
diff --git a/chromium/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
index 53123631344..b9229ad604a 100644
--- a/chromium/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
@@ -80,7 +80,7 @@ TEST_F(PriorityPayloadDecoderTest, VariousPayloads) {
RandStreamId());
set_frame_header(header);
FrameParts expected(header);
- expected.opt_priority = fields;
+ expected.SetOptPriority(fields);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
diff --git a/chromium/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
index 92fd183c7a7..537439f668e 100644
--- a/chromium/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
@@ -108,7 +108,7 @@ TEST_P(PushPromisePayloadDecoderTest, VariousHpackPayloadSizes) {
RandStreamId());
set_frame_header(frame_header);
FrameParts expected(frame_header, hpack_payload, total_pad_length_);
- expected.opt_push_promise = push_promise;
+ expected.SetOptPushPromise(push_promise);
EXPECT_TRUE(
DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
}
diff --git a/chromium/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
index 741c444c769..c28decb358a 100644
--- a/chromium/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
@@ -82,7 +82,7 @@ TEST_F(RstStreamPayloadDecoderTest, AllErrors) {
RandStreamId());
set_frame_header(header);
FrameParts expected(header);
- expected.opt_rst_stream_error_code = error_code;
+ expected.SetOptRstStreamErrorCode(error_code);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
diff --git a/chromium/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
index 1764dc2ee19..6f81f8e7a2c 100644
--- a/chromium/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
@@ -129,7 +129,7 @@ TEST_F(SettingsPayloadDecoderTest, OneRealSetting) {
RandStreamId());
set_frame_header(header);
FrameParts expected(header);
- expected.settings.push_back(fields);
+ expected.AppendSetting(fields);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
@@ -149,7 +149,7 @@ TEST_F(SettingsPayloadDecoderTest, ManySettings) {
Http2SettingFields fields(static_cast<Http2SettingsParameter>(n),
Random().Rand32());
fb.Append(fields);
- expected.settings.push_back(fields);
+ expected.AppendSetting(fields);
}
ASSERT_EQ(size, fb.size());
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
diff --git a/chromium/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc b/chromium/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
index e46d55bd711..4626b368e4c 100644
--- a/chromium/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
+++ b/chromium/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
@@ -86,7 +86,7 @@ TEST_F(WindowUpdatePayloadDecoderTest, VariousPayloads) {
RandFlags(), stream_id);
set_frame_header(header);
FrameParts expected(header);
- expected.opt_window_update_increment = fields.window_size_increment;
+ expected.SetOptWindowUpdateIncrement(fields.window_size_increment);
EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
}
}
diff --git a/chromium/net/http2/hpack/decoder/hpack_block_collector.cc b/chromium/net/http2/hpack/decoder/hpack_block_collector.cc
index 4e433e0efda..2bb90b72d0e 100644
--- a/chromium/net/http2/hpack/decoder/hpack_block_collector.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_block_collector.cc
@@ -17,10 +17,10 @@ using ::testing::AssertionSuccess;
namespace net {
namespace test {
-HpackBlockCollector::HpackBlockCollector() {}
+HpackBlockCollector::HpackBlockCollector() = default;
HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other)
: pending_entry_(other.pending_entry_), entries_(other.entries_) {}
-HpackBlockCollector::~HpackBlockCollector() {}
+HpackBlockCollector::~HpackBlockCollector() = default;
void HpackBlockCollector::OnIndexedHeader(size_t index) {
pending_entry_.OnIndexedHeader(index);
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder.cc b/chromium/net/http2/hpack/decoder/hpack_decoder.cc
index 91a0f03bc35..c3ce24131f8 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder.cc
@@ -17,7 +17,7 @@ HpackDecoder::HpackDecoder(HpackDecoderListener* listener,
block_decoder_(&entry_buffer_),
error_detected_(false) {}
-HpackDecoder::~HpackDecoder() {}
+HpackDecoder::~HpackDecoder() = default;
void HpackDecoder::set_tables_debug_listener(
HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_listener.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_listener.cc
index 8f0e0a01511..f85b9033e35 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_listener.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_listener.cc
@@ -6,11 +6,11 @@
namespace net {
-HpackDecoderListener::HpackDecoderListener() {}
-HpackDecoderListener::~HpackDecoderListener() {}
+HpackDecoderListener::HpackDecoderListener() = default;
+HpackDecoderListener::~HpackDecoderListener() = default;
-HpackDecoderNoOpListener::HpackDecoderNoOpListener() {}
-HpackDecoderNoOpListener::~HpackDecoderNoOpListener() {}
+HpackDecoderNoOpListener::HpackDecoderNoOpListener() = default;
+HpackDecoderNoOpListener::~HpackDecoderNoOpListener() = default;
void HpackDecoderNoOpListener::OnHeaderListStart() {}
void HpackDecoderNoOpListener::OnHeader(HpackEntryType entry_type,
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_state.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_state.cc
index 0e399946a68..60e7207444a 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_state.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_state.cc
@@ -33,7 +33,7 @@ HpackDecoderState::HpackDecoderState(HpackDecoderListener* listener)
error_detected_(false) {
CHECK(listener);
}
-HpackDecoderState::~HpackDecoderState() {}
+HpackDecoderState::~HpackDecoderState() = default;
void HpackDecoderState::set_tables_debug_listener(
HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_state_test.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_state_test.cc
index 3674db03bff..22a8179e848 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_state_test.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_state_test.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "net/http2/hpack/hpack_string.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
#include "net/http2/http2_constants.h"
#include "net/http2/platform/api/http2_string.h"
#include "net/http2/tools/failure.h"
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
index 3e4451c2948..563b7bdac06 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
@@ -53,7 +53,7 @@ HpackDecoderStringBuffer::HpackDecoderStringBuffer()
is_huffman_encoded_(false),
state_(State::RESET),
backing_(Backing::RESET) {}
-HpackDecoderStringBuffer::~HpackDecoderStringBuffer() {}
+HpackDecoderStringBuffer::~HpackDecoderStringBuffer() = default;
void HpackDecoderStringBuffer::Reset() {
DVLOG(3) << "HpackDecoderStringBuffer::Reset";
@@ -168,7 +168,7 @@ void HpackDecoderStringBuffer::BufferStringIfUnbuffered() {
if (state_ != State::RESET && backing_ == Backing::UNBUFFERED) {
DVLOG(2) << "HpackDecoderStringBuffer buffering string of length "
<< value_.size();
- value_.CopyToString(&buffer_);
+ buffer_.assign(value_.data(), value_.size());
if (state_ == State::COMPLETE) {
value_ = buffer_;
}
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_tables.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_tables.cc
index 61e7970b32b..4ff2b06a5c0 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_tables.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -5,6 +5,7 @@
#include "net/http2/hpack/decoder/hpack_decoder_tables.h"
#include "base/logging.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
namespace net {
namespace {
@@ -33,8 +34,8 @@ const std::vector<HpackStringPair>* GetStaticTable() {
} // namespace
-HpackDecoderTablesDebugListener::HpackDecoderTablesDebugListener() {}
-HpackDecoderTablesDebugListener::~HpackDecoderTablesDebugListener() {}
+HpackDecoderTablesDebugListener::HpackDecoderTablesDebugListener() = default;
+HpackDecoderTablesDebugListener::~HpackDecoderTablesDebugListener() = default;
HpackDecoderStaticTable::HpackDecoderStaticTable(
const std::vector<HpackStringPair>* table)
@@ -56,7 +57,7 @@ HpackDecoderDynamicTable::HpackDecoderTableEntry::HpackDecoderTableEntry(
HpackDecoderDynamicTable::HpackDecoderDynamicTable()
: insert_count_(kFirstDynamicTableIndex - 1), debug_listener_(nullptr) {}
-HpackDecoderDynamicTable::~HpackDecoderDynamicTable() {}
+HpackDecoderDynamicTable::~HpackDecoderDynamicTable() = default;
void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) {
DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate " << size_limit;
@@ -133,8 +134,8 @@ void HpackDecoderDynamicTable::RemoveLastEntry() {
}
}
-HpackDecoderTables::HpackDecoderTables() {}
-HpackDecoderTables::~HpackDecoderTables() {}
+HpackDecoderTables::HpackDecoderTables() = default;
+HpackDecoderTables::~HpackDecoderTables() = default;
void HpackDecoderTables::set_debug_listener(
HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_tables.h b/chromium/net/http2/hpack/decoder/hpack_decoder_tables.h
index 1de28147cf9..35c25057887 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_tables.h
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_tables.h
@@ -31,9 +31,6 @@ namespace test {
class HpackDecoderTablesPeer;
} // namespace test
-// TODO(jamessynge): Move to hpack_constants.h
-const size_t kFirstDynamicTableIndex = 62;
-
// HpackDecoderTablesDebugListener supports a QUIC experiment, enabling
// the gathering of information about the time-line of use of HPACK
// dynamic table entries.
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_tables_test.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
index e9e6c545938..8e47aba8307 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/logging.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
#include "net/http2/platform/api/http2_string.h"
#include "net/http2/tools/failure.h"
#include "net/http2/tools/http2_random.h"
@@ -56,7 +57,7 @@ void ShuffleCollection(C* collection, RandomBase* r) {
class HpackDecoderStaticTableTest : public ::testing::Test {
protected:
- HpackDecoderStaticTableTest() {}
+ HpackDecoderStaticTableTest() = default;
std::vector<StaticEntry> shuffled_static_entries() {
std::vector<StaticEntry> entries = MakeSpecStaticEntries();
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
index 61e05ab426f..7a89e82106e 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
@@ -83,7 +83,7 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool>,
HpackDecoderTest() : decoder_(this, 4096) {
fragment_the_hpack_block_ = GetParam();
}
- ~HpackDecoderTest() override {}
+ ~HpackDecoderTest() override = default;
void OnHeaderListStart() override {
ASSERT_FALSE(saw_start_);
diff --git a/chromium/net/http2/hpack/decoder/hpack_entry_collector.cc b/chromium/net/http2/hpack/decoder/hpack_entry_collector.cc
index d4d39d4caef..0ea55dcff45 100644
--- a/chromium/net/http2/hpack/decoder/hpack_entry_collector.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_entry_collector.cc
@@ -60,7 +60,7 @@ HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
started_(true),
ended_(true) {}
-HpackEntryCollector::~HpackEntryCollector() {}
+HpackEntryCollector::~HpackEntryCollector() = default;
void HpackEntryCollector::OnIndexedHeader(size_t index) {
ASSERT_FALSE(started_);
diff --git a/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc
index 713155153d1..4799a6c8fc7 100644
--- a/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc
@@ -15,7 +15,7 @@ HpackWholeEntryBuffer::HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
: max_string_size_bytes_(max_string_size_bytes) {
set_listener(listener);
}
-HpackWholeEntryBuffer::~HpackWholeEntryBuffer() {}
+HpackWholeEntryBuffer::~HpackWholeEntryBuffer() = default;
void HpackWholeEntryBuffer::set_listener(HpackWholeEntryListener* listener) {
CHECK(listener);
diff --git a/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
index b7260e296c1..6626bc8c867 100644
--- a/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
@@ -37,7 +37,7 @@ inline ::testing::PolymorphicMatcher<StringPieceHasSubstrMatcher> HasSubstr(
class MockHpackWholeEntryListener : public HpackWholeEntryListener {
public:
- ~MockHpackWholeEntryListener() override {}
+ ~MockHpackWholeEntryListener() override = default;
MOCK_METHOD1(OnIndexedHeader, void(size_t index));
MOCK_METHOD3(OnNameIndexAndLiteralValue,
@@ -55,7 +55,7 @@ class MockHpackWholeEntryListener : public HpackWholeEntryListener {
class HpackWholeEntryBufferTest : public ::testing::Test {
protected:
HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {}
- ~HpackWholeEntryBufferTest() override {}
+ ~HpackWholeEntryBufferTest() override = default;
StrictMock<MockHpackWholeEntryListener> listener_;
HpackWholeEntryBuffer entry_buffer_;
diff --git a/chromium/net/http2/hpack/decoder/hpack_whole_entry_listener.cc b/chromium/net/http2/hpack/decoder/hpack_whole_entry_listener.cc
index ed18ff1f179..419c3356e8b 100644
--- a/chromium/net/http2/hpack/decoder/hpack_whole_entry_listener.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_whole_entry_listener.cc
@@ -6,9 +6,9 @@
namespace net {
-HpackWholeEntryListener::~HpackWholeEntryListener() {}
+HpackWholeEntryListener::~HpackWholeEntryListener() = default;
-HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() {}
+HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() = default;
void HpackWholeEntryNoOpListener::OnIndexedHeader(size_t index) {}
void HpackWholeEntryNoOpListener::OnNameIndexAndLiteralValue(
diff --git a/chromium/net/http2/hpack/hpack_string.cc b/chromium/net/http2/hpack/hpack_string.cc
index 4db9f48a9fb..570a6cdbd4c 100644
--- a/chromium/net/http2/hpack/hpack_string.cc
+++ b/chromium/net/http2/hpack/hpack_string.cc
@@ -14,8 +14,8 @@ namespace net {
HpackString::HpackString(const char* data) : str_(data) {}
HpackString::HpackString(Http2StringPiece str) : str_(str.as_string()) {}
HpackString::HpackString(Http2String str) : str_(std::move(str)) {}
-HpackString::HpackString(const HpackString& other) : str_(other.str_) {}
-HpackString::~HpackString() {}
+HpackString::HpackString(const HpackString& other) = default;
+HpackString::~HpackString() = default;
Http2StringPiece HpackString::ToStringPiece() const {
return str_;
diff --git a/chromium/net/http2/hpack/http2_hpack_constants.h b/chromium/net/http2/hpack/http2_hpack_constants.h
index a2a29e32e2b..38d5812ff94 100644
--- a/chromium/net/http2/hpack/http2_hpack_constants.h
+++ b/chromium/net/http2/hpack/http2_hpack_constants.h
@@ -17,6 +17,8 @@
namespace net {
+const size_t kFirstDynamicTableIndex = 62;
+
enum class HpackEntryType {
// Entry is an index into the static or dynamic table. Decoding it has no
// effect on the dynamic table.
@@ -55,7 +57,6 @@ HTTP2_EXPORT_PRIVATE Http2String HpackEntryTypeToString(HpackEntryType v);
// Inserts the name of the enum member into |out|.
HTTP2_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
HpackEntryType v);
-
} // namespace net
#endif // NET_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
diff --git a/chromium/net/http2/hpack/huffman/hpack_huffman_decoder.cc b/chromium/net/http2/hpack/huffman/hpack_huffman_decoder.cc
index 3621ca13ca9..68246fd4e07 100644
--- a/chromium/net/http2/hpack/huffman/hpack_huffman_decoder.cc
+++ b/chromium/net/http2/hpack/huffman/hpack_huffman_decoder.cc
@@ -410,9 +410,9 @@ Http2String HuffmanBitBuffer::DebugString() const {
return ss.str();
}
-HpackHuffmanDecoder::HpackHuffmanDecoder() {}
+HpackHuffmanDecoder::HpackHuffmanDecoder() = default;
-HpackHuffmanDecoder::~HpackHuffmanDecoder() {}
+HpackHuffmanDecoder::~HpackHuffmanDecoder() = default;
bool HpackHuffmanDecoder::Decode(Http2StringPiece input, Http2String* output) {
return DecodeShortCodesFirst(input, output);
diff --git a/chromium/net/http2/test_tools/frame_parts.cc b/chromium/net/http2/test_tools/frame_parts.cc
index db0ee356b42..95b84664ecd 100644
--- a/chromium/net/http2/test_tools/frame_parts.cc
+++ b/chromium/net/http2/test_tools/frame_parts.cc
@@ -46,15 +46,15 @@ AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) {
} // namespace
-FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header(header) {
- VLOG(1) << "FrameParts, header: " << frame_header;
+FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) {
+ VLOG(1) << "FrameParts, header: " << frame_header_;
}
FrameParts::FrameParts(const Http2FrameHeader& header, Http2StringPiece payload)
: FrameParts(header) {
VLOG(1) << "FrameParts with payload.size() = " << payload.size();
- this->payload.append(payload.data(), payload.size());
- opt_payload_length = payload.size();
+ this->payload_.append(payload.data(), payload.size());
+ opt_payload_length_ = payload.size();
}
FrameParts::FrameParts(const Http2FrameHeader& header,
Http2StringPiece payload,
@@ -66,31 +66,31 @@ FrameParts::FrameParts(const Http2FrameHeader& header,
FrameParts::FrameParts(const FrameParts& header) = default;
-FrameParts::~FrameParts() {}
+FrameParts::~FrameParts() = default;
AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
#define COMMON_MESSAGE "\n this: " << *this << "\n that: " << that
- VERIFY_EQ(frame_header, that.frame_header) << COMMON_MESSAGE;
- VERIFY_EQ(payload, that.payload) << COMMON_MESSAGE;
- VERIFY_EQ(padding, that.padding) << COMMON_MESSAGE;
- VERIFY_EQ(altsvc_origin, that.altsvc_origin) << COMMON_MESSAGE;
- VERIFY_EQ(altsvc_value, that.altsvc_value) << COMMON_MESSAGE;
- VERIFY_EQ(settings, that.settings) << COMMON_MESSAGE;
+ VERIFY_EQ(frame_header_, that.frame_header_) << COMMON_MESSAGE;
+ VERIFY_EQ(payload_, that.payload_) << COMMON_MESSAGE;
+ VERIFY_EQ(padding_, that.padding_) << COMMON_MESSAGE;
+ VERIFY_EQ(altsvc_origin_, that.altsvc_origin_) << COMMON_MESSAGE;
+ VERIFY_EQ(altsvc_value_, that.altsvc_value_) << COMMON_MESSAGE;
+ VERIFY_EQ(settings_, that.settings_) << COMMON_MESSAGE;
#define VERIFY_OPTIONAL_FIELD(field_name) \
VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name))
- VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_goaway) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_missing_length) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_pad_length) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_ping) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_priority) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_push_promise) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code) << COMMON_MESSAGE;
- VERIFY_OPTIONAL_FIELD(opt_window_update_increment) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_goaway_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_missing_length_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_pad_length_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_ping_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_priority_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_push_promise_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code_) << COMMON_MESSAGE;
+ VERIFY_OPTIONAL_FIELD(opt_window_update_increment_) << COMMON_MESSAGE;
#undef VERIFY_OPTIONAL_FIELD
@@ -98,18 +98,18 @@ AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
}
void FrameParts::SetTotalPadLength(size_t total_pad_length) {
- opt_pad_length.reset();
- padding.clear();
+ opt_pad_length_.reset();
+ padding_.clear();
if (total_pad_length > 0) {
ASSERT_LE(total_pad_length, 256u);
- ASSERT_TRUE(frame_header.IsPadded());
- opt_pad_length = total_pad_length - 1;
+ ASSERT_TRUE(frame_header_.IsPadded());
+ opt_pad_length_ = total_pad_length - 1;
char zero = 0;
- padding.append(opt_pad_length.value(), zero);
+ padding_.append(opt_pad_length_.value(), zero);
}
- if (opt_pad_length) {
- VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length.value();
+ if (opt_pad_length_) {
+ VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length_.value();
} else {
VLOG(1) << "SetTotalPadLength: has no pad length";
}
@@ -117,10 +117,10 @@ void FrameParts::SetTotalPadLength(size_t total_pad_length) {
void FrameParts::SetAltSvcExpected(Http2StringPiece origin,
Http2StringPiece value) {
- altsvc_origin.append(origin.data(), origin.size());
- altsvc_value.append(value.data(), value.size());
- opt_altsvc_origin_length = origin.size();
- opt_altsvc_value_length = value.size();
+ altsvc_origin_.append(origin.data(), origin.size());
+ altsvc_value_.append(value.data(), value.size());
+ opt_altsvc_origin_length_ = origin.size();
+ opt_altsvc_value_length_ = value.size();
}
bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) {
@@ -131,50 +131,51 @@ bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) {
void FrameParts::OnDataStart(const Http2FrameHeader& header) {
VLOG(1) << "OnDataStart: " << header;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this;
- opt_payload_length = header.payload_length;
+ opt_payload_length_ = header.payload_length;
}
void FrameParts::OnDataPayload(const char* data, size_t len) {
- VLOG(1) << "OnDataPayload: len=" << len << "; frame_header: " << frame_header;
+ VLOG(1) << "OnDataPayload: len=" << len
+ << "; frame_header_: " << frame_header_;
ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this;
- ASSERT_TRUE(
- AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+ &opt_payload_length_));
}
void FrameParts::OnDataEnd() {
- VLOG(1) << "OnDataEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnDataEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this;
}
void FrameParts::OnHeadersStart(const Http2FrameHeader& header) {
VLOG(1) << "OnHeadersStart: " << header;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this;
- opt_payload_length = header.payload_length;
+ opt_payload_length_ = header.payload_length;
}
void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) {
VLOG(1) << "OnHeadersPriority: priority: " << priority
- << "; frame_header: " << frame_header;
+ << "; frame_header_: " << frame_header_;
ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this;
- ASSERT_FALSE(opt_priority);
- opt_priority = priority;
- ASSERT_TRUE(opt_payload_length);
- opt_payload_length =
- opt_payload_length.value() - Http2PriorityFields::EncodedSize();
+ ASSERT_FALSE(opt_priority_);
+ opt_priority_ = priority;
+ ASSERT_TRUE(opt_payload_length_);
+ opt_payload_length_ =
+ opt_payload_length_.value() - Http2PriorityFields::EncodedSize();
}
void FrameParts::OnHpackFragment(const char* data, size_t len) {
VLOG(1) << "OnHpackFragment: len=" << len
- << "; frame_header: " << frame_header;
- ASSERT_TRUE(got_start_callback);
- ASSERT_FALSE(got_end_callback);
- ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header)) << *this;
- ASSERT_TRUE(
- AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+ << "; frame_header_: " << frame_header_;
+ ASSERT_TRUE(got_start_callback_);
+ ASSERT_FALSE(got_end_callback_);
+ ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this;
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+ &opt_payload_length_));
}
void FrameParts::OnHeadersEnd() {
- VLOG(1) << "OnHeadersEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnHeadersEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this;
}
@@ -182,72 +183,72 @@ void FrameParts::OnPriorityFrame(const Http2FrameHeader& header,
const Http2PriorityFields& priority) {
VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this;
- ASSERT_FALSE(opt_priority);
- opt_priority = priority;
+ ASSERT_FALSE(opt_priority_);
+ opt_priority_ = priority;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this;
}
void FrameParts::OnContinuationStart(const Http2FrameHeader& header) {
VLOG(1) << "OnContinuationStart: " << header;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this;
- opt_payload_length = header.payload_length;
+ opt_payload_length_ = header.payload_length;
}
void FrameParts::OnContinuationEnd() {
- VLOG(1) << "OnContinuationEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnContinuationEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this;
}
void FrameParts::OnPadLength(size_t trailing_length) {
VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
ASSERT_TRUE(InPaddedFrame()) << *this;
- ASSERT_FALSE(opt_pad_length);
- ASSERT_TRUE(opt_payload_length);
+ ASSERT_FALSE(opt_pad_length_);
+ ASSERT_TRUE(opt_payload_length_);
size_t total_padding_length = trailing_length + 1;
- ASSERT_GE(opt_payload_length.value(), total_padding_length);
- opt_payload_length = opt_payload_length.value() - total_padding_length;
- opt_pad_length = trailing_length;
+ ASSERT_GE(opt_payload_length_.value(), total_padding_length);
+ opt_payload_length_ = opt_payload_length_.value() - total_padding_length;
+ opt_pad_length_ = trailing_length;
}
void FrameParts::OnPadding(const char* pad, size_t skipped_length) {
VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
ASSERT_TRUE(InPaddedFrame()) << *this;
- ASSERT_TRUE(opt_pad_length);
- ASSERT_TRUE(AppendString(Http2StringPiece(pad, skipped_length), &padding,
- &opt_pad_length));
+ ASSERT_TRUE(opt_pad_length_);
+ ASSERT_TRUE(AppendString(Http2StringPiece(pad, skipped_length), &padding_,
+ &opt_pad_length_));
}
void FrameParts::OnRstStream(const Http2FrameHeader& header,
Http2ErrorCode error_code) {
VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this;
- ASSERT_FALSE(opt_rst_stream_error_code);
- opt_rst_stream_error_code = error_code;
+ ASSERT_FALSE(opt_rst_stream_error_code_);
+ opt_rst_stream_error_code_ = error_code;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this;
}
void FrameParts::OnSettingsStart(const Http2FrameHeader& header) {
VLOG(1) << "OnSettingsStart: " << header;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
- ASSERT_EQ(0u, settings.size());
+ ASSERT_EQ(0u, settings_.size());
ASSERT_FALSE(header.IsAck()) << header;
}
void FrameParts::OnSetting(const Http2SettingFields& setting_fields) {
VLOG(1) << "OnSetting: " << setting_fields;
ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this;
- settings.push_back(setting_fields);
+ settings_.push_back(setting_fields);
}
void FrameParts::OnSettingsEnd() {
- VLOG(1) << "OnSettingsEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnSettingsEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
}
void FrameParts::OnSettingsAck(const Http2FrameHeader& header) {
VLOG(1) << "OnSettingsAck: " << header;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
- ASSERT_EQ(0u, settings.size());
+ ASSERT_EQ(0u, settings_.size());
ASSERT_TRUE(header.IsAck());
ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
}
@@ -259,12 +260,12 @@ void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header,
<< "; total_padding_length: " << total_padding_length;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this;
ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize());
- opt_payload_length =
+ opt_payload_length_ =
header.payload_length - Http2PushPromiseFields::EncodedSize();
- ASSERT_FALSE(opt_push_promise);
- opt_push_promise = promise;
+ ASSERT_FALSE(opt_push_promise_);
+ opt_push_promise_ = promise;
if (total_padding_length > 0) {
- ASSERT_GE(opt_payload_length.value(), total_padding_length);
+ ASSERT_GE(opt_payload_length_.value(), total_padding_length);
OnPadLength(total_padding_length - 1);
} else {
ASSERT_FALSE(header.IsPadded());
@@ -272,7 +273,7 @@ void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header,
}
void FrameParts::OnPushPromiseEnd() {
- VLOG(1) << "OnPushPromiseEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnPushPromiseEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this;
}
@@ -281,8 +282,8 @@ void FrameParts::OnPing(const Http2FrameHeader& header,
VLOG(1) << "OnPing header: " << header << " ping: " << ping;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
ASSERT_FALSE(header.IsAck());
- ASSERT_FALSE(opt_ping);
- opt_ping = ping;
+ ASSERT_FALSE(opt_ping_);
+ opt_ping_ = ping;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
}
@@ -291,8 +292,8 @@ void FrameParts::OnPingAck(const Http2FrameHeader& header,
VLOG(1) << "OnPingAck header: " << header << " ping: " << ping;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
ASSERT_TRUE(header.IsAck());
- ASSERT_FALSE(opt_ping);
- opt_ping = ping;
+ ASSERT_FALSE(opt_ping_);
+ opt_ping_ = ping;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
}
@@ -300,20 +301,21 @@ void FrameParts::OnGoAwayStart(const Http2FrameHeader& header,
const Http2GoAwayFields& goaway) {
VLOG(1) << "OnGoAwayStart: " << goaway;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this;
- ASSERT_FALSE(opt_goaway);
- opt_goaway = goaway;
- opt_payload_length = header.payload_length - Http2GoAwayFields::EncodedSize();
+ ASSERT_FALSE(opt_goaway_);
+ opt_goaway_ = goaway;
+ opt_payload_length_ =
+ header.payload_length - Http2GoAwayFields::EncodedSize();
}
void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) {
VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this;
- ASSERT_TRUE(
- AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+ &opt_payload_length_));
}
void FrameParts::OnGoAwayEnd() {
- VLOG(1) << "OnGoAwayEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnGoAwayEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this;
}
@@ -322,8 +324,8 @@ void FrameParts::OnWindowUpdate(const Http2FrameHeader& header,
VLOG(1) << "OnWindowUpdate header: " << header
<< " increment=" << increment;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this;
- ASSERT_FALSE(opt_window_update_increment);
- opt_window_update_increment = increment;
+ ASSERT_FALSE(opt_window_update_increment_);
+ opt_window_update_increment_ = increment;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this;
}
@@ -334,140 +336,140 @@ void FrameParts::OnAltSvcStart(const Http2FrameHeader& header,
<< " origin_length: " << origin_length
<< " value_length: " << value_length;
ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this;
- ASSERT_FALSE(opt_altsvc_origin_length);
- opt_altsvc_origin_length = origin_length;
- ASSERT_FALSE(opt_altsvc_value_length);
- opt_altsvc_value_length = value_length;
+ ASSERT_FALSE(opt_altsvc_origin_length_);
+ opt_altsvc_origin_length_ = origin_length;
+ ASSERT_FALSE(opt_altsvc_value_length_);
+ opt_altsvc_value_length_ = value_length;
}
void FrameParts::OnAltSvcOriginData(const char* data, size_t len) {
VLOG(1) << "OnAltSvcOriginData: len=" << len;
ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
- ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_origin,
- &opt_altsvc_origin_length));
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_origin_,
+ &opt_altsvc_origin_length_));
}
void FrameParts::OnAltSvcValueData(const char* data, size_t len) {
VLOG(1) << "OnAltSvcValueData: len=" << len;
ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
- ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_value,
- &opt_altsvc_value_length));
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_value_,
+ &opt_altsvc_value_length_));
}
void FrameParts::OnAltSvcEnd() {
- VLOG(1) << "OnAltSvcEnd; frame_header: " << frame_header;
+ VLOG(1) << "OnAltSvcEnd; frame_header_: " << frame_header_;
ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this;
}
void FrameParts::OnUnknownStart(const Http2FrameHeader& header) {
VLOG(1) << "OnUnknownStart: " << header;
ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header;
- ASSERT_FALSE(got_start_callback);
- ASSERT_EQ(frame_header, header);
- got_start_callback = true;
- opt_payload_length = header.payload_length;
+ ASSERT_FALSE(got_start_callback_);
+ ASSERT_EQ(frame_header_, header);
+ got_start_callback_ = true;
+ opt_payload_length_ = header.payload_length;
}
void FrameParts::OnUnknownPayload(const char* data, size_t len) {
VLOG(1) << "OnUnknownPayload: len=" << len;
- ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this;
- ASSERT_TRUE(got_start_callback);
- ASSERT_FALSE(got_end_callback);
- ASSERT_TRUE(
- AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+ ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+ ASSERT_TRUE(got_start_callback_);
+ ASSERT_FALSE(got_end_callback_);
+ ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+ &opt_payload_length_));
}
void FrameParts::OnUnknownEnd() {
- VLOG(1) << "OnUnknownEnd; frame_header: " << frame_header;
- ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this;
- ASSERT_TRUE(got_start_callback);
- ASSERT_FALSE(got_end_callback);
- got_end_callback = true;
+ VLOG(1) << "OnUnknownEnd; frame_header_: " << frame_header_;
+ ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+ ASSERT_TRUE(got_start_callback_);
+ ASSERT_FALSE(got_end_callback_);
+ got_end_callback_ = true;
}
void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header,
size_t missing_length) {
VLOG(1) << "OnPaddingTooLong: " << header
<< "; missing_length: " << missing_length;
- ASSERT_EQ(frame_header, header);
- ASSERT_FALSE(got_end_callback);
+ ASSERT_EQ(frame_header_, header);
+ ASSERT_FALSE(got_end_callback_);
ASSERT_TRUE(FrameIsPadded(header));
- ASSERT_FALSE(opt_pad_length);
- ASSERT_FALSE(opt_missing_length);
- opt_missing_length = missing_length;
- got_start_callback = true;
- got_end_callback = true;
+ ASSERT_FALSE(opt_pad_length_);
+ ASSERT_FALSE(opt_missing_length_);
+ opt_missing_length_ = missing_length;
+ got_start_callback_ = true;
+ got_end_callback_ = true;
}
void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) {
VLOG(1) << "OnFrameSizeError: " << header;
- ASSERT_EQ(frame_header, header);
- ASSERT_FALSE(got_end_callback);
- ASSERT_FALSE(has_frame_size_error);
- has_frame_size_error = true;
- got_end_callback = true;
+ ASSERT_EQ(frame_header_, header);
+ ASSERT_FALSE(got_end_callback_);
+ ASSERT_FALSE(has_frame_size_error_);
+ has_frame_size_error_ = true;
+ got_end_callback_ = true;
}
void FrameParts::OutputTo(std::ostream& out) const {
- out << "FrameParts{\n frame_header: " << frame_header << "\n";
- if (!payload.empty()) {
- out << " payload=\"" << EscapeQueryParamValue(payload, false) << "\"\n";
+ out << "FrameParts{\n frame_header_: " << frame_header_ << "\n";
+ if (!payload_.empty()) {
+ out << " payload_=\"" << EscapeQueryParamValue(payload_, false) << "\"\n";
}
- if (!padding.empty()) {
- out << " padding=\"" << EscapeQueryParamValue(padding, false) << "\"\n";
+ if (!padding_.empty()) {
+ out << " padding_=\"" << EscapeQueryParamValue(padding_, false) << "\"\n";
}
- if (!altsvc_origin.empty()) {
- out << " altsvc_origin=\"" << EscapeQueryParamValue(altsvc_origin, false)
+ if (!altsvc_origin_.empty()) {
+ out << " altsvc_origin_=\"" << EscapeQueryParamValue(altsvc_origin_, false)
<< "\"\n";
}
- if (!altsvc_value.empty()) {
- out << " altsvc_value=\"" << EscapeQueryParamValue(altsvc_value, false)
+ if (!altsvc_value_.empty()) {
+ out << " altsvc_value_=\"" << EscapeQueryParamValue(altsvc_value_, false)
<< "\"\n";
}
- if (opt_priority) {
- out << " priority=" << opt_priority.value() << "\n";
+ if (opt_priority_) {
+ out << " priority=" << opt_priority_.value() << "\n";
}
- if (opt_rst_stream_error_code) {
- out << " rst_stream=" << opt_rst_stream_error_code.value() << "\n";
+ if (opt_rst_stream_error_code_) {
+ out << " rst_stream=" << opt_rst_stream_error_code_.value() << "\n";
}
- if (opt_push_promise) {
- out << " push_promise=" << opt_push_promise.value() << "\n";
+ if (opt_push_promise_) {
+ out << " push_promise=" << opt_push_promise_.value() << "\n";
}
- if (opt_ping) {
- out << " ping=" << opt_ping.value() << "\n";
+ if (opt_ping_) {
+ out << " ping=" << opt_ping_.value() << "\n";
}
- if (opt_goaway) {
- out << " goaway=" << opt_goaway.value() << "\n";
+ if (opt_goaway_) {
+ out << " goaway=" << opt_goaway_.value() << "\n";
}
- if (opt_window_update_increment) {
- out << " window_update=" << opt_window_update_increment.value() << "\n";
+ if (opt_window_update_increment_) {
+ out << " window_update=" << opt_window_update_increment_.value() << "\n";
}
- if (opt_payload_length) {
- out << " payload_length=" << opt_payload_length.value() << "\n";
+ if (opt_payload_length_) {
+ out << " payload_length=" << opt_payload_length_.value() << "\n";
}
- if (opt_pad_length) {
- out << " pad_length=" << opt_pad_length.value() << "\n";
+ if (opt_pad_length_) {
+ out << " pad_length=" << opt_pad_length_.value() << "\n";
}
- if (opt_missing_length) {
- out << " missing_length=" << opt_missing_length.value() << "\n";
+ if (opt_missing_length_) {
+ out << " missing_length=" << opt_missing_length_.value() << "\n";
}
- if (opt_altsvc_origin_length) {
- out << " origin_length=" << opt_altsvc_origin_length.value() << "\n";
+ if (opt_altsvc_origin_length_) {
+ out << " origin_length=" << opt_altsvc_origin_length_.value() << "\n";
}
- if (opt_altsvc_value_length) {
- out << " value_length=" << opt_altsvc_value_length.value() << "\n";
+ if (opt_altsvc_value_length_) {
+ out << " value_length=" << opt_altsvc_value_length_.value() << "\n";
}
- if (has_frame_size_error) {
+ if (has_frame_size_error_) {
out << " has_frame_size_error\n";
}
- if (got_start_callback) {
+ if (got_start_callback_) {
out << " got_start_callback\n";
}
- if (got_end_callback) {
+ if (got_end_callback_) {
out << " got_end_callback\n";
}
- for (size_t ndx = 0; ndx < settings.size(); ++ndx) {
- out << " setting[" << ndx << "]=" << settings[ndx];
+ for (size_t ndx = 0; ndx < settings_.size(); ++ndx) {
+ out << " setting[" << ndx << "]=" << settings_[ndx];
}
out << "}";
}
@@ -476,30 +478,30 @@ AssertionResult FrameParts::StartFrameOfType(
const Http2FrameHeader& header,
Http2FrameType expected_frame_type) {
VERIFY_EQ(header.type, expected_frame_type);
- VERIFY_FALSE(got_start_callback);
- VERIFY_FALSE(got_end_callback);
- VERIFY_EQ(frame_header, header);
- got_start_callback = true;
+ VERIFY_FALSE(got_start_callback_);
+ VERIFY_FALSE(got_end_callback_);
+ VERIFY_EQ(frame_header_, header);
+ got_start_callback_ = true;
return AssertionSuccess();
}
AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) {
- VERIFY_TRUE(got_start_callback);
- VERIFY_FALSE(got_end_callback);
- VERIFY_EQ(frame_header.type, expected_frame_type);
+ VERIFY_TRUE(got_start_callback_);
+ VERIFY_FALSE(got_end_callback_);
+ VERIFY_EQ(frame_header_.type, expected_frame_type);
return AssertionSuccess();
}
AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) {
VERIFY_SUCCESS(InFrameOfType(expected_frame_type));
- got_end_callback = true;
+ got_end_callback_ = true;
return AssertionSuccess();
}
AssertionResult FrameParts::InPaddedFrame() {
- VERIFY_TRUE(got_start_callback);
- VERIFY_FALSE(got_end_callback);
- VERIFY_TRUE(FrameIsPadded(frame_header));
+ VERIFY_TRUE(got_start_callback_);
+ VERIFY_FALSE(got_end_callback_);
+ VERIFY_TRUE(FrameIsPadded(frame_header_));
return AssertionSuccess();
}
@@ -509,7 +511,7 @@ AssertionResult FrameParts::AppendString(Http2StringPiece source,
target->append(source.data(), source.size());
if (opt_length != nullptr) {
VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this;
- VERIFY_LE(target->size(), static_cast<size_t>(opt_length->value()))
+ VERIFY_LE(target->size(), opt_length->value())
<< "String too large; source.size() = " << source.size() << "\n"
<< *this;
}
diff --git a/chromium/net/http2/test_tools/frame_parts.h b/chromium/net/http2/test_tools/frame_parts.h
index 1846929b952..7ef392f7d11 100644
--- a/chromium/net/http2/test_tools/frame_parts.h
+++ b/chromium/net/http2/test_tools/frame_parts.h
@@ -10,9 +10,6 @@
// info that a test expects to be recorded during the decoding of a frame
// with the actual recorded value (i.e. by providing a comparator).
-// TODO(jamessynge): Convert FrameParts to a class, hide the members, add
-// getters/setters.
-
#include <stddef.h>
#include <vector>
@@ -29,11 +26,8 @@
namespace net {
namespace test {
-// Forward declarations.
-struct FrameParts;
-std::ostream& operator<<(std::ostream& out, const FrameParts& v);
-
-struct FrameParts : public Http2FrameDecoderListener {
+class FrameParts : public Http2FrameDecoderListener {
+ public:
// The first callback for every type of frame includes the frame header; this
// is the only constructor used during decoding of a frame.
explicit FrameParts(const Http2FrameHeader& header);
@@ -113,36 +107,82 @@ struct FrameParts : public Http2FrameDecoderListener {
size_t missing_length) override;
void OnFrameSizeError(const Http2FrameHeader& header) override;
- // The fields are public for access by tests.
-
- const Http2FrameHeader frame_header;
-
- Http2String payload;
- Http2String padding;
- Http2String altsvc_origin;
- Http2String altsvc_value;
-
- base::Optional<Http2PriorityFields> opt_priority;
- base::Optional<Http2ErrorCode> opt_rst_stream_error_code;
- base::Optional<Http2PushPromiseFields> opt_push_promise;
- base::Optional<Http2PingFields> opt_ping;
- base::Optional<Http2GoAwayFields> opt_goaway;
-
- base::Optional<size_t> opt_pad_length;
- base::Optional<size_t> opt_payload_length;
- base::Optional<size_t> opt_missing_length;
- base::Optional<size_t> opt_altsvc_origin_length;
- base::Optional<size_t> opt_altsvc_value_length;
-
- base::Optional<size_t> opt_window_update_increment;
-
- bool has_frame_size_error = false;
-
- std::vector<Http2SettingFields> settings;
-
- // These booleans are not checked by CompareCollectedFrames.
- bool got_start_callback = false;
- bool got_end_callback = false;
+ void AppendSetting(const Http2SettingFields& setting_fields) {
+ settings_.push_back(setting_fields);
+ }
+
+ const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
+
+ base::Optional<Http2PriorityFields> GetOptPriority() const {
+ return opt_priority_;
+ }
+ base::Optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
+ return opt_rst_stream_error_code_;
+ }
+ base::Optional<Http2PushPromiseFields> GetOptPushPromise() const {
+ return opt_push_promise_;
+ }
+ base::Optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
+ base::Optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
+ base::Optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
+ base::Optional<size_t> GetOptPayloadLength() const {
+ return opt_payload_length_;
+ }
+ base::Optional<size_t> GetOptMissingLength() const {
+ return opt_missing_length_;
+ }
+ base::Optional<size_t> GetOptAltsvcOriginLength() const {
+ return opt_altsvc_origin_length_;
+ }
+ base::Optional<size_t> GetOptAltsvcValueLength() const {
+ return opt_altsvc_value_length_;
+ }
+ base::Optional<size_t> GetOptWindowUpdateIncrement() const {
+ return opt_window_update_increment_;
+ }
+ bool GetHasFrameSizeError() const { return has_frame_size_error_; }
+
+ void SetOptPriority(base::Optional<Http2PriorityFields> opt_priority) {
+ opt_priority_ = opt_priority;
+ }
+ void SetOptRstStreamErrorCode(
+ base::Optional<Http2ErrorCode> opt_rst_stream_error_code) {
+ opt_rst_stream_error_code_ = opt_rst_stream_error_code;
+ }
+ void SetOptPushPromise(
+ base::Optional<Http2PushPromiseFields> opt_push_promise) {
+ opt_push_promise_ = opt_push_promise;
+ }
+ void SetOptPing(base::Optional<Http2PingFields> opt_ping) {
+ opt_ping_ = opt_ping;
+ }
+ void SetOptGoaway(base::Optional<Http2GoAwayFields> opt_goaway) {
+ opt_goaway_ = opt_goaway;
+ }
+ void SetOptPadLength(base::Optional<size_t> opt_pad_length) {
+ opt_pad_length_ = opt_pad_length;
+ }
+ void SetOptPayloadLength(base::Optional<size_t> opt_payload_length) {
+ opt_payload_length_ = opt_payload_length;
+ }
+ void SetOptMissingLength(base::Optional<size_t> opt_missing_length) {
+ opt_missing_length_ = opt_missing_length;
+ }
+ void SetOptAltsvcOriginLength(
+ base::Optional<size_t> opt_altsvc_origin_length) {
+ opt_altsvc_origin_length_ = opt_altsvc_origin_length;
+ }
+ void SetOptAltsvcValueLength(base::Optional<size_t> opt_altsvc_value_length) {
+ opt_altsvc_value_length_ = opt_altsvc_value_length;
+ }
+ void SetOptWindowUpdateIncrement(
+ base::Optional<size_t> opt_window_update_increment) {
+ opt_window_update_increment_ = opt_window_update_increment;
+ }
+
+ void SetHasFrameSizeError(bool has_frame_size_error) {
+ has_frame_size_error_ = has_frame_size_error;
+ }
private:
// ASSERT during an On* method that we're handling a frame of type
@@ -169,8 +209,39 @@ struct FrameParts : public Http2FrameDecoderListener {
::testing::AssertionResult AppendString(Http2StringPiece source,
Http2String* target,
base::Optional<size_t>* opt_length);
+
+ const Http2FrameHeader frame_header_;
+
+ Http2String payload_;
+ Http2String padding_;
+ Http2String altsvc_origin_;
+ Http2String altsvc_value_;
+
+ base::Optional<Http2PriorityFields> opt_priority_;
+ base::Optional<Http2ErrorCode> opt_rst_stream_error_code_;
+ base::Optional<Http2PushPromiseFields> opt_push_promise_;
+ base::Optional<Http2PingFields> opt_ping_;
+ base::Optional<Http2GoAwayFields> opt_goaway_;
+
+ base::Optional<size_t> opt_pad_length_;
+ base::Optional<size_t> opt_payload_length_;
+ base::Optional<size_t> opt_missing_length_;
+ base::Optional<size_t> opt_altsvc_origin_length_;
+ base::Optional<size_t> opt_altsvc_value_length_;
+
+ base::Optional<size_t> opt_window_update_increment_;
+
+ bool has_frame_size_error_ = false;
+
+ std::vector<Http2SettingFields> settings_;
+
+ // These booleans are not checked by CompareCollectedFrames.
+ bool got_start_callback_ = false;
+ bool got_end_callback_ = false;
};
+std::ostream& operator<<(std::ostream& out, const FrameParts& v);
+
} // namespace test
} // namespace net
diff --git a/chromium/net/http2/test_tools/frame_parts_collector.cc b/chromium/net/http2/test_tools/frame_parts_collector.cc
index 18978d74132..9a727d433e5 100644
--- a/chromium/net/http2/test_tools/frame_parts_collector.cc
+++ b/chromium/net/http2/test_tools/frame_parts_collector.cc
@@ -13,8 +13,8 @@
namespace net {
namespace test {
-FramePartsCollector::FramePartsCollector() {}
-FramePartsCollector::~FramePartsCollector() {}
+FramePartsCollector::FramePartsCollector() = default;
+FramePartsCollector::~FramePartsCollector() = default;
void FramePartsCollector::Reset() {
current_frame_.reset();
@@ -101,7 +101,7 @@ Http2FrameDecoderListener* FramePartsCollector::FrameError(
// frame before detecting the error; for example, the DATA payload decoder
// calls OnDataStart before it can detect padding errors, hence before it
// can call OnPaddingTooLong.
- EXPECT_EQ(header, current_frame_->frame_header);
+ EXPECT_EQ(header, current_frame_->GetFrameHeader());
}
Http2FrameDecoderListener* result = current_frame();
collected_frames_.push_back(std::move(current_frame_));
diff --git a/chromium/net/http2/tools/random_decoder_test.cc b/chromium/net/http2/tools/random_decoder_test.cc
index 47769fc3d3b..be5aaa1b2d9 100644
--- a/chromium/net/http2/tools/random_decoder_test.cc
+++ b/chromium/net/http2/tools/random_decoder_test.cc
@@ -28,7 +28,7 @@ using ::testing::AssertionSuccess;
namespace net {
namespace test {
-RandomDecoderTest::RandomDecoderTest() {}
+RandomDecoderTest::RandomDecoderTest() = default;
bool RandomDecoderTest::StopDecodeOnDone() {
return stop_decode_on_done_;
diff --git a/chromium/net/interfaces/BUILD.gn b/chromium/net/interfaces/BUILD.gn
index cbccdbca978..e4b2dccdbf5 100644
--- a/chromium/net/interfaces/BUILD.gn
+++ b/chromium/net/interfaces/BUILD.gn
@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("interfaces") {
sources = [
+ "address_family.mojom",
"host_resolver_service.mojom",
"ip_address.mojom",
"ip_endpoint.mojom",
@@ -13,7 +14,4 @@ mojom("interfaces") {
public_deps = [
"//url/mojo:url_mojom_gurl",
]
-
- # TODO(crbug.com/699569): Convert to use the new JS bindings.
- use_new_js_bindings = false
}
diff --git a/chromium/net/interfaces/address_family.mojom b/chromium/net/interfaces/address_family.mojom
new file mode 100644
index 00000000000..ec011f18716
--- /dev/null
+++ b/chromium/net/interfaces/address_family.mojom
@@ -0,0 +1,12 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module net.interfaces;
+
+// Mirror of net::AddressFamily.
+enum AddressFamily {
+ UNSPECIFIED,
+ IPV4,
+ IPV6,
+};
diff --git a/chromium/net/interfaces/address_family.typemap b/chromium/net/interfaces/address_family.typemap
new file mode 100644
index 00000000000..89e9459f560
--- /dev/null
+++ b/chromium/net/interfaces/address_family.typemap
@@ -0,0 +1,14 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//net/interfaces/address_family.mojom"
+public_headers = [ "//net/base/address_family.h" ]
+traits_headers = [ "//net/interfaces/address_family_traits.h" ]
+sources = [
+ "//net/interfaces/address_family_traits.cc",
+]
+type_mappings = [ "net.interfaces.AddressFamily=net::AddressFamily" ]
+public_deps = [
+ "//net",
+]
diff --git a/chromium/net/interfaces/address_family_traits.cc b/chromium/net/interfaces/address_family_traits.cc
new file mode 100644
index 00000000000..efb947dcf60
--- /dev/null
+++ b/chromium/net/interfaces/address_family_traits.cc
@@ -0,0 +1,45 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/interfaces/address_family_traits.h"
+
+namespace mojo {
+
+// static
+bool EnumTraits<net::interfaces::AddressFamily, net::AddressFamily>::FromMojom(
+ net::interfaces::AddressFamily address_family,
+ net::AddressFamily* out) {
+ using net::interfaces::AddressFamily;
+ switch (address_family) {
+ case AddressFamily::UNSPECIFIED:
+ *out = net::ADDRESS_FAMILY_UNSPECIFIED;
+ return true;
+ case AddressFamily::IPV4:
+ *out = net::ADDRESS_FAMILY_IPV4;
+ return true;
+ case AddressFamily::IPV6:
+ *out = net::ADDRESS_FAMILY_IPV6;
+ return true;
+ }
+ return false;
+}
+
+// static
+net::interfaces::AddressFamily
+EnumTraits<net::interfaces::AddressFamily, net::AddressFamily>::ToMojom(
+ net::AddressFamily address_family) {
+ using net::interfaces::AddressFamily;
+ switch (address_family) {
+ case net::ADDRESS_FAMILY_UNSPECIFIED:
+ return AddressFamily::UNSPECIFIED;
+ case net::ADDRESS_FAMILY_IPV4:
+ return AddressFamily::IPV4;
+ case net::ADDRESS_FAMILY_IPV6:
+ return AddressFamily::IPV6;
+ }
+ NOTREACHED();
+ return AddressFamily::UNSPECIFIED;
+}
+
+} // namespace mojo
diff --git a/chromium/net/interfaces/address_family_traits.h b/chromium/net/interfaces/address_family_traits.h
new file mode 100644
index 00000000000..875b7795aae
--- /dev/null
+++ b/chromium/net/interfaces/address_family_traits.h
@@ -0,0 +1,23 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_INTERFACES_ADDRESS_FAMILY_TRAITS_H_
+#define NET_INTERFACES_ADDRESS_FAMILY_TRAITS_H_
+
+#include "mojo/public/cpp/bindings/enum_traits.h"
+#include "net/interfaces/address_family.mojom.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<net::interfaces::AddressFamily, net::AddressFamily> {
+ static net::interfaces::AddressFamily ToMojom(
+ net::AddressFamily address_family);
+ static bool FromMojom(net::interfaces::AddressFamily address_family,
+ net::AddressFamily* out);
+};
+
+} // namespace mojo
+
+#endif // NET_INTERFACES_ADDRESS_FAMILY_TRAITS_H_
diff --git a/chromium/net/interfaces/host_resolver.typemap b/chromium/net/interfaces/host_resolver.typemap
index 25d0121dd3d..c0f559ceb56 100644
--- a/chromium/net/interfaces/host_resolver.typemap
+++ b/chromium/net/interfaces/host_resolver.typemap
@@ -11,7 +11,6 @@ sources = [
type_mappings = [
"net.interfaces.HostResolverRequestInfo=std::unique_ptr<net::HostResolver::RequestInfo>[move_only]",
"net.interfaces.AddressList=net::AddressList",
- "net.interfaces.AddressFamily=net::AddressFamily",
]
public_deps = [
"//net",
diff --git a/chromium/net/interfaces/host_resolver_service.mojom b/chromium/net/interfaces/host_resolver_service.mojom
index 1c36489a498..4a5e030cd9f 100644
--- a/chromium/net/interfaces/host_resolver_service.mojom
+++ b/chromium/net/interfaces/host_resolver_service.mojom
@@ -13,13 +13,7 @@
module net.interfaces;
import "net/interfaces/ip_endpoint.mojom";
-
-// Mirror of net::AddressFamily.
-enum AddressFamily {
- UNSPECIFIED,
- IPV4,
- IPV6,
-};
+import "net/interfaces/address_family.mojom";
// Mirror of net::HostResolver::RequestInfo.
struct HostResolverRequestInfo {
diff --git a/chromium/net/interfaces/typemaps.gni b/chromium/net/interfaces/typemaps.gni
index 4932e7116cb..b36db71043c 100644
--- a/chromium/net/interfaces/typemaps.gni
+++ b/chromium/net/interfaces/typemaps.gni
@@ -3,6 +3,7 @@
# found in the LICENSE file.
typemaps = [
+ "//net/interfaces/address_family.typemap",
"//net/interfaces/host_resolver.typemap",
"//net/interfaces/ip_address.typemap",
"//net/interfaces/ip_endpoint.typemap",
diff --git a/chromium/net/log/file_net_log_observer.cc b/chromium/net/log/file_net_log_observer.cc
index 3feaa971287..57787866e0a 100644
--- a/chromium/net/log/file_net_log_observer.cc
+++ b/chromium/net/log/file_net_log_observer.cc
@@ -462,7 +462,7 @@ void FileNetLogObserver::WriteQueue::SwapQueue(EventQueue* local_queue) {
memory_ = 0;
}
-FileNetLogObserver::WriteQueue::~WriteQueue() {}
+FileNetLogObserver::WriteQueue::~WriteQueue() = default;
FileNetLogObserver::FileWriter::FileWriter(
const base::FilePath& log_path,
@@ -476,7 +476,7 @@ FileNetLogObserver::FileWriter::FileWriter(
wrote_event_bytes_(false),
task_runner_(std::move(task_runner)) {}
-FileNetLogObserver::FileWriter::~FileWriter() {}
+FileNetLogObserver::FileWriter::~FileWriter() = default;
void FileNetLogObserver::FileWriter::Initialize(
std::unique_ptr<base::Value> constants_value) {
diff --git a/chromium/net/log/net_log.cc b/chromium/net/log/net_log.cc
index bff7a67d1db..3f2ecc927d0 100644
--- a/chromium/net/log/net_log.cc
+++ b/chromium/net/log/net_log.cc
@@ -108,8 +108,7 @@ void NetLog::ThreadSafeObserver::OnAddEntryData(
NetLog::NetLog() : last_id_(0), is_capturing_(0) {
}
-NetLog::~NetLog() {
-}
+NetLog::~NetLog() = default;
void NetLog::AddGlobalEntry(NetLogEventType type) {
AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
diff --git a/chromium/net/log/net_log_entry.cc b/chromium/net/log/net_log_entry.cc
index 1258139f748..3cdfc4528cc 100644
--- a/chromium/net/log/net_log_entry.cc
+++ b/chromium/net/log/net_log_entry.cc
@@ -58,12 +58,12 @@ NetLogEntryData::NetLogEntryData(
time(time),
parameters_callback(parameters_callback) {}
-NetLogEntryData::~NetLogEntryData() {}
+NetLogEntryData::~NetLogEntryData() = default;
NetLogEntry::NetLogEntry(const NetLogEntryData* data,
NetLogCaptureMode capture_mode)
: data_(data), capture_mode_(capture_mode) {}
-NetLogEntry::~NetLogEntry() {}
+NetLogEntry::~NetLogEntry() = default;
} // namespace net
diff --git a/chromium/net/log/net_log_event_type_list.h b/chromium/net/log/net_log_event_type_list.h
index 551953165f9..8e942348ddd 100644
--- a/chromium/net/log/net_log_event_type_list.h
+++ b/chromium/net/log/net_log_event_type_list.h
@@ -2005,7 +2005,11 @@ EVENT_TYPE(QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS)
// ------------------------------------------------------------------------
// QuicConnectionMigration
// ------------------------------------------------------------------------
-
+// Records the QUIC connection migration mode.
+// {
+// "connection_migration_mode": <The connection migration mode>
+// }
+EVENT_TYPE(QUIC_CONNECTION_MIGRATION_MODE)
// Records that QUIC connection migration has been triggered.
// {
// "trigger": <The reason for the migration attempt>
@@ -2091,6 +2095,12 @@ EVENT_TYPE(QUIC_CONNECTION_MIGRATION_ON_PATH_DEGRADING)
// Records that a QUIC connection migration attempt due to efforts to
// migrate back to the default network.
EVENT_TYPE(QUIC_CONNECTION_MIGRATION_ON_MIGRATE_BACK)
+
+// Records a QUIC connection migration failure after probing.
+EVENT_TYPE(QUIC_CONNECTION_MIGRATION_FAILURE_AFTER_PROBING)
+
+// Records a QUIC connection migration success after probing.
+EVENT_TYPE(QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING)
// ------------------------------------------------------------------------
// HttpStreamParser
// ------------------------------------------------------------------------
diff --git a/chromium/net/log/net_log_unittest.cc b/chromium/net/log/net_log_unittest.cc
index e0e8b6695d9..b6dce8b3843 100644
--- a/chromium/net/log/net_log_unittest.cc
+++ b/chromium/net/log/net_log_unittest.cc
@@ -126,7 +126,7 @@ class CountingObserver : public NetLog::ThreadSafeObserver {
class LoggingObserver : public NetLog::ThreadSafeObserver {
public:
- LoggingObserver() {}
+ LoggingObserver() = default;
~LoggingObserver() override {
if (net_log())
@@ -191,8 +191,8 @@ class NetLogTestThread : public base::SimpleThread {
// A thread that adds a bunch of events to the NetLog.
class AddEventsTestThread : public NetLogTestThread {
public:
- AddEventsTestThread() {}
- ~AddEventsTestThread() override {}
+ AddEventsTestThread() = default;
+ ~AddEventsTestThread() override = default;
private:
void RunTestThread() override {
@@ -206,7 +206,7 @@ class AddEventsTestThread : public NetLogTestThread {
// A thread that adds and removes an observer from the NetLog repeatedly.
class AddRemoveObserverTestThread : public NetLogTestThread {
public:
- AddRemoveObserverTestThread() {}
+ AddRemoveObserverTestThread() = default;
~AddRemoveObserverTestThread() override { EXPECT_TRUE(!observer_.net_log()); }
diff --git a/chromium/net/log/net_log_util.cc b/chromium/net/log/net_log_util.cc
index efe45716a2c..e133b7b7151 100644
--- a/chromium/net/log/net_log_util.cc
+++ b/chromium/net/log/net_log_util.cc
@@ -460,7 +460,7 @@ NET_EXPORT void CreateNetLogEntriesForActiveObjects(
context->AssertCalledOnValidThread();
// Contexts should all be using the same NetLog.
DCHECK_EQ((*contexts.begin())->net_log(), context->net_log());
- for (auto* request : context->url_requests()) {
+ for (auto* request : *context->url_requests()) {
requests.push_back(request);
}
}
diff --git a/chromium/net/log/test_net_log.cc b/chromium/net/log/test_net_log.cc
index 8cdcceabd01..36ef00dd4d5 100644
--- a/chromium/net/log/test_net_log.cc
+++ b/chromium/net/log/test_net_log.cc
@@ -18,8 +18,8 @@ namespace net {
// that saves messages to a buffer.
class TestNetLog::Observer : public NetLog::ThreadSafeObserver {
public:
- Observer() {}
- ~Observer() override {}
+ Observer() = default;
+ ~Observer() override = default;
// Returns the list of all entries in the log.
void GetEntries(TestNetLogEntry::List* entry_list) const {
@@ -110,8 +110,7 @@ BoundTestNetLog::BoundTestNetLog()
: net_log_(NetLogWithSource::Make(&test_net_log_, NetLogSourceType::NONE)) {
}
-BoundTestNetLog::~BoundTestNetLog() {
-}
+BoundTestNetLog::~BoundTestNetLog() = default;
void BoundTestNetLog::GetEntries(TestNetLogEntry::List* entry_list) const {
test_net_log_.GetEntries(entry_list);
diff --git a/chromium/net/log/test_net_log_entry.cc b/chromium/net/log/test_net_log_entry.cc
index e8beb757c31..1936ef3e336 100644
--- a/chromium/net/log/test_net_log_entry.cc
+++ b/chromium/net/log/test_net_log_entry.cc
@@ -30,8 +30,7 @@ TestNetLogEntry::TestNetLogEntry(const TestNetLogEntry& entry) {
*this = entry;
}
-TestNetLogEntry::~TestNetLogEntry() {
-}
+TestNetLogEntry::~TestNetLogEntry() = default;
TestNetLogEntry& TestNetLogEntry::operator=(const TestNetLogEntry& entry) {
type = entry.type;
diff --git a/chromium/net/log/trace_net_log_observer.cc b/chromium/net/log/trace_net_log_observer.cc
index 4349c3c714a..ed3286fd35b 100644
--- a/chromium/net/log/trace_net_log_observer.cc
+++ b/chromium/net/log/trace_net_log_observer.cc
@@ -30,7 +30,7 @@ class TracedValue : public base::trace_event::ConvertableToTraceFormat {
: value_(std::move(value)) {}
private:
- ~TracedValue() override {}
+ ~TracedValue() override = default;
void AppendAsTraceFormat(std::string* out) const override {
if (value_) {
diff --git a/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc b/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc
new file mode 100644
index 00000000000..3da56ed6ad3
--- /dev/null
+++ b/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc
@@ -0,0 +1,232 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/values_test_util.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "net/base/net_errors.h"
+#include "net/network_error_logging/network_error_logging_service.h"
+#include "net/reporting/reporting_feature.h"
+#include "net/reporting/reporting_policy.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_fixed.h"
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
+namespace net {
+namespace {
+
+const char kGroup[] = "network-errors";
+const int kMaxAgeSec = 86400;
+
+const char kConfigurePath[] = "/configure";
+const char kFailPath[] = "/fail";
+const char kReportPath[] = "/report";
+
+class HungHttpResponse : public test_server::HttpResponse {
+ public:
+ HungHttpResponse() = default;
+
+ void SendResponse(const test_server::SendBytesCallback& send,
+ const test_server::SendCompleteCallback& done) override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HungHttpResponse);
+};
+
+class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
+ protected:
+ NetworkErrorLoggingEndToEndTest()
+ : test_server_(test_server::EmbeddedTestServer::TYPE_HTTPS),
+ upload_should_hang_(false),
+ upload_received_(false) {
+ scoped_feature_list_.InitWithFeatures(
+ {features::kReporting, features::kNetworkErrorLogging}, {});
+
+ // Make report delivery happen instantly.
+ auto policy = std::make_unique<ReportingPolicy>();
+ policy->delivery_interval = base::TimeDelta::FromSeconds(0);
+
+ URLRequestContextBuilder builder;
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ builder.set_proxy_config_service(
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfig::CreateDirect()));
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+ builder.set_reporting_policy(std::move(policy));
+ builder.set_network_error_logging_enabled(true);
+ url_request_context_ = builder.Build();
+
+ EXPECT_TRUE(url_request_context_->reporting_service());
+ EXPECT_TRUE(url_request_context_->network_error_logging_delegate());
+
+ test_server_.RegisterRequestHandler(base::BindRepeating(
+ &NetworkErrorLoggingEndToEndTest::HandleConfigureRequest,
+ base::Unretained(this)));
+ test_server_.RegisterRequestHandler(
+ base::BindRepeating(&NetworkErrorLoggingEndToEndTest::HandleFailRequest,
+ base::Unretained(this)));
+ test_server_.RegisterRequestHandler(base::BindRepeating(
+ &NetworkErrorLoggingEndToEndTest::HandleReportRequest,
+ base::Unretained(this)));
+ EXPECT_TRUE(test_server_.Start());
+ }
+
+ GURL GetConfigureURL() { return test_server_.GetURL(kConfigurePath); }
+
+ GURL GetFailURL() { return test_server_.GetURL(kFailPath); }
+
+ GURL GetReportURL() { return test_server_.GetURL(kReportPath); }
+
+ std::unique_ptr<test_server::HttpResponse> HandleConfigureRequest(
+ const test_server::HttpRequest& request) {
+ if (request.relative_url != kConfigurePath)
+ return nullptr;
+
+ GURL endpoint_url = GetReportURL();
+
+ auto response = std::make_unique<test_server::BasicHttpResponse>();
+ response->AddCustomHeader(
+ "Report-To",
+ base::StringPrintf("{\"url\":\"%s\",\"group\":\"%s\",\"max-age\":%d}",
+ endpoint_url.spec().c_str(), kGroup, kMaxAgeSec));
+ response->AddCustomHeader(
+ "NEL", base::StringPrintf("{\"report-to\":\"%s\",\"max-age\":%d}",
+ kGroup, kMaxAgeSec));
+ response->set_content_type("text/plain");
+ response->set_content("");
+ return std::move(response);
+ }
+
+ std::unique_ptr<test_server::HttpResponse> HandleFailRequest(
+ const test_server::HttpRequest& request) {
+ if (request.relative_url != kFailPath)
+ return nullptr;
+
+ return std::make_unique<test_server::RawHttpResponse>("", "");
+ }
+
+ std::unique_ptr<test_server::HttpResponse> HandleReportRequest(
+ const test_server::HttpRequest& request) {
+ if (request.relative_url != kReportPath)
+ return nullptr;
+
+ EXPECT_FALSE(upload_received_);
+ upload_received_ = true;
+
+ EXPECT_TRUE(request.has_content);
+ upload_content_ = request.content;
+
+ if (!upload_closure_.is_null())
+ std::move(upload_closure_).Run();
+
+ if (upload_should_hang_)
+ return std::make_unique<HungHttpResponse>();
+
+ auto response = std::make_unique<test_server::BasicHttpResponse>();
+ response->set_content_type("text/plain");
+ response->set_content("");
+ return std::move(response);
+ }
+
+ base::test::ScopedFeatureList scoped_feature_list_;
+ std::unique_ptr<URLRequestContext> url_request_context_;
+ test_server::EmbeddedTestServer test_server_;
+
+ bool upload_should_hang_;
+ bool upload_received_;
+ std::string upload_content_;
+ base::OnceClosure upload_closure_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkErrorLoggingEndToEndTest);
+};
+
+TEST_F(NetworkErrorLoggingEndToEndTest, ReportNetworkError) {
+ TestDelegate configure_delegate;
+ auto configure_request = url_request_context_->CreateRequest(
+ GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ configure_request->set_method("GET");
+ configure_request->Start();
+ base::RunLoop().Run();
+ EXPECT_TRUE(configure_request->status().is_success());
+
+ TestDelegate fail_delegate;
+ auto fail_request = url_request_context_->CreateRequest(
+ GetFailURL(), DEFAULT_PRIORITY, &fail_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ fail_request->set_method("GET");
+ fail_request->Start();
+ base::RunLoop().Run();
+ EXPECT_EQ(URLRequestStatus::FAILED, fail_request->status().status());
+ EXPECT_EQ(ERR_EMPTY_RESPONSE, fail_request->status().error());
+
+ if (!upload_received_) {
+ base::RunLoop run_loop;
+ upload_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ auto reports = base::test::ParseJson(upload_content_);
+
+ base::ListValue* reports_list;
+ ASSERT_TRUE(reports->GetAsList(&reports_list));
+ ASSERT_EQ(1u, reports_list->GetSize());
+ base::DictionaryValue* report_dict;
+ ASSERT_TRUE(reports_list->GetDictionary(0u, &report_dict));
+
+ ExpectDictStringValue("network-error", *report_dict, "type");
+ ExpectDictStringValue(GetFailURL().spec(), *report_dict, "url");
+ base::DictionaryValue* body_dict;
+ ASSERT_TRUE(report_dict->GetDictionary("report", &body_dict));
+
+ ExpectDictStringValue("http.response.empty", *body_dict, "type");
+ ExpectDictIntegerValue(0, *body_dict, "status-code");
+ ExpectDictStringValue(GetFailURL().spec(), *body_dict, "uri");
+}
+
+// Make sure an upload that is in progress at shutdown does not crash.
+// This verifies that https://crbug.com/792978 is fixed.
+TEST_F(NetworkErrorLoggingEndToEndTest, UploadAtShutdown) {
+ upload_should_hang_ = true;
+
+ TestDelegate configure_delegate;
+ auto configure_request = url_request_context_->CreateRequest(
+ GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ configure_request->set_method("GET");
+ configure_request->Start();
+ base::RunLoop().Run();
+ EXPECT_TRUE(configure_request->status().is_success());
+
+ TestDelegate fail_delegate;
+ auto fail_request = url_request_context_->CreateRequest(
+ GetFailURL(), DEFAULT_PRIORITY, &fail_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ fail_request->set_method("GET");
+ fail_request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ // Let Reporting and NEL shut down with the upload still pending to see if
+ // they crash.
+}
+
+} // namespace
+} // namespace net
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 b1773129d8d..e9d6f7bdf53 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service.cc
@@ -92,6 +92,7 @@ const struct {
// http.protocol.error?
{ERR_INVALID_HTTP_RESPONSE, "http.response.invalid"},
{ERR_TOO_MANY_REDIRECTS, "http.response.redirect_loop"},
+ {ERR_EMPTY_RESPONSE, "http.response.empty"},
// http.failed?
{ERR_ABORTED, "abandoned"},
@@ -170,16 +171,21 @@ void NetworkErrorLoggingService::OnNetworkError(const ErrorDetails& details) {
if (!reporting_service_)
return;
- url::Origin origin = url::Origin::Create(details.uri);
+ // It is expected for Reporting uploads to terminate with ERR_ABORTED, since
+ // the ReportingUploader cancels them after receiving the response code and
+ // headers.
+ if (details.is_reporting_upload && details.type == ERR_ABORTED)
+ return;
// NEL is only available to secure origins, so ignore network errors from
// insecure origins. (The check in OnHeader prevents insecure origins from
// setting policies, but this check is needed to ensure that insecure origins
// can't match wildcard policies from secure origins.)
- if (!origin.GetURL().SchemeIsCryptographic())
+ if (!details.uri.SchemeIsCryptographic())
return;
- const OriginPolicy* policy = FindPolicyForOrigin(origin);
+ const OriginPolicy* policy =
+ FindPolicyForOrigin(url::Origin::Create(details.uri));
if (!policy)
return;
@@ -191,14 +197,36 @@ void NetworkErrorLoggingService::OnNetworkError(const ErrorDetails& details) {
CreateReportBody(type_string, details));
}
+void NetworkErrorLoggingService::RemoveBrowsingData(
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
+ if (origin_filter.is_null()) {
+ wildcard_policies_.clear();
+ policies_.clear();
+ return;
+ }
+
+ std::vector<url::Origin> origins_to_remove;
+
+ for (auto it = policies_.begin(); it != policies_.end(); ++it) {
+ if (origin_filter.Run(it->first.GetURL()))
+ origins_to_remove.push_back(it->first);
+ }
+
+ for (auto it = origins_to_remove.begin(); it != origins_to_remove.end();
+ ++it) {
+ MaybeRemoveWildcardPolicy(*it, &policies_[*it]);
+ policies_.erase(*it);
+ }
+}
+
void NetworkErrorLoggingService::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
+ base::TickClock* tick_clock) {
DCHECK(tick_clock);
- tick_clock_ = std::move(tick_clock);
+ tick_clock_ = tick_clock;
}
NetworkErrorLoggingService::NetworkErrorLoggingService()
- : tick_clock_(base::MakeUnique<base::DefaultTickClock>()),
+ : tick_clock_(base::DefaultTickClock::GetInstance()),
reporting_service_(nullptr) {}
bool NetworkErrorLoggingService::ParseHeader(const std::string& json_value,
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 759bb458bc4..5cefaddd831 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.h
+++ b/chromium/net/network_error_logging/network_error_logging_service.h
@@ -67,7 +67,10 @@ class NET_EXPORT NetworkErrorLoggingService
void OnNetworkError(const ErrorDetails& details) override;
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ void RemoveBrowsingData(
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override;
+
+ void SetTickClockForTesting(base::TickClock* tick_clock);
private:
// NEL Policy set by an origin.
@@ -113,7 +116,7 @@ class NET_EXPORT NetworkErrorLoggingService
const std::string& type,
const ErrorDetails& details) const;
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
// Unowned.
ReportingService* reporting_service_;
diff --git a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
index e7192e0f724..e04a2f25af4 100644
--- a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -74,12 +74,17 @@ class TestReportingService : public ReportingService {
NOTREACHED();
}
- void RemoveBrowsingData(
- int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter) override {
+ void RemoveBrowsingData(int data_type_mask,
+ const base::RepeatingCallback<bool(const GURL&)>&
+ origin_filter) override {
NOTREACHED();
}
+ bool RequestIsUpload(const URLRequest& request) override {
+ NOTREACHED();
+ return true;
+ }
+
private:
std::vector<Report> reports_;
@@ -119,6 +124,7 @@ class NetworkErrorLoggingServiceTest : public ::testing::Test {
details.status_code = 0;
details.elapsed_time = base::TimeDelta::FromSeconds(1);
details.type = error_type;
+ details.is_reporting_upload = false;
return details;
}
@@ -131,11 +137,14 @@ class NetworkErrorLoggingServiceTest : public ::testing::Test {
const GURL kUrl_ = GURL("https://example.com/path");
const GURL kUrlDifferentPort_ = GURL("https://example.com:4433/path");
const GURL kUrlSubdomain_ = GURL("https://subdomain.example.com/path");
+ const GURL kUrlDifferentHost_ = GURL("https://example2.com/path");
const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
const url::Origin kOriginDifferentPort_ =
url::Origin::Create(kUrlDifferentPort_);
const url::Origin kOriginSubdomain_ = url::Origin::Create(kUrlSubdomain_);
+ const url::Origin kOriginDifferentHost_ =
+ url::Origin::Create(kUrlDifferentHost_);
const std::string kHeader_ = "{\"report-to\":\"group\",\"max-age\":86400}";
const std::string kHeaderIncludeSubdomains_ =
@@ -280,5 +289,34 @@ TEST_F(NetworkErrorLoggingServiceTest,
EXPECT_TRUE(reports().empty());
}
+TEST_F(NetworkErrorLoggingServiceTest, RemoveAllBrowsingData) {
+ service()->OnHeader(kOrigin_, kHeader_);
+
+ service()->RemoveBrowsingData(base::RepeatingCallback<bool(const GURL&)>());
+
+ service()->OnNetworkError(MakeErrorDetails(kUrl_, ERR_CONNECTION_REFUSED));
+
+ EXPECT_TRUE(reports().empty());
+}
+
+TEST_F(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) {
+ service()->OnHeader(kOrigin_, kHeader_);
+ service()->OnHeader(kOriginDifferentHost_, kHeader_);
+
+ service()->RemoveBrowsingData(
+ base::BindRepeating([](const GURL& origin) -> bool {
+ return origin.host() == "example.com";
+ }));
+
+ service()->OnNetworkError(MakeErrorDetails(kUrl_, ERR_CONNECTION_REFUSED));
+
+ EXPECT_TRUE(reports().empty());
+
+ service()->OnNetworkError(
+ MakeErrorDetails(kUrlDifferentHost_, ERR_CONNECTION_REFUSED));
+
+ EXPECT_EQ(1u, reports().size());
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/nqe/OWNERS b/chromium/net/nqe/OWNERS
index fa91285a8fa..30f461a85f9 100644
--- a/chromium/net/nqe/OWNERS
+++ b/chromium/net/nqe/OWNERS
@@ -1,6 +1,9 @@
-bengr@chromium.org
+# Primary
tbansal@chromium.org
ryansturm@chromium.org
+# Secondary
+bengr@chromium.org
+
# TEAM: net-dev@chromium.org
# COMPONENT: Internals>Network>NetworkQuality \ No newline at end of file
diff --git a/chromium/net/nqe/cached_network_quality.h b/chromium/net/nqe/cached_network_quality.h
index 9f437da93ca..22f60299516 100644
--- a/chromium/net/nqe/cached_network_quality.h
+++ b/chromium/net/nqe/cached_network_quality.h
@@ -41,8 +41,6 @@ class NET_EXPORT_PRIVATE CachedNetworkQuality {
base::TimeTicks last_update_time() { return last_update_time_; }
- const NetworkQuality& network_quality() { return network_quality_; }
-
EffectiveConnectionType effective_connection_type() const {
return effective_connection_type_;
}
diff --git a/chromium/net/nqe/network_id.cc b/chromium/net/nqe/network_id.cc
index 3e5fbe5e6cb..be8d350bbdb 100644
--- a/chromium/net/nqe/network_id.cc
+++ b/chromium/net/nqe/network_id.cc
@@ -17,28 +17,39 @@ namespace internal {
// static
NetworkID NetworkID::FromString(const std::string& network_id) {
std::string base64_decoded;
- if (!base::Base64Decode(network_id, &base64_decoded))
- return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string());
+ if (!base::Base64Decode(network_id, &base64_decoded)) {
+ return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(),
+ INT32_MIN);
+ }
NetworkIDProto network_id_proto;
- if (!network_id_proto.ParseFromString(base64_decoded))
- return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string());
+ if (!network_id_proto.ParseFromString(base64_decoded)) {
+ return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(),
+ INT32_MIN);
+ }
return NetworkID(static_cast<NetworkChangeNotifier::ConnectionType>(
network_id_proto.connection_type()),
- network_id_proto.id());
+ network_id_proto.id(), network_id_proto.signal_strength());
}
NetworkID::NetworkID(NetworkChangeNotifier::ConnectionType type,
- const std::string& id)
- : type(type), id(id) {}
+ const std::string& id,
+ int32_t signal_strength)
+ : type(type), id(id), signal_strength(signal_strength) {
+ // A valid value of |signal_strength| must be between 0 and 4 (both
+ // inclusive).
+ DCHECK((0 <= signal_strength && 4 >= signal_strength) ||
+ (INT32_MIN == signal_strength));
+}
NetworkID::NetworkID(const NetworkID& other) = default;
NetworkID::~NetworkID() = default;
bool NetworkID::operator==(const NetworkID& other) const {
- return type == other.type && id == other.id;
+ return type == other.type && id == other.id &&
+ signal_strength == other.signal_strength;
}
bool NetworkID::operator!=(const NetworkID& other) const {
@@ -49,13 +60,15 @@ NetworkID& NetworkID::operator=(const NetworkID& other) = default;
// Overloaded to support ordered collections.
bool NetworkID::operator<(const NetworkID& other) const {
- return std::tie(type, id) < std::tie(other.type, other.id);
+ return std::tie(type, id, signal_strength) <
+ std::tie(other.type, other.id, other.signal_strength);
}
std::string NetworkID::ToString() const {
NetworkIDProto network_id_proto;
network_id_proto.set_connection_type(static_cast<int>(type));
network_id_proto.set_id(id);
+ network_id_proto.set_signal_strength(signal_strength);
std::string serialized_network_id;
if (!network_id_proto.SerializeToString(&serialized_network_id))
diff --git a/chromium/net/nqe/network_id.h b/chromium/net/nqe/network_id.h
index 65f52d198db..618210c87f5 100644
--- a/chromium/net/nqe/network_id.h
+++ b/chromium/net/nqe/network_id.h
@@ -23,7 +23,9 @@ namespace internal {
struct NET_EXPORT_PRIVATE NetworkID {
static NetworkID FromString(const std::string& network_id);
- NetworkID(NetworkChangeNotifier::ConnectionType type, const std::string& id);
+ NetworkID(NetworkChangeNotifier::ConnectionType type,
+ const std::string& id,
+ int32_t signal_strength);
NetworkID(const NetworkID& other);
~NetworkID();
@@ -50,6 +52,14 @@ struct NET_EXPORT_PRIVATE NetworkID {
// - An empty string in all other cases or if the network name is not
// exposed by platform APIs.
std::string id;
+
+ // Signal strength of the network. Set to INT32_MIN when the value is
+ // unavailable. Otherwise, must be between 0 and 4 (both inclusive). This may
+ // take into account many different radio technology inputs. 0 represents very
+ // poor signal strength while 4 represents a very strong signal strength. The
+ // range is capped between 0 and 4 to ensure that a change in the value
+ // indicates a non-negligible change in the signal quality.
+ int32_t signal_strength;
};
} // namespace internal
diff --git a/chromium/net/nqe/network_id_unittest.cc b/chromium/net/nqe/network_id_unittest.cc
index 3ee6998da8f..68e5d01a4ff 100644
--- a/chromium/net/nqe/network_id_unittest.cc
+++ b/chromium/net/nqe/network_id_unittest.cc
@@ -5,6 +5,7 @@
#include "net/nqe/network_id.h"
#include <string>
+
#include "base/strings/string_number_conversions.h"
#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,7 +18,7 @@ namespace {
TEST(NetworkIDTest, TestSerialize) {
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test1");
+ "test1", 2);
std::string serialized = network_id.ToString();
EXPECT_EQ(network_id, NetworkID::FromString(serialized));
}
diff --git a/chromium/net/nqe/network_qualities_prefs_manager.cc b/chromium/net/nqe/network_qualities_prefs_manager.cc
index 7d860f0283b..be3901575f4 100644
--- a/chromium/net/nqe/network_qualities_prefs_manager.cc
+++ b/chromium/net/nqe/network_qualities_prefs_manager.cc
@@ -14,6 +14,7 @@
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/nqe/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator_params.h"
namespace net {
@@ -27,7 +28,7 @@ namespace {
// (ii) Connection type of the network as reported by network
// change notifier (an enum).
// (iii) Effective connection type of the network (an enum).
-constexpr size_t kMaxCacheSize = 10u;
+constexpr size_t kMaxCacheSize = 20u;
// Parses |value| into a map of NetworkIDs and CachedNetworkQualities,
// and returns the map.
@@ -133,6 +134,19 @@ void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQualityOnPrefSequence(
if (network_id_string.find('.') != std::string::npos)
return;
+ if (cached_network_quality.effective_connection_type() ==
+ network_quality_estimator_->params()->GetDefaultECT(network_id.type)) {
+ // No need to cache the network quality since the default network quality
+ // (synthesized using the platform APIs) matches the observed network
+ // quality.
+ if (!prefs_->RemoveKey(network_id_string)) {
+ // Return early since the prefs was unchanged.
+ return;
+ }
+ pref_delegate_->SetDictionaryValue(*prefs_);
+ return;
+ }
+
prefs_->SetString(network_id_string,
GetNameForEffectiveConnectionType(
cached_network_quality.effective_connection_type()));
diff --git a/chromium/net/nqe/network_qualities_prefs_manager_unittest.cc b/chromium/net/nqe/network_qualities_prefs_manager_unittest.cc
index 29db509e295..44b228ca58a 100644
--- a/chromium/net/nqe/network_qualities_prefs_manager_unittest.cc
+++ b/chromium/net/nqe/network_qualities_prefs_manager_unittest.cc
@@ -16,6 +16,7 @@
#include "base/values.h"
#include "net/base/network_change_notifier.h"
#include "net/nqe/effective_connection_type.h"
+#include "net/nqe/network_id.h"
#include "net/nqe/network_quality_estimator_test_util.h"
#include "net/nqe/network_quality_store.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -74,7 +75,12 @@ class TestPrefDelegate : public NetworkQualitiesPrefsManager::PrefDelegate {
};
TEST(NetworkQualitiesPrefManager, Write) {
- TestNetworkQualityEstimator estimator;
+ // Force set the ECT to Slow 2G so that the ECT does not match the default
+ // ECT for the current connection type. This forces the prefs to be written
+ // for the current connection.
+ std::map<std::string, std::string> variation_params;
+ variation_params["force_effective_connection_type"] = "Slow-2G";
+ TestNetworkQualityEstimator estimator(variation_params);
std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
@@ -88,34 +94,104 @@ TEST(NetworkQualitiesPrefManager, Write) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
- EXPECT_EQ(0u, prefs_delegate_ptr->write_count());
+ EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
// Network quality generated from the default observation must be written.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
+ EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
// Run a request so that effective connection type is recomputed, and
// observers are notified of change in the network quality.
estimator.RunOneRequest();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, prefs_delegate_ptr->write_count());
+ EXPECT_EQ(4u, prefs_delegate_ptr->write_count());
estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
// Run a request so that effective connection type is recomputed, and
// observers are notified of change in the network quality..
estimator.RunOneRequest();
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(5u, prefs_delegate_ptr->write_count());
+
+ // Prefs should not be read again.
+ EXPECT_EQ(1u, prefs_delegate_ptr->read_count());
+
+ manager.ShutdownOnPrefSequence();
+}
+
+TEST(NetworkQualitiesPrefManager, WriteWhenMatchingExpectedECT) {
+ // Force set the ECT to Slow 2G so that the ECT does not match the default
+ // ECT for the current connection type. This forces the prefs to be written
+ // for the current connection.
+ std::map<std::string, std::string> variation_params;
+ variation_params["force_effective_connection_type"] = "Slow-2G";
+ TestNetworkQualityEstimator estimator(variation_params);
+
+ std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
+ TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
+
+ NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
+ manager.InitializeOnNetworkThread(&estimator);
+ base::RunLoop().RunUntilIdle();
+
+ // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
+ EXPECT_EQ(1u, prefs_delegate_ptr->read_count());
+
+ const nqe::internal::NetworkID network_id(
+ NetworkChangeNotifier::ConnectionType::CONNECTION_4G, "test", INT32_MIN);
+
+ estimator.SimulateNetworkChange(network_id.type, network_id.id);
+ EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
+ // Network quality generated from the default observation must be written.
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
+ estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
+ // Run a request so that effective connection type is recomputed, and
+ // observers are notified of change in the network quality.
+ estimator.RunOneRequest();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(4u, prefs_delegate_ptr->write_count());
+
+ estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
+ // Run a request so that effective connection type is recomputed, and
+ // observers are notified of change in the network quality..
+ estimator.RunOneRequest();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(5u, prefs_delegate_ptr->write_count());
+
// Prefs should not be read again.
EXPECT_EQ(1u, prefs_delegate_ptr->read_count());
+ EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_3G,
+ manager.ForceReadPrefsForTesting()
+ .find(network_id)
+ ->second.effective_connection_type());
+
+ estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_4G);
+ estimator.RunOneRequest();
+ base::RunLoop().RunUntilIdle();
+
+ // Cached network quality for |network_id| should be deleted from the prefs
+ // since the expected network quality for |network_id| matches the observed
+ // network quality.
+ EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().count(network_id));
+ EXPECT_EQ(6u, prefs_delegate_ptr->write_count());
+
manager.ShutdownOnPrefSequence();
}
TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
- static const size_t kMaxCacheSize = 10u;
- TestNetworkQualityEstimator estimator;
+ static const size_t kMaxCacheSize = 20u;
+
+ // Force set the ECT to Slow 2G so that the ECT does not match the default
+ // ECT for the current connection type. This forces the prefs to be written
+ // for the current connection.
+ std::map<std::string, std::string> variation_params;
+ variation_params["force_effective_connection_type"] = "Slow-2G";
+ TestNetworkQualityEstimator estimator(variation_params);
std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
@@ -126,7 +202,7 @@ TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");
- EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
estimator.set_recent_effective_connection_type(
EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
@@ -136,7 +212,7 @@ TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
base::RunLoop().RunUntilIdle();
// Verify that the observer was notified, and the updated network quality was
// written to the prefs.
- EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
// Change the network ID.
for (size_t i = 0; i < kMaxCacheSize; ++i) {
@@ -147,7 +223,7 @@ TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
estimator.RunOneRequest();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(std::min(i + 2, kMaxCacheSize),
+ EXPECT_EQ(std::min(i + 3, kMaxCacheSize),
manager.ForceReadPrefsForTesting().size());
}
@@ -155,17 +231,27 @@ TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
read_prefs = manager.ForceReadPrefsForTesting();
// Verify the contents of the prefs.
+ size_t count_2g_entries = 0;
for (std::map<nqe::internal::NetworkID,
nqe::internal::CachedNetworkQuality>::const_iterator it =
read_prefs.begin();
it != read_prefs.end(); ++it) {
+ if (it->first.type ==
+ NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN) {
+ continue;
+ }
EXPECT_EQ(0u, it->first.id.find("test", 0u));
EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_2G,
it->first.type);
EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
it->second.effective_connection_type());
+ ++count_2g_entries;
}
+ // At most one entry should be for the network with connection type
+ // NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN.
+ EXPECT_LE(kMaxCacheSize - 1, count_2g_entries);
+
base::HistogramTester histogram_tester;
estimator.OnPrefsRead(read_prefs);
histogram_tester.ExpectUniqueSample("NQE.Prefs.ReadSize", kMaxCacheSize, 1);
@@ -175,7 +261,12 @@ TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
// Verifies that the prefs are cleared correctly.
TEST(NetworkQualitiesPrefManager, ClearPrefs) {
- TestNetworkQualityEstimator estimator;
+ // Force set the ECT to Slow 2G so that the ECT does not match the default
+ // ECT for the current connection type. This forces the prefs to be written
+ // for the current connection.
+ std::map<std::string, std::string> variation_params;
+ variation_params["force_effective_connection_type"] = "Slow-2G";
+ TestNetworkQualityEstimator estimator(variation_params);
std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
@@ -186,7 +277,7 @@ TEST(NetworkQualitiesPrefManager, ClearPrefs) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
- EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
estimator.set_recent_effective_connection_type(
EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
@@ -196,7 +287,7 @@ TEST(NetworkQualitiesPrefManager, ClearPrefs) {
base::RunLoop().RunUntilIdle();
// Verify that the observer was notified, and the updated network quality was
// written to the prefs.
- EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
+ EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
// Prefs must be completely cleared.
manager.ClearPrefs();
diff --git a/chromium/net/nqe/network_quality.cc b/chromium/net/nqe/network_quality.cc
index cff98ab81a3..d9f23182702 100644
--- a/chromium/net/nqe/network_quality.cc
+++ b/chromium/net/nqe/network_quality.cc
@@ -13,7 +13,10 @@ base::TimeDelta InvalidRTT() {
}
NetworkQuality::NetworkQuality()
- : NetworkQuality(InvalidRTT(), InvalidRTT(), INVALID_RTT_THROUGHPUT) {}
+ : NetworkQuality(InvalidRTT(), InvalidRTT(), INVALID_RTT_THROUGHPUT) {
+ VerifyValueCorrectness();
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+}
NetworkQuality::NetworkQuality(const base::TimeDelta& http_rtt,
const base::TimeDelta& transport_rtt,
@@ -21,13 +24,17 @@ NetworkQuality::NetworkQuality(const base::TimeDelta& http_rtt,
: http_rtt_(http_rtt),
transport_rtt_(transport_rtt),
downstream_throughput_kbps_(downstream_throughput_kbps) {
- DCHECK_GE(downstream_throughput_kbps_, INVALID_RTT_THROUGHPUT);
+ VerifyValueCorrectness();
+ DETACH_FROM_SEQUENCE(sequence_checker_);
}
NetworkQuality::NetworkQuality(const NetworkQuality& other)
: NetworkQuality(other.http_rtt_,
other.transport_rtt_,
- other.downstream_throughput_kbps_) {}
+ other.downstream_throughput_kbps_) {
+ VerifyValueCorrectness();
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+}
NetworkQuality::~NetworkQuality() = default;
@@ -35,16 +42,20 @@ NetworkQuality& NetworkQuality::operator=(const NetworkQuality& other) {
http_rtt_ = other.http_rtt_;
transport_rtt_ = other.transport_rtt_;
downstream_throughput_kbps_ = other.downstream_throughput_kbps_;
+ VerifyValueCorrectness();
+ DETACH_FROM_SEQUENCE(sequence_checker_);
return *this;
}
bool NetworkQuality::operator==(const NetworkQuality& other) const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return http_rtt_ == other.http_rtt_ &&
transport_rtt_ == other.transport_rtt_ &&
downstream_throughput_kbps_ == other.downstream_throughput_kbps_;
}
bool NetworkQuality::IsFaster(const NetworkQuality& other) const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return (http_rtt() == InvalidRTT() || other.http_rtt() == InvalidRTT() ||
http_rtt() <= other.http_rtt()) &&
(transport_rtt() == InvalidRTT() ||
@@ -55,6 +66,13 @@ bool NetworkQuality::IsFaster(const NetworkQuality& other) const {
downstream_throughput_kbps() >= other.downstream_throughput_kbps());
}
+void NetworkQuality::VerifyValueCorrectness() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, http_rtt_.InMilliseconds());
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, transport_rtt_.InMilliseconds());
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, downstream_throughput_kbps_);
+}
+
} // namespace internal
} // namespace nqe
} // namespace net
diff --git a/chromium/net/nqe/network_quality.h b/chromium/net/nqe/network_quality.h
index 73afb69fd63..de9d275b81d 100644
--- a/chromium/net/nqe/network_quality.h
+++ b/chromium/net/nqe/network_quality.h
@@ -9,6 +9,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
@@ -53,28 +54,46 @@ class NET_EXPORT_PRIVATE NetworkQuality {
bool IsFaster(const NetworkQuality& other) const;
// Returns the estimate of the round trip time at the HTTP layer.
- const base::TimeDelta& http_rtt() const { return http_rtt_; }
+ const base::TimeDelta& http_rtt() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return http_rtt_;
+ }
- void set_http_rtt(const base::TimeDelta& http_rtt) { http_rtt_ = http_rtt; }
+ void set_http_rtt(base::TimeDelta http_rtt) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ http_rtt_ = http_rtt;
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, http_rtt_.InMilliseconds());
+ }
// Returns the estimate of the round trip time at the transport layer.
- const base::TimeDelta& transport_rtt() const { return transport_rtt_; }
+ const base::TimeDelta& transport_rtt() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return transport_rtt_;
+ }
- void set_transport_rtt(const base::TimeDelta& transport_rtt) {
+ void set_transport_rtt(base::TimeDelta transport_rtt) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
transport_rtt_ = transport_rtt;
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, transport_rtt_.InMilliseconds());
}
// Returns the estimate of the downstream throughput in Kbps (Kilobits per
// second).
int32_t downstream_throughput_kbps() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return downstream_throughput_kbps_;
}
void set_downstream_throughput_kbps(int32_t downstream_throughput_kbps) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
downstream_throughput_kbps_ = downstream_throughput_kbps;
+ DCHECK_LE(INVALID_RTT_THROUGHPUT, downstream_throughput_kbps_);
}
private:
+ // Verifies that the value of network quality is within the expected range.
+ void VerifyValueCorrectness() const;
+
// Estimated round trip time at the HTTP layer.
base::TimeDelta http_rtt_;
@@ -83,6 +102,8 @@ class NET_EXPORT_PRIVATE NetworkQuality {
// Estimated downstream throughput in kilobits per second.
int32_t downstream_throughput_kbps_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace internal
diff --git a/chromium/net/nqe/network_quality_estimator.cc b/chromium/net/nqe/network_quality_estimator.cc
index 096398863a5..ff218942cf1 100644
--- a/chromium/net/nqe/network_quality_estimator.cc
+++ b/chromium/net/nqe/network_quality_estimator.cc
@@ -14,9 +14,8 @@
#include "base/logging.h"
#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/sparse_histogram.h"
-#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -52,22 +51,6 @@ class HostResolver;
namespace {
-// Returns the histogram that should be used to record the given statistic.
-// |max_limit| is the maximum value that can be stored in the histogram.
-base::HistogramBase* GetHistogram(const std::string& statistic_name,
- NetworkChangeNotifier::ConnectionType type,
- int32_t max_limit) {
- const base::LinearHistogram::Sample kLowerLimit = 1;
- DCHECK_GT(max_limit, kLowerLimit);
- const size_t kBucketCount = 50;
-
- return base::Histogram::FactoryGet(
- "NQE." + statistic_name +
- NetworkQualityEstimatorParams::GetNameForConnectionType(type),
- kLowerLimit, max_limit, kBucketCount,
- base::HistogramBase::kUmaTargetedHistogramFlag);
-}
-
NetworkQualityObservationSource ProtocolSourceToObservationSource(
SocketPerformanceWatcherFactory::Protocol protocol) {
switch (protocol) {
@@ -124,40 +107,6 @@ const char* GetHistogramSuffixObservedThroughput(
return kSuffixes[arraysize(kSuffixes) - 1];
}
-// The least significant kTrimBits of the metric will be discarded. If the
-// trimmed metric value is greater than what can be fit in kBitsPerMetric bits,
-// then the largest value that can be represented in kBitsPerMetric bits is
-// returned.
-const int32_t kTrimBits = 5;
-
-// Maximum number of bits in which one metric should fit. Restricting the amount
-// of space allocated to a single metric makes it possile to fit multiple
-// metrics in a single histogram sample, and ensures that all those metrics
-// are recorded together as a single tuple.
-const int32_t kBitsPerMetric = 7;
-
-static_assert(32 >= kBitsPerMetric * 4,
- "Four metrics would not fit in a 32-bit int");
-
-// Trims the |metric| by removing the last kTrimBits, and then rounding down
-// the |metric| such that the |metric| fits in kBitsPerMetric.
-int32_t FitInKBitsPerMetricBits(int32_t metric) {
- // Remove the last kTrimBits. This will allow the metric to fit within
- // kBitsPerMetric while losing only the least significant bits.
- DCHECK_LE(0, metric);
- metric = metric >> kTrimBits;
-
- // kLargestValuePossible is the largest value that can be recorded using
- // kBitsPerMetric.
- static const int32_t kLargestValuePossible = (1 << kBitsPerMetric) - 1;
- if (metric > kLargestValuePossible) {
- // Fit |metric| in kBitsPerMetric by clamping it down.
- metric = kLargestValuePossible;
- }
- DCHECK_EQ(0, metric >> kBitsPerMetric) << metric;
- return metric;
-}
-
void RecordRTTAccuracy(base::StringPiece prefix,
int32_t metric,
base::TimeDelta measuring_duration,
@@ -218,24 +167,25 @@ NetworkQualityEstimator::NetworkQualityEstimator(
: params_(std::move(params)),
use_localhost_requests_(false),
disable_offline_check_(false),
- tick_clock_(new base::DefaultTickClock()),
+ tick_clock_(base::DefaultTickClock::GetInstance()),
last_connection_change_(tick_clock_->NowTicks()),
current_network_id_(nqe::internal::NetworkID(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN,
- std::string())),
+ std::string(),
+ INT32_MIN)),
http_downstream_throughput_kbps_observations_(
params_.get(),
- tick_clock_.get(),
+ tick_clock_,
params_->weight_multiplier_per_second(),
params_->weight_multiplier_per_signal_strength_level()),
http_rtt_ms_observations_(
params_.get(),
- tick_clock_.get(),
+ tick_clock_,
params_->weight_multiplier_per_second(),
params_->weight_multiplier_per_signal_strength_level()),
transport_rtt_ms_observations_(
params_.get(),
- tick_clock_.get(),
+ tick_clock_,
params_->weight_multiplier_per_second(),
params_->weight_multiplier_per_signal_strength_level()),
effective_connection_type_at_last_main_frame_(
@@ -271,7 +221,7 @@ NetworkQualityEstimator::NetworkQualityEstimator(
this, params_.get(), base::ThreadTaskRunnerHandle::Get(),
base::Bind(&NetworkQualityEstimator::OnNewThroughputObservationAvailable,
base::Unretained(this)),
- tick_clock_.get(), net_log_));
+ tick_clock_, net_log_));
watcher_factory_.reset(new nqe::internal::SocketWatcherFactory(
base::ThreadTaskRunnerHandle::Get(),
@@ -280,7 +230,7 @@ NetworkQualityEstimator::NetworkQualityEstimator(
base::Unretained(this)),
base::Bind(&NetworkQualityEstimator::ShouldSocketWatcherNotifyRTT,
base::Unretained(this)),
- tick_clock_.get()));
+ tick_clock_));
// Record accuracy after a 15 second interval. The values used here must
// remain in sync with the suffixes specified in
@@ -378,6 +328,45 @@ void NetworkQualityEstimator::NotifyStartTransaction(
throughput_analyzer_->NotifyStartTransaction(request);
}
+bool NetworkQualityEstimator::IsHangingRequest(
+ base::TimeDelta observed_http_rtt) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (transport_rtt_observation_count_last_ect_computation_ >=
+ params_->http_rtt_transport_rtt_min_count() &&
+ (params_->hanging_request_http_rtt_upper_bound_transport_rtt_multiplier() <=
+ 0 ||
+ observed_http_rtt <
+ params_->hanging_request_http_rtt_upper_bound_transport_rtt_multiplier() *
+ GetTransportRTT().value_or(base::TimeDelta::FromSeconds(10)))) {
+ // If there are sufficient number of transport RTT samples available, use
+ // the transport RTT estimate to determine if the request is hanging.
+ UMA_HISTOGRAM_TIMES("NQE.RTT.NotAHangingRequest.TransportRTT",
+ observed_http_rtt);
+ return false;
+ }
+
+ if (params_->hanging_request_http_rtt_upper_bound_http_rtt_multiplier() <=
+ 0 ||
+ observed_http_rtt <
+ params_->hanging_request_http_rtt_upper_bound_http_rtt_multiplier() *
+ GetHttpRTT().value_or(base::TimeDelta::FromSeconds(10))) {
+ // Use the HTTP RTT estimate to determine if the request is hanging.
+ UMA_HISTOGRAM_TIMES("NQE.RTT.NotAHangingRequest.HttpRTT",
+ observed_http_rtt);
+ return false;
+ }
+
+ if (observed_http_rtt <=
+ params_->hanging_request_upper_bound_min_http_rtt()) {
+ UMA_HISTOGRAM_TIMES("NQE.RTT.NotAHangingRequest.MinHttpBound",
+ observed_http_rtt);
+ return false;
+ }
+ UMA_HISTOGRAM_TIMES("NQE.RTT.HangingRequest", observed_http_rtt);
+ return true;
+}
+
void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) {
TRACE_EVENT0(kNetTracingCategory,
"NetworkQualityEstimator::NotifyHeadersReceived");
@@ -412,8 +401,13 @@ void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) {
if (observed_http_rtt <= base::TimeDelta())
return;
DCHECK_GE(observed_http_rtt, base::TimeDelta());
+
+ if (IsHangingRequest(observed_http_rtt))
+ return;
+
Observation http_rtt_observation(observed_http_rtt.InMilliseconds(),
- tick_clock_->NowTicks(), signal_strength_,
+ tick_clock_->NowTicks(),
+ current_network_id_.signal_strength,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP);
AddAndNotifyObserversOfRTT(http_rtt_observation);
throughput_analyzer_->NotifyBytesRead(request);
@@ -532,107 +526,6 @@ void NetworkQualityEstimator::NotifyRequestCompleted(const URLRequest& request,
return;
throughput_analyzer_->NotifyRequestCompleted(request);
- RecordCorrelationMetric(request, net_error);
-}
-
-void NetworkQualityEstimator::RecordCorrelationMetric(const URLRequest& request,
- int net_error) const {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // The histogram is recorded randomly to reduce overhead involved with sparse
- // histograms. Furthermore, recording the correlation on each request is
- // unnecessary.
- if (RandDouble() >= params_->correlation_uma_logging_probability())
- return;
-
- if (request.response_info().was_cached ||
- !request.response_info().network_accessed) {
- return;
- }
-
- LoadTimingInfo load_timing_info;
- request.GetLoadTimingInfo(&load_timing_info);
- // If the load timing info is unavailable, it probably means that the request
- // did not go over the network.
- if (load_timing_info.send_start.is_null() ||
- load_timing_info.receive_headers_end.is_null()) {
- return;
- }
-
- // Record UMA only for successful requests that have completed.
- if (net_error != OK)
- return;
- if (!request.response_info().headers.get() ||
- request.response_info().headers->response_code() != HTTP_OK) {
- return;
- }
- if (load_timing_info.receive_headers_end < last_main_frame_request_)
- return;
-
- // Use the system clock instead of |tick_clock_| to compare the current
- // timestamp with the |load_timing_info| timestamp since the latter is set by
- // the system clock, and may be different from |tick_clock_| in tests.
- const base::TimeTicks now = base::TimeTicks::Now();
- // Record UMA only for requests that started recently.
- if (now - last_main_frame_request_ > base::TimeDelta::FromSeconds(15))
- return;
-
- if (last_connection_change_ >= last_main_frame_request_)
- return;
-
- DCHECK_GE(now, load_timing_info.send_start);
-
- int32_t rtt = 0;
-
- if (estimated_quality_at_last_main_frame_.downstream_throughput_kbps() ==
- nqe::internal::INVALID_RTT_THROUGHPUT) {
- return;
- }
-
- if (UseTransportRTT()) {
- if (estimated_quality_at_last_main_frame_.transport_rtt() ==
- nqe::internal::InvalidRTT()) {
- return;
- }
- rtt = FitInKBitsPerMetricBits(
- estimated_quality_at_last_main_frame_.transport_rtt().InMilliseconds());
- } else {
- if (estimated_quality_at_last_main_frame_.http_rtt() ==
- nqe::internal::InvalidRTT()) {
- return;
- }
- rtt = FitInKBitsPerMetricBits(
- estimated_quality_at_last_main_frame_.http_rtt().InMilliseconds());
- }
-
- const int32_t downstream_throughput = FitInKBitsPerMetricBits(
- estimated_quality_at_last_main_frame_.downstream_throughput_kbps());
-
- const int32_t resource_load_time = FitInKBitsPerMetricBits(
- (now - load_timing_info.send_start).InMilliseconds());
-
- int64_t resource_size = (request.GetTotalReceivedBytes() * 8) / 1024;
- if (resource_size >= (1 << kBitsPerMetric)) {
- // Too large resource size (at least 128 Kb).
- return;
- }
-
- DCHECK_EQ(
- 0, (rtt | downstream_throughput | resource_load_time | resource_size) >>
- kBitsPerMetric);
-
- // First 32 - (4* kBitsPerMetric) of the sample are unset. Next
- // kBitsPerMetric of the sample contain |rtt|. Next
- // kBitsPerMetric contain |downstream_throughput|. Next kBitsPerMetric
- // contain |resource_load_time|. And, the last kBitsPerMetric
- // contain |resource_size|.
- int32_t sample = rtt;
- sample = (sample << kBitsPerMetric) | downstream_throughput;
- sample = (sample << kBitsPerMetric) | resource_load_time;
- sample = (sample << kBitsPerMetric) | resource_size;
-
- UMA_HISTOGRAM_SPARSE_SLOWLY("NQE.Correlation.ResourceLoadTime.0Kb_128Kb",
- sample);
}
void NetworkQualityEstimator::NotifyURLRequestDestroyed(
@@ -693,7 +586,6 @@ void NetworkQualityEstimator::DisableOfflineCheckForTesting(
bool disable_offline_check) {
DCHECK(thread_checker_.CalledOnValidThread());
disable_offline_check_ = disable_offline_check;
- network_quality_store_->DisableOfflineCheckForTesting(disable_offline_check_);
}
void NetworkQualityEstimator::ReportEffectiveConnectionTypeForTesting(
@@ -751,8 +643,6 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
NetworkChangeNotifier::ConnectionType type) {
DCHECK(thread_checker_.CalledOnValidThread());
- RecordMetricsOnConnectionTypeChanged();
-
// Write the estimates of the previous network to the cache.
network_quality_store_->Add(
current_network_id_, nqe::internal::CachedNetworkQuality(
@@ -785,7 +675,7 @@ void NetworkQualityEstimator::OnConnectionTypeChanged(
}
}
#endif // OS_ANDROID
- signal_strength_.reset();
+ current_network_id_.signal_strength = INT32_MIN;
min_signal_strength_since_connection_change_.reset();
max_signal_strength_since_connection_change_.reset();
network_quality_ = nqe::internal::NetworkQuality();
@@ -811,12 +701,15 @@ void NetworkQualityEstimator::GatherEstimatesForNextConnectionType() {
current_network_id_ = GetCurrentNetworkID();
RecordNetworkIDAvailability();
- MaybeQueryExternalEstimateProvider();
-
// Read any cached estimates for the new network. If cached estimates are
// unavailable, add the default estimates.
if (!ReadCachedNetworkQualityEstimate())
AddDefaultEstimates();
+
+ // Query external estimate later since cached estimate has a higher priority,
+ // and if a cached estimate was available, there is no need to query the
+ // external estimate provider.
+ MaybeQueryExternalEstimateProvider();
ComputeEffectiveConnectionType();
}
@@ -841,74 +734,52 @@ void NetworkQualityEstimator::MaybeQueryExternalEstimateProvider() const {
external_estimate_provider_->Update();
}
-void NetworkQualityEstimator::UpdateSignalStrength() {
+int32_t NetworkQualityEstimator::GetCurrentSignalStrength() const {
DCHECK(thread_checker_.CalledOnValidThread());
- signal_strength_.reset();
#if defined(OS_ANDROID)
if (params_->weight_multiplier_per_signal_strength_level() >= 1.0)
- return;
+ return INT32_MIN;
if (!NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type))
- return;
+ return INT32_MIN;
+ return android::cellular_signal_strength::GetSignalStrengthLevel().value_or(
+ INT32_MIN);
+#endif // OS_ANDROID
+
+ return INT32_MIN;
+}
+
+void NetworkQualityEstimator::UpdateSignalStrength() {
+ DCHECK(thread_checker_.CalledOnValidThread());
- signal_strength_ =
- android::cellular_signal_strength::GetSignalStrengthLevel();
+ int32_t past_signal_strength = current_network_id_.signal_strength;
+ int32_t new_signal_strength = GetCurrentSignalStrength();
- if (!signal_strength_)
+ // Check if there is no change in the signal strength.
+ if (past_signal_strength == new_signal_strength)
return;
+ // Check if the signal strength is unavailable.
+ if (new_signal_strength == INT32_MIN)
+ return;
+
+ // Record the network quality we experienced for the previous signal strength
+ // (for when we return to that signal strength).
+ network_quality_store_->Add(current_network_id_,
+ nqe::internal::CachedNetworkQuality(
+ tick_clock_->NowTicks(), network_quality_,
+ effective_connection_type_));
+
+ current_network_id_.signal_strength = new_signal_strength;
+ // Update network quality from cached value for new signal strength.
+ ReadCachedNetworkQualityEstimate();
+
min_signal_strength_since_connection_change_ =
std::min(min_signal_strength_since_connection_change_.value_or(INT32_MAX),
- signal_strength_.value());
+ current_network_id_.signal_strength);
max_signal_strength_since_connection_change_ =
std::max(max_signal_strength_since_connection_change_.value_or(INT32_MIN),
- signal_strength_.value());
-#endif // OS_ANDROID
-}
-
-void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- base::TimeDelta rtt;
- if (GetRecentHttpRTT(base::TimeTicks(), &rtt)) {
- // Add the 50th percentile value.
- base::HistogramBase* rtt_percentile =
- GetHistogram("RTT.Percentile50.", current_network_id_.type, 10 * 1000);
- rtt_percentile->Add(rtt.InMilliseconds());
-
- // Add the remaining percentile values.
- static const int kPercentiles[] = {0, 10, 90, 100};
- for (size_t i = 0; i < arraysize(kPercentiles); ++i) {
- rtt = GetRTTEstimateInternal(
- base::TimeTicks(), base::Optional<Statistic>(),
- nqe::internal::ObservationCategory::kHttp, kPercentiles[i], nullptr);
-
- rtt_percentile = GetHistogram(
- "RTT.Percentile" + base::IntToString(kPercentiles[i]) + ".",
- current_network_id_.type, 10 * 1000); // 10 seconds
- rtt_percentile->Add(rtt.InMilliseconds());
- }
- }
-
- if (GetRecentTransportRTT(base::TimeTicks(), &rtt, nullptr)) {
- // Add the 50th percentile value.
- base::HistogramBase* transport_rtt_percentile = GetHistogram(
- "TransportRTT.Percentile50.", current_network_id_.type, 10 * 1000);
- transport_rtt_percentile->Add(rtt.InMilliseconds());
-
- // Add the remaining percentile values.
- static const int kPercentiles[] = {0, 10, 90, 100};
- for (size_t i = 0; i < arraysize(kPercentiles); ++i) {
- rtt =
- GetRTTEstimateInternal(base::TimeTicks(), base::Optional<Statistic>(),
- nqe::internal::ObservationCategory::kTransport,
- kPercentiles[i], nullptr);
-
- transport_rtt_percentile = GetHistogram(
- "TransportRTT.Percentile" + base::IntToString(kPercentiles[i]) + ".",
- current_network_id_.type, 10 * 1000); // 10 seconds
- transport_rtt_percentile->Add(rtt.InMilliseconds());
- }
- }
+ current_network_id_.signal_strength);
}
void NetworkQualityEstimator::RecordNetworkIDAvailability() const {
@@ -1264,22 +1135,16 @@ NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics(
*transport_rtt = nqe::internal::InvalidRTT();
*downstream_throughput_kbps = nqe::internal::INVALID_RTT_THROUGHPUT;
- if (params_->forced_effective_connection_type()) {
- *http_rtt = params_
- ->TypicalNetworkQuality(
- params_->forced_effective_connection_type().value())
- .http_rtt();
+ auto forced_ect =
+ params_->GetForcedEffectiveConnectionType(current_network_id_.type);
+ if (forced_ect) {
+ *http_rtt = params_->TypicalNetworkQuality(forced_ect.value()).http_rtt();
*transport_rtt =
- params_
- ->TypicalNetworkQuality(
- params_->forced_effective_connection_type().value())
- .transport_rtt();
+ params_->TypicalNetworkQuality(forced_ect.value()).transport_rtt();
*downstream_throughput_kbps =
- params_
- ->TypicalNetworkQuality(
- params_->forced_effective_connection_type().value())
+ params_->TypicalNetworkQuality(forced_ect.value())
.downstream_throughput_kbps();
- return params_->forced_effective_connection_type().value();
+ return forced_ect.value();
}
// If the device is currently offline, then return
@@ -1301,7 +1166,8 @@ NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics(
*transport_rtt != nqe::internal::InvalidRTT()) {
// Use transport RTT to clamp the HTTP RTT between lower and upper bounds.
// To improve accuracy, the transport RTT estimate is used only when the
- // transport RTT estimate was computed using at least 5 observations.
+ // transport RTT estimate was computed using at least
+ // |params_->http_rtt_transport_rtt_min_count()| observations.
if (transport_rtt_observation_count_last_ect_computation_ >=
params_->http_rtt_transport_rtt_min_count()) {
if (params_->lower_bound_http_rtt_transport_rtt_multiplier() > 0) {
@@ -1475,14 +1341,14 @@ base::TimeDelta NetworkQualityEstimator::GetRTTEstimateInternal(
case nqe::internal::ObservationCategory::kHttp:
return base::TimeDelta::FromMilliseconds(
http_rtt_ms_observations_
- .GetPercentile(start_time, signal_strength_, percentile,
- observations_count)
+ .GetPercentile(start_time, current_network_id_.signal_strength,
+ percentile, observations_count)
.value_or(nqe::internal::INVALID_RTT_THROUGHPUT));
case nqe::internal::ObservationCategory::kTransport:
return base::TimeDelta::FromMilliseconds(
transport_rtt_ms_observations_
- .GetPercentile(start_time, signal_strength_, percentile,
- observations_count)
+ .GetPercentile(start_time, current_network_id_.signal_strength,
+ percentile, observations_count)
.value_or(nqe::internal::INVALID_RTT_THROUGHPUT));
}
}
@@ -1506,7 +1372,8 @@ int32_t NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimateInternal(
// Throughput observations are sorted by kbps from slowest to fastest,
// thus a higher percentile throughput will be faster than a lower one.
return http_downstream_throughput_kbps_observations_
- .GetPercentile(start_time, signal_strength_, 100 - percentile, nullptr)
+ .GetPercentile(start_time, current_network_id_.signal_strength,
+ 100 - percentile, nullptr)
.value_or(nqe::internal::INVALID_RTT_THROUGHPUT);
}
@@ -1524,7 +1391,7 @@ nqe::internal::NetworkID NetworkQualityEstimator::GetCurrentNetworkID() const {
// (that are approximate to begin with).
while (true) {
nqe::internal::NetworkID network_id(
- NetworkChangeNotifier::GetConnectionType(), std::string());
+ NetworkChangeNotifier::GetConnectionType(), std::string(), INT32_MIN);
switch (network_id.type) {
case NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN:
@@ -1561,56 +1428,79 @@ bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() {
if (!params_->persistent_cache_reading_enabled())
return false;
- if (current_network_id_.type !=
- NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI &&
- current_network_id_.type !=
- NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET &&
- !disable_offline_check_) {
- return false;
- }
-
nqe::internal::CachedNetworkQuality cached_network_quality;
const bool cached_estimate_available = network_quality_store_->GetById(
current_network_id_, &cached_network_quality);
- if (network_quality_store_->EligibleForCaching(current_network_id_)) {
- UMA_HISTOGRAM_BOOLEAN("NQE.CachedNetworkQualityAvailable",
- cached_estimate_available);
- }
+ UMA_HISTOGRAM_BOOLEAN("NQE.CachedNetworkQualityAvailable",
+ cached_estimate_available);
if (!cached_estimate_available)
return false;
+ EffectiveConnectionType effective_connection_type =
+ cached_network_quality.effective_connection_type();
+
+ if (effective_connection_type == EFFECTIVE_CONNECTION_TYPE_UNKNOWN ||
+ effective_connection_type == EFFECTIVE_CONNECTION_TYPE_OFFLINE ||
+ effective_connection_type == EFFECTIVE_CONNECTION_TYPE_LAST) {
+ return false;
+ }
+
+ nqe::internal::NetworkQuality network_quality =
+ cached_network_quality.network_quality();
+
const base::TimeTicks now = tick_clock_->NowTicks();
- if (cached_network_quality.network_quality().downstream_throughput_kbps() !=
+ bool update_network_quality_store = false;
+
+ // Populate |network_quality| with synthetic RTT and throughput observations
+ // if they are missing.
+ if (network_quality.http_rtt().InMilliseconds() ==
nqe::internal::INVALID_RTT_THROUGHPUT) {
- Observation througphput_observation(
- cached_network_quality.network_quality().downstream_throughput_kbps(),
- now, INT32_MIN,
- NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE);
- AddAndNotifyObserversOfThroughput(througphput_observation);
+ network_quality.set_http_rtt(
+ params_->TypicalNetworkQuality(effective_connection_type).http_rtt());
+ update_network_quality_store = true;
}
- if (cached_network_quality.network_quality().http_rtt() !=
- nqe::internal::InvalidRTT()) {
- Observation rtt_observation(
- cached_network_quality.network_quality().http_rtt().InMilliseconds(),
- now, INT32_MIN,
- NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE);
- AddAndNotifyObserversOfRTT(rtt_observation);
+ if (network_quality.transport_rtt().InMilliseconds() ==
+ nqe::internal::INVALID_RTT_THROUGHPUT) {
+ network_quality.set_transport_rtt(
+ params_->TypicalNetworkQuality(effective_connection_type)
+ .transport_rtt());
+ update_network_quality_store = true;
}
- if (cached_network_quality.network_quality().transport_rtt() !=
- nqe::internal::InvalidRTT()) {
- Observation rtt_observation(
- cached_network_quality.network_quality()
- .transport_rtt()
- .InMilliseconds(),
- now, INT32_MIN,
- NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE);
- AddAndNotifyObserversOfRTT(rtt_observation);
+ if (network_quality.downstream_throughput_kbps() ==
+ nqe::internal::INVALID_RTT_THROUGHPUT) {
+ network_quality.set_downstream_throughput_kbps(
+ params_->TypicalNetworkQuality(effective_connection_type)
+ .downstream_throughput_kbps());
+ update_network_quality_store = true;
+ }
+
+ if (update_network_quality_store) {
+ network_quality_store_->Add(
+ current_network_id_,
+ nqe::internal::CachedNetworkQuality(now, network_quality,
+ effective_connection_type));
}
+
+ Observation http_rtt_observation(
+ network_quality.http_rtt().InMilliseconds(), now, INT32_MIN,
+ NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE);
+ AddAndNotifyObserversOfRTT(http_rtt_observation);
+
+ Observation transport_rtt_observation(
+ network_quality.transport_rtt().InMilliseconds(), now, INT32_MIN,
+ NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE);
+ AddAndNotifyObserversOfRTT(transport_rtt_observation);
+
+ Observation througphput_observation(
+ network_quality.downstream_throughput_kbps(), now, INT32_MIN,
+ NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE);
+ AddAndNotifyObserversOfThroughput(througphput_observation);
+
ComputeEffectiveConnectionType();
return true;
}
@@ -1631,7 +1521,8 @@ void NetworkQualityEstimator::OnUpdatedEstimateAvailable(
EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE);
UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt);
Observation rtt_observation(
- rtt.InMilliseconds(), tick_clock_->NowTicks(), signal_strength_,
+ rtt.InMilliseconds(), tick_clock_->NowTicks(),
+ current_network_id_.signal_strength,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE);
external_estimate_provider_quality_.set_http_rtt(rtt);
AddAndNotifyObserversOfRTT(rtt_observation);
@@ -1643,7 +1534,8 @@ void NetworkQualityEstimator::OnUpdatedEstimateAvailable(
UMA_HISTOGRAM_COUNTS_1M("NQE.ExternalEstimateProvider.DownlinkBandwidth",
downstream_throughput_kbps);
Observation throughput_observation(
- downstream_throughput_kbps, tick_clock_->NowTicks(), signal_strength_,
+ downstream_throughput_kbps, tick_clock_->NowTicks(),
+ current_network_id_.signal_strength,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE);
external_estimate_provider_quality_.set_downstream_throughput_kbps(
downstream_throughput_kbps);
@@ -1652,19 +1544,15 @@ void NetworkQualityEstimator::OnUpdatedEstimateAvailable(
}
void NetworkQualityEstimator::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
+ base::TickClock* tick_clock) {
DCHECK(thread_checker_.CalledOnValidThread());
- tick_clock_ = std::move(tick_clock);
- http_rtt_ms_observations_.SetTickClockForTesting(tick_clock_.get());
- transport_rtt_ms_observations_.SetTickClockForTesting(tick_clock_.get());
+ tick_clock_ = tick_clock;
+ http_rtt_ms_observations_.SetTickClockForTesting(tick_clock_);
+ transport_rtt_ms_observations_.SetTickClockForTesting(tick_clock_);
http_downstream_throughput_kbps_observations_.SetTickClockForTesting(
- tick_clock_.get());
- throughput_analyzer_->SetTickClockForTesting(tick_clock_.get());
- watcher_factory_->SetTickClockForTesting(tick_clock_.get());
-}
-
-double NetworkQualityEstimator::RandDouble() const {
- return base::RandDouble();
+ tick_clock_);
+ throughput_analyzer_->SetTickClockForTesting(tick_clock_);
+ watcher_factory_->SetTickClockForTesting(tick_clock_);
}
void NetworkQualityEstimator::OnUpdatedTransportRTTAvailable(
@@ -1672,10 +1560,10 @@ void NetworkQualityEstimator::OnUpdatedTransportRTTAvailable(
const base::TimeDelta& rtt,
const base::Optional<nqe::internal::IPHash>& host) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK_NE(nqe::internal::InvalidRTT(), rtt);
+ DCHECK_LT(nqe::internal::INVALID_RTT_THROUGHPUT, rtt.InMilliseconds());
Observation observation(rtt.InMilliseconds(), tick_clock_->NowTicks(),
- signal_strength_,
+ current_network_id_.signal_strength,
ProtocolSourceToObservationSource(protocol), host);
AddAndNotifyObserversOfRTT(observation);
@@ -1778,7 +1666,7 @@ void NetworkQualityEstimator::OnNewThroughputObservationAvailable(
DCHECK_NE(nqe::internal::INVALID_RTT_THROUGHPUT, downstream_kbps);
Observation throughput_observation(downstream_kbps, tick_clock_->NowTicks(),
- signal_strength_,
+ current_network_id_.signal_strength,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP);
AddAndNotifyObserversOfThroughput(throughput_observation);
}
diff --git a/chromium/net/nqe/network_quality_estimator.h b/chromium/net/nqe/network_quality_estimator.h
index c00e1638ea2..343f735479b 100644
--- a/chromium/net/nqe/network_quality_estimator.h
+++ b/chromium/net/nqe/network_quality_estimator.h
@@ -214,6 +214,8 @@ class NET_EXPORT NetworkQualityEstimator
const std::map<nqe::internal::NetworkID,
nqe::internal::CachedNetworkQuality> read_prefs);
+ const NetworkQualityEstimatorParams* params() { return params_.get(); }
+
typedef nqe::internal::Observation Observation;
typedef nqe::internal::ObservationBuffer ObservationBuffer;
@@ -272,10 +274,7 @@ class NET_EXPORT NetworkQualityEstimator
const;
// Overrides the tick clock used by |this| for testing.
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
-
- // Returns a random double in the range [0.0, 1.0). Virtualized for testing.
- virtual double RandDouble() const;
+ void SetTickClockForTesting(base::TickClock* tick_clock);
// Returns the effective type of the current connection based on only the
// observations received after |start_time|. |http_rtt|, |transport_rtt| and
@@ -342,10 +341,28 @@ class NET_EXPORT NetworkQualityEstimator
// effective connection type.
void AddAndNotifyObserversOfThroughput(const Observation& observation);
+ // Returns true if the request with observed HTTP of |observed_http_rtt| is
+ // expected to be a hanging request. The decision is made by comparing
+ // |observed_http_rtt| with the expected HTTP and transport RTT.
+ bool IsHangingRequest(base::TimeDelta observed_http_rtt) const;
+
base::Optional<int32_t> ComputeIncreaseInTransportRTTForTests() {
return ComputeIncreaseInTransportRTT();
}
+ // Returns the current network signal strength by querying the platform APIs.
+ // Set to INT32_MIN when the value is unavailable. Otherwise, must be between
+ // 0 and 4 (both inclusive). This may take into account many different radio
+ // technology inputs. 0 represents very poor signal strength while 4
+ // represents a very strong signal strength. The range is capped between 0 and
+ // 4 to ensure that a change in the value indicates a non-negligible change in
+ // the signal quality.
+ virtual int32_t GetCurrentSignalStrength() const;
+
+ // Forces computation of effective connection type, and notifies observers
+ // if there is a change in its value.
+ void ComputeEffectiveConnectionType();
+
// Observer list for RTT or throughput estimates. Protected for testing.
base::ObserverList<RTTAndThroughputEstimatesObserver>
rtt_and_throughput_estimates_observer_list_;
@@ -408,9 +425,6 @@ class NET_EXPORT NetworkQualityEstimator
// quality is available, OnUpdatedEstimateAvailable() is called.
void MaybeQueryExternalEstimateProvider() const;
- // Records UMA when there is a change in connection type.
- void RecordMetricsOnConnectionTypeChanged() const;
-
// Records UMA on whether the NetworkID was available or not. Called right
// after a network change event.
void RecordNetworkIDAvailability() const;
@@ -500,11 +514,6 @@ class NET_EXPORT NetworkQualityEstimator
// Returns true if the cached network quality estimate was successfully read.
bool ReadCachedNetworkQualityEstimate();
- // Records a correlation metric that can be used for computing the correlation
- // between HTTP-layer RTT, transport-layer RTT, throughput and the time
- // taken to complete |request|.
- void RecordCorrelationMetric(const URLRequest& request, int net_error) const;
-
// Returns true if transport RTT should be used for computing the effective
// connection type.
bool UseTransportRTT() const;
@@ -525,10 +534,6 @@ class NET_EXPORT NetworkQualityEstimator
// Periodically updates |increase_in_transport_rtt_| by posting delayed tasks.
void IncreaseInTransportRTTUpdater();
- // Forces computation of effective connection type, and notifies observers
- // if there is a change in its value.
- void ComputeEffectiveConnectionType();
-
const char* GetNameForStatistic(int i) const;
// Gathers metrics for the next connection type. Called when there is a change
@@ -558,7 +563,7 @@ class NET_EXPORT NetworkQualityEstimator
bool disable_offline_check_;
// Tick clock used by the network quality estimator.
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
// Intervals after the main frame request arrives at which accuracy of network
// quality prediction is recorded.
@@ -651,11 +656,6 @@ class NET_EXPORT NetworkQualityEstimator
// |effective_connection_type_recomputation_interval_| ago).
EffectiveConnectionType effective_connection_type_;
- // Last known value of the wireless signal strength level. If the signal
- // strength level is available, the value is set to between 0 and 4, both
- // inclusive. If the value is unavailable, |signal_strength_| has null value.
- base::Optional<int32_t> signal_strength_;
-
// Minimum and maximum signal strength level observed since last connection
// change. Updated on connection change and main frame requests.
base::Optional<int32_t> min_signal_strength_since_connection_change_;
diff --git a/chromium/net/nqe/network_quality_estimator_params.cc b/chromium/net/nqe/network_quality_estimator_params.cc
index c393f54dd5a..28a9aaa9fb2 100644
--- a/chromium/net/nqe/network_quality_estimator_params.cc
+++ b/chromium/net/nqe/network_quality_estimator_params.cc
@@ -12,6 +12,15 @@
namespace net {
const char kForceEffectiveConnectionType[] = "force_effective_connection_type";
+const char kEffectiveConnectionTypeSlow2GOnCellular[] = "Slow-2G-On-Cellular";
+const base::TimeDelta
+ kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_LAST] =
+ {base::TimeDelta::FromMilliseconds(0),
+ base::TimeDelta::FromMilliseconds(0),
+ base::TimeDelta::FromMilliseconds(2010),
+ base::TimeDelta::FromMilliseconds(1420),
+ base::TimeDelta::FromMilliseconds(272),
+ base::TimeDelta::FromMilliseconds(0)};
namespace {
@@ -164,7 +173,7 @@ void ObtainDefaultObservations(
74);
default_observations[NetworkChangeNotifier::CONNECTION_3G] =
- nqe::internal::NetworkQuality(base::TimeDelta::FromMilliseconds(272),
+ nqe::internal::NetworkQuality(base::TimeDelta::FromMilliseconds(273),
base::TimeDelta::FromMilliseconds(209),
749);
@@ -287,24 +296,35 @@ void ObtainConnectionThresholds(
nqe::internal::NetworkQuality default_effective_connection_type_thresholds
[EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_LAST];
+ DCHECK_LT(base::TimeDelta(), kHttpRttEffectiveConnectionTypeThresholds
+ [EFFECTIVE_CONNECTION_TYPE_SLOW_2G]);
default_effective_connection_type_thresholds
[EFFECTIVE_CONNECTION_TYPE_SLOW_2G] = nqe::internal::NetworkQuality(
// Set to the 66th percentile of 2G RTT observations on Android.
- base::TimeDelta::FromMilliseconds(2010),
+ kHttpRttEffectiveConnectionTypeThresholds
+ [EFFECTIVE_CONNECTION_TYPE_SLOW_2G],
base::TimeDelta::FromMilliseconds(1870),
nqe::internal::INVALID_RTT_THROUGHPUT);
+ DCHECK_LT(
+ base::TimeDelta(),
+ kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_2G]);
default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_2G] =
nqe::internal::NetworkQuality(
// Set to the 50th percentile of RTT observations on Android.
- base::TimeDelta::FromMilliseconds(1420),
+ kHttpRttEffectiveConnectionTypeThresholds
+ [EFFECTIVE_CONNECTION_TYPE_2G],
base::TimeDelta::FromMilliseconds(1280),
nqe::internal::INVALID_RTT_THROUGHPUT);
+ DCHECK_LT(
+ base::TimeDelta(),
+ kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_3G]);
default_effective_connection_type_thresholds[EFFECTIVE_CONNECTION_TYPE_3G] =
nqe::internal::NetworkQuality(
// Set to the 50th percentile of 3G RTT observations on Android.
- base::TimeDelta::FromMilliseconds(273),
+ kHttpRttEffectiveConnectionTypeThresholds
+ [EFFECTIVE_CONNECTION_TYPE_3G],
base::TimeDelta::FromMilliseconds(204),
nqe::internal::INVALID_RTT_THROUGHPUT);
@@ -354,10 +374,24 @@ void ObtainConnectionThresholds(
}
}
-base::Optional<EffectiveConnectionType> GetForcedEffectiveConnectionType(
+std::string GetForcedEffectiveConnectionTypeString(
const std::map<std::string, std::string>& params) {
- std::string forced_value = GetStringValueForVariationParamWithDefaultValue(
+ return GetStringValueForVariationParamWithDefaultValue(
params, kForceEffectiveConnectionType, "");
+}
+
+bool GetForcedEffectiveConnectionTypeOnCellularOnly(
+ const std::map<std::string, std::string>& params) {
+ return GetForcedEffectiveConnectionTypeString(params) ==
+ kEffectiveConnectionTypeSlow2GOnCellular;
+}
+
+base::Optional<EffectiveConnectionType> GetInitForcedEffectiveConnectionType(
+ const std::map<std::string, std::string>& params) {
+ if (GetForcedEffectiveConnectionTypeOnCellularOnly(params)) {
+ return base::nullopt;
+ }
+ std::string forced_value = GetForcedEffectiveConnectionTypeString(params);
base::Optional<EffectiveConnectionType> ect =
GetEffectiveConnectionTypeForName(forced_value);
DCHECK(forced_value.empty() || ect);
@@ -377,19 +411,21 @@ NetworkQualityEstimatorParams::NetworkQualityEstimatorParams(
GetValueForVariationParam(params_,
"throughput_min_transfer_size_kilobytes",
32)),
+ throughput_hanging_requests_cwnd_size_multiplier_(
+ GetDoubleValueForVariationParamWithDefaultValue(
+ params_,
+ "throughput_hanging_requests_cwnd_size_multiplier",
+ -1)),
weight_multiplier_per_second_(GetWeightMultiplierPerSecond(params_)),
weight_multiplier_per_signal_strength_level_(
GetDoubleValueForVariationParamWithDefaultValue(
params_,
"rssi_weight_per_signal_strength_level",
1.0)),
- correlation_uma_logging_probability_(
- GetDoubleValueForVariationParamWithDefaultValue(
- params_,
- "correlation_logging_probability",
- 0.01)),
forced_effective_connection_type_(
- GetForcedEffectiveConnectionType(params_)),
+ GetInitForcedEffectiveConnectionType(params_)),
+ forced_effective_connection_type_on_cellular_only_(
+ GetForcedEffectiveConnectionTypeOnCellularOnly(params_)),
persistent_cache_reading_enabled_(
GetPersistentCacheReadingEnabled(params_)),
min_socket_watcher_notification_interval_(
@@ -398,12 +434,27 @@ NetworkQualityEstimatorParams::NetworkQualityEstimatorParams(
GetDoubleValueForVariationParamWithDefaultValue(
params_,
"lower_bound_http_rtt_transport_rtt_multiplier",
- -1)),
+ 1.0)),
upper_bound_http_rtt_transport_rtt_multiplier_(
GetDoubleValueForVariationParamWithDefaultValue(
params_,
"upper_bound_http_rtt_transport_rtt_multiplier",
-1)),
+ hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_(
+ GetValueForVariationParam(
+ params_,
+ "hanging_request_http_rtt_upper_bound_transport_rtt_multiplier",
+ -1)),
+ hanging_request_http_rtt_upper_bound_http_rtt_multiplier_(
+ GetValueForVariationParam(
+ params_,
+ "hanging_request_http_rtt_upper_bound_http_rtt_multiplier",
+ -1)),
+ hanging_request_upper_bound_min_http_rtt_(
+ base::TimeDelta::FromMilliseconds(GetValueForVariationParam(
+ params_,
+ "hanging_request_upper_bound_min_http_rtt_msec",
+ -1))),
http_rtt_transport_rtt_min_count_(
GetValueForVariationParam(params_,
"http_rtt_transport_rtt_min_count",
@@ -443,8 +494,6 @@ NetworkQualityEstimatorParams::NetworkQualityEstimatorParams(
"socket_watchers_min_notification_interval_msec",
200))),
use_small_responses_(false) {
- DCHECK_LE(0.0, correlation_uma_logging_probability_);
- DCHECK_GE(1.0, correlation_uma_logging_probability_);
DCHECK(lower_bound_http_rtt_transport_rtt_multiplier_ == -1 ||
lower_bound_http_rtt_transport_rtt_multiplier_ > 0);
DCHECK(upper_bound_http_rtt_transport_rtt_multiplier_ == -1 ||
@@ -454,6 +503,20 @@ NetworkQualityEstimatorParams::NetworkQualityEstimatorParams(
lower_bound_http_rtt_transport_rtt_multiplier_ <
upper_bound_http_rtt_transport_rtt_multiplier_);
+ DCHECK(hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 ||
+ hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ > 0);
+ DCHECK(hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ == -1 ||
+ hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ > 0);
+ DCHECK(hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 ||
+ hanging_request_http_rtt_upper_bound_http_rtt_multiplier_ == -1 ||
+ hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ >=
+ hanging_request_http_rtt_upper_bound_http_rtt_multiplier_);
+
+ DCHECK(upper_bound_http_rtt_transport_rtt_multiplier_ == -1 ||
+ hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_ == -1 ||
+ upper_bound_http_rtt_transport_rtt_multiplier_ <
+ hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_);
+
const auto algorithm_it = params_.find("effective_connection_type_algorithm");
effective_connection_type_algorithm_ =
GetEffectiveConnectionTypeAlgorithmFromString(
@@ -481,6 +544,21 @@ bool NetworkQualityEstimatorParams::use_small_responses() const {
return use_small_responses_;
};
+base::Optional<EffectiveConnectionType>
+NetworkQualityEstimatorParams::GetForcedEffectiveConnectionType(
+ NetworkChangeNotifier::ConnectionType connection_type) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (forced_effective_connection_type_) {
+ return forced_effective_connection_type_;
+ }
+
+ if (forced_effective_connection_type_on_cellular_only_ &&
+ net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) {
+ return EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
+ }
+ return base::nullopt;
+}
+
// static
NetworkQualityEstimatorParams::EffectiveConnectionTypeAlgorithm
NetworkQualityEstimatorParams::GetEffectiveConnectionTypeAlgorithmFromString(
@@ -529,12 +607,6 @@ int64_t NetworkQualityEstimatorParams::GetThroughputMinTransferSizeBits()
1000;
}
-// static
-const char* NetworkQualityEstimatorParams::GetNameForConnectionType(
- NetworkChangeNotifier::ConnectionType connection_type) {
- return GetNameForConnectionTypeInternal(connection_type);
-}
-
const nqe::internal::NetworkQuality&
NetworkQualityEstimatorParams::DefaultObservation(
NetworkChangeNotifier::ConnectionType type) const {
@@ -562,4 +634,23 @@ NetworkQualityEstimatorParams::GetEffectiveConnectionTypeAlgorithm() const {
return effective_connection_type_algorithm_;
}
+EffectiveConnectionType NetworkQualityEstimatorParams::GetDefaultECT(
+ NetworkChangeNotifier::ConnectionType connection_type) const {
+ switch (connection_type) {
+ case NetworkChangeNotifier::CONNECTION_UNKNOWN:
+ case NetworkChangeNotifier::CONNECTION_ETHERNET:
+ case NetworkChangeNotifier::CONNECTION_WIFI:
+ case NetworkChangeNotifier::CONNECTION_4G:
+ case NetworkChangeNotifier::CONNECTION_NONE:
+ case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+ return EFFECTIVE_CONNECTION_TYPE_4G;
+ case NetworkChangeNotifier::CONNECTION_2G:
+ return EFFECTIVE_CONNECTION_TYPE_2G;
+ case NetworkChangeNotifier::CONNECTION_3G:
+ return EFFECTIVE_CONNECTION_TYPE_3G;
+ }
+ NOTREACHED();
+ return EFFECTIVE_CONNECTION_TYPE_4G;
+}
+
} // namespace net
diff --git a/chromium/net/nqe/network_quality_estimator_params.h b/chromium/net/nqe/network_quality_estimator_params.h
index 3a1b079580c..14078cdce23 100644
--- a/chromium/net/nqe/network_quality_estimator_params.h
+++ b/chromium/net/nqe/network_quality_estimator_params.h
@@ -21,6 +21,11 @@ namespace net {
// Forces NQE to return a specific effective connection type. Set using the
// |params| provided to the NetworkQualityEstimatorParams constructor.
NET_EXPORT extern const char kForceEffectiveConnectionType[];
+NET_EXPORT extern const char kEffectiveConnectionTypeSlow2GOnCellular[];
+
+// HTTP RTT thresholds for different effective connection types.
+NET_EXPORT extern const base::TimeDelta
+ kHttpRttEffectiveConnectionTypeThresholds[EFFECTIVE_CONNECTION_TYPE_LAST];
// NetworkQualityEstimatorParams computes the configuration parameters for
// the network quality estimator.
@@ -46,10 +51,6 @@ class NET_EXPORT NetworkQualityEstimatorParams {
// a default value is used.
EffectiveConnectionTypeAlgorithm GetEffectiveConnectionTypeAlgorithm() const;
- // Returns a descriptive name corresponding to |connection_type|.
- static const char* GetNameForConnectionType(
- NetworkChangeNotifier::ConnectionType connection_type);
-
// Returns the default observation for connection |type|. The default
// observations are different for different connection types (e.g., 2G, 3G,
// 4G, WiFi). The default observations may be used to determine the network
@@ -87,20 +88,13 @@ class NET_EXPORT NetworkQualityEstimatorParams {
return weight_multiplier_per_signal_strength_level_;
}
- // Returns the fraction of URL requests that should record the correlation
- // UMA.
- double correlation_uma_logging_probability() const {
- return correlation_uma_logging_probability_;
- }
-
// Returns an unset value if the effective connection type has not been forced
// via the |params| provided to this class. Otherwise, returns a value set to
- // the effective connection type that has been forced.
- base::Optional<EffectiveConnectionType> forced_effective_connection_type()
- const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return forced_effective_connection_type_;
- }
+ // the effective connection type that has been forced. Forced ECT can be
+ // forced based on |connection_type| (e.g. Slow-2G on cellular, and default on
+ // other connection type).
+ base::Optional<EffectiveConnectionType> GetForcedEffectiveConnectionType(
+ NetworkChangeNotifier::ConnectionType connection_type);
void SetForcedEffectiveConnectionType(
EffectiveConnectionType forced_effective_connection_type) {
@@ -139,6 +133,14 @@ class NET_EXPORT NetworkQualityEstimatorParams {
effective_connection_type_algorithm_ = algorithm;
}
+ // Number of bytes received during a throughput observation window of duration
+ // 1 HTTP RTT should be at least the value returned by this method times
+ // the typical size of a congestion window. If not, the throughput observation
+ // window is heuristically determined as hanging.
+ double throughput_hanging_requests_cwnd_size_multiplier() const {
+ return throughput_hanging_requests_cwnd_size_multiplier_;
+ }
+
// Returns the multiplier by which the transport RTT should be multipled when
// computing the HTTP RTT. The multiplied value of the transport RTT serves
// as a lower bound to the HTTP RTT estimate. e.g., if the multiplied
@@ -157,6 +159,24 @@ class NET_EXPORT NetworkQualityEstimatorParams {
return upper_bound_http_rtt_transport_rtt_multiplier_;
}
+ // For the purpose of estimating the HTTP RTT, a request is marked as hanging
+ // only if its RTT is at least this times the transport RTT estimate.
+ int hanging_request_http_rtt_upper_bound_transport_rtt_multiplier() const {
+ return hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_;
+ }
+
+ // For the purpose of estimating the HTTP RTT, a request is marked as hanging
+ // only if its RTT is at least this times the HTTP RTT estimate.
+ int hanging_request_http_rtt_upper_bound_http_rtt_multiplier() const {
+ return hanging_request_http_rtt_upper_bound_http_rtt_multiplier_;
+ }
+
+ // For the purpose of estimating the HTTP RTT, a request is marked as hanging
+ // only if its RTT is at least as much the value returned by this method.
+ base::TimeDelta hanging_request_upper_bound_min_http_rtt() const {
+ return hanging_request_upper_bound_min_http_rtt_;
+ }
+
// Returns the number of transport RTT observations that should be available
// before the transport RTT estimate can be used to clamp the HTTP RTT
// estimate. Set to 5 by default which ensures that when the transport RTT
@@ -229,6 +249,10 @@ class NET_EXPORT NetworkQualityEstimatorParams {
return socket_watchers_min_notification_interval_;
}
+ // Returns the default effective connection type for a given connection type.
+ EffectiveConnectionType GetDefaultECT(
+ NetworkChangeNotifier::ConnectionType connection_type) const;
+
private:
// Map containing all field trial parameters related to
// NetworkQualityEstimator field trial.
@@ -236,14 +260,18 @@ class NET_EXPORT NetworkQualityEstimatorParams {
const size_t throughput_min_requests_in_flight_;
const int throughput_min_transfer_size_kilobytes_;
+ const double throughput_hanging_requests_cwnd_size_multiplier_;
const double weight_multiplier_per_second_;
const double weight_multiplier_per_signal_strength_level_;
- const double correlation_uma_logging_probability_;
base::Optional<EffectiveConnectionType> forced_effective_connection_type_;
+ const bool forced_effective_connection_type_on_cellular_only_;
bool persistent_cache_reading_enabled_;
const base::TimeDelta min_socket_watcher_notification_interval_;
const double lower_bound_http_rtt_transport_rtt_multiplier_;
const double upper_bound_http_rtt_transport_rtt_multiplier_;
+ const int hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_;
+ const int hanging_request_http_rtt_upper_bound_http_rtt_multiplier_;
+ const base::TimeDelta hanging_request_upper_bound_min_http_rtt_;
const size_t http_rtt_transport_rtt_min_count_;
const base::TimeDelta increase_in_transport_rtt_logging_interval_;
const base::TimeDelta recent_time_threshold_;
diff --git a/chromium/net/nqe/network_quality_estimator_params_unittest.cc b/chromium/net/nqe/network_quality_estimator_params_unittest.cc
index 3626f192b55..f10db3e4ca6 100644
--- a/chromium/net/nqe/network_quality_estimator_params_unittest.cc
+++ b/chromium/net/nqe/network_quality_estimator_params_unittest.cc
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -139,6 +140,88 @@ TEST(NetworkQualityEstimatorParamsTest, ObtainAlgorithmToUseFromParams) {
}
}
+// Verify that for a given connection type, the default network quality values
+// lie in the same range of ECT as the value returned by GetDefaultECT().
+TEST(NetworkQualityEstimatorParamsTest, GetDefaultECT) {
+ std::map<std::string, std::string> variation_params;
+ NetworkQualityEstimatorParams params(variation_params);
+
+ for (size_t i = 0; i < NetworkChangeNotifier::ConnectionType::CONNECTION_LAST;
+ ++i) {
+ NetworkChangeNotifier::ConnectionType connection_type =
+ static_cast<NetworkChangeNotifier::ConnectionType>(i);
+ EffectiveConnectionType ect = params.GetDefaultECT(connection_type);
+ EXPECT_LE(EFFECTIVE_CONNECTION_TYPE_2G, ect);
+
+ const nqe::internal::NetworkQuality& default_nq =
+ params.DefaultObservation(connection_type);
+
+ // Now verify that |default_nq| corresponds to |ect|.
+ if (ect == EFFECTIVE_CONNECTION_TYPE_4G) {
+ // If the expected effective connection type is 4G, then RTT values in
+ // |default_nq| should be lower than the threshold for ECT of 3G.
+ const nqe::internal::NetworkQuality& threshold_3g =
+ params.ConnectionThreshold(EFFECTIVE_CONNECTION_TYPE_3G);
+
+ EXPECT_LT(default_nq.http_rtt(), threshold_3g.http_rtt());
+ EXPECT_LT(default_nq.transport_rtt(), threshold_3g.transport_rtt());
+ EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
+ threshold_3g.downstream_throughput_kbps() ||
+ threshold_3g.downstream_throughput_kbps() < 0);
+ } else {
+ // If the expected effective connection type is |ect|, then RTT values in
+ // |default_nq| should be (i) higher than the threshold for ECT of |ect|
+ // (ii) Lower than the threshold for |slower_ect|.
+ const nqe::internal::NetworkQuality& threshold_ect =
+ params.ConnectionThreshold(ect);
+ EffectiveConnectionType slower_ect =
+ static_cast<EffectiveConnectionType>(static_cast<int>(ect) - 1);
+ const nqe::internal::NetworkQuality& threshold_slower_ect =
+ params.ConnectionThreshold(slower_ect);
+
+ EXPECT_GT(default_nq.http_rtt(), threshold_ect.http_rtt());
+ EXPECT_GT(default_nq.transport_rtt(), threshold_ect.transport_rtt());
+ EXPECT_TRUE(default_nq.downstream_throughput_kbps() <
+ threshold_ect.downstream_throughput_kbps() ||
+ threshold_ect.downstream_throughput_kbps() < 0);
+
+ EXPECT_LT(default_nq.http_rtt(), threshold_slower_ect.http_rtt());
+ EXPECT_LT(default_nq.transport_rtt(),
+ threshold_slower_ect.transport_rtt());
+ EXPECT_TRUE(default_nq.downstream_throughput_kbps() >
+ threshold_slower_ect.downstream_throughput_kbps() ||
+ threshold_slower_ect.downstream_throughput_kbps() < 0);
+ }
+ }
+}
+
+// Verify ECT when forced ECT is Slow-2G-On-Cellular.
+TEST(NetworkQualityEstimatorParamsTest, GetForcedECTCellularOnly) {
+ std::map<std::string, std::string> variation_params;
+ // Set force-effective-connection-type to Slow-2G-On-Cellular.
+ variation_params[kForceEffectiveConnectionType] =
+ kEffectiveConnectionTypeSlow2GOnCellular;
+
+ NetworkQualityEstimatorParams params(variation_params);
+
+ for (size_t i = 0; i < NetworkChangeNotifier::ConnectionType::CONNECTION_LAST;
+ ++i) {
+ NetworkChangeNotifier::ConnectionType connection_type =
+ static_cast<NetworkChangeNotifier::ConnectionType>(i);
+ base::Optional<EffectiveConnectionType> ect =
+ params.GetForcedEffectiveConnectionType(connection_type);
+
+ if (net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) {
+ // Test for cellular connection types. Make sure that ECT is Slow-2G.
+ EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_SLOW_2G, ect);
+ } else {
+ // Test for non-cellular connection types. Make sure that there is no
+ // forced ect.
+ EXPECT_EQ(base::nullopt, ect);
+ }
+ }
+}
+
} // namespace
} // namespace internal
diff --git a/chromium/net/nqe/network_quality_estimator_test_util.cc b/chromium/net/nqe/network_quality_estimator_test_util.cc
index d9d21f77cd4..3e82cbfc4ac 100644
--- a/chromium/net/nqe/network_quality_estimator_test_util.cc
+++ b/chromium/net/nqe/network_quality_estimator_test_util.cc
@@ -66,12 +66,11 @@ TestNetworkQualityEstimator::TestNetworkQualityEstimator(
std::move(external_estimate_provider),
std::make_unique<NetworkQualityEstimatorParams>(variation_params),
net_log->bound().net_log()),
+ net_log_(std::move(net_log)),
current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
accuracy_recording_intervals_set_(false),
- rand_double_(0.0),
embedded_test_server_(base::FilePath(kTestFilePath)),
- suppress_notifications_for_testing_(suppress_notifications_for_testing),
- net_log_(std::move(net_log)) {
+ suppress_notifications_for_testing_(suppress_notifications_for_testing) {
SetUseLocalHostRequestsForTesting(allow_local_host_requests_for_tests);
SetUseSmallResponsesForTesting(allow_smaller_responses_for_tests);
@@ -90,12 +89,11 @@ TestNetworkQualityEstimator::TestNetworkQualityEstimator(
: NetworkQualityEstimator(std::unique_ptr<ExternalEstimateProvider>(),
std::move(params),
net_log->bound().net_log()),
+ net_log_(std::move(net_log)),
current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN),
accuracy_recording_intervals_set_(false),
- rand_double_(0.0),
embedded_test_server_(base::FilePath(kTestFilePath)),
- suppress_notifications_for_testing_(false),
- net_log_(std::move(net_log)) {
+ suppress_notifications_for_testing_(false) {
// Set up the embedded test server.
EXPECT_TRUE(embedded_test_server_.Start());
}
@@ -262,10 +260,6 @@ TestNetworkQualityEstimator::GetAccuracyRecordingIntervals() const {
return NetworkQualityEstimator::GetAccuracyRecordingIntervals();
}
-double TestNetworkQualityEstimator::RandDouble() const {
- return rand_double_;
-}
-
base::Optional<int32_t>
TestNetworkQualityEstimator::GetBandwidthDelayProductKbits() const {
if (bandwidth_delay_product_kbits_.has_value())
@@ -340,7 +334,8 @@ const NetworkQualityEstimatorParams* TestNetworkQualityEstimator::params()
nqe::internal::NetworkID TestNetworkQualityEstimator::GetCurrentNetworkID()
const {
- return nqe::internal::NetworkID(current_network_type_, current_network_id_);
+ return nqe::internal::NetworkID(current_network_type_, current_network_id_,
+ INT32_MIN);
}
TestNetworkQualityEstimator::LocalHttpTestServer::LocalHttpTestServer(
@@ -366,4 +361,24 @@ void TestNetworkQualityEstimator::
observer);
}
+void TestNetworkQualityEstimator::SetStartTimeNullHttpRtt(
+ const base::TimeDelta http_rtt) {
+ start_time_null_http_rtt_ = http_rtt;
+ // Force compute effective connection type so that the new RTT value is
+ // immediately picked up. This ensures that the next call to
+ // GetEffectiveConnectionType() returns the effective connnection type
+ // that was computed based on |http_rtt|.
+ ComputeEffectiveConnectionType();
+}
+
+void TestNetworkQualityEstimator::SetStartTimeNullTransportRtt(
+ const base::TimeDelta transport_rtt) {
+ start_time_null_transport_rtt_ = transport_rtt;
+ // Force compute effective connection type so that the new RTT value is
+ // immediately picked up. This ensures that the next call to
+ // GetEffectiveConnectionType() returns the effective connnection type
+ // that was computed based on |transport_rtt|.
+ ComputeEffectiveConnectionType();
+}
+
} // namespace net
diff --git a/chromium/net/nqe/network_quality_estimator_test_util.h b/chromium/net/nqe/network_quality_estimator_test_util.h
index 3e245575636..3b188677657 100644
--- a/chromium/net/nqe/network_quality_estimator_test_util.h
+++ b/chromium/net/nqe/network_quality_estimator_test_util.h
@@ -122,9 +122,8 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
void NotifyRTTAndThroughputEstimatesObserverIfPresent(
RTTAndThroughputEstimatesObserver* observer) const override;
- void set_start_time_null_http_rtt(const base::TimeDelta& http_rtt) {
- start_time_null_http_rtt_ = http_rtt;
- }
+ // Force set the HTTP RTT estimate.
+ void SetStartTimeNullHttpRtt(const base::TimeDelta http_rtt);
void set_recent_http_rtt(const base::TimeDelta& recent_http_rtt) {
// Callers should not set effective connection type along with the
@@ -138,9 +137,8 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
bool GetRecentHttpRTT(const base::TimeTicks& start_time,
base::TimeDelta* rtt) const override;
- void set_start_time_null_transport_rtt(const base::TimeDelta& transport_rtt) {
- start_time_null_transport_rtt_ = transport_rtt;
- }
+ // Force set the transport RTT estimate.
+ void SetStartTimeNullTransportRtt(const base::TimeDelta transport_rtt);
void set_recent_transport_rtt(const base::TimeDelta& recent_transport_rtt) {
// Callers should not set effective connection type along with the
@@ -196,10 +194,6 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
const std::vector<base::TimeDelta>& GetAccuracyRecordingIntervals()
const override;
- void set_rand_double(double rand_double) { rand_double_ = rand_double; }
-
- double RandDouble() const override;
-
void set_bandwidth_delay_product_kbits(int32_t value) {
bandwidth_delay_product_kbits_ = value;
}
@@ -237,6 +231,7 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
using NetworkQualityEstimator::OnUpdatedTransportRTTAvailable;
using NetworkQualityEstimator::AddAndNotifyObserversOfRTT;
using NetworkQualityEstimator::AddAndNotifyObserversOfThroughput;
+ using NetworkQualityEstimator::IsHangingRequest;
private:
class LocalHttpTestServer : public EmbeddedTestServer {
@@ -253,6 +248,9 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
// id (instead of invoking platform APIs).
nqe::internal::NetworkID GetCurrentNetworkID() const override;
+ // Net log provided to network quality estimator.
+ std::unique_ptr<net::BoundTestNetLog> net_log_;
+
// If set, GetEffectiveConnectionType() and GetRecentEffectiveConnectionType()
// would return the set values, respectively.
base::Optional<EffectiveConnectionType> effective_connection_type_;
@@ -286,8 +284,6 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
// If set, GetRTTEstimateInternal() would return the set value.
base::Optional<base::TimeDelta> rtt_estimate_internal_;
- double rand_double_;
-
// If set, GetBandwidthDelayProductKbits() would return its set value.
// Otherwise, the base implementation is called.
base::Optional<int32_t> bandwidth_delay_product_kbits_;
@@ -299,9 +295,6 @@ class TestNetworkQualityEstimator : public NetworkQualityEstimator {
base::Optional<size_t> transport_rtt_observation_count_last_ect_computation_;
- // Net log provided to network quality estimator.
- std::unique_ptr<net::BoundTestNetLog> net_log_;
-
DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
};
diff --git a/chromium/net/nqe/network_quality_estimator_unittest.cc b/chromium/net/nqe/network_quality_estimator_unittest.cc
index b8854e3dc76..45a1b31b9f3 100644
--- a/chromium/net/nqe/network_quality_estimator_unittest.cc
+++ b/chromium/net/nqe/network_quality_estimator_unittest.cc
@@ -199,7 +199,8 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
- histogram_tester.ExpectTotalCount("NQE.CachedNetworkQualityAvailable", 0);
+ histogram_tester.ExpectUniqueSample("NQE.CachedNetworkQualityAvailable",
+ false, 2);
base::TimeDelta rtt;
int32_t kbps;
@@ -282,17 +283,9 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
histogram_tester.ExpectUniqueSample("NQE.CachedNetworkQualityAvailable",
- false, 1);
+ false, 3);
histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0);
- histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1);
- histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1);
- histogram_tester.ExpectTotalCount("NQE.RTT.Percentile50.Unknown", 1);
- histogram_tester.ExpectTotalCount("NQE.RTT.Percentile90.Unknown", 1);
- histogram_tester.ExpectTotalCount("NQE.RTT.Percentile100.Unknown", 1);
-
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile50.Unknown", 0);
-
EXPECT_FALSE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
EXPECT_FALSE(
estimator.GetRecentDownlinkThroughputKbps(base::TimeTicks(), &kbps));
@@ -306,7 +299,7 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string());
histogram_tester.ExpectUniqueSample("NQE.CachedNetworkQualityAvailable",
- false, 1);
+ false, 4);
EXPECT_FALSE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
EXPECT_FALSE(
@@ -336,7 +329,7 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
histogram_tester.ExpectBucketCount("NQE.CachedNetworkQualityAvailable", false,
- 1);
+ 4);
}
// Tests that the network quality estimator writes and reads network quality
@@ -359,7 +352,7 @@ TEST(NetworkQualityEstimatorTest, Caching) {
estimator.SimulateNetworkChange(connection_type, connection_id);
histogram_tester.ExpectUniqueSample("NQE.CachedNetworkQualityAvailable",
- false, 1);
+ false, 2);
base::TimeDelta rtt;
int32_t kbps;
@@ -383,6 +376,9 @@ TEST(NetworkQualityEstimatorTest, Caching) {
request->Start();
base::RunLoop().Run();
}
+ histogram_tester.ExpectUniqueSample("NQE.RTT.ObservationSource",
+ NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP,
+ 2);
base::RunLoop().RunUntilIdle();
@@ -399,7 +395,7 @@ TEST(NetworkQualityEstimatorTest, Caching) {
EXPECT_FALSE(estimator.GetTransportRTT());
histogram_tester.ExpectBucketCount("NQE.CachedNetworkQualityAvailable",
- false, 1);
+ false, 2);
// Add the observers before changing the network type.
TestEffectiveConnectionTypeObserver observer;
@@ -422,6 +418,11 @@ TEST(NetworkQualityEstimatorTest, Caching) {
"NQE.RTT.ObservationSource",
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, 1);
histogram_tester.ExpectBucketCount(
+ "NQE.RTT.ObservationSource",
+ NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, 1);
+ histogram_tester.ExpectTotalCount("NQE.RTT.ObservationSource", 4);
+
+ histogram_tester.ExpectBucketCount(
"NQE.Kbps.ObservationSource",
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE, 1);
histogram_tester.ExpectTotalCount(
@@ -433,7 +434,7 @@ TEST(NetworkQualityEstimatorTest, Caching) {
num_net_log_entries);
EXPECT_NE(-1, estimator.GetNetLogLastIntegerValue(
NetLogEventType::NETWORK_QUALITY_CHANGED, "http_rtt_ms"));
- EXPECT_EQ(
+ EXPECT_NE(
-1, estimator.GetNetLogLastIntegerValue(
NetLogEventType::NETWORK_QUALITY_CHANGED, "transport_rtt_ms"));
EXPECT_NE(-1, estimator.GetNetLogLastIntegerValue(
@@ -447,7 +448,7 @@ TEST(NetworkQualityEstimatorTest, Caching) {
histogram_tester.ExpectBucketCount("NQE.CachedNetworkQualityAvailable",
true, 1);
- histogram_tester.ExpectTotalCount("NQE.CachedNetworkQualityAvailable", 2);
+ histogram_tester.ExpectTotalCount("NQE.CachedNetworkQualityAvailable", 3);
base::RunLoop().RunUntilIdle();
// Verify that the cached network quality was read, and observers were
@@ -456,7 +457,7 @@ TEST(NetworkQualityEstimatorTest, Caching) {
EXPECT_LE(2U, observer.effective_connection_types().size());
EXPECT_EQ(estimator.GetEffectiveConnectionType(),
observer.effective_connection_types().back());
- EXPECT_EQ(1U, rtt_observer.observations().size());
+ EXPECT_EQ(2U, rtt_observer.observations().size());
EXPECT_EQ(1U, throughput_observer.observations().size());
}
}
@@ -729,7 +730,7 @@ TEST(NetworkQualityEstimatorTest, DefaultObservations) {
NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
EXPECT_TRUE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
// Taken from network_quality_estimator_params.cc.
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(272), rtt);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(273), rtt);
EXPECT_EQ(rtt, estimator.GetHttpRTT().value());
EXPECT_TRUE(
estimator.GetRecentTransportRTT(base::TimeTicks(), &rtt, nullptr));
@@ -759,7 +760,7 @@ TEST(NetworkQualityEstimatorTest, DefaultObservations) {
"effective_connection_type"));
EXPECT_EQ(4, rtt_throughput_estimates_observer.notifications_received());
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(272),
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(273),
rtt_throughput_estimates_observer.http_rtt());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(209),
rtt_throughput_estimates_observer.transport_rtt());
@@ -767,7 +768,7 @@ TEST(NetworkQualityEstimatorTest, DefaultObservations) {
rtt_throughput_estimates_observer.downstream_throughput_kbps());
EXPECT_EQ(2U, rtt_observer.observations().size());
- EXPECT_EQ(272, rtt_observer.observations().at(0).rtt_ms);
+ EXPECT_EQ(273, rtt_observer.observations().at(0).rtt_ms);
EXPECT_EQ(NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM,
rtt_observer.observations().at(0).source);
EXPECT_EQ(209, rtt_observer.observations().at(1).rtt_ms);
@@ -856,7 +857,7 @@ TEST(NetworkQualityEstimatorTest, DefaultObservationsOverridden) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
EXPECT_TRUE(estimator.GetRecentHttpRTT(base::TimeTicks(), &rtt));
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(272), rtt);
+ EXPECT_EQ(base::TimeDelta::FromMilliseconds(273), rtt);
EXPECT_EQ(rtt, estimator.GetHttpRTT().value());
EXPECT_TRUE(
estimator.GetRecentTransportRTT(base::TimeTicks(), &rtt, nullptr));
@@ -929,15 +930,12 @@ TEST(NetworkQualityEstimatorTest, ObtainThresholdsOnlyRTT) {
};
for (const auto& test : tests) {
- estimator.set_start_time_null_http_rtt(
- base::TimeDelta::FromMilliseconds(test.rtt_msec));
estimator.set_recent_http_rtt(
base::TimeDelta::FromMilliseconds(test.rtt_msec));
estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX);
estimator.set_recent_downlink_throughput_kbps(INT32_MAX);
- // Run one main frame request to force recomputation of effective connection
- // type.
- estimator.RunOneRequest();
+ estimator.SetStartTimeNullHttpRtt(
+ base::TimeDelta::FromMilliseconds(test.rtt_msec));
EXPECT_EQ(test.expected_conn_type, estimator.GetEffectiveConnectionType());
}
}
@@ -987,7 +985,7 @@ TEST(NetworkQualityEstimatorTest, DefaultTransportRTTBasedThresholds) {
estimator.SimulateNetworkChange(NetworkChangeNotifier::CONNECTION_WIFI,
"test");
- estimator.set_start_time_null_transport_rtt(
+ estimator.SetStartTimeNullTransportRtt(
base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
estimator.set_recent_transport_rtt(
base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
@@ -1043,15 +1041,12 @@ TEST(NetworkQualityEstimatorTest, DefaultHttpRTTBasedThresholds) {
estimator.SimulateNetworkChange(NetworkChangeNotifier::CONNECTION_WIFI,
"test");
- estimator.set_start_time_null_http_rtt(
+ estimator.SetStartTimeNullHttpRtt(
base::TimeDelta::FromMilliseconds(test.http_rtt_msec));
estimator.set_recent_http_rtt(
base::TimeDelta::FromMilliseconds(test.http_rtt_msec));
estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX);
estimator.set_recent_downlink_throughput_kbps(INT32_MAX);
- // Run one main frame request to force recomputation of effective connection
- // type.
- estimator.RunOneRequest();
EXPECT_EQ(test.expected_conn_type, estimator.GetEffectiveConnectionType());
}
}
@@ -1102,15 +1097,12 @@ TEST(NetworkQualityEstimatorTest, MAYBE_ObtainThresholdsOnlyTransportRTT) {
};
for (const auto& test : tests) {
- estimator.set_start_time_null_transport_rtt(
- base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
estimator.set_recent_transport_rtt(
base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX);
estimator.set_recent_downlink_throughput_kbps(INT32_MAX);
- // Run one main frame request to force recomputation of effective connection
- // type.
- estimator.RunOneRequest();
+ estimator.SetStartTimeNullTransportRtt(
+ base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
EXPECT_EQ(test.expected_conn_type, estimator.GetEffectiveConnectionType());
}
}
@@ -1163,7 +1155,7 @@ TEST(NetworkQualityEstimatorTest, ObtainThresholdsHttpRTTandThroughput) {
};
for (const auto& test : tests) {
- estimator.set_start_time_null_http_rtt(
+ estimator.SetStartTimeNullHttpRtt(
base::TimeDelta::FromMilliseconds(test.rtt_msec));
estimator.set_recent_http_rtt(
base::TimeDelta::FromMilliseconds(test.rtt_msec));
@@ -1228,17 +1220,14 @@ TEST(NetworkQualityEstimatorTest, ObtainThresholdsTransportRTTandThroughput) {
};
for (const auto& test : tests) {
- estimator.set_start_time_null_transport_rtt(
- base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
estimator.set_recent_transport_rtt(
base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
estimator.set_start_time_null_downlink_throughput_kbps(
test.downlink_throughput_kbps);
estimator.set_recent_downlink_throughput_kbps(
test.downlink_throughput_kbps);
- // Run one main frame request to force recomputation of effective connection
- // type.
- estimator.RunOneRequest();
+ estimator.SetStartTimeNullTransportRtt(
+ base::TimeDelta::FromMilliseconds(test.transport_rtt_msec));
EXPECT_EQ(test.expected_conn_type, estimator.GetEffectiveConnectionType());
}
}
@@ -1563,6 +1552,7 @@ TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) {
std::map<std::string, std::string> variation_params;
variation_params["throughput_min_requests_in_flight"] = "1";
+ variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params,
std::move(external_estimate_provider));
estimator.SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_WIFI,
@@ -1668,9 +1658,7 @@ TEST(NetworkQualityEstimatorTest, TestThroughputNoRequestOverlap) {
// interval, and that the observers are notified of any change.
TEST(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) {
base::HistogramTester histogram_tester;
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
+ base::SimpleTestTickClock tick_clock;
TestEffectiveConnectionTypeObserver observer;
std::map<std::string, std::string> variation_params;
@@ -1680,7 +1668,7 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) {
// |observer| may be notified as soon as it is added. Run the loop to so that
// the notification to |observer| is finished.
base::RunLoop().RunUntilIdle();
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context(true);
@@ -1689,11 +1677,10 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) {
EXPECT_EQ(0U, observer.effective_connection_types().size());
- estimator.set_start_time_null_http_rtt(
- base::TimeDelta::FromMilliseconds(1500));
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(1500));
estimator.set_start_time_null_downlink_throughput_kbps(100000);
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(60));
std::unique_ptr<URLRequest> request(
context.CreateRequest(estimator.GetEchoURL(), DEFAULT_PRIORITY,
@@ -1733,18 +1720,16 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestEffectiveConnectionTypeObserver) {
EXPECT_EQ(1U, observer.effective_connection_types().size());
// Change in connection type should send out notification to the observers.
- estimator.set_start_time_null_http_rtt(
- base::TimeDelta::FromMilliseconds(500));
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(500));
estimator.SimulateNetworkChange(NetworkChangeNotifier::CONNECTION_WIFI,
"test");
- EXPECT_EQ(2U, observer.effective_connection_types().size());
+ EXPECT_EQ(3U, observer.effective_connection_types().size());
// A change in effective connection type does not trigger notification to the
// observers, since it is not accompanied by any new observation or a network
// change event.
- estimator.set_start_time_null_http_rtt(
- base::TimeDelta::FromMilliseconds(100));
- EXPECT_EQ(2U, observer.effective_connection_types().size());
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(100));
+ EXPECT_EQ(4U, observer.effective_connection_types().size());
TestEffectiveConnectionTypeObserver observer_2;
estimator.AddEffectiveConnectionTypeObserver(&observer_2);
@@ -1776,7 +1761,7 @@ TEST(NetworkQualityEstimatorTest, TestTransportRttUsedForHttpRttComputation) {
{
base::TimeDelta::FromMilliseconds(100),
base::TimeDelta::FromMilliseconds(200), "", "",
- base::TimeDelta::FromMilliseconds(100), EFFECTIVE_CONNECTION_TYPE_4G,
+ base::TimeDelta::FromMilliseconds(200), EFFECTIVE_CONNECTION_TYPE_4G,
},
{
base::TimeDelta::FromMilliseconds(100),
@@ -1826,12 +1811,13 @@ TEST(NetworkQualityEstimatorTest, TestTransportRttUsedForHttpRttComputation) {
{
base::TimeDelta::FromMilliseconds(100),
base::TimeDelta::FromMilliseconds(200), "foobar", "",
- base::TimeDelta::FromMilliseconds(100), EFFECTIVE_CONNECTION_TYPE_4G,
+ base::TimeDelta::FromMilliseconds(200), EFFECTIVE_CONNECTION_TYPE_4G,
},
{
base::TimeDelta::FromMilliseconds(100),
base::TimeDelta::FromMilliseconds(4000), "", "",
- base::TimeDelta::FromMilliseconds(100), EFFECTIVE_CONNECTION_TYPE_4G,
+ base::TimeDelta::FromMilliseconds(4000),
+ EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
},
{
base::TimeDelta::FromMilliseconds(100),
@@ -1871,14 +1857,12 @@ TEST(NetworkQualityEstimatorTest, TestTransportRttUsedForHttpRttComputation) {
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- tick_clock->Advance(base::TimeDelta::FromSeconds(1));
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromSeconds(1));
+ estimator.SetTickClockForTesting(&tick_clock);
- estimator.set_start_time_null_http_rtt(test.http_rtt);
- estimator.set_start_time_null_transport_rtt(test.transport_rtt);
+ estimator.SetStartTimeNullHttpRtt(test.http_rtt);
+ estimator.SetStartTimeNullTransportRtt(test.transport_rtt);
// Minimum number of transport RTT samples that should be present before
// transport RTT estimate can be used to clamp the HTTP RTT.
@@ -1887,10 +1871,9 @@ TEST(NetworkQualityEstimatorTest, TestTransportRttUsedForHttpRttComputation) {
// Add one observation to ensure ECT is not computed for each request.
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
- test.http_rtt.InMilliseconds(), tick_clock_ptr->NowTicks(), INT32_MIN,
+ test.http_rtt.InMilliseconds(), tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
- estimator.RunOneRequest();
EXPECT_EQ(test.expected_http_rtt, estimator.GetHttpRTT());
EXPECT_EQ(test.transport_rtt, estimator.GetTransportRTT());
EXPECT_EQ(test.expected_type, estimator.GetEffectiveConnectionType())
@@ -1902,16 +1885,14 @@ TEST(NetworkQualityEstimatorTest, TestTransportRttUsedForHttpRttComputation) {
// that the network quality observers are notified of any change.
TEST(NetworkQualityEstimatorTest, TestRTTAndThroughputEstimatesObserver) {
base::HistogramTester histogram_tester;
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
+ base::SimpleTestTickClock tick_clock;
TestRTTAndThroughputEstimatesObserver observer;
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
estimator.AddRTTAndThroughputEstimatesObserver(&observer);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context(true);
@@ -1928,11 +1909,11 @@ TEST(NetworkQualityEstimatorTest, TestRTTAndThroughputEstimatesObserver) {
base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(100));
base::TimeDelta transport_rtt(base::TimeDelta::FromMilliseconds(200));
int32_t downstream_throughput_kbps(300);
- estimator.set_start_time_null_http_rtt(http_rtt);
- estimator.set_start_time_null_transport_rtt(transport_rtt);
+ estimator.SetStartTimeNullHttpRtt(http_rtt);
+ estimator.SetStartTimeNullTransportRtt(transport_rtt);
estimator.set_start_time_null_downlink_throughput_kbps(
downstream_throughput_kbps);
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(60));
std::unique_ptr<URLRequest> request(
context.CreateRequest(estimator.GetEchoURL(), DEFAULT_PRIORITY,
@@ -1968,10 +1949,9 @@ TEST(NetworkQualityEstimatorTest, TestRTTAndThroughputEstimatesObserver) {
// A change in effective connection type does not trigger notification to the
// observers, since it is not accompanied by any new observation or a network
// change event.
- estimator.set_start_time_null_http_rtt(
- base::TimeDelta::FromMilliseconds(10000));
- estimator.set_start_time_null_http_rtt(base::TimeDelta::FromMilliseconds(1));
- EXPECT_EQ(0, observer.notifications_received() - notifications_received);
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(10000));
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(1));
+ EXPECT_EQ(2, observer.notifications_received() - notifications_received);
TestRTTAndThroughputEstimatesObserver observer_2;
estimator.AddRTTAndThroughputEstimatesObserver(&observer_2);
@@ -2004,17 +1984,15 @@ TEST(NetworkQualityEstimatorTest, TestRTTAndThroughputEstimatesObserver) {
// Tests that the effective connection type is computed on every RTT
// observation if the last computed effective connection type was unknown.
TEST(NetworkQualityEstimatorTest, UnknownEffectiveConnectionType) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
+ base::SimpleTestTickClock tick_clock;
TestEffectiveConnectionTypeObserver observer;
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
estimator.AddEffectiveConnectionTypeObserver(&observer);
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(60));
size_t expected_effective_connection_type_notifications = 0;
estimator.set_recent_effective_connection_type(
@@ -2026,7 +2004,7 @@ TEST(NetworkQualityEstimatorTest, UnknownEffectiveConnectionType) {
"test");
NetworkQualityEstimator::Observation rtt_observation(
- 5000, tick_clock_ptr->NowTicks(), INT32_MIN,
+ 5000, tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP);
for (size_t i = 0; i < 10; ++i) {
@@ -2040,7 +2018,7 @@ TEST(NetworkQualityEstimatorTest, UnknownEffectiveConnectionType) {
// more RTT sample should trigger recomputation of the effective connection
// type since the last computed effective connection type was unknown.
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
- 5000, tick_clock_ptr->NowTicks(), INT32_MIN,
+ 5000, tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
++expected_effective_connection_type_notifications;
EXPECT_EQ(expected_effective_connection_type_notifications,
@@ -2052,15 +2030,13 @@ TEST(NetworkQualityEstimatorTest, UnknownEffectiveConnectionType) {
TEST(NetworkQualityEstimatorTest,
AdaptiveRecomputationEffectiveConnectionType) {
base::HistogramTester histogram_tester;
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
+ base::SimpleTestTickClock tick_clock;
TestEffectiveConnectionTypeObserver observer;
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
estimator.SimulateNetworkChange(NetworkChangeNotifier::CONNECTION_WIFI,
"test");
estimator.AddEffectiveConnectionTypeObserver(&observer);
@@ -2076,7 +2052,7 @@ TEST(NetworkQualityEstimatorTest,
EXPECT_EQ(0U, observer.effective_connection_types().size());
estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(60));
std::unique_ptr<URLRequest> request(
context.CreateRequest(estimator.GetEchoURL(), DEFAULT_PRIORITY,
@@ -2128,7 +2104,7 @@ TEST(NetworkQualityEstimatorTest,
// effective connection type.
for (size_t i = 0; i < rtt_observations_count + 1; ++i) {
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
- 5000, tick_clock_ptr->NowTicks(), INT32_MIN,
+ 5000, tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
if (i == rtt_observations_count) {
@@ -2244,15 +2220,13 @@ TEST(NetworkQualityEstimatorTest, TestRttThroughputObservers) {
}
TEST(NetworkQualityEstimatorTest, TestGlobalSocketWatcherThrottle) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromSeconds(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromSeconds(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
TestRTTObserver rtt_observer;
estimator.AddRTTObserver(&rtt_observer);
@@ -2293,7 +2267,7 @@ TEST(NetworkQualityEstimatorTest, TestGlobalSocketWatcherThrottle) {
EXPECT_EQ(2U, rtt_observer.observations().size());
// Advancing the clock should make it possible to notify new RTT
// notifications.
- tick_clock_ptr->Advance(
+ tick_clock.Advance(
estimator.params()->socket_watchers_min_notification_interval());
EXPECT_TRUE(tcp_watcher->ShouldNotifyUpdatedRTT());
@@ -2305,7 +2279,7 @@ TEST(NetworkQualityEstimatorTest, TestGlobalSocketWatcherThrottle) {
// TestTCPSocketRTT requires kernel support for tcp_info struct, and so it is
// enabled only on certain platforms.
-#if defined(TCP_INFO) || defined(OS_LINUX)
+#if defined(TCP_INFO) || defined(OS_LINUX) || defined(OS_ANDROID)
#define MAYBE_TestTCPSocketRTT TestTCPSocketRTT
#else
#define MAYBE_TestTCPSocketRTT DISABLED_TestTCPSocketRTT
@@ -2313,10 +2287,8 @@ TEST(NetworkQualityEstimatorTest, TestGlobalSocketWatcherThrottle) {
// Tests that the TCP socket notifies the Network Quality Estimator of TCP RTTs,
// which in turn notifies registered RTT observers.
TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromSeconds(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromSeconds(1));
base::HistogramTester histogram_tester;
TestRTTObserver rtt_observer;
@@ -2327,7 +2299,7 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
TestNetworkQualityEstimator estimator(
nullptr, variation_params, true, true,
std::make_unique<BoundTestNetLog>());
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");
@@ -2371,7 +2343,7 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
&test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME_DEPRECATED);
request->Start();
- tick_clock_ptr->Advance(
+ tick_clock.Advance(
estimator.params()->socket_watchers_min_notification_interval());
base::RunLoop().Run();
@@ -2395,13 +2367,6 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile50.2G", 1);
- histogram_tester.ExpectBucketCount("NQE.TransportRTT.Percentile50.2G",
- rtt.InMilliseconds(), 1);
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile10.2G", 1);
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile50.2G", 1);
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile90.2G", 1);
- histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile100.2G", 1);
// Verify that metrics are logged correctly on main-frame requests.
histogram_tester.ExpectTotalCount("NQE.MainFrame.TransportRTT.Percentile50",
@@ -2439,13 +2404,13 @@ TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");
histogram_tester.ExpectBucketCount(
"NQE.RTT.ObservationSource",
- NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, 0);
+ NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, 1);
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
histogram_tester.ExpectBucketCount(
"NQE.RTT.ObservationSource",
- NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, 1);
+ NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE, 2);
}
#if defined(OS_IOS)
@@ -2493,10 +2458,8 @@ TEST(NetworkQualityEstimatorTest, MAYBE_RecordAccuracy) {
for (const auto& accuracy_recording_delay : accuracy_recording_delays) {
for (const auto& test : tests) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromSeconds(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromSeconds(1));
std::unique_ptr<ExternalEstimateProvider> external_estimate_provider(
new TestExternalEstimateProvider(test.rtt, 0));
@@ -2505,10 +2468,10 @@ TEST(NetworkQualityEstimatorTest, MAYBE_RecordAccuracy) {
TestNetworkQualityEstimator estimator(
variation_params, std::move(external_estimate_provider));
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
- tick_clock_ptr->Advance(base::TimeDelta::FromSeconds(1));
+ tick_clock.Advance(base::TimeDelta::FromSeconds(1));
std::vector<base::TimeDelta> accuracy_recording_intervals;
accuracy_recording_intervals.push_back(accuracy_recording_delay);
@@ -2516,10 +2479,10 @@ TEST(NetworkQualityEstimatorTest, MAYBE_RecordAccuracy) {
// RTT is higher than threshold. Network is slow.
// Network was predicted to be slow and actually was slow.
- estimator.set_start_time_null_http_rtt(test.rtt);
+ estimator.SetStartTimeNullHttpRtt(test.rtt);
estimator.set_recent_http_rtt(test.recent_rtt);
estimator.set_rtt_estimate_internal(test.recent_rtt);
- estimator.set_start_time_null_transport_rtt(test.rtt);
+ estimator.SetStartTimeNullTransportRtt(test.rtt);
estimator.set_recent_transport_rtt(test.recent_rtt);
estimator.set_start_time_null_downlink_throughput_kbps(
test.downstream_throughput_kbps);
@@ -2543,7 +2506,7 @@ TEST(NetworkQualityEstimatorTest, MAYBE_RecordAccuracy) {
base::RunLoop().Run();
if (accuracy_recording_delay != base::TimeDelta()) {
- tick_clock_ptr->Advance(accuracy_recording_delay);
+ tick_clock.Advance(accuracy_recording_delay);
// Sleep for some time to ensure that the delayed task is posted.
base::PlatformThread::Sleep(accuracy_recording_delay * 2);
@@ -2675,202 +2638,13 @@ TEST(NetworkQualityEstimatorTest, TestRecordNetworkIDAvailability) {
histogram_tester.ExpectTotalCount("NQE.NetworkIdAvailable", 4);
}
-// Tests that the correlation histogram is recorded correctly based on
-// correlation logging probability set in the variation params.
-TEST(NetworkQualityEstimatorTest, CorrelationHistogram) {
- // Match the values set in network_quality_estimator.cc.
- static const int32_t kTrimBits = 5;
- static const int32_t kBitsPerMetric = 7;
-
- const struct {
- bool use_transport_rtt;
- double rand_double;
- double correlation_logging_probability;
- base::TimeDelta transport_rtt;
- int32_t expected_transport_rtt_milliseconds;
- base::TimeDelta http_rtt;
- int32_t expected_http_rtt_milliseconds;
- int32_t downstream_throughput_kbps;
- int32_t expected_downstream_throughput_kbps;
-
- } tests[] = {
- {
- // Verify that the metric is not recorded if the logging probability
- // is set to 0.0.
- false, 0.5, 0.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is not recorded if the logging probability
- // is lower than the value returned by the random number generator.
- false, 0.3, 0.1, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is recorded if the logging probability is
- // higher than the value returned by the random number generator.
- false, 0.3, 0.4, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is not recorded if the HTTP RTT is
- // unavailable.
- false, 0.3, 0.4, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- nqe::internal::InvalidRTT(), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is not recorded if the transport RTT is
- // unavailable.
- true, 0.3, 0.4, nqe::internal::InvalidRTT(), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is not recorded if the throughput is
- // unavailable.
- false, 0.3, 0.4, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits,
- nqe::internal::INVALID_RTT_THROUGHPUT, 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is recorded if the logging probability is
- // set to 1.0.
- false, 0.5, 1.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that the metric is recorded if the logging probability is
- // set to 1.0.
- true, 0.5, 1.0, base::TimeDelta::FromSeconds(1), 1000 >> kTrimBits,
- base::TimeDelta::FromSeconds(2), 2000 >> kTrimBits, 3000,
- 3000 >> kTrimBits,
- },
- {
- // Verify that if the metric is larger than
- // 2^(kBitsPerMetric + kTrimBits), it is rounded down to
- // (2^(kBitsPerMetric + kTrimBits) - 1) >> kTrimBits.
- false, 0.5, 1.0, base::TimeDelta::FromSeconds(10), 4095 >> kTrimBits,
- base::TimeDelta::FromSeconds(20), 4095 >> kTrimBits, 30000,
- 4095 >> kTrimBits,
- },
- };
-
- for (const auto& test : tests) {
- base::HistogramTester histogram_tester;
-
- std::map<std::string, std::string> variation_params;
- variation_params["correlation_logging_probability"] =
- base::NumberToString(test.correlation_logging_probability);
- if (test.use_transport_rtt) {
- variation_params["effective_connection_type_algorithm"] =
- "TransportRTTOrDownstreamThroughput";
- }
- TestNetworkQualityEstimator estimator(variation_params);
-
- estimator.set_start_time_null_transport_rtt(test.transport_rtt);
- estimator.set_recent_transport_rtt(test.transport_rtt);
- estimator.set_start_time_null_http_rtt(test.http_rtt);
- estimator.set_recent_http_rtt(test.http_rtt);
- estimator.set_start_time_null_downlink_throughput_kbps(
- test.downstream_throughput_kbps);
- estimator.set_rand_double(test.rand_double);
-
- TestDelegate test_delegate;
- TestURLRequestContext context(true);
- context.set_network_quality_estimator(&estimator);
- context.Init();
-
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0);
-
- // Start a main-frame request that should cause network quality estimator to
- // record the network quality at the last main frame request.
- std::unique_ptr<URLRequest> request_1(
- context.CreateRequest(estimator.GetEchoURL(), DEFAULT_PRIORITY,
- &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
- request_1->SetLoadFlags(request_1->load_flags() |
- LOAD_MAIN_FRAME_DEPRECATED);
- request_1->Start();
- base::RunLoop().Run();
-
- if (test.rand_double >= test.correlation_logging_probability) {
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0);
- continue;
- }
- if (!test.use_transport_rtt &&
- test.http_rtt == nqe::internal::InvalidRTT()) {
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0);
- continue;
- }
- if (test.use_transport_rtt &&
- test.transport_rtt == nqe::internal::InvalidRTT()) {
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0);
- continue;
- }
- if (test.downstream_throughput_kbps ==
- nqe::internal::INVALID_RTT_THROUGHPUT) {
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 0);
- continue;
- }
-
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 1);
- std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb");
- // Get the bits at index 0-10 which contain the RTT.
- // 128 is 2^kBitsPerMetric.
- if (test.use_transport_rtt) {
- EXPECT_EQ(test.expected_transport_rtt_milliseconds,
- buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric >>
- kBitsPerMetric);
- } else {
- EXPECT_EQ(test.expected_http_rtt_milliseconds,
- buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric >>
- kBitsPerMetric);
- }
-
- // Get the bits at index 11-17 which contain the downstream throughput.
- EXPECT_EQ(test.expected_downstream_throughput_kbps,
- (buckets.at(0).min >> kBitsPerMetric >> kBitsPerMetric) % 128);
-
- // Get the bits at index 18-24 which contain the resource fetch time.
- EXPECT_LE(0, (buckets.at(0).min >> kBitsPerMetric) % 128);
-
- // Get the bits at index 25-31 which contain the resource load size.
- EXPECT_LE(0, (buckets.at(0).min) % 128);
-
- // Start another main-frame request which is redirected to an HTTPS URL.
- // Redirection should not cause any crashes.
- std::unique_ptr<URLRequest> request_3(
- context.CreateRequest(estimator.GetRedirectURL(), DEFAULT_PRIORITY,
- &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
- request_3->Start();
- base::RunLoop().Run();
- EXPECT_FALSE(request_3->original_url().SchemeIsCryptographic());
- EXPECT_TRUE(request_3->url().SchemeIsCryptographic());
- EXPECT_TRUE(!request_3->response_info().headers.get() ||
- request_3->response_info().headers->response_code() != HTTP_OK);
- // Correlation metric should not be logged for redirected requests.
- histogram_tester.ExpectTotalCount(
- "NQE.Correlation.ResourceLoadTime.0Kb_128Kb", 1);
- }
-}
-
class TestNetworkQualitiesCacheObserver
: public nqe::internal::NetworkQualityStore::NetworkQualitiesCacheObserver {
public:
TestNetworkQualitiesCacheObserver()
: network_id_(net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
- std::string()),
+ std::string(),
+ INT32_MIN),
notification_received_(0) {}
~TestNetworkQualitiesCacheObserver() override = default;
@@ -2907,7 +2681,7 @@ TEST(NetworkQualityEstimatorTest, CacheObserver) {
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test3g");
estimator.RunOneRequest();
- EXPECT_EQ(2u, observer.get_notification_received_and_reset());
+ EXPECT_EQ(4u, observer.get_notification_received_and_reset());
EXPECT_EQ("test3g", observer.network_id().id);
estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
@@ -3045,29 +2819,20 @@ TEST(NetworkQualityEstimatorTest, TypicalNetworkQualities) {
// Set the RTT and throughput values to the typical values for
// |effective_connection_type|. The effective connection type should be
// computed as |effective_connection_type|.
- estimator.set_start_time_null_http_rtt(
+ estimator.SetStartTimeNullHttpRtt(
estimator.params_
->TypicalNetworkQuality(static_cast<EffectiveConnectionType>(
effective_connection_type))
.http_rtt());
- estimator.set_start_time_null_transport_rtt(
+ estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX);
+ estimator.SetStartTimeNullTransportRtt(
estimator.params_
->TypicalNetworkQuality(static_cast<EffectiveConnectionType>(
effective_connection_type))
.transport_rtt());
- estimator.set_start_time_null_downlink_throughput_kbps(INT32_MAX);
-
- // Force recomputation of effective connection type by starting a main
- // frame request.
- std::unique_ptr<URLRequest> request(
- context.CreateRequest(estimator.GetEchoURL(), DEFAULT_PRIORITY,
- &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
- request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME_DEPRECATED);
- request->Start();
- base::RunLoop().Run();
EXPECT_EQ(effective_connection_type,
- estimator.GetEffectiveConnectionType());
+ static_cast<size_t>(estimator.GetEffectiveConnectionType()));
}
}
}
@@ -3080,13 +2845,13 @@ TEST(NetworkQualityEstimatorTest, OnPrefsRead) {
std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality>
read_prefs;
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_ect_2g")] =
+ "test_ect_2g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G);
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_ect_slow_2g")] =
+ "test_ect_slow_2g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_4G,
- "test_ect_4g")] =
+ "test_ect_4g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G);
std::map<std::string, std::string> variation_params;
@@ -3143,7 +2908,8 @@ TEST(NetworkQualityEstimatorTest, OnPrefsRead) {
// Compare the ECT stored in prefs with the observer's last entry.
EXPECT_EQ(
read_prefs[nqe::internal::NetworkID(
- NetworkChangeNotifier::CONNECTION_WIFI, network_name)]
+ NetworkChangeNotifier::CONNECTION_WIFI, network_name,
+ INT32_MIN)]
.effective_connection_type(),
effective_connection_type_observer.effective_connection_types().back());
@@ -3170,7 +2936,8 @@ TEST(NetworkQualityEstimatorTest, OnPrefsRead) {
// Compare with the last entry.
EXPECT_EQ(
read_prefs[nqe::internal::NetworkID(
- NetworkChangeNotifier::CONNECTION_WIFI, network_name)]
+ NetworkChangeNotifier::CONNECTION_WIFI, network_name,
+ INT32_MIN)]
.effective_connection_type(),
effective_connection_type_observer.effective_connection_types().back());
@@ -3191,13 +2958,13 @@ TEST(NetworkQualityEstimatorTest, OnPrefsReadWithReadingDisabled) {
std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality>
read_prefs;
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_ect_2g")] =
+ "test_ect_2g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G);
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_ect_slow_2g")] =
+ "test_ect_slow_2g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_4G,
- "test_ect_4g")] =
+ "test_ect_4g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G);
std::map<std::string, std::string> variation_params;
@@ -3241,7 +3008,7 @@ TEST(NetworkQualityEstimatorTest, OnPrefsReadWithReadingDisabled) {
nqe::internal::CachedNetworkQuality cached_network_quality;
EXPECT_TRUE(estimator.network_quality_store_->GetById(
nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_ect_2g"),
+ "test_ect_2g", INT32_MIN),
&cached_network_quality));
EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_2G,
cached_network_quality.effective_connection_type());
@@ -3317,17 +3084,15 @@ TEST(NetworkQualityEstimatorTest, TestBDPComputation) {
TEST(NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTFullHostsOverlap) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromMinutes(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
- base::TimeTicks now = tick_clock_ptr->NowTicks();
+ base::TimeTicks now = tick_clock.NowTicks();
base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500);
base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20);
@@ -3359,17 +3124,15 @@ TEST(NetworkQualityEstimatorTest,
TEST(NetworkQualityEstimatorTest,
TestComputeIncreaseInTransportRTTPartialHostsOverlap) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromMinutes(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
- base::TimeTicks now = tick_clock_ptr->NowTicks();
+ base::TimeTicks now = tick_clock.NowTicks();
base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500);
base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20);
@@ -3409,7 +3172,7 @@ TEST(NetworkQualityEstimatorTest,
std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality>
read_prefs;
read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI,
- "test_2g")] =
+ "test_2g", INT32_MIN)] =
nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G);
std::map<std::string, std::string> variation_params;
@@ -3514,20 +3277,18 @@ TEST(NetworkQualityEstimatorTest,
// Tests that the ECT is computed when more than N RTT samples have been
// received.
TEST(NetworkQualityEstimatorTest, MaybeComputeECTAfterNSamples) {
- std::unique_ptr<base::SimpleTestTickClock> tick_clock(
- new base::SimpleTestTickClock());
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(1));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.Advance(base::TimeDelta::FromMinutes(1));
std::map<std::string, std::string> variation_params;
variation_params["add_default_platform_observations"] = "false";
TestNetworkQualityEstimator estimator(variation_params);
estimator.DisableOfflineCheckForTesting(true);
base::RunLoop().RunUntilIdle();
- estimator.SetTickClockForTesting(std::move(tick_clock));
+ estimator.SetTickClockForTesting(&tick_clock);
estimator.SimulateNetworkChange(
NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(1));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(1));
const base::TimeDelta rtt = base::TimeDelta::FromSeconds(1);
uint64_t host = 1u;
@@ -3536,21 +3297,143 @@ TEST(NetworkQualityEstimatorTest, MaybeComputeECTAfterNSamples) {
// to observation buffer's size increasing to 1.5x.
for (size_t i = 0; i < estimator.params()->observation_buffer_size(); ++i) {
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
- rtt.InMilliseconds(), tick_clock_ptr->NowTicks(), INT32_MIN,
+ rtt.InMilliseconds(), tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, host));
}
EXPECT_EQ(rtt, estimator.GetHttpRTT().value());
- tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60));
+ tick_clock.Advance(base::TimeDelta::FromMinutes(60));
const base::TimeDelta rtt_new = base::TimeDelta::FromSeconds(3);
for (size_t i = 0;
i < estimator.params()->count_new_observations_received_compute_ect();
++i) {
estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
- rtt_new.InMilliseconds(), tick_clock_ptr->NowTicks(), INT32_MIN,
+ rtt_new.InMilliseconds(), tick_clock.NowTicks(), INT32_MIN,
NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, host));
}
EXPECT_EQ(rtt_new, estimator.GetHttpRTT().value());
}
+// Tests that the hanging request is correctly detected.
+TEST(NetworkQualityEstimatorTest, HangingRequestUsingHttpOnly) {
+ base::HistogramTester histogram_tester;
+
+ std::map<std::string, std::string> variation_params;
+ variation_params["add_default_platform_observations"] = "false";
+ variation_params["hanging_request_http_rtt_upper_bound_http_rtt_multiplier"] =
+ "6";
+ variation_params["hanging_request_upper_bound_min_http_rtt_msec"] = "500";
+
+ TestNetworkQualityEstimator estimator(variation_params);
+
+ // 500 msec.
+ const int32_t hanging_request_threshold =
+ estimator.params()
+ ->hanging_request_upper_bound_min_http_rtt()
+ .InMilliseconds();
+
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(5));
+ base::RunLoop().RunUntilIdle();
+ estimator.SimulateNetworkChange(
+ NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
+
+ const struct {
+ base::TimeDelta observed_http_rtt;
+ std::string histogram_name;
+ } tests[] = {
+ {base::TimeDelta::FromMilliseconds(10),
+ "NQE.RTT.NotAHangingRequest.HttpRTT"},
+ {base::TimeDelta::FromMilliseconds(100),
+ "NQE.RTT.NotAHangingRequest.MinHttpBound"},
+ {base::TimeDelta::FromMilliseconds(hanging_request_threshold - 1),
+ "NQE.RTT.NotAHangingRequest.MinHttpBound"},
+ {base::TimeDelta::FromMilliseconds(hanging_request_threshold + 1),
+ "NQE.RTT.HangingRequest"},
+ {base::TimeDelta::FromMilliseconds(1000), "NQE.RTT.HangingRequest"},
+ };
+
+ for (const auto& test : tests) {
+ EXPECT_EQ(
+ test.observed_http_rtt.InMilliseconds() >= hanging_request_threshold,
+ estimator.IsHangingRequest(test.observed_http_rtt));
+ histogram_tester.ExpectBucketCount(
+ test.histogram_name, test.observed_http_rtt.InMilliseconds(), 1);
+ }
+
+ // Verify total sample count in all histograms.
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.TransportRTT",
+ 0);
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.HttpRTT", 1);
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.MinHttpBound",
+ 2);
+ histogram_tester.ExpectTotalCount("NQE.RTT.HangingRequest", 2);
+}
+
+TEST(NetworkQualityEstimatorTest, HangingRequestUsingTransportAndHttpOnly) {
+ base::HistogramTester histogram_tester;
+
+ std::map<std::string, std::string> variation_params;
+ variation_params["add_default_platform_observations"] = "false";
+ variation_params
+ ["hanging_request_http_rtt_upper_bound_transport_rtt_multiplier"] = "8";
+ variation_params["hanging_request_http_rtt_upper_bound_http_rtt_multiplier"] =
+ "6";
+ variation_params["hanging_request_upper_bound_min_http_rtt_msec"] = "500";
+
+ const base::TimeDelta transport_rtt = base::TimeDelta::FromMilliseconds(100);
+
+ TestNetworkQualityEstimator estimator(variation_params);
+
+ // 800 msec.
+ const int32_t hanging_request_threshold =
+ transport_rtt.InMilliseconds() *
+ estimator.params()
+ ->hanging_request_http_rtt_upper_bound_transport_rtt_multiplier();
+
+ estimator.DisableOfflineCheckForTesting(true);
+ estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(5));
+
+ for (size_t i = 0; i < 100; ++i) {
+ // Throw enough transport RTT samples so that transport RTT estimate is
+ // recomputed.
+ estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation(
+ transport_rtt.InMilliseconds(), base::TimeTicks::Now(), INT32_MIN,
+ NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, 0));
+ }
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(transport_rtt, estimator.GetTransportRTT());
+
+ const struct {
+ base::TimeDelta observed_http_rtt;
+ std::string histogram_name;
+ } tests[] = {
+ {base::TimeDelta::FromMilliseconds(100),
+ "NQE.RTT.NotAHangingRequest.TransportRTT"},
+ {base::TimeDelta::FromMilliseconds(500),
+ "NQE.RTT.NotAHangingRequest.TransportRTT"},
+ {base::TimeDelta::FromMilliseconds(hanging_request_threshold - 1),
+ "NQE.RTT.NotAHangingRequest.TransportRTT"},
+ {base::TimeDelta::FromMilliseconds(hanging_request_threshold + 1),
+ "NQE.RTT.HangingRequest"},
+ {base::TimeDelta::FromMilliseconds(1000), "NQE.RTT.HangingRequest"},
+ };
+
+ for (const auto& test : tests) {
+ EXPECT_EQ(
+ test.observed_http_rtt.InMilliseconds() >= hanging_request_threshold,
+ estimator.IsHangingRequest(test.observed_http_rtt));
+ histogram_tester.ExpectBucketCount(
+ test.histogram_name, test.observed_http_rtt.InMilliseconds(), 1);
+ }
+
+ // Verify total sample count in all histograms.
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.TransportRTT",
+ 3);
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.HttpRTT", 0);
+ histogram_tester.ExpectTotalCount("NQE.RTT.NotAHangingRequest.MinHttpBound",
+ 0);
+ histogram_tester.ExpectTotalCount("NQE.RTT.HangingRequest", 2);
+}
+
} // namespace net
diff --git a/chromium/net/nqe/network_quality_store.cc b/chromium/net/nqe/network_quality_store.cc
index 490f0703d03..6d856225b54 100644
--- a/chromium/net/nqe/network_quality_store.cc
+++ b/chromium/net/nqe/network_quality_store.cc
@@ -14,14 +14,13 @@ namespace nqe {
namespace internal {
-NetworkQualityStore::NetworkQualityStore()
- : disable_offline_check_(false), weak_ptr_factory_(this) {
+NetworkQualityStore::NetworkQualityStore() : weak_ptr_factory_(this) {
static_assert(kMaximumNetworkQualityCacheSize > 0,
"Size of the network quality cache must be > 0");
// This limit should not be increased unless the logic for removing the
// oldest cache entry is rewritten to use a doubly-linked-list LRU queue.
- static_assert(kMaximumNetworkQualityCacheSize <= 10,
- "Size of the network quality cache must <= 10");
+ static_assert(kMaximumNetworkQualityCacheSize <= 20,
+ "Size of the network quality cache must <= 20");
}
NetworkQualityStore::~NetworkQualityStore() {
@@ -40,9 +39,6 @@ void NetworkQualityStore::Add(
return;
}
- if (!EligibleForCaching(network_id))
- return;
-
// Remove the entry from the map, if it is already present.
cached_network_qualities_.erase(network_id);
@@ -71,16 +67,50 @@ void NetworkQualityStore::Add(
bool NetworkQualityStore::GetById(
const nqe::internal::NetworkID& network_id,
- nqe::internal::CachedNetworkQuality* cached_network_quality) {
+ nqe::internal::CachedNetworkQuality* cached_network_quality) const {
DCHECK(thread_checker_.CalledOnValidThread());
- CachedNetworkQualities::const_iterator it =
- cached_network_qualities_.find(network_id);
+ // |matching_it| points to the entry that has the same connection type and
+ // id as |network_id|, and has the signal strength closest to the signal
+ // stength of |network_id|.
+ CachedNetworkQualities::const_iterator matching_it =
+ cached_network_qualities_.end();
+ int matching_it_diff_signal_strength = INT32_MAX;
+
+ for (CachedNetworkQualities::const_iterator it =
+ cached_network_qualities_.begin();
+ it != cached_network_qualities_.end(); ++it) {
+ if (network_id.type != it->first.type || network_id.id != it->first.id) {
+ // The |type| and |id| must match.
+ continue;
+ }
+
+ if (network_id.signal_strength == INT32_MIN) {
+ // Current network does not have a valid signal strength value. Return the
+ // entry without searching for the entry with the closest signal strength.
+ matching_it = it;
+ break;
+ }
+
+ // Determine if the signal strength of |network_id| is closer to the
+ // signal strength of the network at |it| then that of the network at
+ // |matching_it|.
+ int diff_signal_strength =
+ std::abs(network_id.signal_strength - it->first.signal_strength);
+ if (it->first.signal_strength == INT32_MIN)
+ diff_signal_strength = INT32_MAX;
+
+ if (matching_it == cached_network_qualities_.end() ||
+ diff_signal_strength < matching_it_diff_signal_strength) {
+ matching_it = it;
+ matching_it_diff_signal_strength = diff_signal_strength;
+ }
+ }
- if (it == cached_network_qualities_.end())
+ if (matching_it == cached_network_qualities_.end())
return false;
- *cached_network_quality = it->second;
+ *cached_network_quality = matching_it->second;
return true;
}
@@ -102,24 +132,6 @@ void NetworkQualityStore::RemoveNetworkQualitiesCacheObserver(
network_qualities_cache_observer_list_.RemoveObserver(observer);
}
-bool NetworkQualityStore::EligibleForCaching(
- const NetworkID& network_id) const {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // |disable_offline_check_| forces caching of the network quality even if
- // the network is set to offline.
- return network_id.type == NetworkChangeNotifier::CONNECTION_ETHERNET ||
- !network_id.id.empty() ||
- (network_id.type == NetworkChangeNotifier::CONNECTION_NONE &&
- disable_offline_check_);
-}
-
-void NetworkQualityStore::DisableOfflineCheckForTesting(
- bool disable_offline_check) {
- DCHECK(thread_checker_.CalledOnValidThread());
- disable_offline_check_ = disable_offline_check;
-}
-
void NetworkQualityStore::NotifyCacheObserverIfPresent(
NetworkQualitiesCacheObserver* observer) const {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chromium/net/nqe/network_quality_store.h b/chromium/net/nqe/network_quality_store.h
index 6213da79e86..77b7e384c27 100644
--- a/chromium/net/nqe/network_quality_store.h
+++ b/chromium/net/nqe/network_quality_store.h
@@ -56,8 +56,9 @@ class NET_EXPORT_PRIVATE NetworkQualityStore {
// Returns true if the network quality estimate was successfully read
// for a network with ID |network_id|, and sets |cached_network_quality| to
// the estimate read.
- bool GetById(const nqe::internal::NetworkID& network_id,
- nqe::internal::CachedNetworkQuality* cached_network_quality);
+ bool GetById(
+ const nqe::internal::NetworkID& network_id,
+ nqe::internal::CachedNetworkQuality* cached_network_quality) const;
// Adds and removes |observer| from the list of cache observers. The
// observers are notified on the same thread on which it was added. Addition
@@ -67,9 +68,6 @@ class NET_EXPORT_PRIVATE NetworkQualityStore {
void RemoveNetworkQualitiesCacheObserver(
NetworkQualitiesCacheObserver* observer);
- // Returns true if network quality for |network_id| can be cached.
- bool EligibleForCaching(const NetworkID& network_id) const;
-
// If |disable_offline_check| is set to true, the offline check is disabled
// when storing the network quality.
void DisableOfflineCheckForTesting(bool disable_offline_check);
@@ -78,7 +76,7 @@ class NET_EXPORT_PRIVATE NetworkQualityStore {
// Maximum size of the store that holds network quality estimates.
// A smaller size may reduce the cache hit rate due to frequent evictions.
// A larger size may affect performance.
- static const size_t kMaximumNetworkQualityCacheSize = 10;
+ static const size_t kMaximumNetworkQualityCacheSize = 20;
// Notifies |observer| of the current effective connection type if |observer|
// is still registered as an observer.
@@ -99,10 +97,6 @@ class NET_EXPORT_PRIVATE NetworkQualityStore {
base::ObserverList<NetworkQualitiesCacheObserver>
network_qualities_cache_observer_list_;
- // When set to true, disables the offline check when storing the network
- // quality.
- bool disable_offline_check_;
-
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<NetworkQualityStore> weak_ptr_factory_;
diff --git a/chromium/net/nqe/network_quality_store_unittest.cc b/chromium/net/nqe/network_quality_store_unittest.cc
index 40ab2f4e12a..12928c507ff 100644
--- a/chromium/net/nqe/network_quality_store_unittest.cc
+++ b/chromium/net/nqe/network_quality_store_unittest.cc
@@ -38,7 +38,7 @@ TEST(NetworkQualityStoreTest, TestCaching) {
// Entry should not be added.
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test1");
+ "test1", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
network_quality_store.Add(network_id, cached_network_quality_unknown);
EXPECT_FALSE(
@@ -48,7 +48,7 @@ TEST(NetworkQualityStoreTest, TestCaching) {
{
// Entry will be added for (2G, "test1").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test1");
+ "test1", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
network_quality_store.Add(network_id, cached_network_quality_2g_test1);
EXPECT_TRUE(
@@ -60,7 +60,7 @@ TEST(NetworkQualityStoreTest, TestCaching) {
{
// Entry will be added for (2G, "test2").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test2");
+ "test2", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
nqe::internal::CachedNetworkQuality cached_network_quality(
tick_clock.NowTicks(),
@@ -77,7 +77,7 @@ TEST(NetworkQualityStoreTest, TestCaching) {
{
// Entry will be added for (3G, "test3").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_3G,
- "test3");
+ "test3", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
nqe::internal::CachedNetworkQuality cached_network_quality(
tick_clock.NowTicks(),
@@ -92,9 +92,9 @@ TEST(NetworkQualityStoreTest, TestCaching) {
}
{
- // Entry will not be added for (Unknown, "").
+ // Entry will be added for (Unknown, "").
nqe::internal::NetworkID network_id(
- NetworkChangeNotifier::CONNECTION_UNKNOWN, "");
+ NetworkChangeNotifier::CONNECTION_UNKNOWN, "", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
nqe::internal::CachedNetworkQuality set_network_quality(
tick_clock.NowTicks(),
@@ -102,14 +102,14 @@ TEST(NetworkQualityStoreTest, TestCaching) {
base::TimeDelta::FromSeconds(4), 4),
EFFECTIVE_CONNECTION_TYPE_4G);
network_quality_store.Add(network_id, set_network_quality);
- EXPECT_FALSE(
+ EXPECT_TRUE(
network_quality_store.GetById(network_id, &read_network_quality));
}
{
// Existing entry will be read for (2G, "test1").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test1");
+ "test1", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
EXPECT_TRUE(
network_quality_store.GetById(network_id, &read_network_quality));
@@ -120,7 +120,7 @@ TEST(NetworkQualityStoreTest, TestCaching) {
{
// Existing entry will be overwritten for (2G, "test1").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test1");
+ "test1", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
const nqe::internal::CachedNetworkQuality cached_network_quality(
tick_clock.NowTicks(),
@@ -137,13 +137,96 @@ TEST(NetworkQualityStoreTest, TestCaching) {
{
// No entry should exist for (2G, "test4").
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test4");
+ "test4", 0);
nqe::internal::CachedNetworkQuality read_network_quality;
EXPECT_FALSE(
network_quality_store.GetById(network_id, &read_network_quality));
}
}
+TEST(NetworkQualityStoreTest, TestCachingClosestSignalStrength) {
+ nqe::internal::NetworkQualityStore network_quality_store;
+ base::SimpleTestTickClock tick_clock;
+
+ // Cached network quality for network with NetworkID (2G, "test1").
+ const nqe::internal::CachedNetworkQuality cached_network_quality_strength_1(
+ tick_clock.NowTicks(),
+ nqe::internal::NetworkQuality(base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromSeconds(1), 1),
+ EFFECTIVE_CONNECTION_TYPE_2G);
+
+ const nqe::internal::CachedNetworkQuality cached_network_quality_strength_3(
+ tick_clock.NowTicks(),
+ nqe::internal::NetworkQuality(base::TimeDelta::FromSeconds(3),
+ base::TimeDelta::FromSeconds(3), 3),
+ EFFECTIVE_CONNECTION_TYPE_2G);
+
+ {
+ // Entry will be added for (2G, "test1") with signal strength value of 1.
+ nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
+ "test1", 1);
+ nqe::internal::CachedNetworkQuality read_network_quality;
+ network_quality_store.Add(network_id, cached_network_quality_strength_1);
+ EXPECT_TRUE(
+ network_quality_store.GetById(network_id, &read_network_quality));
+ EXPECT_EQ(cached_network_quality_strength_1.network_quality(),
+ read_network_quality.network_quality());
+ }
+
+ {
+ // Entry will be added for (2G, "test1") with signal strength value of 3.
+ nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
+ "test1", 3);
+ nqe::internal::CachedNetworkQuality read_network_quality;
+ network_quality_store.Add(network_id, cached_network_quality_strength_3);
+ EXPECT_TRUE(
+ network_quality_store.GetById(network_id, &read_network_quality));
+ EXPECT_EQ(cached_network_quality_strength_3.network_quality(),
+ read_network_quality.network_quality());
+ }
+
+ {
+ // Now with cached entries for signal strengths 1 and 3, verify across the
+ // range of strength values that the closest value match will be returned
+ // when looking up (2G, "test1", signal_strength).
+ for (int32_t signal_strength = 0; signal_strength <= 4; ++signal_strength) {
+ nqe::internal::CachedNetworkQuality expected_cached_network_quality =
+ signal_strength <= 2 ? cached_network_quality_strength_1
+ : cached_network_quality_strength_3;
+ nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
+ "test1", signal_strength);
+ nqe::internal::CachedNetworkQuality read_network_quality;
+ EXPECT_TRUE(
+ network_quality_store.GetById(network_id, &read_network_quality));
+ EXPECT_EQ(expected_cached_network_quality.network_quality(),
+ read_network_quality.network_quality());
+ }
+ }
+
+ {
+ // Existing entry will be read for (2G, "test1", INT32_MIN).
+ // The first entry in the store matching (2G, "test1", *) would be returned.
+ int32_t signal_strength = INT32_MIN;
+ nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
+ "test1", signal_strength);
+ nqe::internal::CachedNetworkQuality read_network_quality;
+ EXPECT_TRUE(
+ network_quality_store.GetById(network_id, &read_network_quality));
+ EXPECT_TRUE((cached_network_quality_strength_1.network_quality() ==
+ read_network_quality.network_quality()) ||
+ (cached_network_quality_strength_3.network_quality() ==
+ read_network_quality.network_quality()));
+ }
+
+ {
+ // No entry should exist for (2G, "test4").
+ nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
+ "test4", 0);
+ nqe::internal::CachedNetworkQuality read_network_quality;
+ EXPECT_FALSE(
+ network_quality_store.GetById(network_id, &read_network_quality));
+ }
+}
// Tests if the cache size remains bounded. Also, ensure that the cache is
// LRU.
TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) {
@@ -151,7 +234,7 @@ TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) {
base::SimpleTestTickClock tick_clock;
// Add more networks than the maximum size of the cache.
- const size_t network_count = 11;
+ const size_t network_count = 21;
nqe::internal::CachedNetworkQuality read_network_quality(
tick_clock.NowTicks(),
@@ -161,7 +244,7 @@ TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) {
for (size_t i = 0; i < network_count; ++i) {
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test" + base::IntToString(i));
+ "test" + base::IntToString(i), 0);
const nqe::internal::CachedNetworkQuality network_quality(
tick_clock.NowTicks(),
@@ -176,7 +259,7 @@ TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) {
size_t cache_match_count = 0;
for (size_t i = 0; i < network_count; ++i) {
nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
- "test" + base::IntToString(i));
+ "test" + base::IntToString(i), 0);
nqe::internal::CachedNetworkQuality read_network_quality(
tick_clock.NowTicks(),
diff --git a/chromium/net/nqe/observation_buffer_unittest.cc b/chromium/net/nqe/observation_buffer_unittest.cc
index 1f15b79f2db..187e1c5c9fe 100644
--- a/chromium/net/nqe/observation_buffer_unittest.cc
+++ b/chromium/net/nqe/observation_buffer_unittest.cc
@@ -45,10 +45,6 @@ TEST(NetworkQualityObservationBufferTest, BoundedBuffer) {
}
}
-// Test disabled on OS_WIN to avoid linking errors when calling
-// SetTickClockForTesting.
-// TODO(tbansal): crbug.com/651963. Pass the clock through NQE's constructor.
-#if !defined(OS_WIN)
// Verify that the percentiles are monotonically non-decreasing when a weight is
// applied.
TEST(NetworkQualityObservationBufferTest, GetPercentileWithWeights) {
@@ -90,7 +86,6 @@ TEST(NetworkQualityObservationBufferTest, GetPercentileWithWeights) {
}
EXPECT_LT(result_lowest, result_highest);
}
-#endif
// Verifies that the percentiles are correctly computed. All observations have
// the same timestamp.
diff --git a/chromium/net/nqe/proto/network_id_proto.proto b/chromium/net/nqe/proto/network_id_proto.proto
index 28c7fb06e7d..a6d217a8c82 100644
--- a/chromium/net/nqe/proto/network_id_proto.proto
+++ b/chromium/net/nqe/proto/network_id_proto.proto
@@ -9,7 +9,8 @@ option optimize_for = LITE_RUNTIME;
package net.nqe.internal;
// NetworkIDProto contains data that can be used to uniquely identify a network
-// type. Next id: 3
+// type.
+// Next id: 4
message NetworkIDProto {
// Connection type of the network mapped from
// net::NetworkChangeNotifier::ConnectionType.
@@ -17,4 +18,11 @@ message NetworkIDProto {
// Name of this network. This is set to WiFi SSID or the MCCMNC of the
// network.
optional string id = 2;
+ // Signal strength of the network. Set to INT32_MIN when the value is
+ // unavailable. Otherwise, must be between 0 and 4 (both inclusive). This may
+ // take into account many different radio technology inputs. 0 represents very
+ // poor signal strength while 4 represents a very strong signal strength.
+ // The range is capped between 0 and 4 to ensure that a change in the value
+ // indicates a non-negligible change in the signal quality.
+ optional int32 signal_strength = 3;
}
diff --git a/chromium/net/nqe/throughput_analyzer.cc b/chromium/net/nqe/throughput_analyzer.cc
index e72821cd37a..ac685d118eb 100644
--- a/chromium/net/nqe/throughput_analyzer.cc
+++ b/chromium/net/nqe/throughput_analyzer.cc
@@ -215,6 +215,46 @@ void ThroughputAnalyzer::NotifyRequestCompleted(const URLRequest& request) {
MaybeStartThroughputObservationWindow();
}
+bool ThroughputAnalyzer::IsHangingWindow(int64_t bits_received,
+ base::TimeDelta duration,
+ double downstream_kbps_double) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (params_->throughput_hanging_requests_cwnd_size_multiplier() <= 0)
+ return false;
+
+ // Initial congestion window size for TCP connections.
+ static constexpr size_t kCwndSizeKilobytes = 10 * 1.5;
+ static constexpr size_t kCwndSizeBits = kCwndSizeKilobytes * 1000 * 8;
+
+ // Scale the |duration| to one HTTP RTT, and compute the number of bits that
+ // would be received over a duration of one HTTP RTT.
+ size_t bits_received_over_one_http_rtt =
+ bits_received * (network_quality_provider_->GetHttpRTT()
+ .value_or(base::TimeDelta::FromSeconds(10))
+ .InMillisecondsF() /
+ duration.InMillisecondsF());
+
+ // If |is_hanging| is true, it implies that less than
+ // kCwndSizeKilobytes were received over a period of 1 HTTP RTT. For a network
+ // that is not under-utilized, it is expected that at least |kCwndSizeBits|
+ // are received over a duration of 1 HTTP RTT.
+ bool is_hanging =
+ bits_received_over_one_http_rtt <
+ (kCwndSizeBits *
+ params_->throughput_hanging_requests_cwnd_size_multiplier());
+
+ // Record kbps as function of |is_hanging|.
+ if (is_hanging) {
+ UMA_HISTOGRAM_COUNTS_1M("NQE.ThroughputObservation.Hanging",
+ downstream_kbps_double);
+ } else {
+ UMA_HISTOGRAM_COUNTS_1M("NQE.ThroughputObservation.NotHanging",
+ downstream_kbps_double);
+ }
+ return is_hanging;
+}
+
bool ThroughputAnalyzer::MaybeGetThroughputObservation(
int32_t* downstream_kbps) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -248,6 +288,13 @@ bool ThroughputAnalyzer::MaybeGetThroughputObservation(
double downstream_kbps_double =
(bits_received * 1.0f) / duration.InMillisecondsF();
+
+ if (IsHangingWindow(bits_received, duration, downstream_kbps_double)) {
+ requests_.clear();
+ EndThroughputObservationWindow();
+ return false;
+ }
+
// Round-up |downstream_kbps_double|.
*downstream_kbps = static_cast<int64_t>(std::ceil(downstream_kbps_double));
DCHECK(IsCurrentlyTrackingThroughput());
diff --git a/chromium/net/nqe/throughput_analyzer.h b/chromium/net/nqe/throughput_analyzer.h
index a6cb95c7cf5..77350017b3a 100644
--- a/chromium/net/nqe/throughput_analyzer.h
+++ b/chromium/net/nqe/throughput_analyzer.h
@@ -113,6 +113,12 @@ class NET_EXPORT_PRIVATE ThroughputAnalyzer {
// testing.
void EraseHangingRequests(const URLRequest& request);
+ // Returns true if the current throughput observation window is heuristically
+ // determined to contain hanging requests.
+ bool IsHangingWindow(int64_t bits_received,
+ base::TimeDelta duration,
+ double downstream_kbps_double) const;
+
private:
friend class TestThroughputAnalyzer;
diff --git a/chromium/net/nqe/throughput_analyzer_unittest.cc b/chromium/net/nqe/throughput_analyzer_unittest.cc
index 66432232673..629c10379ea 100644
--- a/chromium/net/nqe/throughput_analyzer_unittest.cc
+++ b/chromium/net/nqe/throughput_analyzer_unittest.cc
@@ -104,6 +104,7 @@ class TestThroughputAnalyzer : public internal::ThroughputAnalyzer {
using internal::ThroughputAnalyzer::disable_throughput_measurements;
using internal::ThroughputAnalyzer::CountInFlightRequests;
using internal::ThroughputAnalyzer::EraseHangingRequests;
+ using internal::ThroughputAnalyzer::IsHangingWindow;
private:
int throughput_observations_received_;
@@ -126,12 +127,12 @@ TEST(ThroughputAnalyzerTest, MaximumRequests) {
}};
for (const auto& test : tests) {
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider,
- &params, &tick_clock);
+ &params, tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
@@ -168,7 +169,7 @@ TEST(ThroughputAnalyzerTest, MaximumRequests) {
// Tests that the throughput observation is taken only if there are sufficient
// number of requests in-flight.
TEST(ThroughputAnalyzerTest, TestMinRequestsForThroughputSample) {
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
@@ -177,7 +178,7 @@ TEST(ThroughputAnalyzerTest, TestMinRequestsForThroughputSample) {
num_requests <= params.throughput_min_requests_in_flight() + 1;
++num_requests) {
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider,
- &params, &tick_clock);
+ &params, tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
throughput_analyzer.AddIPAddressResolution(&context);
@@ -270,7 +271,7 @@ TEST(ThroughputAnalyzerTest, TestHangingRequests) {
for (const auto& test : tests) {
base::HistogramTester histogram_tester;
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
if (test.http_rtt >= base::TimeDelta())
network_quality_provider.SetHttpRtt(test.http_rtt);
@@ -283,7 +284,7 @@ TEST(ThroughputAnalyzerTest, TestHangingRequests) {
const size_t num_requests = params.throughput_min_requests_in_flight();
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider,
- &params, &tick_clock);
+ &params, tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
throughput_analyzer.AddIPAddressResolution(&context);
@@ -557,13 +558,13 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) {
};
for (const auto& test : tests) {
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
// Localhost requests are not allowed for estimation purposes.
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider,
- &params, &tick_clock);
+ &params, tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
@@ -658,7 +659,7 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithNetworkRequestsOverlap) {
};
for (const auto& test : tests) {
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
// Localhost requests are not allowed for estimation purposes.
std::map<std::string, std::string> variation_params;
@@ -666,7 +667,7 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithNetworkRequestsOverlap) {
base::IntToString(test.throughput_min_requests_in_flight);
NetworkQualityEstimatorParams params(variation_params);
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider,
- &params, &tick_clock);
+ &params, tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
throughput_analyzer.AddIPAddressResolution(&context);
@@ -716,13 +717,13 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithNetworkRequestsOverlap) {
// of network requests overlap, and the minimum number of in flight requests
// when taking an observation is more than 1.
TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) {
- base::DefaultTickClock tick_clock;
+ base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
variation_params["throughput_min_requests_in_flight"] = "3";
NetworkQualityEstimatorParams params(variation_params);
TestThroughputAnalyzer throughput_analyzer(&network_quality_provider, &params,
- &tick_clock);
+ tick_clock);
TestDelegate test_delegate;
TestURLRequestContext context;
throughput_analyzer.AddIPAddressResolution(&context);
@@ -783,6 +784,63 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) {
EXPECT_EQ(1, throughput_analyzer.throughput_observations_received());
}
+TEST(ThroughputAnalyzerTest, TestHangingWindow) {
+ static constexpr size_t kCwndSizeKilobytes = 10 * 1.5;
+ static constexpr size_t kCwndSizeBits = kCwndSizeKilobytes * 1000 * 8;
+
+ base::SimpleTestTickClock tick_clock;
+
+ TestNetworkQualityProvider network_quality_provider;
+ int64_t http_rtt_msec = 1000;
+ network_quality_provider.SetHttpRtt(
+ base::TimeDelta::FromMilliseconds(http_rtt_msec));
+ std::map<std::string, std::string> variation_params;
+ variation_params["throughput_hanging_requests_cwnd_size_multiplier"] = "1";
+ NetworkQualityEstimatorParams params(variation_params);
+
+ TestThroughputAnalyzer throughput_analyzer(&network_quality_provider, &params,
+ &tick_clock);
+
+ const struct {
+ size_t bits_received;
+ base::TimeDelta window_duration;
+ bool expected_hanging;
+ } tests[] = {
+ {100, base::TimeDelta::FromMilliseconds(http_rtt_msec), true},
+ {kCwndSizeBits - 1, base::TimeDelta::FromMilliseconds(http_rtt_msec),
+ true},
+ {kCwndSizeBits + 1, base::TimeDelta::FromMilliseconds(http_rtt_msec),
+ false},
+ {2 * (kCwndSizeBits - 1),
+ base::TimeDelta::FromMilliseconds(http_rtt_msec * 2), true},
+ {2 * (kCwndSizeBits + 1),
+ base::TimeDelta::FromMilliseconds(http_rtt_msec * 2), false},
+ {kCwndSizeBits / 2 - 1,
+ base::TimeDelta::FromMilliseconds(http_rtt_msec / 2), true},
+ {kCwndSizeBits / 2 + 1,
+ base::TimeDelta::FromMilliseconds(http_rtt_msec / 2), false},
+ };
+
+ for (const auto& test : tests) {
+ base::HistogramTester histogram_tester;
+ double kbps = test.bits_received / test.window_duration.InMillisecondsF();
+ EXPECT_EQ(test.expected_hanging,
+ throughput_analyzer.IsHangingWindow(test.bits_received,
+ test.window_duration, kbps));
+
+ if (test.expected_hanging) {
+ histogram_tester.ExpectUniqueSample("NQE.ThroughputObservation.Hanging",
+ kbps, 1);
+ histogram_tester.ExpectTotalCount("NQE.ThroughputObservation.NotHanging",
+ 0);
+ } else {
+ histogram_tester.ExpectTotalCount("NQE.ThroughputObservation.Hanging", 0);
+ histogram_tester.ExpectUniqueSample(
+ "NQE.ThroughputObservation.NotHanging", kbps, 1);
+ }
+ }
+}
+
} // namespace
} // namespace nqe
diff --git a/chromium/net/ntlm/ntlm_buffer_reader.cc b/chromium/net/ntlm/ntlm_buffer_reader.cc
index b23e38b851c..8bba339a998 100644
--- a/chromium/net/ntlm/ntlm_buffer_reader.cc
+++ b/chromium/net/ntlm/ntlm_buffer_reader.cc
@@ -25,7 +25,7 @@ NtlmBufferReader::NtlmBufferReader(const uint8_t* ptr, size_t len)
: NtlmBufferReader(
base::StringPiece(reinterpret_cast<const char*>(ptr), len)) {}
-NtlmBufferReader::~NtlmBufferReader() {}
+NtlmBufferReader::~NtlmBufferReader() = default;
bool NtlmBufferReader::CanRead(size_t len) const {
return CanReadFrom(GetCursor(), len);
diff --git a/chromium/net/ntlm/ntlm_buffer_writer.cc b/chromium/net/ntlm/ntlm_buffer_writer.cc
index da6bc773cc7..300812b4c4d 100644
--- a/chromium/net/ntlm/ntlm_buffer_writer.cc
+++ b/chromium/net/ntlm/ntlm_buffer_writer.cc
@@ -18,7 +18,7 @@ namespace ntlm {
NtlmBufferWriter::NtlmBufferWriter(size_t buffer_len)
: buffer_(buffer_len, 0), cursor_(0) {}
-NtlmBufferWriter::~NtlmBufferWriter() {}
+NtlmBufferWriter::~NtlmBufferWriter() = default;
bool NtlmBufferWriter::CanWrite(size_t len) const {
if (!GetBufferPtr())
diff --git a/chromium/net/ntlm/ntlm_client.cc b/chromium/net/ntlm/ntlm_client.cc
index a034fd37fbd..f8e12f5fdec 100644
--- a/chromium/net/ntlm/ntlm_client.cc
+++ b/chromium/net/ntlm/ntlm_client.cc
@@ -144,7 +144,7 @@ NtlmClient::NtlmClient(NtlmFeatures features)
GenerateNegotiateMessage();
}
-NtlmClient::~NtlmClient() {}
+NtlmClient::~NtlmClient() = default;
Buffer NtlmClient::GetNegotiateMessage() const {
return negotiate_message_;
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher.cc b/chromium/net/proxy/dhcp_proxy_script_fetcher.cc
index 839c59bbd31..71a32c213b8 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher.cc
@@ -12,13 +12,13 @@ std::string DhcpProxyScriptFetcher::GetFetcherName() const {
return std::string();
}
-DhcpProxyScriptFetcher::DhcpProxyScriptFetcher() {}
+DhcpProxyScriptFetcher::DhcpProxyScriptFetcher() = default;
-DhcpProxyScriptFetcher::~DhcpProxyScriptFetcher() {}
+DhcpProxyScriptFetcher::~DhcpProxyScriptFetcher() = default;
-DoNothingDhcpProxyScriptFetcher::DoNothingDhcpProxyScriptFetcher() {}
+DoNothingDhcpProxyScriptFetcher::DoNothingDhcpProxyScriptFetcher() = default;
-DoNothingDhcpProxyScriptFetcher::~DoNothingDhcpProxyScriptFetcher() {}
+DoNothingDhcpProxyScriptFetcher::~DoNothingDhcpProxyScriptFetcher() = default;
int DoNothingDhcpProxyScriptFetcher::Fetch(
base::string16* utf16_text, const CompletionCallback& callback) {
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
index 0590690344b..b0188eaf020 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_factory.cc
@@ -13,9 +13,9 @@
namespace net {
-DhcpProxyScriptFetcherFactory::DhcpProxyScriptFetcherFactory() {}
+DhcpProxyScriptFetcherFactory::DhcpProxyScriptFetcherFactory() = default;
-DhcpProxyScriptFetcherFactory::~DhcpProxyScriptFetcherFactory() {}
+DhcpProxyScriptFetcherFactory::~DhcpProxyScriptFetcherFactory() = default;
std::unique_ptr<DhcpProxyScriptFetcher> DhcpProxyScriptFetcherFactory::Create(
URLRequestContext* context) {
diff --git a/chromium/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc b/chromium/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
index 03ed2c9d118..b7e407c9b32 100644
--- a/chromium/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
+++ b/chromium/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
@@ -674,7 +674,7 @@ TEST(DhcpProxyScriptFetcherWin, OnShutdown) {
client.ResetTestState();
EXPECT_THAT(client.RunTestThatMayFailSync(), IsError(ERR_CONTEXT_SHUT_DOWN));
- EXPECT_EQ(0u, context.url_requests().size());
+ EXPECT_EQ(0u, context.url_requests()->size());
}
} // namespace
diff --git a/chromium/net/proxy/dhcpcsvc_init_win.cc b/chromium/net/proxy/dhcpcsvc_init_win.cc
index d243f1859aa..d9079606782 100644
--- a/chromium/net/proxy/dhcpcsvc_init_win.cc
+++ b/chromium/net/proxy/dhcpcsvc_init_win.cc
@@ -7,6 +7,8 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include <windows.h> // Must be in front of other Windows header files.
+
#include <dhcpcsdk.h>
#include <dhcpv6csdk.h>
diff --git a/chromium/net/proxy/mock_proxy_resolver.cc b/chromium/net/proxy/mock_proxy_resolver.cc
index 2d6889d05bd..0daea49ccdc 100644
--- a/chromium/net/proxy/mock_proxy_resolver.cc
+++ b/chromium/net/proxy/mock_proxy_resolver.cc
@@ -31,7 +31,7 @@ MockAsyncProxyResolver::Job::Job(MockAsyncProxyResolver* resolver,
const CompletionCallback& callback)
: resolver_(resolver), url_(url), results_(results), callback_(callback) {}
-MockAsyncProxyResolver::Job::~Job() {}
+MockAsyncProxyResolver::Job::~Job() = default;
void MockAsyncProxyResolver::Job::CompleteNow(int rv) {
CompletionCallback callback = callback_;
@@ -41,7 +41,7 @@ void MockAsyncProxyResolver::Job::CompleteNow(int rv) {
callback.Run(rv);
}
-MockAsyncProxyResolver::~MockAsyncProxyResolver() {}
+MockAsyncProxyResolver::~MockAsyncProxyResolver() = default;
int MockAsyncProxyResolver::GetProxyForURL(
const GURL& url,
@@ -77,8 +77,7 @@ void MockAsyncProxyResolver::RemovePendingJob(Job* job) {
pending_jobs_.erase(it);
}
-MockAsyncProxyResolver::MockAsyncProxyResolver() {
-}
+MockAsyncProxyResolver::MockAsyncProxyResolver() = default;
MockAsyncProxyResolverFactory::Request::Request(
MockAsyncProxyResolverFactory* factory,
@@ -90,8 +89,7 @@ MockAsyncProxyResolverFactory::Request::Request(
resolver_(resolver),
callback_(callback) {}
-MockAsyncProxyResolverFactory::Request::~Request() {
-}
+MockAsyncProxyResolverFactory::Request::~Request() = default;
void MockAsyncProxyResolverFactory::Request::CompleteNow(
int rv,
diff --git a/chromium/net/proxy/mock_proxy_script_fetcher.cc b/chromium/net/proxy/mock_proxy_script_fetcher.cc
index e07bde57a8b..8e0d3dd39c7 100644
--- a/chromium/net/proxy/mock_proxy_script_fetcher.cc
+++ b/chromium/net/proxy/mock_proxy_script_fetcher.cc
@@ -18,7 +18,7 @@ MockProxyScriptFetcher::MockProxyScriptFetcher()
waiting_for_fetch_(false),
is_shutdown_(false) {}
-MockProxyScriptFetcher::~MockProxyScriptFetcher() {}
+MockProxyScriptFetcher::~MockProxyScriptFetcher() = default;
// ProxyScriptFetcher implementation.
int MockProxyScriptFetcher::Fetch(const GURL& url, base::string16* text,
diff --git a/chromium/net/proxy/multi_threaded_proxy_resolver.cc b/chromium/net/proxy/multi_threaded_proxy_resolver.cc
index 4edab19ff6d..a50b3f946ba 100644
--- a/chromium/net/proxy/multi_threaded_proxy_resolver.cc
+++ b/chromium/net/proxy/multi_threaded_proxy_resolver.cc
@@ -224,7 +224,7 @@ class Job : public base::RefCountedThreadSafe<Job> {
friend class base::RefCountedThreadSafe<Job>;
- virtual ~Job() {}
+ virtual ~Job() = default;
private:
const Type type_;
@@ -270,7 +270,7 @@ class CreateResolverJob : public Job {
}
protected:
- ~CreateResolverJob() override {}
+ ~CreateResolverJob() override = default;
private:
// Runs the completion callback on the origin thread.
@@ -338,7 +338,7 @@ class MultiThreadedProxyResolver::GetProxyForURLJob : public Job {
}
protected:
- ~GetProxyForURLJob() override {}
+ ~GetProxyForURLJob() override = default;
private:
// Runs the completion callback on the origin thread.
diff --git a/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc b/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
index 59524eb717b..8cc5bb6306c 100644
--- a/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
+++ b/chromium/net/proxy/multi_threaded_proxy_resolver_unittest.cc
@@ -142,7 +142,7 @@ class BlockableProxyResolverFactory : public ProxyResolverFactory {
public:
BlockableProxyResolverFactory() : ProxyResolverFactory(false) {}
- ~BlockableProxyResolverFactory() override {}
+ ~BlockableProxyResolverFactory() override = default;
int CreateProxyResolver(
const scoped_refptr<ProxyResolverScriptData>& script_data,
diff --git a/chromium/net/proxy/network_delegate_error_observer.cc b/chromium/net/proxy/network_delegate_error_observer.cc
index e51b39994f2..6fe0aaace05 100644
--- a/chromium/net/proxy/network_delegate_error_observer.cc
+++ b/chromium/net/proxy/network_delegate_error_observer.cc
@@ -43,8 +43,7 @@ NetworkDelegateErrorObserver::Core::Core(
DCHECK(origin_runner);
}
-NetworkDelegateErrorObserver::Core::~Core() {}
-
+NetworkDelegateErrorObserver::Core::~Core() = default;
void NetworkDelegateErrorObserver::Core::NotifyPACScriptError(
int line_number,
diff --git a/chromium/net/proxy/network_delegate_error_observer_unittest.cc b/chromium/net/proxy/network_delegate_error_observer_unittest.cc
index 3055340fbc9..8a6fe3c027b 100644
--- a/chromium/net/proxy/network_delegate_error_observer_unittest.cc
+++ b/chromium/net/proxy/network_delegate_error_observer_unittest.cc
@@ -22,7 +22,7 @@ namespace {
class TestNetworkDelegate : public NetworkDelegateImpl {
public:
TestNetworkDelegate() : got_pac_error_(false) {}
- ~TestNetworkDelegate() override {}
+ ~TestNetworkDelegate() override = default;
bool got_pac_error() const { return got_pac_error_; }
diff --git a/chromium/net/proxy/pac_js_library.h b/chromium/net/proxy/pac_js_library.h
new file mode 100644
index 00000000000..a26ea80a7e6
--- /dev/null
+++ b/chromium/net/proxy/pac_js_library.h
@@ -0,0 +1,282 @@
+// Copyright (c) 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_PROXY_PAC_JS_LIBRARY_H_
+#define NET_PROXY_PAC_JS_LIBRARY_H_
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Akhil Arora <akhil.arora@sun.com>
+ * Tomi Leppikangas <Tomi.Leppikangas@oulu.fi>
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// The following code was formatted from:
+// 'mozilla/netwerk/base/src/nsProxyAutoConfig.js' (1.55)
+//
+// Using the command:
+// $ cat nsProxyAutoConfig.js |
+// awk '/var pacUtils/,/EOF/' |
+// sed -e 's/^\s*$/""/g' |
+// sed -e 's/"\s*[+]\s*$/"/g' |
+// sed -e 's/"$/" \\/g' |
+// sed -e 's/\/(ipaddr);/\/.exec(ipaddr);/g' |
+// grep -v '^var pacUtils ='
+//
+// isPlainHost() was removed.
+#define PAC_JS_LIBRARY \
+ "function dnsDomainIs(host, domain) {\n" \
+ " return (host.length >= domain.length &&\n" \
+ " host.substring(host.length - domain.length) == domain);\n" \
+ "}\n" \
+ "" \
+ "function dnsDomainLevels(host) {\n" \
+ " return host.split('.').length-1;\n" \
+ "}\n" \
+ "" \
+ "function convert_addr(ipchars) {\n" \
+ " var bytes = ipchars.split('.');\n" \
+ " var result = ((bytes[0] & 0xff) << 24) |\n" \
+ " ((bytes[1] & 0xff) << 16) |\n" \
+ " ((bytes[2] & 0xff) << 8) |\n" \
+ " (bytes[3] & 0xff);\n" \
+ " return result;\n" \
+ "}\n" \
+ "" \
+ "function isInNet(ipaddr, pattern, maskstr) {\n" \
+ " var test = " \
+ "/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n" \
+ " if (test == null) {\n" \
+ " ipaddr = dnsResolve(ipaddr);\n" \
+ " if (ipaddr == null)\n" \
+ " return false;\n" \
+ " } else if (test[1] > 255 || test[2] > 255 || \n" \
+ " test[3] > 255 || test[4] > 255) {\n" \
+ " return false; // not an IP address\n" \
+ " }\n" \
+ " var host = convert_addr(ipaddr);\n" \
+ " var pat = convert_addr(pattern);\n" \
+ " var mask = convert_addr(maskstr);\n" \
+ " return ((host & mask) == (pat & mask));\n" \
+ " \n" \
+ "}\n" \
+ "" \
+ "function isResolvable(host) {\n" \
+ " var ip = dnsResolve(host);\n" \
+ " return (ip != null);\n" \
+ "}\n" \
+ "" \
+ "function localHostOrDomainIs(host, hostdom) {\n" \
+ " return (host == hostdom) ||\n" \
+ " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" \
+ "}\n" \
+ "" \
+ "function shExpMatch(url, pattern) {\n" \
+ " pattern = pattern.replace(/\\./g, '\\\\.');\n" \
+ " pattern = pattern.replace(/\\*/g, '.*');\n" \
+ " pattern = pattern.replace(/\\?/g, '.');\n" \
+ " var newRe = new RegExp('^'+pattern+'$');\n" \
+ " return newRe.test(url);\n" \
+ "}\n" \
+ "" \
+ "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
+ "" \
+ "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, " \
+ "AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" \
+ "" \
+ "function weekdayRange() {\n" \
+ " function getDay(weekday) {\n" \
+ " if (weekday in wdays) {\n" \
+ " return wdays[weekday];\n" \
+ " }\n" \
+ " return -1;\n" \
+ " }\n" \
+ " var date = new Date();\n" \
+ " var argc = arguments.length;\n" \
+ " var wday;\n" \
+ " if (argc < 1)\n" \
+ " return false;\n" \
+ " if (arguments[argc - 1] == 'GMT') {\n" \
+ " argc--;\n" \
+ " wday = date.getUTCDay();\n" \
+ " } else {\n" \
+ " wday = date.getDay();\n" \
+ " }\n" \
+ " var wd1 = getDay(arguments[0]);\n" \
+ " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
+ " return (wd1 == -1 || wd2 == -1) ? false\n" \
+ " : (wd1 <= wday && wday <= wd2);\n" \
+ "}\n" \
+ "" \
+ "function dateRange() {\n" \
+ " function getMonth(name) {\n" \
+ " if (name in months) {\n" \
+ " return months[name];\n" \
+ " }\n" \
+ " return -1;\n" \
+ " }\n" \
+ " var date = new Date();\n" \
+ " var argc = arguments.length;\n" \
+ " if (argc < 1) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " var isGMT = (arguments[argc - 1] == 'GMT');\n" \
+ "\n" \
+ " if (isGMT) {\n" \
+ " argc--;\n" \
+ " }\n" \
+ " // function will work even without explict handling of this case\n" \
+ " if (argc == 1) {\n" \
+ " var tmp = parseInt(arguments[0]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" \
+ "getMonth(arguments[0]));\n" \
+ " } else if (tmp < 32) {\n" \
+ " return ((isGMT ? date.getUTCDate() : date.getDate()) == " \
+ "tmp);\n" \
+ " } else { \n" \
+ " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) " \
+ "==\n" \
+ "tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " var year = date.getFullYear();\n" \
+ " var date1, date2;\n" \
+ " date1 = new Date(year, 0, 1, 0, 0, 0);\n" \
+ " date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
+ " var adjustMonth = false;\n" \
+ " for (var i = 0; i < (argc >> 1); i++) {\n" \
+ " var tmp = parseInt(arguments[i]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " var mon = getMonth(arguments[i]);\n" \
+ " date1.setMonth(mon);\n" \
+ " } else if (tmp < 32) {\n" \
+ " adjustMonth = (argc <= 2);\n" \
+ " date1.setDate(tmp);\n" \
+ " } else {\n" \
+ " date1.setFullYear(tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " for (var i = (argc >> 1); i < argc; i++) {\n" \
+ " var tmp = parseInt(arguments[i]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " var mon = getMonth(arguments[i]);\n" \
+ " date2.setMonth(mon);\n" \
+ " } else if (tmp < 32) {\n" \
+ " date2.setDate(tmp);\n" \
+ " } else {\n" \
+ " date2.setFullYear(tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " if (adjustMonth) {\n" \
+ " date1.setMonth(date.getMonth());\n" \
+ " date2.setMonth(date.getMonth());\n" \
+ " }\n" \
+ " if (isGMT) {\n" \
+ " var tmp = date;\n" \
+ " tmp.setFullYear(date.getUTCFullYear());\n" \
+ " tmp.setMonth(date.getUTCMonth());\n" \
+ " tmp.setDate(date.getUTCDate());\n" \
+ " tmp.setHours(date.getUTCHours());\n" \
+ " tmp.setMinutes(date.getUTCMinutes());\n" \
+ " tmp.setSeconds(date.getUTCSeconds());\n" \
+ " date = tmp;\n" \
+ " }\n" \
+ " return ((date1 <= date) && (date <= date2));\n" \
+ "}\n" \
+ "" \
+ "function timeRange() {\n" \
+ " var argc = arguments.length;\n" \
+ " var date = new Date();\n" \
+ " var isGMT= false;\n" \
+ "\n" \
+ " if (argc < 1) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " if (arguments[argc - 1] == 'GMT') {\n" \
+ " isGMT = true;\n" \
+ " argc--;\n" \
+ " }\n" \
+ "\n" \
+ " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
+ " var date1, date2;\n" \
+ " date1 = new Date();\n" \
+ " date2 = new Date();\n" \
+ "\n" \
+ " if (argc == 1) {\n" \
+ " return (hour == arguments[0]);\n" \
+ " } else if (argc == 2) {\n" \
+ " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
+ " } else {\n" \
+ " switch (argc) {\n" \
+ " case 6:\n" \
+ " date1.setSeconds(arguments[2]);\n" \
+ " date2.setSeconds(arguments[5]);\n" \
+ " case 4:\n" \
+ " var middle = argc >> 1;\n" \
+ " date1.setHours(arguments[0]);\n" \
+ " date1.setMinutes(arguments[1]);\n" \
+ " date2.setHours(arguments[middle]);\n" \
+ " date2.setMinutes(arguments[middle + 1]);\n" \
+ " if (middle == 2) {\n" \
+ " date2.setSeconds(59);\n" \
+ " }\n" \
+ " break;\n" \
+ " default:\n" \
+ " throw 'timeRange: bad number of arguments'\n" \
+ " }\n" \
+ " }\n" \
+ "\n" \
+ " if (isGMT) {\n" \
+ " date.setFullYear(date.getUTCFullYear());\n" \
+ " date.setMonth(date.getUTCMonth());\n" \
+ " date.setDate(date.getUTCDate());\n" \
+ " date.setHours(date.getUTCHours());\n" \
+ " date.setMinutes(date.getUTCMinutes());\n" \
+ " date.setSeconds(date.getUTCSeconds());\n" \
+ " }\n" \
+ " return ((date1 <= date) && (date <= date2));\n" \
+ "}\n"
+
+// This is a Microsoft extension to PAC for IPv6, see:
+// http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
+#define PAC_JS_LIBRARY_EX \
+ "function isResolvableEx(host) {\n" \
+ " var ipList = dnsResolveEx(host);\n" \
+ " return (ipList != '');\n" \
+ "}\n"
+
+#endif // NET_PROXY_PAC_JS_LIBRARY_H_
diff --git a/chromium/net/proxy/polling_proxy_config_service.cc b/chromium/net/proxy/polling_proxy_config_service.cc
index 0208979c5b1..7a78400ad08 100644
--- a/chromium/net/proxy/polling_proxy_config_service.cc
+++ b/chromium/net/proxy/polling_proxy_config_service.cc
@@ -98,7 +98,7 @@ class PollingProxyConfigService::Core
private:
friend class base::RefCountedThreadSafe<Core>;
- ~Core() {}
+ ~Core() = default;
void PollAsync(GetConfigFunction func) {
ProxyConfig config;
diff --git a/chromium/net/proxy/proxy_bypass_rules.cc b/chromium/net/proxy/proxy_bypass_rules.cc
index 2d22ae909c7..dddfe43548a 100644
--- a/chromium/net/proxy/proxy_bypass_rules.cc
+++ b/chromium/net/proxy/proxy_bypass_rules.cc
@@ -136,18 +136,15 @@ bool IsIPAddress(const std::string& domain) {
} // namespace
-ProxyBypassRules::Rule::Rule() {
-}
+ProxyBypassRules::Rule::Rule() = default;
-ProxyBypassRules::Rule::~Rule() {
-}
+ProxyBypassRules::Rule::~Rule() = default;
bool ProxyBypassRules::Rule::Equals(const Rule& rule) const {
return ToString() == rule.ToString();
}
-ProxyBypassRules::ProxyBypassRules() {
-}
+ProxyBypassRules::ProxyBypassRules() = default;
ProxyBypassRules::ProxyBypassRules(const ProxyBypassRules& rhs) {
AssignFrom(rhs);
diff --git a/chromium/net/proxy/proxy_config.cc b/chromium/net/proxy/proxy_config.cc
index 87e17d8eb48..1f4ae8b1d16 100644
--- a/chromium/net/proxy/proxy_config.cc
+++ b/chromium/net/proxy/proxy_config.cc
@@ -45,8 +45,7 @@ ProxyConfig::ProxyRules::ProxyRules()
ProxyConfig::ProxyRules::ProxyRules(const ProxyRules& other) = default;
-ProxyConfig::ProxyRules::~ProxyRules() {
-}
+ProxyConfig::ProxyRules::~ProxyRules() = default;
void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const {
if (empty()) {
@@ -198,8 +197,7 @@ ProxyConfig::ProxyConfig()
ProxyConfig::ProxyConfig(const ProxyConfig& config) = default;
-ProxyConfig::~ProxyConfig() {
-}
+ProxyConfig::~ProxyConfig() = default;
ProxyConfig& ProxyConfig::operator=(const ProxyConfig& config) = default;
diff --git a/chromium/net/proxy/proxy_config_service_fixed.cc b/chromium/net/proxy/proxy_config_service_fixed.cc
index 3081ea5afa1..ebcdbd382f7 100644
--- a/chromium/net/proxy/proxy_config_service_fixed.cc
+++ b/chromium/net/proxy/proxy_config_service_fixed.cc
@@ -10,7 +10,7 @@ ProxyConfigServiceFixed::ProxyConfigServiceFixed(const ProxyConfig& pc)
: pc_(pc) {
}
-ProxyConfigServiceFixed::~ProxyConfigServiceFixed() {}
+ProxyConfigServiceFixed::~ProxyConfigServiceFixed() = default;
ProxyConfigService::ConfigAvailability
ProxyConfigServiceFixed::GetLatestProxyConfig(ProxyConfig* config) {
diff --git a/chromium/net/proxy/proxy_config_service_linux.cc b/chromium/net/proxy/proxy_config_service_linux.cc
index a28ed5b4e19..bd7bce55741 100644
--- a/chromium/net/proxy/proxy_config_service_linux.cc
+++ b/chromium/net/proxy/proxy_config_service_linux.cc
@@ -5,12 +5,7 @@
#include "net/proxy/proxy_config_service_linux.h"
#include <errno.h>
-#if defined(USE_GCONF)
-#include <gconf/gconf-client.h>
-#endif // defined(USE_GCONF)
#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
@@ -18,8 +13,6 @@
#include <utility>
#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/debug/leak_annotations.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -36,14 +29,11 @@
#include "base/task_scheduler/task_traits.h"
#include "base/threading/thread_restrictions.h"
#include "base/timer/timer.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_util.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_server.h"
-#include "url/url_canon.h"
#if defined(USE_GIO)
-#include "library_loaders/libgio.h" // nogncheck
+#include <gio/gio.h>
#endif // defined(USE_GIO)
namespace net {
@@ -94,8 +84,7 @@ std::string FixupProxyHostScheme(ProxyServer::Scheme scheme,
} // namespace
-ProxyConfigServiceLinux::Delegate::~Delegate() {
-}
+ProxyConfigServiceLinux::Delegate::~Delegate() = default;
bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVarForScheme(
base::StringPiece variable,
@@ -204,324 +193,8 @@ namespace {
const int kDebounceTimeoutMilliseconds = 250;
-#if defined(USE_GCONF)
-// This setting getter uses gconf, as used in GNOME 2 and some GNOME 3 desktops.
-class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
- public:
- SettingGetterImplGConf()
- : client_(nullptr),
- system_proxy_id_(0),
- system_http_proxy_id_(0),
- notify_delegate_(nullptr),
- debounce_timer_(new base::OneShotTimer()) {}
-
- ~SettingGetterImplGConf() override {
- // client_ should have been released before now, from
- // Delegate::OnDestroy(), while running on the UI thread. However
- // on exiting the process, it may happen that Delegate::OnDestroy()
- // task is left pending on the glib loop after the loop was quit,
- // and pending tasks may then be deleted without being run.
- if (client_) {
- // gconf client was not cleaned up.
- if (task_runner_->RunsTasksInCurrentSequence()) {
- // We are on the UI thread so we can clean it safely. This is
- // the case at least for ui_tests running under Valgrind in
- // bug 16076.
- VLOG(1) << "~SettingGetterImplGConf: releasing gconf client";
- ShutDown();
- } else {
- // This is very bad! We are deleting the setting getter but we're not on
- // the UI thread. This is not supposed to happen: the setting getter is
- // owned by the proxy config service's delegate, which is supposed to be
- // destroyed on the UI thread only. We will get change notifications to
- // a deleted object if we continue here, so fail now.
- LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!";
- }
- }
- DCHECK(!client_);
- }
-
- bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner)
- override {
- DCHECK(glib_task_runner->RunsTasksInCurrentSequence());
- DCHECK(!client_);
- DCHECK(!task_runner_.get());
- task_runner_ = glib_task_runner;
-
- client_ = gconf_client_get_default();
- if (!client_) {
- // It's not clear whether/when this can return NULL.
- LOG(ERROR) << "Unable to create a gconf client";
- task_runner_ = nullptr;
- return false;
- }
- GError* error = nullptr;
- bool added_system_proxy = false;
- // We need to add the directories for which we'll be asking
- // for notifications, and we might as well ask to preload them.
- // These need to be removed again in ShutDown(); we are careful
- // here to only leave client_ non-NULL if both have been added.
- gconf_client_add_dir(client_, "/system/proxy",
- GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
- if (!error) {
- added_system_proxy = true;
- gconf_client_add_dir(client_, "/system/http_proxy",
- GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
- }
- if (!error)
- return true;
-
- LOG(ERROR) << "Error requesting gconf directory: " << error->message;
- g_error_free(error);
- if (added_system_proxy)
- gconf_client_remove_dir(client_, "/system/proxy", nullptr);
- g_object_unref(client_);
- client_ = nullptr;
- task_runner_ = nullptr;
- return false;
- }
-
- void ShutDown() override {
- if (client_) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- // We must explicitly disable gconf notifications here, because the gconf
- // client will be shared between all setting getters, and they do not all
- // have the same lifetimes. (For instance, incognito sessions get their
- // own, which is destroyed when the session ends.)
- gconf_client_notify_remove(client_, system_http_proxy_id_);
- gconf_client_notify_remove(client_, system_proxy_id_);
- gconf_client_remove_dir(client_, "/system/http_proxy", nullptr);
- gconf_client_remove_dir(client_, "/system/proxy", nullptr);
- g_object_unref(client_);
- client_ = nullptr;
- task_runner_ = nullptr;
- }
- debounce_timer_.reset();
- }
-
- bool SetUpNotifications(
- ProxyConfigServiceLinux::Delegate* delegate) override {
- DCHECK(client_);
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- GError* error = nullptr;
- notify_delegate_ = delegate;
- // We have to keep track of the IDs returned by gconf_client_notify_add() so
- // that we can remove them in ShutDown(). (Otherwise, notifications will be
- // delivered to this object after it is deleted, which is bad, m'kay?)
- system_proxy_id_ = gconf_client_notify_add(client_, "/system/proxy",
- OnGConfChangeNotification, this,
- nullptr, &error);
- if (!error) {
- system_http_proxy_id_ = gconf_client_notify_add(
- client_, "/system/http_proxy", OnGConfChangeNotification, this,
- nullptr, &error);
- }
- if (!error) {
- // Simulate a change to avoid possibly losing updates before this point.
- OnChangeNotification();
- return true;
- }
-
- LOG(ERROR) << "Error requesting gconf notifications: " << error->message;
- g_error_free(error);
- ShutDown();
- return false;
- }
-
- const scoped_refptr<base::SequencedTaskRunner>& GetNotificationTaskRunner()
- override {
- return task_runner_;
- }
-
- ProxyConfigSource GetConfigSource() override {
- return PROXY_CONFIG_SOURCE_GCONF;
- }
-
- bool GetString(StringSetting key, std::string* result) override {
- switch (key) {
- case PROXY_MODE:
- return GetStringByPath("/system/proxy/mode", result);
- case PROXY_AUTOCONF_URL:
- return GetStringByPath("/system/proxy/autoconfig_url", result);
- case PROXY_HTTP_HOST:
- return GetStringByPath("/system/http_proxy/host", result);
- case PROXY_HTTPS_HOST:
- return GetStringByPath("/system/proxy/secure_host", result);
- case PROXY_FTP_HOST:
- return GetStringByPath("/system/proxy/ftp_host", result);
- case PROXY_SOCKS_HOST:
- return GetStringByPath("/system/proxy/socks_host", result);
- }
- return false; // Placate compiler.
- }
- bool GetBool(BoolSetting key, bool* result) override {
- switch (key) {
- case PROXY_USE_HTTP_PROXY:
- return GetBoolByPath("/system/http_proxy/use_http_proxy", result);
- case PROXY_USE_SAME_PROXY:
- return GetBoolByPath("/system/http_proxy/use_same_proxy", result);
- case PROXY_USE_AUTHENTICATION:
- return GetBoolByPath("/system/http_proxy/use_authentication", result);
- }
- return false; // Placate compiler.
- }
- bool GetInt(IntSetting key, int* result) override {
- switch (key) {
- case PROXY_HTTP_PORT:
- return GetIntByPath("/system/http_proxy/port", result);
- case PROXY_HTTPS_PORT:
- return GetIntByPath("/system/proxy/secure_port", result);
- case PROXY_FTP_PORT:
- return GetIntByPath("/system/proxy/ftp_port", result);
- case PROXY_SOCKS_PORT:
- return GetIntByPath("/system/proxy/socks_port", result);
- }
- return false; // Placate compiler.
- }
- bool GetStringList(StringListSetting key,
- std::vector<std::string>* result) override {
- switch (key) {
- case PROXY_IGNORE_HOSTS:
- return GetStringListByPath("/system/http_proxy/ignore_hosts", result);
- }
- return false; // Placate compiler.
- }
-
- bool BypassListIsReversed() override {
- // This is a KDE-specific setting.
- return false;
- }
-
- bool MatchHostsUsingSuffixMatching() override { return false; }
-
- private:
- bool GetStringByPath(base::StringPiece key, std::string* result) {
- DCHECK(client_);
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- GError* error = nullptr;
- gchar* value = gconf_client_get_string(client_, key.data(), &error);
- if (HandleGError(error, key.data()))
- return false;
- if (!value)
- return false;
- *result = value;
- g_free(value);
- return true;
- }
- bool GetBoolByPath(base::StringPiece key, bool* result) {
- DCHECK(client_);
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- GError* error = nullptr;
- // We want to distinguish unset values from values defaulting to
- // false. For that we need to use the type-generic
- // gconf_client_get() rather than gconf_client_get_bool().
- GConfValue* gconf_value = gconf_client_get(client_, key.data(), &error);
- if (HandleGError(error, key.data()))
- return false;
- if (!gconf_value) {
- // Unset.
- return false;
- }
- if (gconf_value->type != GCONF_VALUE_BOOL) {
- gconf_value_free(gconf_value);
- return false;
- }
- gboolean bool_value = gconf_value_get_bool(gconf_value);
- *result = static_cast<bool>(bool_value);
- gconf_value_free(gconf_value);
- return true;
- }
- bool GetIntByPath(base::StringPiece key, int* result) {
- DCHECK(client_);
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- GError* error = nullptr;
- int value = gconf_client_get_int(client_, key.data(), &error);
- if (HandleGError(error, key.data()))
- return false;
- // We don't bother to distinguish an unset value because callers
- // don't care. 0 is returned if unset.
- *result = value;
- return true;
- }
- bool GetStringListByPath(base::StringPiece key,
- std::vector<std::string>* result) {
- DCHECK(client_);
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- GError* error = nullptr;
- GSList* list =
- gconf_client_get_list(client_, key.data(), GCONF_VALUE_STRING, &error);
- if (HandleGError(error, key.data()))
- return false;
- if (!list)
- return false;
- for (GSList *it = list; it; it = it->next) {
- result->push_back(static_cast<char*>(it->data));
- g_free(it->data);
- }
- g_slist_free(list);
- return true;
- }
-
- // Logs and frees a glib error. Returns false if there was no error
- // (error is NULL).
- bool HandleGError(GError* error, base::StringPiece key) {
- if (!error)
- return false;
-
- LOG(ERROR) << "Error getting gconf value for " << key << ": "
- << error->message;
- g_error_free(error);
- return true;
- }
-
- // This is the callback from the debounce timer.
- void OnDebouncedNotification() {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- CHECK(notify_delegate_);
- // Forward to a method on the proxy config service delegate object.
- notify_delegate_->OnCheckProxyConfigSettings();
- }
-
- void OnChangeNotification() {
- // We don't use Reset() because the timer may not yet be running.
- // (In that case Stop() is a no-op.)
- debounce_timer_->Stop();
- debounce_timer_->Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds),
- this, &SettingGetterImplGConf::OnDebouncedNotification);
- }
-
- // gconf notification callback, dispatched on the default glib main loop.
- static void OnGConfChangeNotification(GConfClient* client, guint cnxn_id,
- GConfEntry* entry, gpointer user_data) {
- VLOG(1) << "gconf change notification for key "
- << gconf_entry_get_key(entry);
- // We don't track which key has changed, just that something did change.
- SettingGetterImplGConf* setting_getter =
- reinterpret_cast<SettingGetterImplGConf*>(user_data);
- setting_getter->OnChangeNotification();
- }
-
- GConfClient* client_;
- // These ids are the values returned from gconf_client_notify_add(), which we
- // will need in order to later call gconf_client_notify_remove().
- guint system_proxy_id_;
- guint system_http_proxy_id_;
-
- ProxyConfigServiceLinux::Delegate* notify_delegate_;
- std::unique_ptr<base::OneShotTimer> debounce_timer_;
-
- // Task runner for the thread that we make gconf calls on. It should
- // be the UI thread and all our methods should be called on this
- // thread. Only for assertions.
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf);
-};
-#endif // defined(USE_GCONF)
-
#if defined(USE_GIO)
-const char kProxyGConfSchema[] = "org.gnome.system.proxy";
+const char kProxyGSettingsSchema[] = "org.gnome.system.proxy";
// This setting getter uses gsettings, as used in most GNOME 3 desktops.
class SettingGetterImplGSettings
@@ -544,7 +217,7 @@ class SettingGetterImplGSettings
// after the loop was quit, and pending tasks may then be deleted
// without being run.
if (client_) {
- // gconf client was not cleaned up.
+ // gsettings client was not cleaned up.
if (task_runner_->RunsTasksInCurrentSequence()) {
// We are on the UI thread so we can clean it safely. This is
// the case at least for ui_tests running under Valgrind in
@@ -559,18 +232,8 @@ class SettingGetterImplGSettings
DCHECK(!client_);
}
- bool SchemaExists(base::StringPiece schema_name) {
- const gchar* const* schemas = libgio_loader_.g_settings_list_schemas();
- while (*schemas) {
- if (!strcmp(schema_name.data(), static_cast<const char*>(*schemas)))
- return true;
- schemas++;
- }
- return false;
- }
-
- // LoadAndCheckVersion() must be called *before* Init()!
- bool LoadAndCheckVersion(base::Environment* env);
+ // CheckVersion() must be called *before* Init()!
+ bool CheckVersion(base::Environment* env);
bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner)
override {
@@ -578,18 +241,19 @@ class SettingGetterImplGSettings
DCHECK(!client_);
DCHECK(!task_runner_.get());
- if (!SchemaExists(kProxyGConfSchema) ||
- !(client_ = libgio_loader_.g_settings_new(kProxyGConfSchema))) {
+ if (!g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
+ kProxyGSettingsSchema, FALSE) ||
+ !(client_ = g_settings_new(kProxyGSettingsSchema))) {
// It's not clear whether/when this can return NULL.
LOG(ERROR) << "Unable to create a gsettings client";
return false;
}
task_runner_ = glib_task_runner;
// We assume these all work if the above call worked.
- http_client_ = libgio_loader_.g_settings_get_child(client_, "http");
- https_client_ = libgio_loader_.g_settings_get_child(client_, "https");
- ftp_client_ = libgio_loader_.g_settings_get_child(client_, "ftp");
- socks_client_ = libgio_loader_.g_settings_get_child(client_, "socks");
+ http_client_ = g_settings_get_child(client_, "http");
+ https_client_ = g_settings_get_child(client_, "https");
+ ftp_client_ = g_settings_get_child(client_, "ftp");
+ socks_client_ = g_settings_get_child(client_, "socks");
DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_);
return true;
}
@@ -714,7 +378,7 @@ class SettingGetterImplGSettings
base::StringPiece key,
std::string* result) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- gchar* value = libgio_loader_.g_settings_get_string(client, key.data());
+ gchar* value = g_settings_get_string(client, key.data());
if (!value)
return false;
*result = value;
@@ -723,20 +387,19 @@ class SettingGetterImplGSettings
}
bool GetBoolByPath(GSettings* client, base::StringPiece key, bool* result) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- *result = static_cast<bool>(
- libgio_loader_.g_settings_get_boolean(client, key.data()));
+ *result = static_cast<bool>(g_settings_get_boolean(client, key.data()));
return true;
}
bool GetIntByPath(GSettings* client, base::StringPiece key, int* result) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- *result = libgio_loader_.g_settings_get_int(client, key.data());
+ *result = g_settings_get_int(client, key.data());
return true;
}
bool GetStringListByPath(GSettings* client,
base::StringPiece key,
std::vector<std::string>* result) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- gchar** list = libgio_loader_.g_settings_get_strv(client, key.data());
+ gchar** list = g_settings_get_strv(client, key.data());
if (!list)
return false;
for (size_t i = 0; list[i]; ++i) {
@@ -787,70 +450,25 @@ class SettingGetterImplGSettings
// thread. Only for assertions.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
- LibGioLoader libgio_loader_;
-
DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings);
};
-bool SettingGetterImplGSettings::LoadAndCheckVersion(
+bool SettingGetterImplGSettings::CheckVersion(
base::Environment* env) {
- // LoadAndCheckVersion() must be called *before* Init()!
+ // CheckVersion() must be called *before* Init()!
DCHECK(!client_);
- // The APIs to query gsettings were introduced after the minimum glib
- // version we target, so we can't link directly against them. We load them
- // dynamically at runtime, and if they don't exist, return false here. (We
- // support linking directly via gyp flags though.) Additionally, even when
- // they are present, we do two additional checks to make sure we should use
- // them and not gconf. First, we attempt to load the schema for proxy
- // settings. Second, we check for the program that was used in older
- // versions of GNOME to configure proxy settings, and return false if it
- // exists. Some distributions (e.g. Ubuntu 11.04) have the API and schema
- // but don't use gsettings for proxy settings, but they do have the old
- // binary, so we detect these systems that way.
-
- {
- // TODO(phajdan.jr): Redesign the code to load library on different thread.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
- // Try also without .0 at the end; on some systems this may be required.
- if (!libgio_loader_.Load("libgio-2.0.so.0") &&
- !libgio_loader_.Load("libgio-2.0.so")) {
- VLOG(1) << "Cannot load gio library. Will fall back to gconf.";
- return false;
- }
-
- // g_type_init will be deprecated in 2.36. 2.35 is the development
- // version for 2.36, hence do not call g_type_init starting 2.35.
- // http://developer.gnome.org/gobject/unstable/gobject-Type-Information.html#g-type-init
- if (libgio_loader_.glib_check_version(2, 35, 0)) {
- libgio_loader_.g_type_init();
- }
- }
-
GSettings* client = nullptr;
- if (SchemaExists(kProxyGConfSchema)) {
- ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/380782
- client = libgio_loader_.g_settings_new(kProxyGConfSchema);
+ if (g_settings_schema_source_lookup(g_settings_schema_source_get_default(),
+ kProxyGSettingsSchema, FALSE)) {
+ client = g_settings_new(kProxyGSettingsSchema);
}
if (!client) {
- VLOG(1) << "Cannot create gsettings client. Will fall back to gconf.";
+ VLOG(1) << "Cannot create gsettings client.";
return false;
}
g_object_unref(client);
- // Yes, we're on the UI thread. Yes, we're accessing the file system.
- // Sadly, we don't have much choice. We need the proxy settings and we
- // need them now, and to figure out where to get them, we have to check
- // for this binary. See http://crbug.com/69057 for additional details.
- {
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- if (base::ExecutableExistsInPath(env, "gnome-network-properties")) {
- VLOG(1) << "Found gnome-network-properties. Will fall back to gconf.";
- return false;
- }
- }
-
VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings.";
return true;
}
@@ -865,7 +483,7 @@ int StringToIntOrDefault(base::StringPiece value, int default_value) {
return default_value;
}
-// This is the KDE version that reads kioslaverc and simulates gconf.
+// This is the KDE version that reads kioslaverc and simulates gsettings.
// Doing this allows the main Delegate code, as well as the unit tests
// for it, to stay the same - and the settings map fairly well besides.
class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter {
@@ -906,10 +524,10 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter {
// back as well. So if there is a .kde4 directory, check the timestamps
// of the config directories within and use the newest one.
// Note that we should currently be running in the UI thread, because in
- // the gconf version, that is the only thread that can access the proxy
- // settings (a gconf restriction). As noted below, the initial read of
- // the proxy settings will be done in this thread anyway, so we check
- // for .kde4 here in this thread as well.
+ // the gsettings version, that is the only thread that can access the
+ // proxy settings (a gsettings restriction). As noted below, the initial
+ // read of the proxy settings will be done in this thread anyway, so we
+ // check for .kde4 here in this thread as well.
base::FilePath kde3_path = base::FilePath(home).Append(".kde");
base::FilePath kde3_config = KDEHomeToConfigPath(kde3_path);
base::FilePath kde4_path = base::FilePath(home).Append(".kde4");
@@ -1379,7 +997,7 @@ bool ProxyConfigServiceLinux::Delegate::GetProxyFromSettings(
host += ":" + base::IntToString(port);
}
- // gconf settings do not appear to distinguish between SOCKS version. We
+ // gsettings settings do not appear to distinguish between SOCKS version. We
// default to version 5. For more information on this policy decision, see:
// http://code.google.com/p/chromium/issues/detail?id=55912#c2
ProxyServer::Scheme scheme = (host_key == SettingGetter::PROXY_SOCKS_HOST) ?
@@ -1398,9 +1016,8 @@ bool ProxyConfigServiceLinux::Delegate::GetConfigFromSettings(
ProxyConfig* config) {
std::string mode;
if (!setting_getter_->GetString(SettingGetter::PROXY_MODE, &mode)) {
- // We expect this to always be set, so if we don't see it then we
- // probably have a gconf/gsettings problem, and so we don't have a valid
- // proxy config.
+ // We expect this to always be set, so if we don't see it then we probably
+ // have a gsettings problem, and so we don't have a valid proxy config.
return false;
}
if (mode == "none") {
@@ -1538,6 +1155,7 @@ ProxyConfigServiceLinux::Delegate::Delegate(
: env_var_getter_(std::move(env_var_getter)) {
// Figure out which SettingGetterImpl to use, if any.
switch (base::nix::GetDesktopEnvironment(env_var_getter_.get())) {
+ case base::nix::DESKTOP_ENVIRONMENT_CINNAMON:
case base::nix::DESKTOP_ENVIRONMENT_GNOME:
case base::nix::DESKTOP_ENVIRONMENT_PANTHEON:
case base::nix::DESKTOP_ENVIRONMENT_UNITY:
@@ -1546,16 +1164,11 @@ ProxyConfigServiceLinux::Delegate::Delegate(
std::unique_ptr<SettingGetterImplGSettings> gs_getter(
new SettingGetterImplGSettings());
// We have to load symbols and check the GNOME version in use to decide
- // if we should use the gsettings getter. See LoadAndCheckVersion().
- if (gs_getter->LoadAndCheckVersion(env_var_getter_.get()))
+ // if we should use the gsettings getter. See CheckVersion().
+ if (gs_getter->CheckVersion(env_var_getter_.get()))
setting_getter_ = std::move(gs_getter);
}
#endif
-#if defined(USE_GCONF)
- // Fall back on gconf if gsettings is unavailable or incorrect.
- if (!setting_getter_)
- setting_getter_.reset(new SettingGetterImplGConf());
-#endif
break;
case base::nix::DESKTOP_ENVIRONMENT_KDE3:
case base::nix::DESKTOP_ENVIRONMENT_KDE4:
@@ -1578,7 +1191,7 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner,
const scoped_refptr<base::SequencedTaskRunner>& main_task_runner) {
// We should be running on the default glib main loop thread right
- // now. gconf can only be accessed from this thread.
+ // now. gsettings can only be accessed from this thread.
DCHECK(glib_task_runner->RunsTasksInCurrentSequence());
glib_task_runner_ = glib_task_runner;
main_task_runner_ = main_task_runner;
@@ -1596,7 +1209,7 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
// the ProxyService.
// Note: It would be nice to prioritize environment variables
- // and only fall back to gconf if env vars were unset. But
+ // and only fall back to gsettings if env vars were unset. But
// gnome-terminal "helpfully" sets http_proxy and no_proxy, and it
// does so even if the proxy mode is set to auto, which would
// mislead us.
@@ -1609,7 +1222,7 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
VLOG(1) << "Obtained proxy settings from "
<< ProxyConfigSourceToString(cached_config_.source());
- // If gconf proxy mode is "none", meaning direct, then we take
+ // If gsettings proxy mode is "none", meaning direct, then we take
// that to be a valid config and will not check environment
// variables. The alternative would have been to look for a proxy
// whereever we can find one.
@@ -1656,7 +1269,7 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
}
// Depending on the SettingGetter in use, this method will be called
-// on either the UI thread (GConf) or the file thread (KDE).
+// on either the UI thread (GSettings) or the file thread (KDE).
void ProxyConfigServiceLinux::Delegate::SetUpNotifications() {
scoped_refptr<base::SequencedTaskRunner> required_loop =
setting_getter_->GetNotificationTaskRunner();
@@ -1698,7 +1311,7 @@ ProxyConfigService::ConfigAvailability
}
// Depending on the SettingGetter in use, this method will be called
-// on either the UI thread (GConf) or the file thread (KDE).
+// on either the UI thread (GSettings) or the file thread (KDE).
void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() {
scoped_refptr<base::SequencedTaskRunner> required_loop =
setting_getter_->GetNotificationTaskRunner();
diff --git a/chromium/net/proxy/proxy_config_service_linux_unittest.cc b/chromium/net/proxy/proxy_config_service_linux_unittest.cc
index 795b2665f75..11584acb1b3 100644
--- a/chromium/net/proxy/proxy_config_service_linux_unittest.cc
+++ b/chromium/net/proxy/proxy_config_service_linux_unittest.cc
@@ -58,12 +58,12 @@ struct EnvVarValues {
#undef TRUE
#undef FALSE
-// So as to distinguish between an unset gconf boolean variable and
+// So as to distinguish between an unset boolean variable and
// one that is false.
enum BoolSettingValue { UNSET = 0, TRUE, FALSE };
-// Set of values for all gconf settings that we might query.
-struct GConfValues {
+// Set of values for all gsettings settings that we might query.
+struct GSettingsValues {
// strings
const char* mode;
const char* autoconfig_url;
@@ -85,7 +85,7 @@ struct GConfValues {
};
// Mapping from a setting name to the location of the corresponding
-// value (inside a EnvVarValues or GConfValues struct).
+// value (inside a EnvVarValues or GSettingsValues struct).
template <typename key_type, typename value_type>
struct SettingsTable {
typedef std::map<key_type, value_type*> map_type;
@@ -192,7 +192,7 @@ class MockSettingGetter : public ProxyConfigServiceLinux::SettingGetter {
// Zeros all environment values.
void Reset() {
- GConfValues zero_values = {0};
+ GSettingsValues zero_values = {0};
values = zero_values;
}
@@ -259,7 +259,7 @@ class MockSettingGetter : public ProxyConfigServiceLinux::SettingGetter {
bool MatchHostsUsingSuffixMatching() override { return false; }
// Intentionally public, for convenience when setting up a test.
- GConfValues values;
+ GSettingsValues values;
private:
scoped_refptr<base::SequencedTaskRunner> task_runner_;
@@ -302,7 +302,7 @@ class SyncConfigGetter : public ProxyConfigService::Observer {
Wait();
}
- // Does gconf setup and initial fetch of the proxy config,
+ // Does gsettings setup and initial fetch of the proxy config,
// all on the calling thread (meant to be the thread with the
// default glib main loop, which is the glib thread).
void SetupAndInitialFetch() {
@@ -449,7 +449,7 @@ class ProxyConfigServiceLinuxTest : public PlatformTest {
// Builds an identifier for each test in an array.
#define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
-TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
+TEST_F(ProxyConfigServiceLinuxTest, BasicGSettingsTest) {
std::vector<std::string> empty_ignores;
std::vector<std::string> google_ignores;
@@ -462,7 +462,7 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
std::string description;
// Input.
- GConfValues values;
+ GSettingsValues values;
// Expected outputs (availability and fields of ProxyConfig).
ProxyConfigService::ConfigAvailability availability;
@@ -1099,7 +1099,7 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
}
}
-TEST_F(ProxyConfigServiceLinuxTest, GconfNotification) {
+TEST_F(ProxyConfigServiceLinuxTest, GSettingsNotification) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
MockSettingGetter* setting_getter = new MockSettingGetter;
ProxyConfigServiceLinux* service =
diff --git a/chromium/net/proxy/proxy_config_source.cc b/chromium/net/proxy/proxy_config_source.cc
index 6dd6071a653..7ab9ce1330c 100644
--- a/chromium/net/proxy/proxy_config_source.cc
+++ b/chromium/net/proxy/proxy_config_source.cc
@@ -14,7 +14,6 @@ const char* const kSourceNames[] = {
"UNKNOWN",
"SYSTEM",
"SYSTEM FAILED",
- "GCONF",
"GSETTINGS",
"KDE",
"ENV",
diff --git a/chromium/net/proxy/proxy_config_source.h b/chromium/net/proxy/proxy_config_source.h
index a7e375ab749..ea69e17b7c5 100644
--- a/chromium/net/proxy/proxy_config_source.h
+++ b/chromium/net/proxy/proxy_config_source.h
@@ -17,7 +17,6 @@ enum ProxyConfigSource {
PROXY_CONFIG_SOURCE_SYSTEM, // System settings (Win/Mac).
PROXY_CONFIG_SOURCE_SYSTEM_FAILED, // Default settings after failure to
// determine system settings.
- PROXY_CONFIG_SOURCE_GCONF, // GConf (Linux)
PROXY_CONFIG_SOURCE_GSETTINGS, // GSettings (Linux).
PROXY_CONFIG_SOURCE_KDE, // KDE (Linux).
PROXY_CONFIG_SOURCE_ENV, // Environment variables.
diff --git a/chromium/net/proxy/proxy_info.cc b/chromium/net/proxy/proxy_info.cc
index 642a421f900..01879dfff88 100644
--- a/chromium/net/proxy/proxy_info.cc
+++ b/chromium/net/proxy/proxy_info.cc
@@ -17,8 +17,7 @@ ProxyInfo::ProxyInfo()
ProxyInfo::ProxyInfo(const ProxyInfo& other) = default;
-ProxyInfo::~ProxyInfo() {
-}
+ProxyInfo::~ProxyInfo() = default;
void ProxyInfo::Use(const ProxyInfo& other) {
proxy_resolve_start_time_ = other.proxy_resolve_start_time_;
@@ -65,6 +64,10 @@ void ProxyInfo::OverrideProxyList(const ProxyList& proxy_list) {
proxy_list_ = proxy_list;
}
+void ProxyInfo::SetAlternativeProxy(const ProxyServer& proxy_server) {
+ alternative_proxy_ = proxy_server;
+}
+
std::string ProxyInfo::ToPacString() const {
return proxy_list_.ToPacString();
}
@@ -93,4 +96,10 @@ void ProxyInfo::Reset() {
did_use_pac_script_ = false;
}
+const NetworkTrafficAnnotationTag ProxyInfo::traffic_annotation() const {
+ // TODO(crbug.com/656607): Get appropriate annotation from the origin of
+ // config_source_.
+ return NO_TRAFFIC_ANNOTATION_BUG_656607;
+}
+
} // namespace net
diff --git a/chromium/net/proxy/proxy_info.h b/chromium/net/proxy/proxy_info.h
index eb3f90fe330..fd3c11780a9 100644
--- a/chromium/net/proxy/proxy_info.h
+++ b/chromium/net/proxy/proxy_info.h
@@ -14,6 +14,7 @@
#include "net/proxy/proxy_list.h"
#include "net/proxy/proxy_retry_info.h"
#include "net/proxy/proxy_server.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -71,6 +72,10 @@ class NET_EXPORT ProxyInfo {
// proxy configuration.
void OverrideProxyList(const ProxyList& proxy_list);
+ // Sets the alternative service to try when connecting to the first valid
+ // proxy server, but does not otherwise reset the proxy configuration.
+ void SetAlternativeProxy(const ProxyServer& proxy_server);
+
// Returns true if this proxy info specifies a direct connection.
bool is_direct() const {
// We don't implicitly fallback to DIRECT unless it was added to the list.
@@ -134,6 +139,9 @@ class NET_EXPORT ProxyInfo {
// Returns the source for configuration settings used for proxy resolution.
ProxyConfigSource config_source() const { return config_source_; }
+ // Returns traffic annotation tag based on current config source.
+ const NetworkTrafficAnnotationTag traffic_annotation() const;
+
// See description in ProxyList::ToPacString().
std::string ToPacString() const;
@@ -158,6 +166,9 @@ class NET_EXPORT ProxyInfo {
return proxy_list_;
}
+ // Returns the alternative proxy, which may be invalid.
+ const ProxyServer& alternative_proxy() const { return alternative_proxy_; }
+
base::TimeTicks proxy_resolve_start_time() const {
return proxy_resolve_start_time_;
}
@@ -181,6 +192,10 @@ class NET_EXPORT ProxyInfo {
// try. If proxy_list_ is empty, then there is nothing left to fall back to.
ProxyList proxy_list_;
+ // An alternative to proxy_server() (in the sense of HTTP Alternative
+ // Services).
+ ProxyServer alternative_proxy_;
+
// List of proxies that have been tried already.
ProxyRetryInfoMap proxy_retry_info_;
diff --git a/chromium/net/proxy/proxy_list.cc b/chromium/net/proxy/proxy_list.cc
index 2f65c720419..9eefac0483e 100644
--- a/chromium/net/proxy/proxy_list.cc
+++ b/chromium/net/proxy/proxy_list.cc
@@ -19,13 +19,11 @@ using base::TimeTicks;
namespace net {
-ProxyList::ProxyList() {
-}
+ProxyList::ProxyList() = default;
ProxyList::ProxyList(const ProxyList& other) = default;
-ProxyList::~ProxyList() {
-}
+ProxyList::~ProxyList() = default;
void ProxyList::Set(const std::string& proxy_uri_list) {
proxies_.clear();
diff --git a/chromium/net/proxy/proxy_resolver_factory.cc b/chromium/net/proxy/proxy_resolver_factory.cc
index fc7173e96bd..9e88ff4e3c1 100644
--- a/chromium/net/proxy/proxy_resolver_factory.cc
+++ b/chromium/net/proxy/proxy_resolver_factory.cc
@@ -13,7 +13,6 @@ ProxyResolverFactory::ProxyResolverFactory(bool expects_pac_bytes)
: expects_pac_bytes_(expects_pac_bytes) {
}
-ProxyResolverFactory::~ProxyResolverFactory() {
-}
+ProxyResolverFactory::~ProxyResolverFactory() = default;
} // namespace net
diff --git a/chromium/net/proxy/proxy_resolver_script.h b/chromium/net/proxy/proxy_resolver_script.h
deleted file mode 100644
index e838bed599f..00000000000
--- a/chromium/net/proxy/proxy_resolver_script.h
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 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_PROXY_PROXY_RESOLVER_SCRIPT_H_
-#define NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
-
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Akhil Arora <akhil.arora@sun.com>
- * Tomi Leppikangas <Tomi.Leppikangas@oulu.fi>
- * Darin Fisher <darin@meer.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// The following code was formatted from:
-// 'mozilla/netwerk/base/src/nsProxyAutoConfig.js' (1.55)
-//
-// Using the command:
-// $ cat nsProxyAutoConfig.js |
-// awk '/var pacUtils/,/EOF/' |
-// sed -e 's/^\s*$/""/g' |
-// sed -e 's/"\s*[+]\s*$/"/g' |
-// sed -e 's/"$/" \\/g' |
-// sed -e 's/\/(ipaddr);/\/.exec(ipaddr);/g' |
-// grep -v '^var pacUtils ='
-//
-// isPlainHost() was removed.
-#define PROXY_RESOLVER_SCRIPT \
- "function dnsDomainIs(host, domain) {\n" \
- " return (host.length >= domain.length &&\n" \
- " host.substring(host.length - domain.length) == domain);\n" \
- "}\n" \
- "" \
- "function dnsDomainLevels(host) {\n" \
- " return host.split('.').length-1;\n" \
- "}\n" \
- "" \
- "function convert_addr(ipchars) {\n" \
- " var bytes = ipchars.split('.');\n" \
- " var result = ((bytes[0] & 0xff) << 24) |\n" \
- " ((bytes[1] & 0xff) << 16) |\n" \
- " ((bytes[2] & 0xff) << 8) |\n" \
- " (bytes[3] & 0xff);\n" \
- " return result;\n" \
- "}\n" \
- "" \
- "function isInNet(ipaddr, pattern, maskstr) {\n" \
- " var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n" \
- " if (test == null) {\n" \
- " ipaddr = dnsResolve(ipaddr);\n" \
- " if (ipaddr == null)\n" \
- " return false;\n" \
- " } else if (test[1] > 255 || test[2] > 255 || \n" \
- " test[3] > 255 || test[4] > 255) {\n" \
- " return false; // not an IP address\n" \
- " }\n" \
- " var host = convert_addr(ipaddr);\n" \
- " var pat = convert_addr(pattern);\n" \
- " var mask = convert_addr(maskstr);\n" \
- " return ((host & mask) == (pat & mask));\n" \
- " \n" \
- "}\n" \
- "" \
- "function isResolvable(host) {\n" \
- " var ip = dnsResolve(host);\n" \
- " return (ip != null);\n" \
- "}\n" \
- "" \
- "function localHostOrDomainIs(host, hostdom) {\n" \
- " return (host == hostdom) ||\n" \
- " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" \
- "}\n" \
- "" \
- "function shExpMatch(url, pattern) {\n" \
- " pattern = pattern.replace(/\\./g, '\\\\.');\n" \
- " pattern = pattern.replace(/\\*/g, '.*');\n" \
- " pattern = pattern.replace(/\\?/g, '.');\n" \
- " var newRe = new RegExp('^'+pattern+'$');\n" \
- " return newRe.test(url);\n" \
- "}\n" \
- "" \
- "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
- "" \
- "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" \
- "" \
- "function weekdayRange() {\n" \
- " function getDay(weekday) {\n" \
- " if (weekday in wdays) {\n" \
- " return wdays[weekday];\n" \
- " }\n" \
- " return -1;\n" \
- " }\n" \
- " var date = new Date();\n" \
- " var argc = arguments.length;\n" \
- " var wday;\n" \
- " if (argc < 1)\n" \
- " return false;\n" \
- " if (arguments[argc - 1] == 'GMT') {\n" \
- " argc--;\n" \
- " wday = date.getUTCDay();\n" \
- " } else {\n" \
- " wday = date.getDay();\n" \
- " }\n" \
- " var wd1 = getDay(arguments[0]);\n" \
- " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
- " return (wd1 == -1 || wd2 == -1) ? false\n" \
- " : (wd1 <= wday && wday <= wd2);\n" \
- "}\n" \
- "" \
- "function dateRange() {\n" \
- " function getMonth(name) {\n" \
- " if (name in months) {\n" \
- " return months[name];\n" \
- " }\n" \
- " return -1;\n" \
- " }\n" \
- " var date = new Date();\n" \
- " var argc = arguments.length;\n" \
- " if (argc < 1) {\n" \
- " return false;\n" \
- " }\n" \
- " var isGMT = (arguments[argc - 1] == 'GMT');\n" \
- "\n" \
- " if (isGMT) {\n" \
- " argc--;\n" \
- " }\n" \
- " // function will work even without explict handling of this case\n" \
- " if (argc == 1) {\n" \
- " var tmp = parseInt(arguments[0]);\n" \
- " if (isNaN(tmp)) {\n" \
- " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" \
- "getMonth(arguments[0]));\n" \
- " } else if (tmp < 32) {\n" \
- " return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" \
- " } else { \n" \
- " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" \
- "tmp);\n" \
- " }\n" \
- " }\n" \
- " var year = date.getFullYear();\n" \
- " var date1, date2;\n" \
- " date1 = new Date(year, 0, 1, 0, 0, 0);\n" \
- " date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
- " var adjustMonth = false;\n" \
- " for (var i = 0; i < (argc >> 1); i++) {\n" \
- " var tmp = parseInt(arguments[i]);\n" \
- " if (isNaN(tmp)) {\n" \
- " var mon = getMonth(arguments[i]);\n" \
- " date1.setMonth(mon);\n" \
- " } else if (tmp < 32) {\n" \
- " adjustMonth = (argc <= 2);\n" \
- " date1.setDate(tmp);\n" \
- " } else {\n" \
- " date1.setFullYear(tmp);\n" \
- " }\n" \
- " }\n" \
- " for (var i = (argc >> 1); i < argc; i++) {\n" \
- " var tmp = parseInt(arguments[i]);\n" \
- " if (isNaN(tmp)) {\n" \
- " var mon = getMonth(arguments[i]);\n" \
- " date2.setMonth(mon);\n" \
- " } else if (tmp < 32) {\n" \
- " date2.setDate(tmp);\n" \
- " } else {\n" \
- " date2.setFullYear(tmp);\n" \
- " }\n" \
- " }\n" \
- " if (adjustMonth) {\n" \
- " date1.setMonth(date.getMonth());\n" \
- " date2.setMonth(date.getMonth());\n" \
- " }\n" \
- " if (isGMT) {\n" \
- " var tmp = date;\n" \
- " tmp.setFullYear(date.getUTCFullYear());\n" \
- " tmp.setMonth(date.getUTCMonth());\n" \
- " tmp.setDate(date.getUTCDate());\n" \
- " tmp.setHours(date.getUTCHours());\n" \
- " tmp.setMinutes(date.getUTCMinutes());\n" \
- " tmp.setSeconds(date.getUTCSeconds());\n" \
- " date = tmp;\n" \
- " }\n" \
- " return ((date1 <= date) && (date <= date2));\n" \
- "}\n" \
- "" \
- "function timeRange() {\n" \
- " var argc = arguments.length;\n" \
- " var date = new Date();\n" \
- " var isGMT= false;\n" \
- "\n" \
- " if (argc < 1) {\n" \
- " return false;\n" \
- " }\n" \
- " if (arguments[argc - 1] == 'GMT') {\n" \
- " isGMT = true;\n" \
- " argc--;\n" \
- " }\n" \
- "\n" \
- " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
- " var date1, date2;\n" \
- " date1 = new Date();\n" \
- " date2 = new Date();\n" \
- "\n" \
- " if (argc == 1) {\n" \
- " return (hour == arguments[0]);\n" \
- " } else if (argc == 2) {\n" \
- " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
- " } else {\n" \
- " switch (argc) {\n" \
- " case 6:\n" \
- " date1.setSeconds(arguments[2]);\n" \
- " date2.setSeconds(arguments[5]);\n" \
- " case 4:\n" \
- " var middle = argc >> 1;\n" \
- " date1.setHours(arguments[0]);\n" \
- " date1.setMinutes(arguments[1]);\n" \
- " date2.setHours(arguments[middle]);\n" \
- " date2.setMinutes(arguments[middle + 1]);\n" \
- " if (middle == 2) {\n" \
- " date2.setSeconds(59);\n" \
- " }\n" \
- " break;\n" \
- " default:\n" \
- " throw 'timeRange: bad number of arguments'\n" \
- " }\n" \
- " }\n" \
- "\n" \
- " if (isGMT) {\n" \
- " date.setFullYear(date.getUTCFullYear());\n" \
- " date.setMonth(date.getUTCMonth());\n" \
- " date.setDate(date.getUTCDate());\n" \
- " date.setHours(date.getUTCHours());\n" \
- " date.setMinutes(date.getUTCMinutes());\n" \
- " date.setSeconds(date.getUTCSeconds());\n" \
- " }\n" \
- " return ((date1 <= date) && (date <= date2));\n" \
- "}\n"
-
-// This is a Microsoft extension to PAC for IPv6, see:
-// http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
-#define PROXY_RESOLVER_SCRIPT_EX \
- "function isResolvableEx(host) {\n" \
- " var ipList = dnsResolveEx(host);\n" \
- " return (ipList != '');\n" \
- "}\n"
-
-#endif // NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
diff --git a/chromium/net/proxy/proxy_resolver_script_data.cc b/chromium/net/proxy/proxy_resolver_script_data.cc
index 8c4fd3187ae..d62095551c7 100644
--- a/chromium/net/proxy/proxy_resolver_script_data.cc
+++ b/chromium/net/proxy/proxy_resolver_script_data.cc
@@ -71,6 +71,6 @@ ProxyResolverScriptData::ProxyResolverScriptData(Type type,
utf16_(utf16) {
}
-ProxyResolverScriptData::~ProxyResolverScriptData() {}
+ProxyResolverScriptData::~ProxyResolverScriptData() = default;
} // namespace net
diff --git a/chromium/net/proxy/proxy_resolver_v8.cc b/chromium/net/proxy/proxy_resolver_v8.cc
index c26ecff3715..40f3e0314bb 100644
--- a/chromium/net/proxy/proxy_resolver_v8.cc
+++ b/chromium/net/proxy/proxy_resolver_v8.cc
@@ -24,8 +24,8 @@
#include "gin/v8_initializer.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
+#include "net/proxy/pac_js_library.h"
#include "net/proxy/proxy_info.h"
-#include "net/proxy/proxy_resolver_script.h"
#include "net/proxy/proxy_resolver_script_data.h"
#include "url/gurl.h"
#include "url/url_canon.h"
@@ -34,8 +34,7 @@
// Notes on the javascript environment:
//
// For the majority of the PAC utility functions, we use the same code
-// as Firefox. See the javascript library that proxy_resolver_scipt.h
-// pulls in.
+// as Firefox. See the javascript library that pac_js_library.h pulls in.
//
// In addition, we implement a subset of Microsoft's extensions to PAC.
// - myIpAddressEx()
@@ -570,10 +569,7 @@ class ProxyResolverV8::Context {
// (This script should never fail, as it is a string literal!)
// Note that the two string literals are concatenated.
int rv = RunScript(
- ASCIILiteralToV8String(
- isolate_,
- PROXY_RESOLVER_SCRIPT
- PROXY_RESOLVER_SCRIPT_EX),
+ ASCIILiteralToV8String(isolate_, PAC_JS_LIBRARY PAC_JS_LIBRARY_EX),
kPacUtilityResourceName);
if (rv != OK) {
NOTREACHED();
@@ -855,7 +851,7 @@ ProxyResolverV8::ProxyResolverV8(std::unique_ptr<Context> context)
DCHECK(context_);
}
-ProxyResolverV8::~ProxyResolverV8() {}
+ProxyResolverV8::~ProxyResolverV8() = default;
int ProxyResolverV8::GetProxyForURL(const GURL& query_url,
ProxyInfo* results,
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc b/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
index 4eaf8327578..ceb921654f3 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_unittest.cc
@@ -725,6 +725,21 @@ class BlockableHostResolver : public HostResolver {
return ERR_DNS_CACHE_MISS;
}
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) override {
+ NOTREACHED();
+ return ERR_DNS_CACHE_MISS;
+ }
+
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
void IncreaseNumOfCancelledRequests() { num_cancelled_requests_++; }
void SetAction(const base::Callback<void(void)>& action) {
diff --git a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
index 4d3ac69bf99..0128610b0b9 100644
--- a/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
+++ b/chromium/net/proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc
@@ -822,6 +822,21 @@ class BlockableHostResolver : public HostResolver {
return ERR_DNS_CACHE_MISS;
}
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) override {
+ NOTREACHED();
+ return ERR_DNS_CACHE_MISS;
+ }
+
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
void IncreaseNumOfCancelledRequests() { num_cancelled_requests_++; }
void SetAction(const base::Callback<void(void)>& action) { action_ = action; }
diff --git a/chromium/net/proxy/proxy_script_decider_unittest.cc b/chromium/net/proxy/proxy_script_decider_unittest.cc
index 1a2a368b8ea..15c5d0f319b 100644
--- a/chromium/net/proxy/proxy_script_decider_unittest.cc
+++ b/chromium/net/proxy/proxy_script_decider_unittest.cc
@@ -162,9 +162,9 @@ class MockDhcpProxyScriptFetcher : public DhcpProxyScriptFetcher {
DISALLOW_COPY_AND_ASSIGN(MockDhcpProxyScriptFetcher);
};
-MockDhcpProxyScriptFetcher::MockDhcpProxyScriptFetcher() { }
+MockDhcpProxyScriptFetcher::MockDhcpProxyScriptFetcher() = default;
-MockDhcpProxyScriptFetcher::~MockDhcpProxyScriptFetcher() { }
+MockDhcpProxyScriptFetcher::~MockDhcpProxyScriptFetcher() = default;
int MockDhcpProxyScriptFetcher::Fetch(base::string16* utf16_text,
const CompletionCallback& callback) {
@@ -756,8 +756,8 @@ class AsyncFailDhcpFetcher
: public DhcpProxyScriptFetcher,
public base::SupportsWeakPtr<AsyncFailDhcpFetcher> {
public:
- AsyncFailDhcpFetcher() {}
- ~AsyncFailDhcpFetcher() override {}
+ AsyncFailDhcpFetcher() = default;
+ ~AsyncFailDhcpFetcher() override = default;
int Fetch(base::string16* utf16_text,
const CompletionCallback& callback) override {
diff --git a/chromium/net/proxy/proxy_script_fetcher_impl.cc b/chromium/net/proxy/proxy_script_fetcher_impl.cc
index c736c590409..fe427e2af08 100644
--- a/chromium/net/proxy/proxy_script_fetcher_impl.cc
+++ b/chromium/net/proxy/proxy_script_fetcher_impl.cc
@@ -35,7 +35,17 @@ const int kDefaultMaxResponseBytes = 1048576; // 1 megabyte
// The maximum duration (in milliseconds) allowed for fetching the PAC script.
// Responses exceeding this will fail with ERR_TIMED_OUT.
-const int kDefaultMaxDurationMs = 300000; // 5 minutes
+//
+// This timeout applies to both scripts fetched in the course of WPAD, as well
+// as explicitly configured ones.
+//
+// If the default timeout is too high, auto-detect can stall for a long time,
+// and if it is too low then slow loading scripts may be skipped.
+//
+// 30 seconds is a compromise between those competing goals. This value also
+// appears to match Microsoft Edge (based on testing).
+constexpr base::TimeDelta kDefaultMaxDuration =
+ base::TimeDelta::FromSeconds(30);
// Returns true if |mime_type| is one of the known PAC mime type.
bool IsPacMimeType(const std::string& mime_type) {
@@ -82,7 +92,7 @@ ProxyScriptFetcherImpl::ProxyScriptFetcherImpl(
result_code_(OK),
result_text_(NULL),
max_response_bytes_(kDefaultMaxResponseBytes),
- max_duration_(base::TimeDelta::FromMilliseconds(kDefaultMaxDurationMs)),
+ max_duration_(kDefaultMaxDuration),
weak_factory_(this) {
DCHECK(url_request_context);
}
@@ -175,7 +185,7 @@ int ProxyScriptFetcherImpl::Fetch(
// requests, PAC requests are aren't blocked on them.
cur_request_ = url_request_context_->CreateRequest(url, MAXIMUM_PRIORITY,
this, traffic_annotation);
- cur_request_->set_method("GET");
+ cur_request_->set_is_pac_request(true);
// Make sure that the PAC script is downloaded using a direct connection,
// to avoid circular dependencies (fetching is a part of proxy resolution).
diff --git a/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc b/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
index c7d1f53da44..5390c549592 100644
--- a/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/chromium/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -140,8 +140,8 @@ GURL GetTestFileUrl(const std::string& relpath) {
class BasicNetworkDelegate : public NetworkDelegateImpl {
public:
- BasicNetworkDelegate() {}
- ~BasicNetworkDelegate() override {}
+ BasicNetworkDelegate() = default;
+ ~BasicNetworkDelegate() override = default;
private:
int OnBeforeURLRequest(URLRequest* request,
@@ -551,15 +551,15 @@ TEST_F(ProxyScriptFetcherImplTest, OnShutdown) {
int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
callback.callback());
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
- EXPECT_EQ(1u, context_.url_requests().size());
+ EXPECT_EQ(1u, context_.url_requests()->size());
pac_fetcher.OnShutdown();
- EXPECT_EQ(0u, context_.url_requests().size());
+ EXPECT_EQ(0u, context_.url_requests()->size());
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONTEXT_SHUT_DOWN));
// Make sure there's no asynchronous completion notification.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, context_.url_requests().size());
+ EXPECT_EQ(0u, context_.url_requests()->size());
EXPECT_FALSE(callback.have_result());
result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
@@ -578,7 +578,7 @@ TEST_F(ProxyScriptFetcherImplTest, OnShutdownWithNoLiveRequest) {
int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
callback.callback());
EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
- EXPECT_EQ(0u, context_.url_requests().size());
+ EXPECT_EQ(0u, context_.url_requests()->size());
}
} // namespace
diff --git a/chromium/net/proxy/proxy_service.cc b/chromium/net/proxy/proxy_service.cc
index 0503ae963e7..369a1ca0c22 100644
--- a/chromium/net/proxy/proxy_service.cc
+++ b/chromium/net/proxy/proxy_service.cc
@@ -125,7 +125,7 @@ const int64_t kDelayAfterNetworkChangesMs = 2000;
// TODO(eroman): Figure out what Internet Explorer does.
class DefaultPollPolicy : public ProxyService::PacPollPolicy {
public:
- DefaultPollPolicy() {}
+ DefaultPollPolicy() = default;
Mode GetNextDelay(int initial_error,
TimeDelta current_delay,
@@ -180,7 +180,7 @@ class ProxyConfigServiceDirect : public ProxyConfigService {
// Proxy resolver that fails every time.
class ProxyResolverNull : public ProxyResolver {
public:
- ProxyResolverNull() {}
+ ProxyResolverNull() = default;
// ProxyResolver implementation.
int GetProxyForURL(const GURL& url,
@@ -322,8 +322,8 @@ std::unique_ptr<base::Value> NetLogFinishedResolvingProxyCallback(
#if defined(OS_CHROMEOS)
class UnsetProxyConfigService : public ProxyConfigService {
public:
- UnsetProxyConfigService() {}
- ~UnsetProxyConfigService() override {}
+ UnsetProxyConfigService() = default;
+ ~UnsetProxyConfigService() override = default;
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
@@ -773,18 +773,17 @@ class ProxyService::ProxyScriptDeciderPoller {
const ProxyService::PacPollPolicy*
ProxyService::ProxyScriptDeciderPoller::poll_policy_ = NULL;
-// ProxyService::PacRequest ---------------------------------------------------
+// ProxyService::Request ---------------------------------------------------
-class ProxyService::PacRequest
- : public base::RefCounted<ProxyService::PacRequest> {
+class ProxyService::Request : public base::RefCounted<ProxyService::Request> {
public:
- PacRequest(ProxyService* service,
- const GURL& url,
- const std::string& method,
- ProxyDelegate* proxy_delegate,
- ProxyInfo* results,
- const CompletionCallback& user_callback,
- const NetLogWithSource& net_log)
+ Request(ProxyService* service,
+ const GURL& url,
+ const std::string& method,
+ ProxyDelegate* proxy_delegate,
+ ProxyInfo* results,
+ const CompletionCallback& user_callback,
+ const NetLogWithSource& net_log)
: service_(service),
user_callback_(user_callback),
results_(results),
@@ -811,7 +810,7 @@ class ProxyService::PacRequest
return resolver()->GetProxyForURL(
url_, results_,
- base::Bind(&PacRequest::QueryComplete, base::Unretained(this)),
+ base::Bind(&Request::QueryComplete, base::Unretained(this)),
&resolve_job_, net_log_);
}
@@ -892,15 +891,15 @@ class ProxyService::PacRequest
}
private:
- friend class base::RefCounted<ProxyService::PacRequest>;
+ friend class base::RefCounted<ProxyService::Request>;
- ~PacRequest() {}
+ ~Request() = default;
// Callback for when the ProxyResolver request has completed.
void QueryComplete(int result_code) {
result_code = QueryDidComplete(result_code);
- // Remove this completed PacRequest from the service's pending list.
+ // Remove this completed Request from the service's pending list.
/// (which will probably cause deletion of |this|).
if (!user_callback_.is_null()) {
CompletionCallback callback = user_callback_;
@@ -1020,7 +1019,7 @@ int ProxyService::ResolveProxy(const GURL& raw_url,
const std::string& method,
ProxyInfo* result,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** pac_request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log) {
DCHECK(!callback.is_null());
@@ -1032,7 +1031,7 @@ int ProxyService::ResolveProxyHelper(const GURL& raw_url,
const std::string& method,
ProxyInfo* result,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** pac_request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -1066,8 +1065,8 @@ int ProxyService::ResolveProxyHelper(const GURL& raw_url,
if (callback.is_null())
return ERR_IO_PENDING;
- scoped_refptr<PacRequest> req(new PacRequest(
- this, url, method, proxy_delegate, result, callback, net_log));
+ scoped_refptr<Request> req(new Request(this, url, method, proxy_delegate,
+ result, callback, net_log));
if (current_state_ == STATE_READY) {
// Start the resolve request.
@@ -1146,7 +1145,7 @@ void ProxyService::SuspendAllPendingRequests() {
for (PendingRequests::iterator it = pending_requests_.begin();
it != pending_requests_.end();
++it) {
- PacRequest* req = it->get();
+ Request* req = it->get();
if (req->is_started()) {
req->CancelResolveJob();
@@ -1161,14 +1160,14 @@ void ProxyService::SetReady() {
current_state_ = STATE_READY;
// Make a copy in case |this| is deleted during the synchronous completion
- // of one of the requests. If |this| is deleted then all of the PacRequest
+ // of one of the requests. If |this| is deleted then all of the Request
// instances will be Cancel()-ed.
PendingRequests pending_copy = pending_requests_;
for (PendingRequests::iterator it = pending_copy.begin();
it != pending_copy.end();
++it) {
- PacRequest* req = it->get();
+ Request* req = it->get();
if (!req->is_started() && !req->was_cancelled()) {
req->net_log()->EndEvent(
NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC);
@@ -1256,7 +1255,7 @@ int ProxyService::ReconsiderProxyAfterError(const GURL& url,
int net_error,
ProxyInfo* result,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** pac_request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -1329,25 +1328,25 @@ void ProxyService::ReportSuccess(const ProxyInfo& result,
}
}
-void ProxyService::CancelPacRequest(PacRequest* req) {
+void ProxyService::CancelRequest(Request* req) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(req);
req->Cancel();
RemovePendingRequest(req);
}
-LoadState ProxyService::GetLoadState(const PacRequest* req) const {
+LoadState ProxyService::GetLoadState(const Request* req) const {
CHECK(req);
if (current_state_ == STATE_WAITING_FOR_INIT_PROXY_RESOLVER)
return init_proxy_resolver_->GetLoadState();
return req->GetLoadState();
}
-bool ProxyService::ContainsPendingRequest(PacRequest* req) {
+bool ProxyService::ContainsPendingRequest(Request* req) {
return pending_requests_.count(req) == 1;
}
-void ProxyService::RemovePendingRequest(PacRequest* req) {
+void ProxyService::RemovePendingRequest(Request* req) {
DCHECK(ContainsPendingRequest(req));
pending_requests_.erase(req);
}
@@ -1502,7 +1501,7 @@ ProxyService::CreateSystemProxyConfigService(
// Assume we got called on the thread that runs the default glib
// main loop, so the current thread is where we should be running
- // gconf calls from.
+ // gsettings calls from.
scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner =
base::ThreadTaskRunnerHandle::Get();
diff --git a/chromium/net/proxy/proxy_service.h b/chromium/net/proxy/proxy_service.h
index 687418ed2a1..b615543a987 100644
--- a/chromium/net/proxy/proxy_service.h
+++ b/chromium/net/proxy/proxy_service.h
@@ -119,9 +119,8 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
~ProxyService() override;
- // Used internally to handle PAC queries.
- // TODO(eroman): consider naming this simply "Request".
- class PacRequest;
+ // Used to track proxy resolution requests that complete asynchronously.
+ class Request;
// Determines the appropriate proxy for |url| for a |method| request and
// stores the result in |results|. If |method| is empty, the caller can expect
@@ -133,9 +132,9 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
// ResolveProxy.
//
// The caller is responsible for ensuring that |results| and |callback|
- // remain valid until the callback is run or until |pac_request| is cancelled
- // via CancelPacRequest. |pac_request| is only valid while the completion
- // callback is still pending. NULL can be passed for |pac_request| if
+ // remain valid until the callback is run or until |request| is cancelled
+ // via CancelRequest. |request| is only valid while the completion
+ // callback is still pending. NULL can be passed for |request| if
// the caller will not need to cancel the request.
//
// We use the three possible proxy access types in the following order,
@@ -150,7 +149,7 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
const std::string& method,
ProxyInfo* results,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log);
@@ -170,7 +169,7 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
// list of possible values. The semantics of this call are otherwise
// similar to ResolveProxy.
//
- // NULL can be passed for |pac_request| if the caller will not need to
+ // NULL can be passed for |request| if the caller will not need to
// cancel the request.
//
// Returns ERR_FAILED if there is not another proxy config to try.
@@ -181,7 +180,7 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
int net_error,
ProxyInfo* results,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log);
@@ -208,11 +207,11 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
void ReportSuccess(const ProxyInfo& proxy_info,
ProxyDelegate* proxy_delegate);
- // Call this method with a non-null |pac_request| to cancel the PAC request.
- void CancelPacRequest(PacRequest* pac_request);
+ // Call this method with a non-null |request| to cancel the PAC request.
+ void CancelRequest(Request* request);
- // Returns the LoadState for this |pac_request| which must be non-NULL.
- LoadState GetLoadState(const PacRequest* pac_request) const;
+ // Returns the LoadState for this |request| which must be non-NULL.
+ LoadState GetLoadState(const Request* request) const;
// Sets the ProxyScriptFetcher and DhcpProxyScriptFetcher dependencies. This
// is needed if the ProxyResolver is of type ProxyResolverWithoutFetch.
@@ -318,11 +317,11 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
private:
FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigAfterFailedAutodetect);
FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigFromPACToDirect);
- friend class PacRequest;
+ friend class Request;
class InitProxyResolver;
class ProxyScriptDeciderPoller;
- typedef std::set<scoped_refptr<PacRequest>> PendingRequests;
+ typedef std::set<scoped_refptr<Request>> PendingRequests;
enum State {
STATE_NONE,
@@ -361,7 +360,7 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
const std::string& method,
ProxyInfo* results,
const CompletionCallback& callback,
- PacRequest** pac_request,
+ Request** request,
ProxyDelegate* proxy_delegate,
const NetLogWithSource& net_log);
@@ -374,10 +373,10 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
void SetReady();
// Returns true if |pending_requests_| contains |req|.
- bool ContainsPendingRequest(PacRequest* req);
+ bool ContainsPendingRequest(Request* req);
// Removes |req| from the list of pending requests.
- void RemovePendingRequest(PacRequest* req);
+ void RemovePendingRequest(Request* req);
// Called when proxy resolution has completed (either synchronously or
// asynchronously). Handles logging the result, and cleaning out
diff --git a/chromium/net/proxy/proxy_service_unittest.cc b/chromium/net/proxy/proxy_service_unittest.cc
index 6a423fe6e63..ce48b205253 100644
--- a/chromium/net/proxy/proxy_service_unittest.cc
+++ b/chromium/net/proxy/proxy_service_unittest.cc
@@ -51,7 +51,7 @@ namespace {
// This polling policy will decide to poll every 1 ms.
class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
public:
- ImmediatePollPolicy() {}
+ ImmediatePollPolicy() = default;
Mode GetNextDelay(int error,
base::TimeDelta current_delay,
@@ -68,7 +68,7 @@ class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
// will never trigger a poll
class NeverPollPolicy : public ProxyService::PacPollPolicy {
public:
- NeverPollPolicy() {}
+ NeverPollPolicy() = default;
Mode GetNextDelay(int error,
base::TimeDelta current_delay,
@@ -84,7 +84,7 @@ class NeverPollPolicy : public ProxyService::PacPollPolicy {
// This polling policy starts a poll immediately after network activity.
class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
public:
- ImmediateAfterActivityPollPolicy() {}
+ ImmediateAfterActivityPollPolicy() = default;
Mode GetNextDelay(int error,
base::TimeDelta current_delay,
@@ -214,23 +214,10 @@ class TestResolveProxyDelegate : public ProxyDelegate {
return proxy_retry_info_;
}
- void OnTunnelConnectCompleted(const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) override {}
void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
- void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) override {}
- void OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) override {}
bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override {
return true;
}
- void GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const override {}
void OnAlternativeProxyBroken(
const ProxyServer& alternative_proxy_server) override {}
@@ -253,27 +240,14 @@ class TestProxyFallbackProxyDelegate : public ProxyDelegate {
const std::string& method,
const ProxyRetryInfoMap& proxy_retry_info,
ProxyInfo* result) override {}
- void OnTunnelConnectCompleted(const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) override {}
void OnFallback(const ProxyServer& bad_proxy, int net_error) override {
proxy_server_ = bad_proxy;
proxy_fallback_net_error_ = net_error;
on_proxy_fallback_called_ = true;
}
- void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) override {}
- void OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) override {}
bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override {
return true;
}
- void GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const override {}
void OnAlternativeProxyBroken(
const ProxyServer& alternative_proxy_server) override {}
@@ -525,7 +499,7 @@ TEST_F(ProxyServiceTest, PAC) {
ProxyInfo info;
TestCompletionCallback callback;
- ProxyService::PacRequest* request;
+ ProxyService::Request* request;
BoundTestNetLog log;
int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
@@ -1974,7 +1948,7 @@ TEST_F(ProxyServiceTest, CancelInProgressRequest) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
&request2, nullptr, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1989,7 +1963,7 @@ TEST_F(ProxyServiceTest, CancelInProgressRequest) {
GetPendingJobsForURLs(resolver, url1, url2, url3);
// Cancel the second request
- service.CancelPacRequest(request2);
+ service.CancelRequest(request2);
JobMap jobs = GetPendingJobsForURLs(resolver, url1, url3);
@@ -2035,7 +2009,7 @@ TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
ProxyInfo info1;
TestCompletionCallback callback1;
- ProxyService::PacRequest* request1;
+ ProxyService::Request* request1;
int rv =
service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
&request1, nullptr, NetLogWithSource());
@@ -2047,14 +2021,14 @@ TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
&request2, nullptr, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ProxyInfo info3;
TestCompletionCallback callback3;
- ProxyService::PacRequest* request3;
+ ProxyService::Request* request3;
rv = service.ResolveProxy(url3, std::string(), &info3, callback3.callback(),
&request3, nullptr, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2204,7 +2178,7 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
// Start 3 requests.
ProxyInfo info1;
TestCompletionCallback callback1;
- ProxyService::PacRequest* request1;
+ ProxyService::Request* request1;
BoundTestNetLog log1;
int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
callback1.callback(), &request1, nullptr,
@@ -2217,7 +2191,7 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
callback2.callback(), &request2, nullptr,
NetLogWithSource());
@@ -2234,8 +2208,8 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
EXPECT_TRUE(factory->pending_requests().empty());
// Cancel the first 2 jobs.
- service.CancelPacRequest(request1);
- service.CancelPacRequest(request2);
+ service.CancelRequest(request1);
+ service.CancelRequest(request2);
// At this point the ProxyService should be waiting for the
// ProxyScriptFetcher to invoke its completion callback, notifying it of
@@ -2311,7 +2285,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
&request2, nullptr, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2395,7 +2369,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
&request2, nullptr, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2472,7 +2446,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
ProxyInfo info2;
TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
+ ProxyService::Request* request2;
rv = service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
callback2.callback(), &request2, nullptr,
NetLogWithSource());
@@ -3726,7 +3700,7 @@ TEST_F(ProxyServiceTest, OnShutdownWithLiveRequest) {
ProxyInfo info;
TestCompletionCallback callback;
- ProxyService::PacRequest* request;
+ ProxyService::Request* request;
int rv = service.ResolveProxy(GURL("http://request/"), std::string(), &info,
callback.callback(), &request, nullptr,
NetLogWithSource());
@@ -3762,7 +3736,7 @@ TEST_F(ProxyServiceTest, OnShutdownFollowedByRequest) {
ProxyInfo info;
TestCompletionCallback callback;
- ProxyService::PacRequest* request;
+ ProxyService::Request* request;
int rv = service.ResolveProxy(GURL("http://request/"), std::string(), &info,
callback.callback(), &request, nullptr,
NetLogWithSource());
diff --git a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
index 015c910c848..16ad25497e2 100644
--- a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
+++ b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -35,6 +35,7 @@
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_string_piece.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -379,7 +380,7 @@ class DeleteStreamDelegate : public TestDelegateBase {
} // namespace
class BidirectionalStreamQuicImplTest
- : public ::testing::TestWithParam<QuicTransportVersion> {
+ : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
protected:
static const bool kFin = true;
static const bool kIncludeVersion = true;
@@ -397,21 +398,27 @@ class BidirectionalStreamQuicImplTest
};
BidirectionalStreamQuicImplTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
read_buffer_(new IOBufferWithSize(4096)),
connection_id_(2),
stream_id_(GetNthClientInitiatedStreamId(0)),
- client_maker_(GetParam(),
+ client_maker_(version_,
connection_id_,
&clock_,
kDefaultServerHostName,
- Perspective::IS_CLIENT),
- server_maker_(GetParam(),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
+ server_maker_(version_,
connection_id_,
&clock_,
kDefaultServerHostName,
- Perspective::IS_SERVER),
- random_generator_(0) {
+ Perspective::IS_SERVER,
+ false),
+ random_generator_(0),
+ destination_(kDefaultServerHostName, kDefaultServerPort) {
IPAddress ip(192, 0, 2, 33);
peer_addr_ = IPEndPoint(ip, 443);
self_addr_ = IPEndPoint(ip, 8435);
@@ -475,7 +482,8 @@ class BidirectionalStreamQuicImplTest
helper_.get(), alarm_factory_.get(),
new QuicChromiumPacketWriter(socket.get(), runner_.get()),
true /* owns_writer */, Perspective::IS_CLIENT,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(
+ net::ParsedQuicVersion(net::PROTOCOL_QUIC_CRYPTO, version_)));
base::TimeTicks dns_end = base::TimeTicks::Now();
base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
@@ -490,10 +498,13 @@ class BidirectionalStreamQuicImplTest
/*migrate_session_on_network_change*/ false,
/*migrate_session_early*/ false,
/*migrate_session_on_network_change_v2*/ false,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
kQuicYieldAfterPacketsRead,
QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
- /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
- "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr,
+ client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
+ DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start,
+ dns_end, &push_promise_index_, nullptr,
base::ThreadTaskRunnerHandle::Get().get(),
/*socket_performance_watcher=*/nullptr, net_log().bound().net_log()));
session_->Initialize();
@@ -574,12 +585,26 @@ class BidirectionalStreamQuicImplTest
RequestPriority request_priority,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset) {
+ return ConstructRequestHeadersPacketInner(
+ packet_number, stream_id, fin, request_priority, 0,
+ spdy_headers_frame_length, offset);
+ }
+
+ std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacketInner(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool fin,
+ RequestPriority request_priority,
+ QuicStreamId parent_stream_id,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset) {
SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(request_priority);
std::unique_ptr<QuicReceivedPacket> packet(
client_maker_.MakeRequestHeadersPacket(
packet_number, stream_id, kIncludeVersion, fin, priority,
- std::move(request_headers_), spdy_headers_frame_length, offset));
+ std::move(request_headers_), parent_stream_id,
+ spdy_headers_frame_length, offset));
DVLOG(2) << "packet(" << packet_number << "): " << std::endl
<< QuicTextUtils::HexDump(packet->AsStringPiece());
return packet;
@@ -598,7 +623,7 @@ class BidirectionalStreamQuicImplTest
std::unique_ptr<QuicReceivedPacket> packet(
client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
packet_number, stream_id_, kIncludeVersion, fin, priority,
- std::move(request_headers_), header_stream_offset,
+ std::move(request_headers_), 0, header_stream_offset,
spdy_headers_frame_length, data));
DVLOG(2) << "packet(" << packet_number << "): " << std::endl
<< QuicTextUtils::HexDump(packet->AsStringPiece());
@@ -744,10 +769,12 @@ class BidirectionalStreamQuicImplTest
QuicChromiumClientSession* session() const { return session_.get(); }
QuicStreamId GetNthClientInitiatedStreamId(int n) {
- return test::GetNthClientInitiatedStreamId(GetParam(), n);
+ return test::GetNthClientInitiatedStreamId(version_, n);
}
protected:
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
BoundTestNetLog net_log_;
scoped_refptr<TestTaskRunner> runner_;
std::unique_ptr<MockWrite[]> mock_writes_;
@@ -773,11 +800,14 @@ class BidirectionalStreamQuicImplTest
std::unique_ptr<StaticSocketDataProvider> socket_data_;
std::vector<PacketToWrite> writes_;
QuicClientPushPromiseIndex push_promise_index_;
+ HostPortPair destination_;
};
-INSTANTIATE_TEST_CASE_P(Version,
- BidirectionalStreamQuicImplTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ Version,
+ BidirectionalStreamQuicImplTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
SetRequest("GET", "/", DEFAULT_PRIORITY);
@@ -801,7 +831,8 @@ TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
delegate->set_trailers_expected(true);
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
ConfirmHandshake();
@@ -886,8 +917,8 @@ TEST_P(BidirectionalStreamQuicImplTest, LoadTimingTwoRequests) {
// SetRequest() again for second request as |request_headers_| was moved.
SetRequest("GET", "/", DEFAULT_PRIORITY);
AddWrite(ConstructRequestHeadersPacketInner(
- 2, GetNthClientInitiatedStreamId(1), kFin, DEFAULT_PRIORITY, nullptr,
- &offset));
+ 2, GetNthClientInitiatedStreamId(1), kFin, DEFAULT_PRIORITY,
+ GetNthClientInitiatedStreamId(0), nullptr, &offset));
AddWrite(ConstructInitialSettingsPacket(3, &offset));
AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
Initialize();
@@ -902,13 +933,15 @@ TEST_P(BidirectionalStreamQuicImplTest, LoadTimingTwoRequests) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
// Start second request.
scoped_refptr<IOBuffer> read_buffer2(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate2(
new TestDelegateBase(read_buffer2.get(), kReadBufferSize));
- delegate2->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate2->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
delegate2->WaitUntilNextCallback(kOnStreamReady);
@@ -991,7 +1024,8 @@ TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) {
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
delegate->DoNotSendRequestHeadersAutomatically();
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
EXPECT_FALSE(delegate->is_ready());
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1098,7 +1132,8 @@ TEST_P(BidirectionalStreamQuicImplTest,
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
delegate->DoNotSendRequestHeadersAutomatically();
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1205,7 +1240,8 @@ TEST_P(BidirectionalStreamQuicImplTest,
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
delegate->DoNotSendRequestHeadersAutomatically();
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1297,7 +1333,8 @@ TEST_P(BidirectionalStreamQuicImplTest,
std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
read_buffer.get(), kReadBufferSize, DeleteStreamDelegate::ON_FAILED));
delegate->DoNotSendRequestHeadersAutomatically();
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1330,7 +1367,8 @@ TEST_P(BidirectionalStreamQuicImplTest,
std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
read_buffer.get(), kReadBufferSize, DeleteStreamDelegate::ON_FAILED));
delegate->DoNotSendRequestHeadersAutomatically();
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1368,7 +1406,8 @@ TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1446,7 +1485,8 @@ TEST_P(BidirectionalStreamQuicImplTest, PutRequest) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
// Send a DATA frame.
@@ -1527,7 +1567,8 @@ TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1610,7 +1651,8 @@ TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
ConfirmHandshake();
@@ -1655,7 +1697,8 @@ TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
ConfirmHandshake();
@@ -1713,7 +1756,8 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1770,7 +1814,8 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeStartConfirmed) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnFailed);
EXPECT_TRUE(delegate->on_failed_called());
EXPECT_THAT(delegate->error(), IsError(ERR_CONNECTION_CLOSED));
@@ -1792,7 +1837,8 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeStartNotConfirmed) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnFailed);
EXPECT_TRUE(delegate->on_failed_called());
EXPECT_THAT(delegate->error(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
@@ -1815,7 +1861,8 @@ TEST_P(BidirectionalStreamQuicImplTest, SessionCloseDuringOnStreamReady) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
read_buffer.get(), kReadBufferSize, DeleteStreamDelegate::ON_FAILED));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnFailed);
@@ -1845,7 +1892,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnStreamReady) {
std::unique_ptr<DeleteStreamDelegate> delegate(
new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
DeleteStreamDelegate::ON_STREAM_READY));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1874,7 +1922,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamAfterReadData) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1929,7 +1978,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
std::unique_ptr<DeleteStreamDelegate> delegate(
new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
DeleteStreamDelegate::ON_HEADERS_RECEIVED));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -1975,7 +2025,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
read_buffer.get(), kReadBufferSize, DeleteStreamDelegate::ON_DATA_READ));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -2034,7 +2085,8 @@ TEST_P(BidirectionalStreamQuicImplTest, AsyncFinRead) {
std::unique_ptr<TestDelegateBase> delegate(
new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
ConfirmHandshake();
delegate->WaitUntilNextCallback(kOnStreamReady);
@@ -2096,7 +2148,8 @@ TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
std::unique_ptr<DeleteStreamDelegate> delegate(
new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
DeleteStreamDelegate::ON_TRAILERS_RECEIVED));
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
delegate->WaitUntilNextCallback(kOnStreamReady);
// Server acks the request.
@@ -2164,7 +2217,8 @@ TEST_P(BidirectionalStreamQuicImplTest, ReleaseStreamFails) {
delegate->set_trailers_expected(true);
// QuicChromiumClientSession::Handle::RequestStream() returns OK synchronously
// because Initialize() has established a Session.
- delegate->Start(&request, net_log().bound(), session()->CreateHandle());
+ delegate->Start(&request, net_log().bound(),
+ session()->CreateHandle(destination_));
// Now closes the underlying session.
session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
delegate->WaitUntilNextCallback(kOnFailed);
diff --git a/chromium/net/quic/chromium/crypto/proof_source_chromium.cc b/chromium/net/quic/chromium/crypto/proof_source_chromium.cc
index fdce1e9b170..6231a159aad 100644
--- a/chromium/net/quic/chromium/crypto/proof_source_chromium.cc
+++ b/chromium/net/quic/chromium/crypto/proof_source_chromium.cc
@@ -6,6 +6,7 @@
#include "base/strings/string_number_conversions.h"
#include "crypto/openssl_util.h"
+#include "net/cert/x509_util.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "third_party/boringssl/src/include/openssl/digest.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
@@ -41,12 +42,8 @@ bool ProofSourceChromium::Initialize(const base::FilePath& cert_path,
std::vector<string> certs;
for (const scoped_refptr<X509Certificate>& cert : certs_in_file) {
- std::string der_encoded_cert;
- if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(),
- &der_encoded_cert)) {
- return false;
- }
- certs.push_back(der_encoded_cert);
+ certs.emplace_back(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
}
chain_ = new ProofSource::Chain(certs);
diff --git a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc
index 5217270b6d4..da638941406 100644
--- a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc
+++ b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -10,6 +10,7 @@
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "crypto/signature_verifier.h"
@@ -32,7 +33,7 @@ using std::string;
namespace net {
ProofVerifyDetailsChromium::ProofVerifyDetailsChromium()
- : pkp_bypassed(false) {}
+ : pkp_bypassed(false), is_fatal_cert_error(false) {}
ProofVerifyDetailsChromium::~ProofVerifyDetailsChromium() {}
@@ -226,9 +227,9 @@ QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
// Note that this is a completely synchronous operation: The CT Log Verifier
// gets all the data it needs for SCT verification and does not do any
// external communication.
- cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct,
- &verify_details_->ct_verify_result.scts,
- net_log_);
+ cert_transparency_verifier_->Verify(
+ hostname, cert_.get(), std::string(), cert_sct,
+ &verify_details_->ct_verify_result.scts, net_log_);
// We call VerifySignature first to avoid copying of server_config and
// signature.
@@ -378,8 +379,7 @@ int ProofVerifierChromium::Job::DoVerifyCert(int result) {
}
int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.CertVerificationResult",
- -result);
+ base::UmaHistogramSparse("Net.QuicSession.CertVerificationResult", -result);
cert_verifier_request_.reset();
const CertVerifyResult& cert_verify_result =
@@ -490,6 +490,10 @@ int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
result = ct_result;
}
+ verify_details_->is_fatal_cert_error =
+ IsCertStatusError(cert_status) && !IsCertStatusMinorError(cert_status) &&
+ transport_security_state_->ShouldSSLErrorsBeFatal(hostname_);
+
if (result != OK) {
std::string error_string = ErrorToString(result);
error_details_ = StringPrintf("Failed to verify certificate chain: %s",
@@ -518,7 +522,7 @@ bool ProofVerifierChromium::Job::VerifySignature(
size_t size_bits;
X509Certificate::PublicKeyType type;
- X509Certificate::GetPublicKeyInfo(cert_->os_cert_handle(), &size_bits, &type);
+ X509Certificate::GetPublicKeyInfo(cert_->cert_buffer(), &size_bits, &type);
if (type == X509Certificate::kPublicKeyTypeRSA) {
crypto::SignatureVerifier::HashAlgorithm hash_alg =
crypto::SignatureVerifier::SHA256;
diff --git a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.h b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.h
index f5b0db5028d..53ddce4e6eb 100644
--- a/chromium/net/quic/chromium/crypto/proof_verifier_chromium.h
+++ b/chromium/net/quic/chromium/crypto/proof_verifier_chromium.h
@@ -48,6 +48,10 @@ class NET_EXPORT_PRIVATE ProofVerifyDetailsChromium
// True if PKP was bypassed due to a local trust anchor.
bool pkp_bypassed;
+
+ // True if there was a certificate error which should be treated as fatal,
+ // and false otherwise.
+ bool is_fatal_cert_error;
};
// ProofVerifyContextChromium is the implementation-specific information that a
diff --git a/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc b/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
index 51956f303ef..696efbbad07 100644
--- a/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
+++ b/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
@@ -15,6 +15,7 @@
#include "net/cert/ct_serialization.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cert/x509_util.h"
#include "net/http/transport_security_state.h"
#include "net/quic/chromium/crypto/proof_source_chromium.h"
#include "net/quic/core/crypto/proof_verifier.h"
@@ -126,7 +127,7 @@ class ProofVerifierChromiumTest : public ::testing::Test {
}
scoped_refptr<X509Certificate> GetTestServerCertificate() {
- static const char kTestCert[] = "quic_test.example.com.crt";
+ static const char kTestCert[] = "quic-chain.pem";
return ImportCertFromFile(GetTestCertsDirectory(), kTestCert);
}
@@ -134,20 +135,17 @@ class ProofVerifierChromiumTest : public ::testing::Test {
scoped_refptr<X509Certificate> cert = GetTestServerCertificate();
ASSERT_TRUE(cert);
- std::string der_bytes;
- ASSERT_TRUE(
- X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
-
certs->clear();
- certs->push_back(der_bytes);
+ certs->emplace_back(
+ x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
}
std::string GetTestSignature() {
ProofSourceChromium source;
source.Initialize(
- GetTestCertsDirectory().AppendASCII("quic_test.example.com.crt"),
- GetTestCertsDirectory().AppendASCII("quic_test.example.com.key.pkcs8"),
- GetTestCertsDirectory().AppendASCII("quic_test.example.com.key.sct"));
+ GetTestCertsDirectory().AppendASCII("quic-chain.pem"),
+ GetTestCertsDirectory().AppendASCII("quic-leaf-cert.key"),
+ base::FilePath());
std::string signature;
source.GetProof(QuicSocketAddress(), kTestHostname, kTestConfig,
QUIC_VERSION_35, kTestChloHash,
@@ -161,12 +159,9 @@ class ProofVerifierChromiumTest : public ::testing::Test {
der_test_cert.data(), der_test_cert.length());
ASSERT_TRUE(test_cert.get());
- std::string der_bytes;
- ASSERT_TRUE(X509Certificate::GetDEREncoded(test_cert->os_cert_handle(),
- &der_bytes));
-
certs->clear();
- certs->push_back(der_bytes);
+ certs->emplace_back(
+ x509_util::CryptoBufferAsStringPiece(test_cert->cert_buffer()));
}
void CheckSCT(bool sct_expected_ok) {
@@ -445,6 +440,67 @@ HashValueVector MakeHashValueVector(uint8_t tag) {
return hashes;
}
+TEST_F(ProofVerifierChromiumTest, IsFatalErrorNotSetForNonFatalError) {
+ scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
+ ASSERT_TRUE(test_cert);
+
+ CertVerifyResult dummy_result;
+ dummy_result.cert_status = MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
+ dummy_result.verified_cert = test_cert;
+
+ MockCertVerifier dummy_verifier;
+ 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());
+
+ std::unique_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
+ QuicAsyncStatus status = proof_verifier.VerifyProof(
+ kTestHostname, kTestPort, kTestConfig, QUIC_VERSION_35, kTestChloHash,
+ certs_, kTestEmptySCT, GetTestSignature(), verify_context_.get(),
+ &error_details_, &details_, std::move(callback));
+ ASSERT_EQ(QUIC_FAILURE, status);
+
+ ProofVerifyDetailsChromium* verify_details =
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
+ EXPECT_FALSE(verify_details->is_fatal_cert_error);
+}
+
+TEST_F(ProofVerifierChromiumTest, IsFatalErrorSetForFatalError) {
+ scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
+ ASSERT_TRUE(test_cert);
+
+ CertVerifyResult dummy_result;
+ dummy_result.cert_status = MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
+ dummy_result.verified_cert = test_cert;
+
+ MockCertVerifier dummy_verifier;
+ dummy_verifier.AddResultForCert(test_cert.get(), dummy_result,
+ ERR_CERT_DATE_INVALID);
+
+ const base::Time expiry =
+ 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());
+
+ std::unique_ptr<DummyProofVerifierCallback> callback(
+ new DummyProofVerifierCallback);
+ QuicAsyncStatus status = proof_verifier.VerifyProof(
+ kTestHostname, kTestPort, kTestConfig, QUIC_VERSION_35, kTestChloHash,
+ certs_, kTestEmptySCT, GetTestSignature(), verify_context_.get(),
+ &error_details_, &details_, std::move(callback));
+ ASSERT_EQ(QUIC_FAILURE, status);
+ ProofVerifyDetailsChromium* verify_details =
+ static_cast<ProofVerifyDetailsChromium*>(details_.get());
+ EXPECT_TRUE(verify_details->is_fatal_cert_error);
+}
+
// Test that PKP is enforced for certificates that chain up to known roots.
TEST_F(ProofVerifierChromiumTest, PKPEnforced) {
scoped_refptr<X509Certificate> test_cert = GetTestServerCertificate();
diff --git a/chromium/net/quic/chromium/crypto_test_utils_chromium.cc b/chromium/net/quic/chromium/crypto_test_utils_chromium.cc
index 238822c89e9..4ced45fa73a 100644
--- a/chromium/net/quic/chromium/crypto_test_utils_chromium.cc
+++ b/chromium/net/quic/chromium/crypto_test_utils_chromium.cc
@@ -82,9 +82,9 @@ std::unique_ptr<ProofSource> ProofSourceForTesting() {
std::unique_ptr<ProofSourceChromium> source(new ProofSourceChromium());
base::FilePath certs_dir = GetTestCertsDirectory();
CHECK(source->Initialize(
- certs_dir.AppendASCII("quic_chain.crt"),
- certs_dir.AppendASCII("quic_test.example.com.key.pkcs8"),
- certs_dir.AppendASCII("quic_test.example.com.key.sct")));
+ certs_dir.AppendASCII("quic-chain.pem"),
+ certs_dir.AppendASCII("quic-leaf-cert.key"),
+ certs_dir.AppendASCII("quic-leaf-cert.key.sct")));
return std::move(source);
}
@@ -93,17 +93,13 @@ std::unique_ptr<ProofVerifier> ProofVerifierForTesting() {
std::unique_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier());
net::CertVerifyResult verify_result;
verify_result.verified_cert =
- ImportCertFromFile(GetTestCertsDirectory(), "quic_test.example.com.crt");
- cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(),
- "test.example.com", verify_result, OK);
- verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
+ ImportCertFromFile(GetTestCertsDirectory(), "quic-chain.pem");
cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(),
"test.example.com", verify_result, OK);
return std::make_unique<TestProofVerifierChromium>(
std::move(cert_verifier), std::make_unique<TransportSecurityState>(),
std::make_unique<MultiLogCTVerifier>(),
- std::make_unique<CTPolicyEnforcer>(), "quic_root.crt");
+ std::make_unique<CTPolicyEnforcer>(), "quic-root.pem");
}
ProofVerifyContext* ProofVerifyContextForTesting() {
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.cc b/chromium/net/quic/chromium/quic_chromium_client_session.cc
index 1d30aba28ac..c578354f612 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_session.cc
@@ -9,6 +9,7 @@
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/single_thread_task_runner.h"
@@ -65,9 +66,6 @@ const size_t kTokenBindingSignatureMapSize = 10;
// migrating sessions need to wait for a new network to connect.
const size_t kWaitTimeForNewNetworkSecs = 10;
-// With exponential backoff, altogether we allow using non-default network
-// for up to 255 seconds before close the session.
-const int kMaxRetryCount = 7;
const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
// Maximum RTT time for this session when set initial timeout for probing
@@ -118,7 +116,7 @@ std::unique_ptr<base::Value> NetLogQuicConnectionMigrationFailureCallback(
std::string reason,
NetLogCaptureMode capture_mode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("connection_id", base::Uint64ToString(connection_id));
+ dict->SetString("connection_id", base::NumberToString(connection_id));
dict->SetString("reason", reason);
return std::move(dict);
}
@@ -127,7 +125,7 @@ std::unique_ptr<base::Value> NetLogQuicConnectionMigrationSuccessCallback(
QuicConnectionId connection_id,
NetLogCaptureMode capture_mode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("connection_id", base::Uint64ToString(connection_id));
+ dict->SetString("connection_id", base::NumberToString(connection_id));
return std::move(dict);
}
@@ -247,9 +245,11 @@ class QuicServerPushHelper : public ServerPushDelegate::ServerPushHelper {
} // namespace
QuicChromiumClientSession::Handle::Handle(
- const base::WeakPtr<QuicChromiumClientSession>& session)
+ const base::WeakPtr<QuicChromiumClientSession>& session,
+ const HostPortPair& destination)
: MultiplexedSessionHandle(session),
session_(session),
+ destination_(destination),
net_log_(session_->net_log()),
was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
net_error_(OK),
@@ -660,8 +660,11 @@ QuicChromiumClientSession::QuicChromiumClientSession(
bool migrate_sessions_on_network_change,
bool migrate_session_early_v2,
bool migrate_sessions_on_network_change_v2,
+ base::TimeDelta max_time_on_non_default_network,
+ int max_migrations_to_non_default_network_on_path_degrading,
int yield_after_packets,
QuicTime::Delta yield_after_duration,
+ bool headers_include_h2_stream_dependency,
int cert_verify_flags,
const QuicConfig& config,
QuicCryptoClientConfig* crypto_config,
@@ -681,6 +684,10 @@ QuicChromiumClientSession::QuicChromiumClientSession(
migrate_session_early_v2_(migrate_session_early_v2),
migrate_session_on_network_change_v2_(
migrate_sessions_on_network_change_v2),
+ max_time_on_non_default_network_(max_time_on_non_default_network),
+ max_migrations_to_non_default_network_on_path_degrading_(
+ max_migrations_to_non_default_network_on_path_degrading),
+ current_migrations_to_non_default_network_on_path_degrading_(0),
clock_(clock),
yield_after_packets_(yield_after_packets),
yield_after_duration_(yield_after_duration),
@@ -692,6 +699,7 @@ QuicChromiumClientSession::QuicChromiumClientSession(
transport_security_state_(transport_security_state),
server_info_(std::move(server_info)),
pkp_bypassed_(false),
+ is_fatal_cert_error_(false),
num_total_streams_(0),
task_runner_(task_runner),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::QUIC_SESSION)),
@@ -710,6 +718,8 @@ QuicChromiumClientSession::QuicChromiumClientSession(
probing_manager_(this, task_runner_),
retry_migrate_back_count_(0),
migration_pending_(false),
+ headers_include_h2_stream_dependency_(
+ headers_include_h2_stream_dependency),
weak_factory_(this) {
default_network_ = socket->GetBoundNetwork();
sockets_.push_back(std::move(socket));
@@ -815,10 +825,10 @@ QuicChromiumClientSession::~QuicChromiumClientSession() {
// The MTU used by QUIC is limited to a fairly small set of predefined values
// (initial values and MTU discovery values), but does not fare well when
// bucketed. Because of that, a sparse histogram is used here.
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ClientSideMtu",
- connection()->max_packet_length());
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ServerSideMtu",
- stats.max_received_packet_size);
+ base::UmaHistogramSparse("Net.QuicSession.ClientSideMtu",
+ connection()->max_packet_length());
+ base::UmaHistogramSparse("Net.QuicSession.ServerSideMtu",
+ stats.max_received_packet_size);
UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.MtuProbesSent",
connection()->mtu_probe_count());
@@ -856,6 +866,26 @@ void QuicChromiumClientSession::Initialize() {
set_max_uncompressed_header_bytes(kMaxUncompressedHeaderSize);
}
+size_t QuicChromiumClientSession::WriteHeaders(
+ QuicStreamId id,
+ SpdyHeaderBlock headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicReferenceCountedPointer<QuicAckListenerInterface>
+ ack_notifier_delegate) {
+ if (headers_include_h2_stream_dependency_) {
+ SpdyStreamId parent_stream_id = 0;
+ bool exclusive = false;
+ priority_dependency_state_.OnStreamCreation(id, priority, &parent_stream_id,
+ &exclusive);
+ return QuicSpdySession::WriteHeaders(id, std::move(headers), fin, priority,
+ parent_stream_id, exclusive,
+ std::move(ack_notifier_delegate));
+ }
+ return QuicSpdySession::WriteHeaders(id, std::move(headers), fin, priority,
+ std::move(ack_notifier_delegate));
+}
+
void QuicChromiumClientSession::OnHeadersHeadOfLineBlocking(
QuicTime::Delta delta) {
UMA_HISTOGRAM_TIMES(
@@ -863,6 +893,29 @@ void QuicChromiumClientSession::OnHeadersHeadOfLineBlocking(
base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()));
}
+void QuicChromiumClientSession::UnregisterStreamPriority(QuicStreamId id) {
+ if (headers_include_h2_stream_dependency_) {
+ priority_dependency_state_.OnStreamDestruction(id);
+ }
+ QuicSpdySession::UnregisterStreamPriority(id);
+}
+
+void QuicChromiumClientSession::UpdateStreamPriority(
+ QuicStreamId id,
+ SpdyPriority new_priority) {
+ if (headers_include_h2_stream_dependency_) {
+ auto updates = priority_dependency_state_.OnStreamUpdate(id, new_priority);
+ for (auto update : updates) {
+ QuicSpdyStream* stream = GetSpdyDataStream(update.id);
+ DCHECK(stream);
+ int weight = Spdy3PriorityToHttp2Weight(stream->priority());
+ WritePriority(update.id, update.dependent_stream_id, weight,
+ update.exclusive);
+ }
+ }
+ QuicSpdySession::UpdateStreamPriority(id, new_priority);
+}
+
void QuicChromiumClientSession::OnStreamFrame(const QuicStreamFrame& frame) {
// Record total number of stream frames.
UMA_HISTOGRAM_COUNTS_1M("Net.QuicNumStreamFramesInPacket", 1);
@@ -891,6 +944,25 @@ void QuicChromiumClientSession::RemoveHandle(Handle* handle) {
handles_.erase(handle);
}
+// TODO(zhongyi): replace migration_session_* booleans with
+// ConnectionMigrationMode.
+ConnectionMigrationMode QuicChromiumClientSession::connection_migration_mode()
+ const {
+ if (migrate_session_early_v2_)
+ return ConnectionMigrationMode::FULL_MIGRATION_V2;
+
+ if (migrate_session_on_network_change_v2_)
+ return ConnectionMigrationMode::NO_MIGRATION_ON_PATH_DEGRADING_V2;
+
+ if (migrate_session_early_)
+ return ConnectionMigrationMode::FULL_MIGRATION_V1;
+
+ if (migrate_session_on_network_change_)
+ return ConnectionMigrationMode::NO_MIGRATION_ON_PATH_DEGRADING_V1;
+
+ return ConnectionMigrationMode::NO_MIGRATION;
+}
+
int QuicChromiumClientSession::WaitForHandshakeConfirmation(
const CompletionCallback& callback) {
if (!connection()->connected())
@@ -904,11 +976,6 @@ int QuicChromiumClientSession::WaitForHandshakeConfirmation(
}
int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) {
- if (stream_factory_ && stream_factory_->IsQuicBroken(this)) {
- DVLOG(1) << "QUIC broken.";
- return ERR_QUIC_PROTOCOL_ERROR;
- }
-
if (goaway_received()) {
DVLOG(1) << "Going away.";
return ERR_CONNECTION_CLOSED;
@@ -1070,6 +1137,7 @@ bool QuicChromiumClientSession::GetSSLInfo(SSLInfo* ssl_info) const {
ssl_info->security_bits = security_bits;
ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL;
ssl_info->pinning_failure_log = pinning_failure_log_;
+ ssl_info->is_fatal_cert_error = is_fatal_cert_error_;
ssl_info->UpdateCertificateTransparencyInfo(*ct_verify_result_);
@@ -1357,7 +1425,7 @@ void QuicChromiumClientSession::OnConnectionClosed(
logger_->OnConnectionClosed(error, error_details, source);
if (source == ConnectionCloseSource::FROM_PEER) {
if (IsCryptoHandshakeConfirmed()) {
- UMA_HISTOGRAM_SPARSE_SLOWLY(
+ base::UmaHistogramSparse(
"Net.QuicSession.ConnectionCloseErrorCodeServer.HandshakeConfirmed",
error);
base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
@@ -1367,11 +1435,11 @@ void QuicChromiumClientSession::OnConnectionClosed(
if (num_streams > 0)
histogram->AddCount(error, num_streams);
}
- UMA_HISTOGRAM_SPARSE_SLOWLY(
- "Net.QuicSession.ConnectionCloseErrorCodeServer", error);
+ base::UmaHistogramSparse("Net.QuicSession.ConnectionCloseErrorCodeServer",
+ error);
} else {
if (IsCryptoHandshakeConfirmed()) {
- UMA_HISTOGRAM_SPARSE_SLOWLY(
+ base::UmaHistogramSparse(
"Net.QuicSession.ConnectionCloseErrorCodeClient.HandshakeConfirmed",
error);
base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
@@ -1381,8 +1449,8 @@ void QuicChromiumClientSession::OnConnectionClosed(
if (num_streams > 0)
histogram->AddCount(error, num_streams);
}
- UMA_HISTOGRAM_SPARSE_SLOWLY(
- "Net.QuicSession.ConnectionCloseErrorCodeClient", error);
+ base::UmaHistogramSparse("Net.QuicSession.ConnectionCloseErrorCodeClient",
+ error);
}
if (error == QUIC_NETWORK_IDLE_TIMEOUT) {
@@ -1400,7 +1468,7 @@ void QuicChromiumClientSession::OnConnectionClosed(
UMA_HISTOGRAM_COUNTS_1M(
"Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveTLPCount",
connection()->sent_packet_manager().GetConsecutiveTlpCount());
- UMA_HISTOGRAM_SPARSE_SLOWLY(
+ base::UmaHistogramSparse(
"Net.QuicSession.TimedOutWithOpenStreams.LocalPort",
connection()->self_address().port());
}
@@ -1430,19 +1498,19 @@ void QuicChromiumClientSession::OnConnectionClosed(
RecordHandshakeFailureReason(HANDSHAKE_FAILURE_PUBLIC_RESET);
} else if (connection()->GetStats().packets_received == 0) {
RecordHandshakeFailureReason(HANDSHAKE_FAILURE_BLACK_HOLE);
- UMA_HISTOGRAM_SPARSE_SLOWLY(
+ base::UmaHistogramSparse(
"Net.QuicSession.ConnectionClose.HandshakeFailureBlackHole.QuicError",
error);
} else {
RecordHandshakeFailureReason(HANDSHAKE_FAILURE_UNKNOWN);
- UMA_HISTOGRAM_SPARSE_SLOWLY(
+ base::UmaHistogramSparse(
"Net.QuicSession.ConnectionClose.HandshakeFailureUnknown.QuicError",
error);
}
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion",
- connection()->transport_version());
+ base::UmaHistogramSparse("Net.QuicSession.QuicVersion",
+ connection()->transport_version());
NotifyFactoryOfSessionGoingAway();
QuicSession::OnConnectionClosed(error, error_details, source);
@@ -1479,10 +1547,10 @@ void QuicChromiumClientSession::OnConnectivityProbeReceived(
int QuicChromiumClientSession::HandleWriteError(
int error_code,
scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> packet) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -error_code);
+ base::UmaHistogramSparse("Net.QuicSession.WriteError", -error_code);
if (IsCryptoHandshakeConfirmed()) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError.HandshakeConfirmed",
- -error_code);
+ base::UmaHistogramSparse("Net.QuicSession.WriteError.HandshakeConfirmed",
+ -error_code);
}
if (stream_factory_ == nullptr ||
!stream_factory_->migrate_sessions_on_network_change()) {
@@ -1626,19 +1694,26 @@ void QuicChromiumClientSession::OnProbeNetworkSucceeded(
// be acquired by connection and used as default on success.
if (!MigrateToSocket(std::move(socket), std::move(reader),
std::move(writer))) {
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE_AFTER_PROBING);
return;
}
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS_AFTER_PROBING);
if (network == default_network_) {
DVLOG(1) << "Client successfully migrated to default network.";
CancelMigrateBackToDefaultNetworkTimer();
- } else if (!migrate_back_to_default_timer_.IsRunning()) {
- // We get off the |default_network|, stay on |network| for now but
- // try to migrate back to default network after 1 second.
+ } else {
DVLOG(1) << "Client successfully got off default network after "
<< "successful probing network: " << network << ".";
- StartMigrateBackToDefaultNetworkTimer(
- base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs));
+ current_migrations_to_non_default_network_on_path_degrading_++;
+ if (!migrate_back_to_default_timer_.IsRunning()) {
+ // Session gets off the |default_network|, stay on |network| for now but
+ // try to migrate back to default network after 1 second.
+ StartMigrateBackToDefaultNetworkTimer(
+ base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs));
+ }
}
}
@@ -1734,6 +1809,8 @@ void QuicChromiumClientSession::OnNetworkDisconnectedV2(
void QuicChromiumClientSession::OnNetworkMadeDefault(
NetworkChangeNotifier::NetworkHandle new_network,
const NetLogWithSource& migration_net_log) {
+ net_log_.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_ON_NETWORK_MADE_DEFAULT);
LogMetricsOnNetworkMadeDefault();
if (!migrate_session_on_network_change_ &&
@@ -1748,6 +1825,7 @@ void QuicChromiumClientSession::OnNetworkMadeDefault(
migration_net_log);
return;
}
+ current_migrations_to_non_default_network_on_path_degrading_ = 0;
// Connection migration v2.
// If we are already on the new network.
@@ -1829,12 +1907,22 @@ void QuicChromiumClientSession::OnPathDegrading() {
stream_factory_->FindAlternateNetwork(
GetDefaultSocket()->GetBoundNetwork());
if (alternate_network != NetworkChangeNotifier::kInvalidNetworkHandle) {
- // Probe alternative network, we will migrate to the probed network
- // and decide whether we want to migrate back to the default network
- // on success.
- StartProbeNetwork(alternate_network,
- connection()->peer_address().impl().socket_address(),
- migration_net_log);
+ if (GetDefaultSocket()->GetBoundNetwork() == default_network_ &&
+ current_migrations_to_non_default_network_on_path_degrading_ >=
+ max_migrations_to_non_default_network_on_path_degrading_) {
+ HistogramAndLogMigrationFailure(
+ migration_net_log, MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED,
+ connection_id(),
+ "Exceeds maximum number of migrations on path degrading");
+ } else {
+ // Probe alternative network, session will migrate to the probed
+ // network and decide whether it wants to migrate back to the default
+ // network on success.
+ StartProbeNetwork(
+ alternate_network,
+ connection()->peer_address().impl().socket_address(),
+ migration_net_log);
+ }
} else {
HistogramAndLogMigrationFailure(
migration_net_log, MIGRATION_STATUS_DISABLED, connection_id(),
@@ -1890,6 +1978,7 @@ void QuicChromiumClientSession::OnProofVerifyDetailsAvailable(
ct_verify_result_ = std::move(ct_verify_result_copy);
logger_->OnCertificateVerified(*cert_verify_result_);
pkp_bypassed_ = verify_details_chromium->pkp_bypassed;
+ is_fatal_cert_error_ = verify_details_chromium->is_fatal_cert_error;
}
void QuicChromiumClientSession::StartReading() {
@@ -1900,8 +1989,7 @@ void QuicChromiumClientSession::StartReading() {
void QuicChromiumClientSession::CloseSessionOnError(int net_error,
QuicErrorCode quic_error) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.CloseSessionOnError",
- -net_error);
+ base::UmaHistogramSparse("Net.QuicSession.CloseSessionOnError", -net_error);
if (!callback_.is_null()) {
base::ResetAndReturn(&callback_).Run(net_error);
@@ -1922,8 +2010,7 @@ void QuicChromiumClientSession::CloseSessionOnError(int net_error,
void QuicChromiumClientSession::CloseSessionOnErrorLater(
int net_error,
QuicErrorCode quic_error) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.CloseSessionOnError",
- -net_error);
+ base::UmaHistogramSparse("Net.QuicSession.CloseSessionOnError", -net_error);
if (!callback_.is_null()) {
base::ResetAndReturn(&callback_).Run(net_error);
@@ -2114,13 +2201,14 @@ void QuicChromiumClientSession::TryMigrateBackToDefaultNetwork(
}
void QuicChromiumClientSession::MaybeRetryMigrateBackToDefaultNetwork() {
- if (retry_migrate_back_count_ > kMaxRetryCount) {
+ base::TimeDelta retry_migrate_back_timeout =
+ base::TimeDelta::FromSeconds(UINT64_C(1) << retry_migrate_back_count_);
+ if (retry_migrate_back_timeout > max_time_on_non_default_network_) {
// Mark session as going away to accept no more streams.
stream_factory_->OnSessionGoingAway(this);
return;
}
- TryMigrateBackToDefaultNetwork(
- base::TimeDelta::FromSeconds(UINT64_C(1) << retry_migrate_back_count_));
+ TryMigrateBackToDefaultNetwork(retry_migrate_back_timeout);
}
bool QuicChromiumClientSession::ShouldMigrateSession(
@@ -2202,9 +2290,8 @@ void QuicChromiumClientSession::LogMetricsOnNetworkDisconnected() {
"Net.QuicNetworkGapBetweenWriteErrorAndDisconnection",
write_error_to_disconnection_gap, base::TimeDelta::FromMilliseconds(1),
base::TimeDelta::FromMinutes(10), 100);
- UMA_HISTOGRAM_SPARSE_SLOWLY(
- "Net.QuicSession.WriteError.NetworkDisconnected",
- -most_recent_write_error_);
+ base::UmaHistogramSparse("Net.QuicSession.WriteError.NetworkDisconnected",
+ -most_recent_write_error_);
most_recent_write_error_ = 0;
most_recent_write_error_timestamp_ = base::TimeTicks();
}
@@ -2249,7 +2336,7 @@ std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
dict->SetInteger("total_streams", num_total_streams_);
dict->SetString("peer_address", peer_address().ToString());
- dict->SetString("connection_id", base::Uint64ToString(connection_id()));
+ dict->SetString("connection_id", base::NumberToString(connection_id()));
dict->SetBoolean("connected", connection()->connected());
const QuicConnectionStats& stats = connection()->GetStats();
dict->SetInteger("packets_sent", stats.packets_sent);
@@ -2268,9 +2355,9 @@ std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
}
std::unique_ptr<QuicChromiumClientSession::Handle>
-QuicChromiumClientSession::CreateHandle() {
+QuicChromiumClientSession::CreateHandle(const HostPortPair& destination) {
return std::make_unique<QuicChromiumClientSession::Handle>(
- weak_factory_.GetWeakPtr());
+ weak_factory_.GetWeakPtr(), destination);
}
void QuicChromiumClientSession::OnReadError(
@@ -2283,7 +2370,7 @@ void QuicChromiumClientSession::OnReadError(
return;
}
DVLOG(1) << "Closing session on read error: " << result;
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result);
+ base::UmaHistogramSparse("Net.QuicSession.ReadError", -result);
connection()->CloseConnection(QUIC_PACKET_READ_ERROR, ErrorToString(result),
ConnectionCloseBehavior::SILENT_CLOSE);
}
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.h b/chromium/net/quic/chromium/quic_chromium_client_session.h
index 886a9b8ca9a..6cbe4582f4f 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session.h
+++ b/chromium/net/quic/chromium/quic_chromium_client_session.h
@@ -40,6 +40,7 @@
#include "net/quic/core/quic_spdy_client_session_base.h"
#include "net/quic/core/quic_time.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/spdy/chromium/http2_priority_dependencies.h"
#include "net/spdy/chromium/multiplexed_session.h"
#include "net/spdy/chromium/server_push_delegate.h"
@@ -69,6 +70,15 @@ enum class MigrationResult {
FAILURE // Migration failed for other reasons.
};
+// Mode of connection migration.
+enum class ConnectionMigrationMode {
+ NO_MIGRATION,
+ NO_MIGRATION_ON_PATH_DEGRADING_V1,
+ FULL_MIGRATION_V1,
+ NO_MIGRATION_ON_PATH_DEGRADING_V2,
+ FULL_MIGRATION_V2
+};
+
// Result of a connectivity probing attempt.
enum class ProbingResult {
PENDING, // Probing started, pending result.
@@ -95,7 +105,10 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
: public MultiplexedSessionHandle,
public QuicClientPushPromiseIndex::Delegate {
public:
- explicit Handle(const base::WeakPtr<QuicChromiumClientSession>& session);
+ // Constructs a handle to |session| which was created via the alternative
+ // server |destination|.
+ Handle(const base::WeakPtr<QuicChromiumClientSession>& session,
+ const HostPortPair& destination);
Handle(const Handle& other) = delete;
~Handle() override;
@@ -169,9 +182,17 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Returns the session's server ID.
QuicServerId server_id() const { return server_id_; }
+ // Returns the alternative server used for this session.
+ HostPortPair destination() const { return destination_; }
+
// Returns the session's net log.
const NetLogWithSource& net_log() const { return net_log_; }
+ // Returns the session's connection migration mode.
+ ConnectionMigrationMode connection_migration_mode() const {
+ return session_->connection_migration_mode();
+ }
+
// QuicClientPushPromiseIndex::Delegate implementation
bool CheckVary(const SpdyHeaderBlock& client_request,
const SpdyHeaderBlock& promise_request,
@@ -212,6 +233,8 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// Underlying session which may be destroyed before this handle.
base::WeakPtr<QuicChromiumClientSession> session_;
+ HostPortPair destination_;
+
// Stream request created by |RequestStream()|.
std::unique_ptr<StreamRequest> stream_request_;
@@ -318,8 +341,11 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
bool migrate_session_on_network_change,
bool migrate_sesion_early_v2,
bool migrate_session_on_network_change_v2,
+ base::TimeDelta max_time_on_non_default_network,
+ int max_migrations_to_non_default_network_on_path_degrading,
int yield_after_packets,
QuicTime::Delta yield_after_duration,
+ bool headers_include_h2_stream_dependency,
int cert_verify_flags,
const QuicConfig& config,
QuicCryptoClientConfig* crypto_config,
@@ -338,6 +364,9 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
void AddHandle(Handle* handle);
void RemoveHandle(Handle* handle);
+ // Returns the session's connection migration mode.
+ ConnectionMigrationMode connection_migration_mode() const;
+
// Waits for the handshake to be confirmed and invokes |callback| when
// that happens. If the handshake has already been confirmed, returns OK.
// If the connection has already been closed, returns a net error. If the
@@ -380,7 +409,16 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
const QuicSocketAddress& peer_address) override;
// QuicSpdySession methods:
+ size_t WriteHeaders(QuicStreamId id,
+ SpdyHeaderBlock headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicReferenceCountedPointer<QuicAckListenerInterface>
+ ack_listener) override;
void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) override;
+ void UnregisterStreamPriority(QuicStreamId id) override;
+ void UpdateStreamPriority(QuicStreamId id,
+ SpdyPriority new_priority) override;
// QuicSession methods:
void OnStreamFrame(const QuicStreamFrame& frame) override;
@@ -451,7 +489,8 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
const NetLogWithSource& net_log() const { return net_log_; }
// Returns a Handle to this session.
- std::unique_ptr<QuicChromiumClientSession::Handle> CreateHandle();
+ std::unique_ptr<QuicChromiumClientSession::Handle> CreateHandle(
+ const HostPortPair& destination);
// Returns the number of client hello messages that have been sent on the
// crypto stream. If the handshake has completed then this is one greater
@@ -652,6 +691,11 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
bool migrate_session_on_network_change_;
bool migrate_session_early_v2_;
bool migrate_session_on_network_change_v2_;
+ base::TimeDelta max_time_on_non_default_network_;
+ // Maximum allowed number of migrations to non-default network triggered by
+ // path degrading per default network.
+ int max_migrations_to_non_default_network_on_path_degrading_;
+ int current_migrations_to_non_default_network_on_path_degrading_;
QuicClock* clock_; // Unowned.
int yield_after_packets_;
QuicTime::Delta yield_after_duration_;
@@ -671,6 +715,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
std::unique_ptr<ct::CTVerifyResult> ct_verify_result_;
std::string pinning_failure_log_;
bool pkp_bypassed_;
+ bool is_fatal_cert_error_;
HandleSet handles_;
StreamRequestQueue stream_requests_;
std::vector<CompletionCallback> waiting_for_confirmation_callbacks_;
@@ -708,6 +753,12 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
// sockets_.size(). Then in MigrateSessionOnError, check to see if
// the current sockets_.size() == the passed in value.
bool migration_pending_; // True while migration is underway.
+
+ // If true, client headers will include HTTP/2 stream dependency info derived
+ // from SpdyPriority.
+ bool headers_include_h2_stream_dependency_;
+ Http2PriorityDependencies priority_dependency_state_;
+
base::WeakPtrFactory<QuicChromiumClientSession> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientSession);
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
index 293479de195..aaa3b2ebe44 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -34,6 +34,7 @@
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_client_promised_info.h"
#include "net/quic/core/quic_packet_writer.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/impl/quic_test_impl.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -81,26 +82,32 @@ class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
};
class QuicChromiumClientSessionTest
- : public ::testing::TestWithParam<QuicTransportVersion> {
+ : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
public:
QuicChromiumClientSessionTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
socket_data_(
new SequencedSocketData(default_read_.get(), 1, nullptr, 0)),
random_(0),
helper_(&clock_, &random_),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
- client_maker_(GetParam(),
+ destination_(kServerHostname, kServerPort),
+ client_maker_(version_,
0,
&clock_,
kServerHostname,
- Perspective::IS_CLIENT),
- server_maker_(GetParam(),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
+ server_maker_(version_,
0,
&clock_,
kServerHostname,
- Perspective::IS_SERVER) {
+ Perspective::IS_SERVER,
+ false) {
// Advance the time, because timers do not like uninitialized times.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
@@ -126,7 +133,8 @@ class QuicChromiumClientSessionTest
QuicConnection* connection = new QuicConnection(
0, QuicSocketAddress(QuicSocketAddressImpl(kIpEndPoint)), &helper_,
&alarm_factory_, writer, true, Perspective::IS_CLIENT,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(
+ net::ParsedQuicVersion(net::PROTOCOL_QUIC_CRYPTO, version_)));
session_.reset(new TestingQuicChromiumClientSession(
connection, std::move(socket),
/*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
@@ -136,12 +144,14 @@ class QuicChromiumClientSessionTest
/*migrate_session_on_network_change*/ false,
/*migrate_session_early_v2*/ false,
/*migrate_session_on_network_change_v2*/ false,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
kQuicYieldAfterPacketsRead,
QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
- /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
- "CONNECTION_UNKNOWN", base::TimeTicks::Now(), base::TimeTicks::Now(),
- &push_promise_index_, &test_push_delegate_,
- base::ThreadTaskRunnerHandle::Get().get(),
+ /*cert_verify_flags=*/0, client_headers_include_h2_stream_dependency_,
+ DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
+ base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
+ &test_push_delegate_, base::ThreadTaskRunnerHandle::Get().get(),
/*socket_performance_watcher=*/nullptr, &net_log_));
scoped_refptr<X509Certificate> cert(
@@ -173,13 +183,15 @@ class QuicChromiumClientSessionTest
}
QuicStreamId GetNthClientInitiatedStreamId(int n) {
- return test::GetNthClientInitiatedStreamId(GetParam(), n);
+ return test::GetNthClientInitiatedStreamId(version_, n);
}
QuicStreamId GetNthServerInitiatedStreamId(int n) {
- return test::GetNthServerInitiatedStreamId(GetParam(), n);
+ return test::GetNthServerInitiatedStreamId(version_, n);
}
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
QuicFlagSaver flags_; // Save/restore all QUIC flag values.
QuicCryptoClientConfig crypto_config_;
TestNetLog net_log_;
@@ -195,6 +207,7 @@ class QuicChromiumClientSessionTest
MockCryptoClientStreamFactory crypto_client_stream_factory_;
QuicClientPushPromiseIndex push_promise_index_;
QuicServerId server_id_;
+ HostPortPair destination_;
std::unique_ptr<TestingQuicChromiumClientSession> session_;
TestServerPushDelegate test_push_delegate_;
QuicConnectionVisitorInterface* visitor_;
@@ -204,9 +217,58 @@ class QuicChromiumClientSessionTest
ProofVerifyDetailsChromium verify_details_;
};
-INSTANTIATE_TEST_CASE_P(Tests,
- QuicChromiumClientSessionTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ QuicChromiumClientSessionTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
+
+TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ std::unique_ptr<QuicEncryptedPacket> settings_packet(
+ client_maker_.MakeInitialSettingsPacket(1, nullptr));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
+ socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
+ arraysize(writes)));
+ Initialize();
+
+ SSLInfo ssl_info;
+ ProofVerifyDetailsChromium details;
+ details.cert_verify_result.verified_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ details.cert_verify_result.cert_status =
+ MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
+ details.is_fatal_cert_error = false;
+ CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
+
+ ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
+ EXPECT_FALSE(ssl_info.is_fatal_cert_error);
+}
+
+TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
+ std::unique_ptr<QuicEncryptedPacket> settings_packet(
+ client_maker_.MakeInitialSettingsPacket(1, nullptr));
+ MockWrite writes[] = {
+ MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
+ socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
+ arraysize(writes)));
+ Initialize();
+
+ SSLInfo ssl_info;
+ ProofVerifyDetailsChromium details;
+ details.cert_verify_result.verified_cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ details.cert_verify_result.cert_status =
+ MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
+ details.is_fatal_cert_error = true;
+ CompleteCryptoHandshake();
+ session_->OnProofVerifyDetailsAvailable(details);
+ ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(ssl_info.is_fatal_cert_error);
+}
TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
@@ -234,10 +296,10 @@ TEST_P(QuicChromiumClientSessionTest, Handle) {
EXPECT_EQ(&net_log_, session_net_log.net_log());
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
EXPECT_TRUE(handle->IsConnected());
EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
- EXPECT_EQ(GetParam(), handle->GetQuicVersion());
+ EXPECT_EQ(version_, handle->GetQuicVersion());
EXPECT_EQ(server_id_, handle->server_id());
EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
@@ -265,7 +327,7 @@ TEST_P(QuicChromiumClientSessionTest, Handle) {
// Veirfy that the handle works correctly after the session is closed.
EXPECT_FALSE(handle->IsConnected());
EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
- EXPECT_EQ(GetParam(), handle->GetQuicVersion());
+ EXPECT_EQ(version_, handle->GetQuicVersion());
EXPECT_EQ(server_id_, handle->server_id());
EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
@@ -276,7 +338,7 @@ TEST_P(QuicChromiumClientSessionTest, Handle) {
{
// Verify that CreateHandle() works even after the session is closed.
std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
EXPECT_FALSE(handle2->IsConnected());
EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
ASSERT_EQ(ERR_CONNECTION_CLOSED,
@@ -289,7 +351,7 @@ TEST_P(QuicChromiumClientSessionTest, Handle) {
// Veirfy that the handle works correctly after the session is deleted.
EXPECT_FALSE(handle->IsConnected());
EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
- EXPECT_EQ(GetParam(), handle->GetQuicVersion());
+ EXPECT_EQ(version_, handle->GetQuicVersion());
EXPECT_EQ(server_id_, handle->server_id());
EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
@@ -314,7 +376,7 @@ TEST_P(QuicChromiumClientSessionTest, StreamRequest) {
// Request a stream and verify that a stream was created.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
callback.callback()));
@@ -337,7 +399,7 @@ TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
// Request a stream and verify that a stream was created.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
callback.callback()));
@@ -359,7 +421,7 @@ TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
// Request a stream and verify that a stream was created.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/true,
@@ -390,7 +452,7 @@ TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
// Request a stream and cancel it without releasing the stream.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
callback.callback()));
@@ -423,7 +485,7 @@ TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
// Request a stream and verify that it's pending.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/false,
@@ -463,9 +525,9 @@ TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
// Request two streams which will both be pending.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(
@@ -512,7 +574,7 @@ TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
// Request a stream and verify that it's pending.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/false,
@@ -547,7 +609,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
// Request a stream and verify that it failed.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_CONNECTION_CLOSED,
handle->RequestStream(/*requires_confirmation=*/false,
@@ -567,7 +629,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
// Request a stream and verify that it's pending.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/true,
@@ -604,7 +666,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
// Request a stream and verify that it's pending.
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/false,
@@ -942,7 +1004,7 @@ TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
}
std::unique_ptr<QuicChromiumClientSession::Handle> handle =
- session_->CreateHandle();
+ session_->CreateHandle(destination_);
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING,
handle->RequestStream(/*requires_confirmation=*/false,
diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
index a23dc368084..e1f489c13fd 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -16,6 +16,7 @@
#include "net/quic/core/quic_spdy_client_session_base.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_spdy_session_peer.h"
@@ -154,11 +155,14 @@ class QuicChromiumClientStreamTest
: public ::testing::TestWithParam<QuicTransportVersion> {
public:
QuicChromiumClientStreamTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
- session_(new MockQuicConnection(&helper_,
- &alarm_factory_,
- Perspective::IS_CLIENT,
- SupportedTransportVersions(GetParam())),
+ : crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
+ session_(new MockQuicConnection(
+ &helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT,
+ SupportedVersions(
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, GetParam()))),
&push_promise_index_) {
stream_ = new QuicChromiumClientStream(kTestStreamId, &session_,
NetLogWithSource());
diff --git a/chromium/net/quic/chromium/quic_connection_logger.cc b/chromium/net/quic/chromium/quic_connection_logger.cc
index 38794d10225..86f4d568f36 100644
--- a/chromium/net/quic/chromium/quic_connection_logger.cc
+++ b/chromium/net/quic/chromium/quic_connection_logger.cc
@@ -13,8 +13,8 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "net/base/ip_address.h"
@@ -56,7 +56,7 @@ std::unique_ptr<base::Value> NetLogQuicPacketSentCallback(
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("transmission_type", transmission_type);
dict->SetString("packet_number",
- base::Uint64ToString(serialized_packet.packet_number));
+ base::NumberToString(serialized_packet.packet_number));
dict->SetInteger("size", serialized_packet.encrypted_length);
dict->SetString("sent_time_us",
base::Int64ToString(sent_time.ToDebuggingValue()));
@@ -68,8 +68,8 @@ std::unique_ptr<base::Value> NetLogQuicPacketRetransmittedCallback(
QuicPacketNumber new_packet_number,
NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("old_packet_number", base::Uint64ToString(old_packet_number));
- dict->SetString("new_packet_number", base::Uint64ToString(new_packet_number));
+ dict->SetString("old_packet_number", base::NumberToString(old_packet_number));
+ dict->SetString("new_packet_number", base::NumberToString(new_packet_number));
return std::move(dict);
}
@@ -77,7 +77,7 @@ std::unique_ptr<base::Value> NetLogQuicDuplicatePacketCallback(
QuicPacketNumber packet_number,
NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("packet_number", base::Uint64ToString(packet_number));
+ dict->SetString("packet_number", base::NumberToString(packet_number));
return std::move(dict);
}
@@ -85,10 +85,10 @@ std::unique_ptr<base::Value> NetLogQuicPacketHeaderCallback(
const QuicPacketHeader* header,
NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- dict->SetString("connection_id", base::Uint64ToString(header->connection_id));
+ dict->SetString("connection_id", base::NumberToString(header->connection_id));
dict->SetInteger("reset_flag", header->reset_flag);
dict->SetInteger("version_flag", header->version_flag);
- dict->SetString("packet_number", base::Uint64ToString(header->packet_number));
+ dict->SetString("packet_number", base::NumberToString(header->packet_number));
return std::move(dict);
}
@@ -98,7 +98,7 @@ std::unique_ptr<base::Value> NetLogQuicStreamFrameCallback(
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", frame->stream_id);
dict->SetBoolean("fin", frame->fin);
- dict->SetString("offset", base::Uint64ToString(frame->offset));
+ dict->SetString("offset", base::NumberToString(frame->offset));
dict->SetInteger("length", frame->data_length);
return std::move(dict);
}
@@ -108,7 +108,7 @@ std::unique_ptr<base::Value> NetLogQuicAckFrameCallback(
NetLogCaptureMode /* capture_mode */) {
auto dict = std::make_unique<base::DictionaryValue>();
dict->SetString("largest_observed",
- base::Uint64ToString(frame->deprecated_largest_observed));
+ base::NumberToString(frame->largest_acked));
dict->SetString("delta_time_largest_observed_us",
base::Int64ToString(frame->ack_delay_time.ToMicroseconds()));
@@ -117,9 +117,9 @@ std::unique_ptr<base::Value> NetLogQuicAckFrameCallback(
// V34 and above express acked packets, but only print
// missing packets, because it's typically a shorter list.
for (QuicPacketNumber packet = frame->packets.Min();
- packet < frame->deprecated_largest_observed; ++packet) {
+ packet < frame->largest_acked; ++packet) {
if (!frame->packets.Contains(packet)) {
- missing->AppendString(base::Uint64ToString(packet));
+ missing->AppendString(base::NumberToString(packet));
}
}
}
@@ -163,7 +163,7 @@ std::unique_ptr<base::Value> NetLogQuicWindowUpdateFrameCallback(
NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetInteger("stream_id", frame->stream_id);
- dict->SetString("byte_offset", base::Uint64ToString(frame->byte_offset));
+ dict->SetString("byte_offset", base::NumberToString(frame->byte_offset));
return std::move(dict);
}
@@ -191,7 +191,7 @@ std::unique_ptr<base::Value> NetLogQuicStopWaitingFrameCallback(
auto dict = std::make_unique<base::DictionaryValue>();
auto sent_info = std::make_unique<base::DictionaryValue>();
sent_info->SetString("least_unacked",
- base::Uint64ToString(frame->least_unacked));
+ base::NumberToString(frame->least_unacked));
dict->Set("sent_info", std::move(sent_info));
return std::move(dict);
}
@@ -201,9 +201,9 @@ std::unique_ptr<base::Value> NetLogQuicVersionNegotiationPacketCallback(
NetLogCaptureMode /* capture_mode */) {
auto dict = std::make_unique<base::DictionaryValue>();
auto versions = std::make_unique<base::ListValue>();
- for (QuicTransportVersionVector::const_iterator it = packet->versions.begin();
+ for (ParsedQuicVersionVector::const_iterator it = packet->versions.begin();
it != packet->versions.end(); ++it) {
- versions->AppendString(QuicVersionToString(*it));
+ versions->AppendString(ParsedQuicVersionToString(*it));
}
dict->Set("versions", std::move(versions));
return std::move(dict);
@@ -356,8 +356,8 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
break;
}
case RST_STREAM_FRAME:
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeClient",
- frame.rst_stream_frame->error_code);
+ base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeClient",
+ frame.rst_stream_frame->error_code);
break;
case CONNECTION_CLOSE_FRAME:
break;
@@ -398,8 +398,8 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
break;
}
case RST_STREAM_FRAME:
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeClient",
- frame.rst_stream_frame->error_code);
+ base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeClient",
+ frame.rst_stream_frame->error_code);
net_log_.AddEvent(NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_SENT,
base::Bind(&NetLogQuicRstStreamFrameCallback,
frame.rst_stream_frame));
@@ -522,7 +522,7 @@ void QuicConnectionLogger::OnDuplicatePacket(QuicPacketNumber packet_number) {
}
void QuicConnectionLogger::OnProtocolVersionMismatch(
- QuicTransportVersion received_version) {
+ ParsedQuicVersion received_version) {
// TODO(rtenneti): Add logging.
}
@@ -597,8 +597,8 @@ void QuicConnectionLogger::OnStopWaitingFrame(
}
void QuicConnectionLogger::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeServer",
- frame.error_code);
+ base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeServer",
+ frame.error_code);
if (!net_log_is_capturing_)
return;
net_log_.AddEvent(NetLogEventType::QUIC_SESSION_RST_STREAM_FRAME_RECEIVED,
diff --git a/chromium/net/quic/chromium/quic_connection_logger.h b/chromium/net/quic/chromium/quic_connection_logger.h
index 173f85a7c93..07b6894e456 100644
--- a/chromium/net/quic/chromium/quic_connection_logger.h
+++ b/chromium/net/quic/chromium/quic_connection_logger.h
@@ -58,7 +58,7 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
void OnIncorrectConnectionId(QuicConnectionId connection_id) override;
void OnUndecryptablePacket() override;
void OnDuplicatePacket(QuicPacketNumber packet_number) override;
- void OnProtocolVersionMismatch(QuicTransportVersion version) override;
+ void OnProtocolVersionMismatch(ParsedQuicVersion version) override;
void OnPacketHeader(const QuicPacketHeader& header) override;
void OnStreamFrame(const QuicStreamFrame& frame) override;
void OnAckFrame(const QuicAckFrame& frame) override;
diff --git a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
index b601451884d..0d041521e6a 100644
--- a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
+++ b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
@@ -132,12 +132,7 @@ class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> {
CertVerifyResult verify_result;
verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test.example.com.crt");
- cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
- "test.example.com", verify_result,
- OK);
- verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
+ GetTestCertsDirectory(), "quic-chain.pem");
cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
"test.example.com", verify_result,
OK);
@@ -181,8 +176,7 @@ class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> {
server_config_options_.token_binding_params = QuicTagVector{kTB10, kP256};
server_.reset(new QuicSimpleServer(
crypto_test_utils::ProofSourceForTesting(), server_config_,
- server_config_options_, AllSupportedTransportVersions(),
- &response_cache_));
+ server_config_options_, AllSupportedVersions(), &response_cache_));
server_->Listen(server_address_);
server_address_ = server_->server_address();
server_->StartReading();
diff --git a/chromium/net/quic/chromium/quic_http_stream.cc b/chromium/net/quic/chromium/quic_http_stream.cc
index f0d4f17280b..9c503970fbc 100644
--- a/chromium/net/quic/chromium/quic_http_stream.cc
+++ b/chromium/net/quic/chromium/quic_http_stream.cc
@@ -50,6 +50,7 @@ QuicHttpStream::QuicHttpStream(
next_state_(STATE_NONE),
stream_(nullptr),
request_info_(nullptr),
+ can_send_early_(false),
request_body_stream_(nullptr),
priority_(MINIMUM_PRIORITY),
response_info_(nullptr),
@@ -98,6 +99,7 @@ HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion(
}
int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& stream_net_log,
const CompletionCallback& callback) {
@@ -114,9 +116,15 @@ int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
stream_net_log.AddEvent(
NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
quic_session()->net_log().source().ToEventParametersCallback());
+ stream_net_log.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_MODE,
+ NetLog::IntCallback(
+ "connection_migration_mode",
+ static_cast<int>(quic_session()->connection_migration_mode())));
stream_net_log_ = stream_net_log;
request_info_ = request_info;
+ can_send_early_ = can_send_early;
request_time_ = base::Time::Now();
priority_ = priority;
@@ -378,8 +386,9 @@ bool QuicHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
bool QuicHttpStream::GetAlternativeService(
AlternativeService* alternative_service) const {
alternative_service->protocol = kProtoQUIC;
- alternative_service->host = quic_session()->server_id().host();
- alternative_service->port = quic_session()->server_id().port();
+ const HostPortPair& destination = quic_session()->destination();
+ alternative_service->host = destination.host();
+ alternative_service->port = destination.port();
return true;
}
@@ -510,8 +519,9 @@ int QuicHttpStream::DoLoop(int rv) {
int QuicHttpStream::DoRequestStream() {
next_state_ = STATE_REQUEST_STREAM_COMPLETE;
+
return quic_session()->RequestStream(
- request_info_->method == "POST",
+ !can_send_early_,
base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
}
@@ -548,6 +558,7 @@ int QuicHttpStream::DoSetRequestPriority() {
// Set priority according to request
DCHECK(stream_);
DCHECK(response_info_);
+
SpdyPriority priority = ConvertRequestPriorityToQuicPriority(priority_);
stream_->SetPriority(priority);
next_state_ = STATE_SEND_HEADERS;
diff --git a/chromium/net/quic/chromium/quic_http_stream.h b/chromium/net/quic/chromium/quic_http_stream.h
index 77945b8f352..55d7732b2f4 100644
--- a/chromium/net/quic/chromium/quic_http_stream.h
+++ b/chromium/net/quic/chromium/quic_http_stream.h
@@ -44,6 +44,7 @@ class NET_EXPORT_PRIVATE QuicHttpStream : public MultiplexedHttpStream {
// HttpStream implementation.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override;
@@ -150,6 +151,9 @@ class NET_EXPORT_PRIVATE QuicHttpStream : public MultiplexedHttpStream {
// Only valid before the response body is read.
const HttpRequestInfo* request_info_;
+ // Whether this request can be sent without confirmation.
+ bool can_send_early_;
+
// The request body to send, if any, owned by the caller.
UploadDataStream* request_body_stream_;
// Time the request was issued.
diff --git a/chromium/net/quic/chromium/quic_http_stream_test.cc b/chromium/net/quic/chromium/quic_http_stream_test.cc
index 990e6e8869f..a1e3b7aec2c 100644
--- a/chromium/net/quic/chromium/quic_http_stream_test.cc
+++ b/chromium/net/quic/chromium/quic_http_stream_test.cc
@@ -43,6 +43,7 @@
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/quic_write_blocked_list.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_string_piece.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -77,7 +78,7 @@ const uint16_t kDefaultServerPort = 443;
class TestQuicConnection : public QuicConnection {
public:
- TestQuicConnection(const QuicTransportVersionVector& versions,
+ TestQuicConnection(const ParsedQuicVersionVector& versions,
QuicConnectionId connection_id,
IPEndPoint address,
QuicChromiumConnectionHelper* helper,
@@ -162,7 +163,7 @@ class QuicHttpStreamPeer {
};
class QuicHttpStreamTest
- : public ::testing::TestWithParam<QuicTransportVersion> {
+ : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
public:
void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
@@ -183,21 +184,26 @@ class QuicHttpStreamTest
};
QuicHttpStreamTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
read_buffer_(new IOBufferWithSize(4096)),
promise_id_(GetNthServerInitiatedStreamId(0)),
stream_id_(GetNthClientInitiatedStreamId(0)),
connection_id_(2),
- client_maker_(GetParam(),
+ client_maker_(version_,
connection_id_,
&clock_,
kDefaultServerHostName,
- Perspective::IS_CLIENT),
- server_maker_(GetParam(),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
+ server_maker_(version_,
connection_id_,
&clock_,
kDefaultServerHostName,
- Perspective::IS_SERVER),
+ Perspective::IS_SERVER,
+ false),
random_generator_(0),
response_offset_(0) {
IPAddress ip(192, 0, 2, 33);
@@ -276,8 +282,9 @@ class QuicHttpStreamTest
alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
connection_ = new TestQuicConnection(
- SupportedTransportVersions(GetParam()), connection_id_, peer_addr_,
- helper_.get(), alarm_factory_.get(),
+ SupportedVersions(
+ net::ParsedQuicVersion(net::PROTOCOL_QUIC_CRYPTO, version_)),
+ connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
new QuicChromiumPacketWriter(
socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
connection_->set_visitor(&visitor_);
@@ -305,19 +312,23 @@ class QuicHttpStreamTest
/*migrate_session_on_network_change*/ false,
/*migrate_session_early_v2*/ false,
/*migrate_session_on_network_change_v2*/ false,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
kQuicYieldAfterPacketsRead,
QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
- /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
- "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr,
+ client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
+ DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start,
+ dns_end, &push_promise_index_, nullptr,
base::ThreadTaskRunnerHandle::Get().get(),
/*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
session_->Initialize();
TestCompletionCallback callback;
session_->CryptoConnect(callback.callback());
- stream_.reset(new QuicHttpStream(session_->CreateHandle()));
- promised_stream_.reset(new QuicHttpStream(session_->CreateHandle()));
-
+ stream_ = std::make_unique<QuicHttpStream>(
+ session_->CreateHandle(HostPortPair("www.example.org", 443)));
+ promised_stream_ = std::make_unique<QuicHttpStream>(
+ session_->CreateHandle(HostPortPair("www.example.org", 443)));
push_promise_[":path"] = "/bar";
push_promise_[":authority"] = "www.example.org";
push_promise_[":version"] = "HTTP/1.1";
@@ -384,11 +395,26 @@ class QuicHttpStreamTest
RequestPriority request_priority,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset) {
+ return InnerConstructRequestHeadersPacket(
+ packet_number, stream_id, should_include_version, fin, request_priority,
+ 0, spdy_headers_frame_length, offset);
+ }
+
+ std::unique_ptr<QuicReceivedPacket> InnerConstructRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ RequestPriority request_priority,
+ QuicStreamId parent_stream_id,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* offset) {
SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(request_priority);
return client_maker_.MakeRequestHeadersPacket(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(request_headers_), spdy_headers_frame_length, offset);
+ std::move(request_headers_), parent_stream_id,
+ spdy_headers_frame_length, offset);
}
std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
@@ -530,13 +556,16 @@ class QuicHttpStreamTest
}
QuicStreamId GetNthClientInitiatedStreamId(int n) {
- return test::GetNthClientInitiatedStreamId(GetParam(), n);
+ return test::GetNthClientInitiatedStreamId(version_, n);
}
QuicStreamId GetNthServerInitiatedStreamId(int n) {
- return test::GetNthServerInitiatedStreamId(GetParam(), n);
+ return test::GetNthServerInitiatedStreamId(version_, n);
}
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
+
BoundTestNetLog net_log_;
MockSendAlgorithm* send_algorithm_;
scoped_refptr<TestTaskRunner> runner_;
@@ -583,9 +612,11 @@ class QuicHttpStreamTest
QuicStreamOffset response_offset_;
};
-INSTANTIATE_TEST_CASE_P(Version,
- QuicHttpStreamTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ QuicHttpStreamTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
Initialize();
@@ -601,7 +632,7 @@ TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
Initialize();
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
QuicChromiumClientStream::Handle* client_stream =
QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
@@ -628,7 +659,7 @@ TEST_P(QuicHttpStreamTest, GetRequest) {
EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -684,7 +715,8 @@ TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
SetRequest("GET", "/", DEFAULT_PRIORITY);
AddWrite(InnerConstructRequestHeadersPacket(
3, GetNthClientInitiatedStreamId(1), kIncludeVersion, kFin,
- DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
+ DEFAULT_PRIORITY, GetNthClientInitiatedStreamId(0),
+ &spdy_request_header_frame_length, &offset));
AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); // Ack the responses.
Initialize();
@@ -693,16 +725,17 @@ TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
request_.url = GURL("https://www.example.org/");
// Start first request.
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
// Start a second request.
- QuicHttpStream stream2(session_->CreateHandle());
+ QuicHttpStream stream2(
+ session_->CreateHandle(HostPortPair("www.example.org", 443)));
TestCompletionCallback callback2;
EXPECT_EQ(OK,
- stream2.InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback2.callback()));
EXPECT_EQ(OK,
stream2.SendRequest(headers_, &response_, callback2.callback()));
@@ -773,7 +806,7 @@ TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
@@ -866,7 +899,7 @@ TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -916,7 +949,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
session_->connection()->CloseConnection(
@@ -938,7 +971,7 @@ TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
SSLInfo ssl_info;
@@ -962,7 +995,7 @@ TEST_P(QuicHttpStreamTest, GetAlternativeService) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
AlternativeService alternative_service;
@@ -995,7 +1028,7 @@ TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1034,7 +1067,7 @@ TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1069,7 +1102,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
@@ -1114,7 +1147,7 @@ TEST_P(QuicHttpStreamTest, SendPostRequest) {
IsOk());
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1185,7 +1218,7 @@ TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
IsOk());
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1260,7 +1293,7 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
TestCompletionCallback().callback(), NetLogWithSource()));
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
ASSERT_EQ(ERR_IO_PENDING,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1334,7 +1367,7 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
TestCompletionCallback().callback(), NetLogWithSource()));
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
ASSERT_EQ(ERR_IO_PENDING,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1402,7 +1435,7 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
TestCompletionCallback().callback(), NetLogWithSource()));
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
ASSERT_EQ(ERR_IO_PENDING,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1462,7 +1495,7 @@ TEST_P(QuicHttpStreamTest, DestroyedEarly) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
EXPECT_EQ(OK,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1506,8 +1539,9 @@ TEST_P(QuicHttpStreamTest, Priority) {
request_.method = "GET";
request_.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK,
+ stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
+ callback_.callback()));
// Check that priority is highest.
QuicChromiumClientStream::Handle* reliable_stream =
@@ -1573,7 +1607,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
size_t chunk_size = strlen(kUploadData);
chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
QuicHttpStream* stream = stream_.get();
DeleteStreamCallback delete_stream_callback(std::move(stream_));
@@ -1601,7 +1635,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
TestCompletionCallback().callback(), NetLogWithSource()));
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1635,7 +1669,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
TestCompletionCallback().callback(), NetLogWithSource()));
ASSERT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
stream_->SendRequest(headers_, &response_, callback_.callback()));
@@ -1650,7 +1684,7 @@ TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
// TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
@@ -1662,9 +1696,9 @@ TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
// Receive the promised response headers.
response_headers_ = promised_response_.Clone();
@@ -1716,7 +1750,7 @@ TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
// TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
@@ -1728,9 +1762,9 @@ TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
// Now sending a matching request will rendezvous with the promised
// stream, but pending secondary validation.
@@ -1790,7 +1824,7 @@ TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
// TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
@@ -1802,9 +1836,9 @@ TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
// Now sending a matching request will rendezvous with the promised
// stream, but pending secondary validation.
@@ -1832,7 +1866,7 @@ TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
// TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
@@ -1848,9 +1882,9 @@ TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
// Receive the promised response headers.
response_headers_ = promised_response_.Clone();
@@ -1902,7 +1936,7 @@ TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
// TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
@@ -1925,7 +1959,7 @@ TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
push_promise_["accept-encoding"] = "gzip";
@@ -1939,9 +1973,9 @@ TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
headers_.SetHeader("accept-encoding", "gzip");
@@ -2016,7 +2050,7 @@ TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
request_.url = GURL("https://www.example.org/");
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
push_promise_["accept-encoding"] = "gzip";
@@ -2030,9 +2064,9 @@ TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
// Make the second stream that will exercise the first step of the
// server push rendezvous mechanism.
- EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
- net_log_.bound(),
- callback_.callback()));
+ EXPECT_EQ(OK, promised_stream_->InitializeStream(
+ &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
+ callback_.callback()));
headers_.SetHeader("accept-encoding", "sdch");
@@ -2131,7 +2165,7 @@ TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
TestCompletionCallback().callback(), NetLogWithSource()));
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
int result = stream_->SendRequest(headers_, &response_, callback_.callback());
@@ -2167,7 +2201,7 @@ TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
TestCompletionCallback().callback(), NetLogWithSource()));
EXPECT_EQ(OK,
- stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
int result = stream_->SendRequest(headers_, &response_, callback_.callback());
diff --git a/chromium/net/quic/chromium/quic_http_utils.cc b/chromium/net/quic/chromium/quic_http_utils.cc
index c811fee1f05..664ab42bd65 100644
--- a/chromium/net/quic/chromium/quic_http_utils.cc
+++ b/chromium/net/quic/chromium/quic_http_utils.cc
@@ -58,10 +58,7 @@ QuicTransportVersionVector FilterSupportedAltSvcVersions(
for (uint32_t quic_version_label : quic_alt_svc.version) {
for (QuicTransportVersion supported : supported_versions) {
QuicVersionLabel supported_version_label_network_order =
- FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label
- ? QuicVersionToQuicVersionLabel(supported)
- : QuicEndian::HostToNet32(
- QuicVersionToQuicVersionLabel(supported));
+ QuicVersionToQuicVersionLabel(supported);
if (supported_version_label_network_order == quic_version_label) {
supported_alt_svc_versions.push_back(supported);
RecordAltSvcFormat(IETF_FORMAT);
diff --git a/chromium/net/quic/chromium/quic_http_utils_test.cc b/chromium/net/quic/chromium/quic_http_utils_test.cc
index 74fff2d443f..cf506ccd2bf 100644
--- a/chromium/net/quic/chromium/quic_http_utils_test.cc
+++ b/chromium/net/quic/chromium/quic_http_utils_test.cc
@@ -48,12 +48,6 @@ TEST(QuicHttpUtilsTest, FilterSupportedAltSvcVersions) {
QuicVersionToQuicVersionLabel(QUIC_VERSION_41),
QuicVersionToQuicVersionLabel(QUIC_VERSION_42)};
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- for (uint32_t& version_label : alt_svc_versions_ietf) {
- version_label = QuicEndian::HostToNet32(version_label);
- }
- }
-
QuicTransportVersionVector supported_alt_svc_versions = {QUIC_VERSION_38,
QUIC_VERSION_41};
SpdyAltSvcWireFormat::AlternativeService altsvc;
diff --git a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
index 253796bad1d..5cc6b57804b 100644
--- a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
+++ b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -119,12 +119,15 @@ struct PoolingTestParams {
os << "DIFFERENT";
break;
}
+ os << ", client_headers_include_h2_stream_dependency: "
+ << p.client_headers_include_h2_stream_dependency;
os << " }";
return os;
}
QuicTransportVersion version;
DestinationType destination_type;
+ bool client_headers_include_h2_stream_dependency;
};
std::string GenerateQuicVersionsListForAltSvcHeader(
@@ -143,9 +146,12 @@ std::vector<PoolingTestParams> GetPoolingTestParams() {
QuicTransportVersionVector all_supported_versions =
AllSupportedTransportVersions();
for (const QuicTransportVersion version : all_supported_versions) {
- params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
- params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
- params.push_back(PoolingTestParams{version, DIFFERENT});
+ params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
+ params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
+ params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
+ params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
+ params.push_back(PoolingTestParams{version, DIFFERENT, false});
+ params.push_back(PoolingTestParams{version, DIFFERENT, true});
}
return params;
}
@@ -234,23 +240,26 @@ class TestSocketPerformanceWatcherFactory
DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
};
-class QuicNetworkTransactionTest
- : public PlatformTest,
- public ::testing::WithParamInterface<QuicTransportVersion> {
+class QuicNetworkTransactionTest : public PlatformTest,
+ public ::testing::WithParamInterface<
+ std::tuple<QuicTransportVersion, bool>> {
protected:
QuicNetworkTransactionTest()
- : version_(GetParam()),
+ : version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
supported_versions_(SupportedTransportVersions(version_)),
client_maker_(version_,
0,
&clock_,
kDefaultServerHostName,
- Perspective::IS_CLIENT),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
server_maker_(version_,
0,
&clock_,
kDefaultServerHostName,
- Perspective::IS_SERVER),
+ Perspective::IS_SERVER,
+ false),
cert_transparency_verifier_(new MultiLogCTVerifier()),
ssl_config_service_(new SSLConfigServiceDefaults),
proxy_service_(ProxyService::CreateDirect()),
@@ -448,11 +457,24 @@ class QuicNetworkTransactionTest
bool fin,
SpdyHeaderBlock headers,
QuicStreamOffset* offset) {
+ return ConstructClientRequestHeadersPacket(packet_number, stream_id,
+ should_include_version, fin,
+ std::move(headers), 0, offset);
+ }
+
+ std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
+ QuicStreamOffset* offset) {
SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(headers), offset);
+ std::move(headers), parent_stream_id, offset);
}
std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket(
@@ -516,6 +538,8 @@ class QuicNetworkTransactionTest
void CreateSession(const QuicTransportVersionVector& supported_versions) {
session_params_.enable_quic = true;
session_params_.quic_supported_versions = supported_versions;
+ session_params_.quic_headers_include_h2_stream_dependency =
+ client_headers_include_h2_stream_dependency_;
session_context_.quic_clock = &clock_;
session_context_.quic_random = &random_generator_;
@@ -754,6 +778,7 @@ class QuicNetworkTransactionTest
}
const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
QuicTransportVersionVector supported_versions_;
QuicFlagSaver flags_; // Save/restore all QUIC flag values.
MockClock clock_;
@@ -804,9 +829,11 @@ class QuicNetworkTransactionTest
}
};
-INSTANTIATE_TEST_CASE_P(Version,
- QuicNetworkTransactionTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ QuicNetworkTransactionTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
base::HistogramTester histograms;
@@ -1942,7 +1969,7 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -1971,6 +1998,12 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
quic_data.AddWrite(client_maker_.MakeDataPacket(
10, kHeadersStreamId, true, false, settings_offset, settings_data));
+ if (FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp) {
+ quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket(
+ 11, true, QuicTime::Delta::Infinite(), 0, 1, 1,
+ QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
+ }
+
quic_data.AddRead(ASYNC, ERR_IO_PENDING);
quic_data.AddRead(ASYNC, OK);
quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -2032,7 +2065,7 @@ TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2131,7 +2164,7 @@ TEST_P(QuicNetworkTransactionTest,
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2299,7 +2332,7 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2328,6 +2361,12 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
quic_data.AddWrite(client_maker_.MakeDataPacket(
10, kHeadersStreamId, true, false, settings_offset, settings_data));
+ if (FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp) {
+ quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket(
+ 11, true, QuicTime::Delta::Infinite(), 0, 1, 1,
+ QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
+ }
+
quic_data.AddRead(ASYNC, ERR_IO_PENDING);
quic_data.AddRead(ASYNC, OK);
quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -2416,7 +2455,7 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2445,6 +2484,12 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
quic_data.AddWrite(client_maker_.MakeDataPacket(
10, kHeadersStreamId, true, false, settings_offset, settings_data));
+ if (FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp) {
+ quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket(
+ 11, true, QuicTime::Delta::Infinite(), 0, 1, 1,
+ QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
+ }
+
quic_data.AddRead(ASYNC, ERR_IO_PENDING);
quic_data.AddRead(ASYNC, OK);
quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -2536,7 +2581,7 @@ TEST_P(QuicNetworkTransactionTest,
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2573,6 +2618,12 @@ TEST_P(QuicNetworkTransactionTest,
quic_data.AddWrite(client_maker_.MakeDataPacket(
11, kHeadersStreamId, false, false, settings_offset, settings_data));
+ if (FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp) {
+ quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket(
+ 12, false, QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
+ QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
+ }
+
quic_data.AddRead(ASYNC, ERR_IO_PENDING);
quic_data.AddRead(ASYNC, OK);
quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -2648,7 +2699,7 @@ TEST_P(QuicNetworkTransactionTest,
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2773,7 +2824,7 @@ TEST_P(QuicNetworkTransactionTest,
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -2968,7 +3019,7 @@ TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
std::string request_data;
quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1, GetNthClientInitiatedStreamId(0), true, true, priority,
- GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
+ GetRequestHeaders("GET", "https", "/"), 0, nullptr, &header_stream_offset,
&request_data));
std::string settings_data;
@@ -3045,6 +3096,72 @@ TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
ASSERT_TRUE(http_data.AllReadDataConsumed());
}
+// Verify that when an origin has two alt-svc advertisements, one local and one
+// remote, that when the local is broken the request will go over QUIC via
+// the remote Alt-Svc.
+// This is a regression test for crbug/825646.
+TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
+ session_params_.quic_allow_remote_alt_svc = true;
+
+ GURL origin1 = request_.url; // mail.example.org
+ GURL origin2("https://www.example.org/");
+ ASSERT_NE(origin1.host(), origin2.host());
+
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
+ ASSERT_TRUE(cert->VerifyNameMatch("www.example.org", false));
+ ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org", false));
+
+ ProofVerifyDetailsChromium verify_details;
+ verify_details.cert_verify_result.verified_cert = cert;
+ verify_details.cert_verify_result.is_issued_by_known_root = true;
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ MockQuicData mock_quic_data;
+ QuicStreamOffset request_header_offset(0);
+ QuicStreamOffset response_header_offset(0);
+ mock_quic_data.AddWrite(
+ ConstructInitialSettingsPacket(1, &request_header_offset));
+ mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
+ 2, GetNthClientInitiatedStreamId(0), true, true,
+ GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
+ 1, GetNthClientInitiatedStreamId(0), false, false,
+ GetResponseHeaders("200 OK"), &response_header_offset));
+ mock_quic_data.AddRead(ConstructServerDataPacket(
+ 2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!"));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(3, 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_);
+ MockQuicData mock_quic_data2;
+ mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+ AddHangingNonAlternateProtocolSocketData();
+
+ CreateSession();
+
+ // Set up alternative service for |origin1|.
+ AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
+ AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ AlternativeServiceInfoVector alternative_services;
+ alternative_services.push_back(
+ AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
+ local_alternative, expiration,
+ session_->params().quic_supported_versions));
+ alternative_services.push_back(
+ AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
+ remote_alternative, expiration,
+ session_->params().quic_supported_versions));
+ http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
+ alternative_services);
+
+ http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
+
+ SendRequestAndExpectQuicResponse("hello!");
+}
+
// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
// request is reset from, then QUIC will be marked as broken and the request
// retried over TCP. Then, subsequent requests will go over a new QUIC
@@ -3088,14 +3205,15 @@ TEST_P(QuicNetworkTransactionTest,
// Second request will go over the pooled QUIC connection, but will be
// reset by the server.
- QuicTestPacketMaker client_maker2(version_, 0, &clock_, origin2.host(),
- Perspective::IS_CLIENT);
+ QuicTestPacketMaker client_maker2(
+ version_, 0, &clock_, origin2.host(), Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, false);
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
GetRequestHeaders("GET", "https", "/", &client_maker2),
- &request_header_offset));
+ GetNthClientInitiatedStreamId(0), &request_header_offset));
mock_quic_data.AddRead(ConstructServerRstPacket(
3, false, GetNthClientInitiatedStreamId(1), QUIC_HEADERS_TOO_LARGE));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
@@ -3118,52 +3236,23 @@ TEST_P(QuicNetworkTransactionTest,
socket_factory_.AddSocketDataProvider(&http_data);
socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
- // Then the next request to the second origin will go over a new QUIC
- // connection.
- MockQuicData mock_quic_data2;
- QuicTestPacketMaker client_maker3(version_, 0, &clock_, origin2.host(),
- Perspective::IS_CLIENT);
- QuicTestPacketMaker server_maker3(version_, 0, &clock_, origin2.host(),
- Perspective::IS_SERVER);
- QuicStreamOffset request_header_offset2(0);
- QuicStreamOffset response_header_offset2(0);
-
- crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
-
- mock_quic_data2.AddWrite(
- client_maker3.MakeInitialSettingsPacket(1, &request_header_offset2));
- mock_quic_data2.AddWrite(
- client_maker3.MakeRequestHeadersPacketWithOffsetTracking(
- 2, GetNthClientInitiatedStreamId(0), true, true,
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", "https", "/", &client_maker3),
- &request_header_offset2));
- mock_quic_data2.AddRead(
- server_maker2.MakeResponseHeadersPacketWithOffsetTracking(
- 1, GetNthClientInitiatedStreamId(0), false, false,
- GetResponseHeaders("200 OK"), &response_header_offset2));
- mock_quic_data2.AddRead(server_maker2.MakeDataPacket(
- 2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!"));
- mock_quic_data2.AddWrite(ConstructClientAckPacket(3, 2, 1, 1));
- mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data2.AddRead(ASYNC, 0); // EOF
-
- mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
+ // Then the next request to the second origin will be sent over TCP.
+ socket_factory_.AddSocketDataProvider(&http_data);
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
CreateSession();
// Set up alternative service for |origin1|.
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
http_server_properties_.SetQuicAlternativeService(
- url::SchemeHostPort(origin1),
- AlternativeService(kProtoQUIC, "mail.example.com", 443), expiration,
+ url::SchemeHostPort(origin1), alternative1, expiration,
supported_versions_);
// Set up alternative service for |origin2|.
- AlternativeServiceInfoVector alternative_services;
+ AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
http_server_properties_.SetQuicAlternativeService(
- url::SchemeHostPort(origin2),
- AlternativeService(kProtoQUIC, "www.example.com", 443), expiration,
+ url::SchemeHostPort(origin2), alternative2, expiration,
supported_versions_);
// First request opens connection to |destination1|
@@ -3175,10 +3264,14 @@ TEST_P(QuicNetworkTransactionTest,
// After it is reset, it will fail back to QUIC and mark QUIC as broken.
request_.url = origin2;
SendRequestAndExpectHttpResponse("hello world");
+ EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
+ << alternative1.ToString();
+ EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
+ << alternative2.ToString();
// The third request should use a new QUIC connection, not the broken
// QUIC connection.
- SendRequestAndExpectQuicResponse("hello!");
+ SendRequestAndExpectHttpResponse("hello world");
}
TEST_P(QuicNetworkTransactionTest,
@@ -3250,7 +3343,8 @@ TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
// as version negotiation has been completed.
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
- GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ GetRequestHeaders("GET", "https", "/"), GetNthClientInitiatedStreamId(0),
+ &request_header_offset));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), false, false,
GetResponseHeaders("200 OK"), &response_header_offset));
@@ -3302,7 +3396,8 @@ TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
// as version negotiation has been completed.
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
- GetRequestHeaders("GET", "http", "/"), &request_header_offset));
+ GetRequestHeaders("GET", "http", "/"), GetNthClientInitiatedStreamId(0),
+ &request_header_offset));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), false, false,
GetResponseHeaders("200 OK"), &response_header_offset));
@@ -3366,7 +3461,8 @@ TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
// Second request.
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
- GetRequestHeaders("GET", "https", "/"), &request_header_offset));
+ GetRequestHeaders("GET", "https", "/"), GetNthClientInitiatedStreamId(0),
+ &request_header_offset));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), false, false,
GetResponseHeaders("200 OK"), &response_header_offset));
@@ -3433,14 +3529,15 @@ TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1));
// Second request.
- QuicTestPacketMaker client_maker2(version_, 0, &clock_, origin2.host(),
- Perspective::IS_CLIENT);
+ QuicTestPacketMaker client_maker2(
+ version_, 0, &clock_, origin2.host(), Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, false);
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
GetRequestHeaders("GET", "https", "/", &client_maker2),
- &request_header_offset));
+ GetNthClientInitiatedStreamId(0), &request_header_offset));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), false, false,
GetResponseHeaders("200 OK"), &response_header_offset));
@@ -3534,8 +3631,9 @@ TEST_P(QuicNetworkTransactionTest,
QuicStreamOffset request_header_offset = 0;
QuicStreamOffset response_header_offset = 0;
- QuicTestPacketMaker client_maker(version_, 0, &clock_, "mail.example.org",
- Perspective::IS_CLIENT);
+ QuicTestPacketMaker client_maker(
+ version_, 0, &clock_, "mail.example.org", Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
server_maker_.set_hostname("www.example.org");
client_maker_.set_hostname("www.example.org");
MockQuicData mock_quic_data;
@@ -3557,7 +3655,7 @@ TEST_P(QuicNetworkTransactionTest,
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
4, GetNthClientInitiatedStreamId(1), false, true,
GetRequestHeaders("GET", "https", "/", &client_maker),
- &request_header_offset));
+ GetNthClientInitiatedStreamId(0), &request_header_offset));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), false, false,
GetResponseHeaders("200 OK"), &response_header_offset));
@@ -5327,6 +5425,8 @@ class QuicNetworkTransactionWithDestinationTest
protected:
QuicNetworkTransactionWithDestinationTest()
: version_(GetParam().version),
+ client_headers_include_h2_stream_dependency_(
+ GetParam().client_headers_include_h2_stream_dependency),
supported_versions_(SupportedTransportVersions(version_)),
destination_type_(GetParam().destination_type),
cert_transparency_verifier_(new MultiLogCTVerifier()),
@@ -5345,6 +5445,8 @@ class QuicNetworkTransactionWithDestinationTest
session_params.enable_quic = true;
session_params.quic_allow_remote_alt_svc = true;
session_params.quic_supported_versions = supported_versions_;
+ session_params.quic_headers_include_h2_stream_dependency =
+ client_headers_include_h2_stream_dependency_;
HttpNetworkSession::Context session_context;
@@ -5404,11 +5506,21 @@ class QuicNetworkTransactionWithDestinationTest
url::SchemeHostPort("https", origin, 443), alternative_service,
expiration, supported_versions_);
}
+ std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ QuicStreamOffset* offset,
+ QuicTestPacketMaker* maker) {
+ return ConstructClientRequestHeadersPacket(
+ packet_number, stream_id, should_include_version, 0, offset, maker);
+ }
std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
bool should_include_version,
+ QuicStreamId parent_stream_id,
QuicStreamOffset* offset,
QuicTestPacketMaker* maker) {
SpdyPriority priority =
@@ -5416,7 +5528,7 @@ class QuicNetworkTransactionWithDestinationTest
SpdyHeaderBlock headers(maker->GetRequestHeaders("GET", "https", "/"));
return maker->MakeRequestHeadersPacketWithOffsetTracking(
packet_number, stream_id, should_include_version, true, priority,
- std::move(headers), offset);
+ std::move(headers), parent_stream_id, offset);
}
std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket(
@@ -5532,7 +5644,8 @@ class QuicNetworkTransactionWithDestinationTest
}
MockClock clock_;
- QuicTransportVersion version_;
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
QuicTransportVersionVector supported_versions_;
DestinationType destination_type_;
std::string origin1_;
@@ -5557,7 +5670,7 @@ class QuicNetworkTransactionWithDestinationTest
SSLSocketDataProvider ssl_data_;
};
-INSTANTIATE_TEST_CASE_P(Version,
+INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequnece,
QuicNetworkTransactionWithDestinationTest,
::testing::ValuesIn(GetPoolingTestParams()));
@@ -5626,41 +5739,40 @@ TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
verify_details.cert_verify_result.is_issued_by_known_root = true;
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
- QuicTestPacketMaker client_maker1(version_, 0, &clock_, origin1_,
- Perspective::IS_CLIENT);
- QuicTestPacketMaker server_maker1(version_, 0, &clock_, origin1_,
- Perspective::IS_SERVER);
+ QuicTestPacketMaker client_maker(
+ version_, 0, &clock_, origin1_, Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
+ QuicTestPacketMaker server_maker(version_, 0, &clock_, origin1_,
+ Perspective::IS_SERVER, false);
QuicStreamOffset request_header_offset(0);
QuicStreamOffset response_header_offset(0);
MockQuicData mock_quic_data;
- mock_quic_data.AddWrite(ConstructInitialSettingsPacket(
- 1, &request_header_offset, &client_maker1));
+ mock_quic_data.AddWrite(
+ ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
2, GetNthClientInitiatedStreamId(0), true, &request_header_offset,
- &client_maker1));
+ &client_maker));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
1, GetNthClientInitiatedStreamId(0), &response_header_offset,
- &server_maker1));
+ &server_maker));
mock_quic_data.AddRead(ConstructServerDataPacket(
- 2, GetNthClientInitiatedStreamId(0), &server_maker1));
- mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
+ 2, GetNthClientInitiatedStreamId(0), &server_maker));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
- QuicTestPacketMaker client_maker2(version_, 0, &clock_, origin2_,
- Perspective::IS_CLIENT);
- QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2_,
- Perspective::IS_SERVER);
+ client_maker.set_hostname(origin2_);
+ server_maker.set_hostname(origin2_);
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
- 4, GetNthClientInitiatedStreamId(1), false, &request_header_offset,
- &client_maker2));
+ 4, GetNthClientInitiatedStreamId(1), false,
+ GetNthClientInitiatedStreamId(0), &request_header_offset, &client_maker));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, GetNthClientInitiatedStreamId(1), &response_header_offset,
- &server_maker2));
+ &server_maker));
mock_quic_data.AddRead(ConstructServerDataPacket(
- 4, GetNthClientInitiatedStreamId(1), &server_maker2));
- mock_quic_data.AddWrite(ConstructClientAckPacket(5, 4, 3, 1, &client_maker2));
+ 4, GetNthClientInitiatedStreamId(1), &server_maker));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
@@ -5708,10 +5820,11 @@ TEST_P(QuicNetworkTransactionWithDestinationTest,
verify_details2.cert_verify_result.is_issued_by_known_root = true;
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
- QuicTestPacketMaker client_maker1(version_, 0, &clock_, origin1_,
- Perspective::IS_CLIENT);
+ QuicTestPacketMaker client_maker1(
+ version_, 0, &clock_, origin1_, Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
QuicTestPacketMaker server_maker1(version_, 0, &clock_, origin1_,
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, false);
MockQuicData mock_quic_data1;
QuicStreamOffset header_stream_offset1 = 0;
@@ -5731,12 +5844,11 @@ TEST_P(QuicNetworkTransactionWithDestinationTest,
mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
- AddHangingSocketData();
-
- QuicTestPacketMaker client_maker2(version_, 0, &clock_, origin2_,
- Perspective::IS_CLIENT);
+ QuicTestPacketMaker client_maker2(
+ version_, 0, &clock_, origin2_, Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_);
QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2_,
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, false);
MockQuicData mock_quic_data2;
QuicStreamOffset header_stream_offset2 = 0;
@@ -5756,8 +5868,6 @@ TEST_P(QuicNetworkTransactionWithDestinationTest,
mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
- AddHangingSocketData();
-
SendRequestAndExpectQuicResponse(origin1_);
SendRequestAndExpectQuicResponse(origin2_);
diff --git a/chromium/net/quic/chromium/quic_proxy_client_socket.cc b/chromium/net/quic/chromium/quic_proxy_client_socket.cc
index e1e39a1b2eb..82736b78460 100644
--- a/chromium/net/quic/chromium/quic_proxy_client_socket.cc
+++ b/chromium/net/quic/chromium/quic_proxy_client_socket.cc
@@ -16,6 +16,7 @@
#include "net/log/net_log_source.h"
#include "net/log/net_log_source_type.h"
#include "net/spdy/chromium/spdy_http_utils.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -30,6 +31,7 @@ QuicProxyClientSocket::QuicProxyClientSocket(
stream_(std::move(stream)),
session_(std::move(session)),
read_buf_(nullptr),
+ write_buf_len_(0),
endpoint_(endpoint),
auth_(auth_controller),
user_agent_(user_agent),
@@ -108,6 +110,7 @@ void QuicProxyClientSocket::Disconnect() {
read_callback_.Reset();
read_buf_ = nullptr;
write_callback_.Reset();
+ write_buf_len_ = 0;
next_state_ = STATE_DISCONNECTED;
@@ -159,6 +162,11 @@ int64_t QuicProxyClientSocket::GetTotalReceivedBytes() const {
return stream_->NumBytesConsumed();
}
+void QuicProxyClientSocket::ApplySocketTag(const SocketTag& tag) {
+ // |session_| can be tagged, but |stream_| cannot.
+ CHECK(false);
+}
+
int QuicProxyClientSocket::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
@@ -205,9 +213,11 @@ void QuicProxyClientSocket::OnReadComplete(int rv) {
}
}
-int QuicProxyClientSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int QuicProxyClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(connect_callback_.is_null());
DCHECK(write_callback_.is_null());
@@ -221,16 +231,24 @@ int QuicProxyClientSocket::Write(IOBuffer* buf,
QuicStringPiece(buf->data(), buf_len), false,
base::Bind(&QuicProxyClientSocket::OnWriteComplete,
weak_factory_.GetWeakPtr()));
+ if (rv == OK)
+ return buf_len;
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
write_callback_ = callback;
+ write_buf_len_ = buf_len;
+ }
return rv;
}
void QuicProxyClientSocket::OnWriteComplete(int rv) {
- if (!write_callback_.is_null())
+ if (!write_callback_.is_null()) {
+ if (rv == OK)
+ rv = write_buf_len_;
+ write_buf_len_ = 0;
base::ResetAndReturn(&write_callback_).Run(rv);
+ }
}
int QuicProxyClientSocket::SetReceiveBufferSize(int32_t size) {
diff --git a/chromium/net/quic/chromium/quic_proxy_client_socket.h b/chromium/net/quic/chromium/quic_proxy_client_socket.h
index 3b0795eb9be..37f2b847333 100644
--- a/chromium/net/quic/chromium/quic_proxy_client_socket.h
+++ b/chromium/net/quic/chromium/quic_proxy_client_socket.h
@@ -13,6 +13,7 @@
#include "net/quic/chromium/quic_chromium_client_session.h"
#include "net/quic/chromium/quic_chromium_client_stream.h"
#include "net/spdy/chromium/spdy_read_queue.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -34,7 +35,7 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
const NetLogWithSource& net_log,
HttpAuthController* auth_controller);
- /// On destruction Disconnect() is called.
+ // On destruction Disconnect() is called.
~QuicProxyClientSocket() override;
// ProxyClientSocket methods:
@@ -61,6 +62,7 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -68,7 +70,8 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
@@ -122,6 +125,8 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
IOBuffer* read_buf_;
// Stores the callback for Write().
CompletionCallback write_callback_;
+ // Stores the write buffer length for Write().
+ int write_buf_len_;
// CONNECT request and response.
HttpRequestInfo request_;
diff --git a/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc b/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
index a91b5960fe6..87a39c6e666 100644
--- a/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
+++ b/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
@@ -28,6 +28,7 @@
#include "net/quic/chromium/quic_test_packet_maker.h"
#include "net/quic/chromium/test_task_runner.h"
#include "net/quic/core/crypto/null_encrypter.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
@@ -36,6 +37,7 @@
#include "net/socket/socket_test_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -74,7 +76,7 @@ const QuicStreamId kClientDataStreamId1 = kHeadersStreamId + 2;
} // namespace
class QuicProxyClientSocketTest
- : public ::testing::TestWithParam<QuicTransportVersion> {
+ : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
protected:
static const bool kFin = true;
static const bool kIncludeVersion = true;
@@ -103,19 +105,23 @@ class QuicProxyClientSocketTest
}
QuicProxyClientSocketTest()
- : version_(GetParam()),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : version_(std::get<0>(GetParam())),
+ client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
connection_id_(2),
client_maker_(version_,
connection_id_,
&clock_,
kProxyHost,
- Perspective::IS_CLIENT),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
server_maker_(version_,
connection_id_,
&clock_,
kProxyHost,
- Perspective::IS_SERVER),
+ Perspective::IS_SERVER,
+ false),
random_generator_(0),
header_stream_offset_(0),
response_offset_(0),
@@ -169,7 +175,9 @@ class QuicProxyClientSocketTest
QuicConnection* connection = new QuicConnection(
connection_id_, QuicSocketAddress(QuicSocketAddressImpl(peer_addr_)),
helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
- Perspective::IS_CLIENT, SupportedTransportVersions(GetParam()));
+ Perspective::IS_CLIENT,
+ SupportedVersions(
+ net::ParsedQuicVersion(net::PROTOCOL_QUIC_CRYPTO, version_)));
connection->set_visitor(&visitor_);
QuicConnectionPeer::SetSendAlgorithm(connection, send_algorithm_);
@@ -195,16 +203,20 @@ class QuicProxyClientSocketTest
/*migrate_session_on_network_change*/ false,
/*migrate_session_early_v2*/ false,
/*migrate_session_on_network_change_v2*/ false,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
kQuicYieldAfterPacketsRead,
QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
- /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
- "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_, nullptr,
+ client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
+ DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start,
+ dns_end, &push_promise_index_, nullptr,
base::ThreadTaskRunnerHandle::Get().get(),
/*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
writer->set_delegate(session_.get());
- session_handle_ = session_->CreateHandle();
+ session_handle_ =
+ session_->CreateHandle(HostPortPair("mail.example.org", 80));
session_->Initialize();
TestCompletionCallback callback;
@@ -281,8 +293,8 @@ class QuicProxyClientSocketTest
PopulateConnectRequestIR(&block);
return client_maker_.MakeRequestHeadersPacket(
packet_number, kClientDataStreamId1, kIncludeVersion, !kFin,
- ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), nullptr,
- &header_stream_offset_);
+ ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
+ nullptr, &header_stream_offset_);
}
std::unique_ptr<QuicReceivedPacket> ConstructConnectAuthRequestPacket(
@@ -292,8 +304,8 @@ class QuicProxyClientSocketTest
block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
return client_maker_.MakeRequestHeadersPacket(
packet_number, kClientDataStreamId1, kIncludeVersion, !kFin,
- ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), nullptr,
- &header_stream_offset_);
+ ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
+ nullptr, &header_stream_offset_);
}
std::unique_ptr<QuicReceivedPacket> ConstructDataPacket(
@@ -430,14 +442,15 @@ class QuicProxyClientSocketTest
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(len));
memcpy(buf->data(), data, len);
EXPECT_EQ(rv,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
}
void AssertSyncWriteSucceeds(const char* data, int len) {
scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(len));
memcpy(buf->data(), data, len);
- EXPECT_THAT(sock_->Write(buf.get(), buf->size(), CompletionCallback()),
- IsOk());
+ EXPECT_EQ(len, sock_->Write(buf.get(), buf->size(), CompletionCallback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
}
void AssertSyncReadEquals(const char* data, int len) {
@@ -476,7 +489,8 @@ class QuicProxyClientSocketTest
ASSERT_EQ(SpdyString(data, len), SpdyString(read_buf_->data(), len));
}
- QuicTransportVersion version_;
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
// order of destruction of these members matter
MockClock clock_;
@@ -1103,7 +1117,7 @@ TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
// asynchronous starting with the second time it's called while the UDP socket
// is write-blocked. Therefore, at least two writes need to be called on
// |sock_| to get an asynchronous one.
- AssertWriteReturns(kMsg2, kLen2, OK);
+ AssertWriteReturns(kMsg2, kLen2, kLen2);
AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
AssertAsyncReadEquals(kMsg3, kLen3);
@@ -1112,7 +1126,7 @@ TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
// Now the write will complete
ResumeAndRun();
- EXPECT_EQ(OK, write_callback_.WaitForResult());
+ EXPECT_EQ(kLen2, write_callback_.WaitForResult());
}
// ----------- Reading/Writing on Closed socket
@@ -1259,7 +1273,7 @@ TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
// asynchronous starting with the second time it's called while the UDP socket
// is write-blocked. Therefore, at least two writes need to be called on
// |sock_| to get an asynchronous one.
- AssertWriteReturns(kMsg1, kLen1, OK);
+ AssertWriteReturns(kMsg1, kLen1, kLen1);
// This second write will be async. This is the pending write that's being
// tested.
@@ -1288,7 +1302,7 @@ TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
// asynchronous starting with the second time it's called while the UDP socket
// is write-blocked. Therefore, at least two writes need to be called on
// |sock_| to get an asynchronous one.
- AssertWriteReturns(kMsg1, kLen1, OK);
+ AssertWriteReturns(kMsg1, kLen1, kLen1);
// This second write will be async. This is the pending write that's being
// tested.
@@ -1362,7 +1376,7 @@ TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
// asynchronous starting with the second time it's called while the UDP socket
// is write-blocked. Therefore, at least two writes need to be called on
// |sock_| to get an asynchronous one.
- AssertWriteReturns(kMsg2, kLen2, OK);
+ AssertWriteReturns(kMsg2, kLen2, kLen2);
AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
ResumeAndRun();
@@ -1482,7 +1496,7 @@ TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
// asynchronous starting with the second time it's called while the UDP socket
// is write-blocked. Therefore, at least two writes need to be called on
// |sock_| to get an asynchronous one.
- AssertWriteReturns(kMsg1, kLen1, OK);
+ AssertWriteReturns(kMsg1, kLen1, kLen1);
AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
ResumeAndRun();
@@ -1493,9 +1507,11 @@ TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
EXPECT_FALSE(write_callback_.have_result());
}
-INSTANTIATE_TEST_CASE_P(Version,
- QuicProxyClientSocketTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+INSTANTIATE_TEST_CASE_P(
+ VersionIncludeStreamDependencySequnece,
+ QuicProxyClientSocketTest,
+ ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
+ ::testing::Bool()));
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/chromium/quic_stream_factory.cc b/chromium/net/quic/chromium/quic_stream_factory.cc
index f680339d1e2..97a53067b4d 100644
--- a/chromium/net/quic/chromium/quic_stream_factory.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory.cc
@@ -12,8 +12,8 @@
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
@@ -49,6 +49,7 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_client_promised_info.h"
#include "net/quic/core/quic_connection.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_clock.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/socket/client_socket_factory.h"
@@ -317,7 +318,8 @@ class QuicStreamFactory::Job {
~Job();
- int Run(const CompletionCallback& callback);
+ int Run(const CompletionCallback& host_resolution_callback,
+ const CompletionCallback& callback);
int DoLoop(int rv);
int DoResolveHost();
@@ -340,6 +342,10 @@ class QuicStreamFactory::Job {
void AddRequest(QuicStreamRequest* request) {
stream_requests_.insert(request);
+ if (io_state_ == STATE_RESOLVE_HOST ||
+ io_state_ == STATE_RESOLVE_HOST_COMPLETE) {
+ request->ExpectOnHostResolution();
+ }
}
void RemoveRequest(QuicStreamRequest* request) {
@@ -352,6 +358,10 @@ class QuicStreamFactory::Job {
return stream_requests_;
}
+ bool IsHostResolutionComplete() const {
+ return io_state_ == STATE_NONE || io_state_ >= STATE_CONNECT;
+ }
+
private:
enum IoState {
STATE_NONE,
@@ -373,6 +383,7 @@ class QuicStreamFactory::Job {
const NetLogWithSource net_log_;
int num_sent_client_hellos_;
QuicChromiumClientSession* session_;
+ CompletionCallback host_resolution_callback_;
CompletionCallback callback_;
AddressList address_list_;
base::TimeTicks dns_resolution_start_time_;
@@ -424,10 +435,14 @@ QuicStreamFactory::Job::~Job() {
// non-null.
}
-int QuicStreamFactory::Job::Run(const CompletionCallback& callback) {
+int QuicStreamFactory::Job::Run(
+ const CompletionCallback& host_resolution_callback,
+ const CompletionCallback& callback) {
int rv = DoLoop(OK);
- if (rv == ERR_IO_PENDING)
+ if (rv == ERR_IO_PENDING) {
+ host_resolution_callback_ = host_resolution_callback;
callback_ = callback;
+ }
return rv > 0 ? OK : rv;
}
@@ -462,7 +477,12 @@ int QuicStreamFactory::Job::DoLoop(int rv) {
}
void QuicStreamFactory::Job::OnIOComplete(int rv) {
+ IoState start_state = io_state_;
rv = DoLoop(rv);
+ if (start_state == STATE_RESOLVE_HOST_COMPLETE &&
+ !host_resolution_callback_.is_null()) {
+ base::ResetAndReturn(&host_resolution_callback_).Run(rv);
+ }
if (rv != ERR_IO_PENDING && !callback_.is_null()) {
base::ResetAndReturn(&callback_).Run(rv);
}
@@ -500,7 +520,7 @@ int QuicStreamFactory::Job::DoResolveHostComplete(int rv) {
// Inform the factory of this resolution, which will set up
// a session alias, if possible.
- if (factory_->OnResolution(key_, address_list_))
+ if (factory_->HasMatchingIpSession(key_, address_list_))
return OK;
io_state_ = STATE_CONNECT;
@@ -567,7 +587,7 @@ int QuicStreamFactory::Job::DoConnectComplete(int rv) {
// existing session instead.
AddressList address(
session_->connection()->peer_address().impl().socket_address());
- if (factory_->OnResolution(key_, address)) {
+ if (factory_->HasMatchingIpSession(key_, address)) {
session_->connection()->CloseConnection(
QUIC_CONNECTION_IP_POOLED, "An active session exists for the given IP.",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
@@ -581,7 +601,7 @@ int QuicStreamFactory::Job::DoConnectComplete(int rv) {
}
QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory)
- : factory_(factory) {}
+ : factory_(factory), expect_on_host_resolution_(false) {}
QuicStreamRequest::~QuicStreamRequest() {
if (factory_ && !callback_.is_null())
@@ -600,6 +620,7 @@ int QuicStreamRequest::Request(const HostPortPair& destination,
DCHECK_NE(quic_version, QUIC_VERSION_UNSUPPORTED);
DCHECK(net_error_details);
DCHECK(callback_.is_null());
+ DCHECK(host_resolution_callback_.is_null());
DCHECK(factory_);
net_error_details_ = net_error_details;
@@ -611,13 +632,24 @@ int QuicStreamRequest::Request(const HostPortPair& destination,
net_log_ = net_log;
callback_ = callback;
} else {
+ DCHECK(!expect_on_host_resolution_);
factory_ = nullptr;
}
+
if (rv == OK)
DCHECK(session_);
return rv;
}
+bool QuicStreamRequest::WaitForHostResolution(
+ const CompletionCallback& callback) {
+ DCHECK(host_resolution_callback_.is_null());
+ if (expect_on_host_resolution_) {
+ host_resolution_callback_ = callback;
+ }
+ return expect_on_host_resolution_;
+}
+
void QuicStreamRequest::SetSession(
std::unique_ptr<QuicChromiumClientSession::Handle> session) {
session_ = move(session);
@@ -628,6 +660,18 @@ void QuicStreamRequest::OnRequestComplete(int rv) {
base::ResetAndReturn(&callback_).Run(rv);
}
+void QuicStreamRequest::ExpectOnHostResolution() {
+ expect_on_host_resolution_ = true;
+}
+
+void QuicStreamRequest::OnHostResolutionComplete(int rv) {
+ DCHECK(expect_on_host_resolution_);
+ expect_on_host_resolution_ = false;
+ if (!host_resolution_callback_.is_null()) {
+ base::ResetAndReturn(&host_resolution_callback_).Run(rv);
+ }
+}
+
base::TimeDelta QuicStreamRequest::GetTimeDelayForWaitingJob() const {
if (!factory_)
return base::TimeDelta();
@@ -671,9 +715,12 @@ QuicStreamFactory::QuicStreamFactory(
bool migrate_sessions_early,
bool migrate_sessions_on_network_change_v2,
bool migrate_sessions_early_v2,
+ base::TimeDelta max_time_on_non_default_network,
+ int max_migrations_to_non_default_network_on_path_degrading,
bool allow_server_migration,
bool race_cert_verification,
bool estimate_initial_rtt,
+ bool headers_include_h2_stream_dependency,
const QuicTagVector& connection_options,
const QuicTagVector& client_connection_options,
bool enable_token_binding)
@@ -701,7 +748,8 @@ QuicStreamFactory::QuicStreamFactory(
std::make_unique<ProofVerifierChromium>(cert_verifier,
ct_policy_enforcer,
transport_security_state,
- cert_transparency_verifier)),
+ cert_transparency_verifier),
+ TlsClientHandshaker::CreateSslCtx()),
mark_quic_broken_when_network_blackholes_(
mark_quic_broken_when_network_blackholes),
store_server_configs_in_properties_(store_server_configs_in_properties),
@@ -720,6 +768,9 @@ QuicStreamFactory::QuicStreamFactory(
NetworkChangeNotifier::AreNetworkHandlesSupported()),
migrate_sessions_early_v2_(migrate_sessions_early_v2 &&
migrate_sessions_on_network_change_v2_),
+ max_time_on_non_default_network_(max_time_on_non_default_network),
+ max_migrations_to_non_default_network_on_path_degrading_(
+ max_migrations_to_non_default_network_on_path_degrading),
migrate_sessions_on_network_change_(
!migrate_sessions_on_network_change_v2_ &&
migrate_sessions_on_network_change &&
@@ -730,6 +781,8 @@ QuicStreamFactory::QuicStreamFactory(
allow_server_migration_(allow_server_migration),
race_cert_verification_(race_cert_verification),
estimate_initial_rtt(estimate_initial_rtt),
+ headers_include_h2_stream_dependency_(
+ headers_include_h2_stream_dependency),
need_to_check_persisted_supports_quic_(true),
num_push_streams_created_(0),
task_runner_(nullptr),
@@ -906,7 +959,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id,
static_cast<QuicChromiumClientSession*>(promised->session());
DCHECK(session);
if (session->server_id().privacy_mode() == server_id.privacy_mode()) {
- request->SetSession(session->CreateHandle());
+ request->SetSession(session->CreateHandle(destination));
++num_push_streams_created_;
return OK;
}
@@ -922,7 +975,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id,
SessionMap::iterator it = active_sessions_.find(server_id);
if (it != active_sessions_.end()) {
QuicChromiumClientSession* session = it->second;
- request->SetSession(session->CreateHandle());
+ request->SetSession(session->CreateHandle(destination));
return OK;
}
}
@@ -947,7 +1000,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id,
QuicChromiumClientSession* session = key_value.second;
if (destination.Equals(all_sessions_[session].destination()) &&
session->CanPool(server_id.host(), server_id.privacy_mode())) {
- request->SetSession(session->CreateHandle());
+ request->SetSession(session->CreateHandle(destination));
return OK;
}
}
@@ -964,8 +1017,11 @@ int QuicStreamFactory::Create(const QuicServerId& server_id,
std::unique_ptr<Job> job = std::make_unique<Job>(
this, quic_version, host_resolver_, key, WasQuicRecentlyBroken(server_id),
priority, cert_verify_flags, net_log);
- int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
- base::Unretained(this), job.get()));
+ int rv = job->Run(
+ base::BindRepeating(&QuicStreamFactory::OnJobHostResolutionComplete,
+ base::Unretained(this), job.get()),
+ base::BindRepeating(&QuicStreamFactory::OnJobComplete,
+ base::Unretained(this), job.get()));
if (rv == ERR_IO_PENDING) {
job->AddRequest(request);
active_jobs_[server_id] = std::move(job);
@@ -981,7 +1037,7 @@ int QuicStreamFactory::Create(const QuicServerId& server_id,
if (it == active_sessions_.end())
return ERR_QUIC_PROTOCOL_ERROR;
QuicChromiumClientSession* session = it->second;
- request->SetSession(session->CreateHandle());
+ request->SetSession(session->CreateHandle(destination));
}
return rv;
}
@@ -1008,8 +1064,8 @@ size_t QuicStreamFactory::QuicSessionKey::EstimateMemoryUsage() const {
EstimateServerIdMemoryUsage(server_id_);
}
-bool QuicStreamFactory::OnResolution(const QuicSessionKey& key,
- const AddressList& address_list) {
+bool QuicStreamFactory::HasMatchingIpSession(const QuicSessionKey& key,
+ const AddressList& address_list) {
const QuicServerId& server_id(key.server_id());
DCHECK(!HasActiveSession(server_id));
for (const IPEndPoint& address : address_list) {
@@ -1028,6 +1084,14 @@ bool QuicStreamFactory::OnResolution(const QuicSessionKey& key,
return false;
}
+void QuicStreamFactory::OnJobHostResolutionComplete(Job* job, int rv) {
+ auto iter = active_jobs_.find(job->key().server_id());
+ DCHECK(iter != active_jobs_.end());
+ for (auto* request : iter->second->stream_requests()) {
+ request->OnHostResolutionComplete(rv);
+ }
+}
+
void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
auto iter = active_jobs_.find(job->key().server_id());
DCHECK(iter != active_jobs_.end());
@@ -1040,7 +1104,7 @@ void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
QuicChromiumClientSession* session = session_it->second;
for (auto* request : iter->second->stream_requests()) {
// Do not notify |request| yet.
- request->SetSession(session->CreateHandle());
+ request->SetSession(session->CreateHandle(job->key().destination()));
}
}
@@ -1060,19 +1124,6 @@ void QuicStreamFactory::OnCertVerifyJobComplete(CertVerifierJob* job, int rv) {
active_cert_verifier_jobs_.erase(job->server_id());
}
-bool QuicStreamFactory::IsQuicBroken(QuicChromiumClientSession* session) {
- const AlternativeService alternative_service(
- kProtoQUIC, session->server_id().host_port_pair());
- if (!http_server_properties_->IsAlternativeServiceBroken(
- alternative_service)) {
- return false;
- }
- // No longer send requests to a server for which QUIC is broken, but
- // continue to service existing requests.
- OnSessionGoingAway(session);
- return true;
-}
-
void QuicStreamFactory::OnIdleSession(QuicChromiumClientSession* session) {}
void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
@@ -1128,7 +1179,7 @@ void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
}
void QuicStreamFactory::CloseAllSessions(int error, QuicErrorCode quic_error) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.CloseAllSessionsError", -error);
+ base::UmaHistogramSparse("Net.QuicSession.CloseAllSessionsError", -error);
while (!active_sessions_.empty()) {
size_t initial_size = active_sessions_.size();
active_sessions_.begin()->second->CloseSessionOnError(error, quic_error);
@@ -1404,7 +1455,9 @@ int QuicStreamFactory::CreateSession(const QuicSessionKey& key,
QuicConnection* connection = new QuicConnection(
connection_id, QuicSocketAddress(QuicSocketAddressImpl(addr)),
helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
- Perspective::IS_CLIENT, {quic_version});
+ Perspective::IS_CLIENT,
+ ParsedQuicVersionVector{
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, quic_version)});
connection->set_ping_timeout(ping_timeout_);
connection->SetMaxPacketLength(max_packet_length_);
@@ -1435,11 +1488,14 @@ int QuicStreamFactory::CreateSession(const QuicSessionKey& key,
clock_, transport_security_state_, std::move(server_info), server_id,
require_confirmation, migrate_sessions_early_,
migrate_sessions_on_network_change_, migrate_sessions_early_v2_,
- migrate_sessions_on_network_change_v2_, yield_after_packets_,
- yield_after_duration_, cert_verify_flags, config, &crypto_config_,
- network_connection_.connection_description(), dns_resolution_start_time,
- dns_resolution_end_time, &push_promise_index_, push_delegate_,
- task_runner_, std::move(socket_performance_watcher), net_log.net_log());
+ migrate_sessions_on_network_change_v2_, max_time_on_non_default_network_,
+ max_migrations_to_non_default_network_on_path_degrading_,
+ yield_after_packets_, yield_after_duration_,
+ headers_include_h2_stream_dependency_, cert_verify_flags, config,
+ &crypto_config_, network_connection_.connection_description(),
+ dns_resolution_start_time, dns_resolution_end_time, &push_promise_index_,
+ push_delegate_, task_runner_, std::move(socket_performance_watcher),
+ net_log.net_log());
all_sessions_[*session] = key; // owning pointer
writer->set_delegate(*session);
diff --git a/chromium/net/quic/chromium/quic_stream_factory.h b/chromium/net/quic/chromium/quic_stream_factory.h
index ae26f7f4539..3607f5df51d 100644
--- a/chromium/net/quic/chromium/quic_stream_factory.h
+++ b/chromium/net/quic/chromium/quic_stream_factory.h
@@ -84,6 +84,7 @@ enum QuicConnectionMigrationStatus {
MIGRATION_STATUS_NON_MIGRATABLE_STREAM,
MIGRATION_STATUS_DISABLED,
MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
+ MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED,
MIGRATION_STATUS_MAX
};
@@ -118,6 +119,23 @@ class NET_EXPORT_PRIVATE QuicStreamRequest {
NetErrorDetails* net_error_details,
const CompletionCallback& callback);
+ // This function must be called after Request() returns ERR_IO_PENDING.
+ // Returns true if Request() requires host resolution and it hasn't completed
+ // yet. If true is returned, |callback| will run when host resolution
+ // completes. It will be called with the result after host resolution during
+ // the connection process. For example, if host resolution returns OK and then
+ // crypto handshake returns ERR_IO_PENDING, then |callback| will run with
+ // ERR_IO_PENDING.
+ bool WaitForHostResolution(const CompletionCallback& callback);
+
+ // Tells QuicStreamRequest it should expect OnHostResolutionComplete()
+ // to be called in the future.
+ void ExpectOnHostResolution();
+
+ // Will be called by the associated QuicStreamFactory::Job when host
+ // resolution completes asynchronously after Request().
+ void OnHostResolutionComplete(int rv);
+
void OnRequestComplete(int rv);
// Helper method that calls |factory_|'s GetTimeDelayForWaitingJob(). It
@@ -144,6 +162,12 @@ class NET_EXPORT_PRIVATE QuicStreamRequest {
NetErrorDetails* net_error_details_; // Unowned.
std::unique_ptr<QuicChromiumClientSession::Handle> session_;
+ // Set in Request(). If true, then OnHostResolutionComplete() is expected to
+ // be called in the future.
+ bool expect_on_host_resolution_;
+ // Callback passed to WaitForHostResolution().
+ CompletionCallback host_resolution_callback_;
+
DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest);
};
@@ -211,9 +235,12 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
bool migrate_sessions_early,
bool migrate_sessions_on_network_change_v2,
bool migrate_sessions_early_v2,
+ base::TimeDelta max_time_on_non_default_network,
+ int max_migrations_to_non_default_network_on_path_degrading,
bool allow_server_migration,
bool race_cert_verification,
bool estimate_initial_rtt,
+ bool headers_include_h2_stream_dependency,
const QuicTagVector& connection_options,
const QuicTagVector& client_connection_options,
bool enable_token_binding);
@@ -250,9 +277,6 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// Called by a session when it becomes idle.
void OnIdleSession(QuicChromiumClientSession* session);
- // Returns true if QUIC is know to be broken for |session|.
- bool IsQuicBroken(QuicChromiumClientSession* session);
-
// Called by a session when it is going away and no more streams should be
// created on it.
void OnSessionGoingAway(QuicChromiumClientSession* session);
@@ -369,7 +393,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
typedef std::map<QuicServerId, std::unique_ptr<CertVerifierJob>>
CertVerifierJobMap;
- bool OnResolution(const QuicSessionKey& key, const AddressList& address_list);
+ bool HasMatchingIpSession(const QuicSessionKey& key,
+ const AddressList& address_list);
+ void OnJobHostResolutionComplete(Job* job, int rv);
void OnJobComplete(Job* job, int rv);
void OnCertVerifyJobComplete(CertVerifierJob* job, int rv);
bool HasActiveSession(const QuicServerId& server_id) const;
@@ -506,6 +532,13 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// connection experiences poor connectivity.
const bool migrate_sessions_early_v2_;
+ // Maximum time sessions could use on non-default network before try to
+ // migrate back to default network.
+ const base::TimeDelta max_time_on_non_default_network_;
+
+ // Maximum number of migrations to non default network on path degrading.
+ const int max_migrations_to_non_default_network_on_path_degrading_;
+
// Set if migration should be attempted on active sessions when primary
// interface changes.
const bool migrate_sessions_on_network_change_;
@@ -524,6 +557,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// If true, estimate the initial RTT based on network type.
bool estimate_initial_rtt;
+ // If true, client headers will include HTTP/2 stream dependency info
+ // derived from SpdyPriority.
+ bool headers_include_h2_stream_dependency_;
+
// Local address of socket that was created in CreateSession.
IPEndPoint local_address_;
// True if we need to check HttpServerProperties if QUIC was supported last
diff --git a/chromium/net/quic/chromium/quic_stream_factory_fuzzer.cc b/chromium/net/quic/chromium/quic_stream_factory_fuzzer.cc
index 8e34162add7..55ea51e2f41 100644
--- a/chromium/net/quic/chromium/quic_stream_factory_fuzzer.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory_fuzzer.cc
@@ -7,8 +7,8 @@
#include "base/test/fuzzed_data_provider.h"
#include "net/base/test_completion_callback.h"
-#include "net/cert/cert_verifier.h"
-#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cert/do_nothing_ct_verifier.h"
+#include "net/cert/mock_cert_verifier.h"
#include "net/cert/x509_certificate.h"
#include "net/dns/fuzzed_host_resolver.h"
#include "net/http/http_server_properties_impl.h"
@@ -22,6 +22,7 @@
#include "net/socket/fuzzed_socket_factory.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
+#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/gtest_util.h"
namespace net {
@@ -32,18 +33,6 @@ const char kCertData[] = {
#include "net/data/ssl/certificates/wildcard.inc"
};
-class MockSSLConfigService : public SSLConfigService {
- public:
- MockSSLConfigService() {}
-
- void GetSSLConfig(SSLConfig* config) override { *config = config_; }
-
- private:
- ~MockSSLConfigService() override {}
-
- SSLConfig config_;
-};
-
} // namespace
namespace test {
@@ -62,12 +51,12 @@ const int kCertVerifyFlags = 0;
struct Env {
Env() : host_port_pair(kServerHostName, kServerPort), random_generator(0) {
clock.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- ssl_config_service = new MockSSLConfigService;
+ ssl_config_service = base::MakeRefCounted<SSLConfigServiceDefaults>();
crypto_client_stream_factory.set_use_mock_crypter(true);
- cert_verifier = CertVerifier::CreateDefault();
+ cert_verifier = std::make_unique<MockCertVerifier>();
channel_id_service =
std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
- cert_transparency_verifier = std::make_unique<MultiLogCTVerifier>();
+ cert_transparency_verifier = std::make_unique<DoNothingCTVerifier>();
verify_details.cert_verify_result.verified_cert =
X509Certificate::CreateFromBytes(kCertData, arraysize(kCertData));
CHECK(verify_details.cert_verify_result.verified_cert);
@@ -109,6 +98,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bool allow_server_migration = data_provider.ConsumeBool();
bool race_cert_verification = data_provider.ConsumeBool();
bool estimate_initial_rtt = data_provider.ConsumeBool();
+ bool headers_include_h2_stream_dependency = data_provider.ConsumeBool();
bool enable_token_binding = data_provider.ConsumeBool();
env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details);
@@ -116,20 +106,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bool migrate_sessions_on_network_change = false;
bool migrate_sessions_early = false;
bool migrate_sessions_early_v2 = false;
-
- bool migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool();
-
- if (migrate_sessions_on_network_change_v2) {
- migrate_sessions_early_v2 = data_provider.ConsumeBool();
- } else {
- migrate_sessions_on_network_change = data_provider.ConsumeBool();
- if (migrate_sessions_on_network_change)
- migrate_sessions_early = data_provider.ConsumeBool();
+ bool migrate_sessions_on_network_change_v2 = false;
+
+ if (!close_sessions_on_ip_change) {
+ migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool();
+ if (migrate_sessions_on_network_change_v2) {
+ migrate_sessions_early_v2 = data_provider.ConsumeBool();
+ } else {
+ migrate_sessions_on_network_change = data_provider.ConsumeBool();
+ if (migrate_sessions_on_network_change)
+ migrate_sessions_early = data_provider.ConsumeBool();
+ }
}
- if (migrate_sessions_on_network_change)
- close_sessions_on_ip_change = false;
-
std::unique_ptr<QuicStreamFactory> factory =
std::make_unique<QuicStreamFactory>(
env->net_log.net_log(), &host_resolver, env->ssl_config_service.get(),
@@ -144,8 +133,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
kMaxTimeForCryptoHandshakeSecs, kInitialIdleTimeoutSecs,
connect_using_default_network, migrate_sessions_on_network_change,
migrate_sessions_early, migrate_sessions_on_network_change_v2,
- migrate_sessions_early_v2, allow_server_migration,
- race_cert_verification, estimate_initial_rtt, env->connection_options,
+ migrate_sessions_early_v2,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
+ allow_server_migration, race_cert_verification, estimate_initial_rtt,
+ headers_include_h2_stream_dependency, env->connection_options,
env->client_connection_options, enable_token_binding);
QuicStreamRequest request(factory.get());
@@ -167,7 +159,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
HttpRequestInfo request_info;
request_info.method = kMethod;
request_info.url = GURL(kUrl);
- stream->InitializeStream(&request_info, DEFAULT_PRIORITY, env->net_log,
+ stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY, env->net_log,
CompletionCallback());
HttpResponseInfo response;
diff --git a/chromium/net/quic/chromium/quic_stream_factory_peer.cc b/chromium/net/quic/chromium/quic_stream_factory_peer.cc
index b338abdd021..21a7b74fae4 100644
--- a/chromium/net/quic/chromium/quic_stream_factory_peer.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory_peer.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/quic/chromium/quic_chromium_client_session.h"
#include "net/quic/chromium/quic_http_stream.h"
#include "net/quic/chromium/quic_stream_factory.h"
@@ -137,11 +138,7 @@ void QuicStreamFactoryPeer::CacheDummyServerConfig(
scoped_refptr<X509Certificate> cert(
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
DCHECK(cert);
- std::string der_bytes;
- bool success =
- X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes);
- DCHECK(success);
- certs.push_back(der_bytes);
+ certs.emplace_back(x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
QuicCryptoClientConfig* crypto_config = &factory->crypto_config_;
QuicCryptoClientConfig::CachedState* cached =
diff --git a/chromium/net/quic/chromium/quic_stream_factory_test.cc b/chromium/net/quic/chromium/quic_stream_factory_test.cc
index 7f484e21662..5cec9cce259 100644
--- a/chromium/net/quic/chromium/quic_stream_factory_test.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory_test.cc
@@ -14,9 +14,9 @@
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "net/base/mock_network_change_notifier.h"
-#include "net/cert/cert_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
-#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cert/do_nothing_ct_verifier.h"
+#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -102,19 +102,24 @@ const char kServer4Url[] = "https://images.example.org/";
// and enable_connection_racting.
struct TestParams {
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ version: " << QuicVersionToString(p.version) << " }";
+ os << "{ version: " << QuicVersionToString(p.version)
+ << ", client_headers_include_h2_stream_dependency: "
+ << p.client_headers_include_h2_stream_dependency << " }";
return os;
}
QuicTransportVersion version;
+ bool client_headers_include_h2_stream_dependency;
};
std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
QuicTransportVersionVector all_supported_versions =
AllSupportedTransportVersions();
- for (const auto& version : all_supported_versions)
- params.push_back(TestParams{version});
+ for (const auto& version : all_supported_versions) {
+ params.push_back(TestParams{version, false});
+ params.push_back(TestParams{version, true});
+ }
return params;
}
@@ -136,12 +141,15 @@ struct PoolingTestParams {
os << "DIFFERENT";
break;
}
+ os << ", client_headers_include_h2_stream_dependency: "
+ << p.client_headers_include_h2_stream_dependency;
os << " }";
return os;
}
QuicTransportVersion version;
DestinationType destination_type;
+ bool client_headers_include_h2_stream_dependency;
};
std::vector<PoolingTestParams> GetPoolingTestParams() {
@@ -149,9 +157,12 @@ std::vector<PoolingTestParams> GetPoolingTestParams() {
QuicTransportVersionVector all_supported_versions =
AllSupportedTransportVersions();
for (const QuicTransportVersion version : all_supported_versions) {
- params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
- params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
- params.push_back(PoolingTestParams{version, DIFFERENT});
+ params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
+ params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
+ params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
+ params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
+ params.push_back(PoolingTestParams{version, DIFFERENT, false});
+ params.push_back(PoolingTestParams{version, DIFFERENT, true});
}
return params;
}
@@ -193,26 +204,31 @@ class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
class QuicStreamFactoryTestBase {
protected:
- explicit QuicStreamFactoryTestBase(QuicTransportVersion version)
+ QuicStreamFactoryTestBase(QuicTransportVersion version,
+ bool client_headers_include_h2_stream_dependency)
: ssl_config_service_(new MockSSLConfigService),
socket_factory_(new MockClientSocketFactory),
random_generator_(0),
runner_(new TestTaskRunner(&clock_)),
version_(version),
+ client_headers_include_h2_stream_dependency_(
+ client_headers_include_h2_stream_dependency),
client_maker_(version_,
0,
&clock_,
kDefaultServerHostName,
- Perspective::IS_CLIENT),
+ Perspective::IS_CLIENT,
+ client_headers_include_h2_stream_dependency_),
server_maker_(version_,
0,
&clock_,
kDefaultServerHostName,
- Perspective::IS_SERVER),
- cert_verifier_(CertVerifier::CreateDefault()),
+ Perspective::IS_SERVER,
+ false),
+ cert_verifier_(std::make_unique<MockCertVerifier>()),
channel_id_service_(
new ChannelIDService(new DefaultChannelIDStore(nullptr))),
- cert_transparency_verifier_(new MultiLogCTVerifier()),
+ cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
scoped_mock_network_change_notifier_(nullptr),
factory_(nullptr),
host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
@@ -256,9 +272,11 @@ class QuicStreamFactoryTestBase {
/*connect_using_default_network*/ true,
migrate_sessions_on_network_change_, migrate_sessions_early_,
migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_,
+ base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
+ kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
allow_server_migration_, race_cert_verification_, estimate_initial_rtt_,
- connection_options_, client_connection_options_,
- /*enable_token_binding*/ false));
+ client_headers_include_h2_stream_dependency_, connection_options_,
+ client_connection_options_, /*enable_token_binding*/ false));
}
void InitializeConnectionMigrationTest(
@@ -412,7 +430,7 @@ class QuicStreamFactoryTestBase {
size_t spdy_headers_frame_len;
return client_maker_.MakeRequestHeadersPacket(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(headers), &spdy_headers_frame_len);
+ std::move(headers), 0, &spdy_headers_frame_len);
}
std::unique_ptr<QuicEncryptedPacket> ConstructGetRequestPacket(
@@ -428,7 +446,7 @@ class QuicStreamFactoryTestBase {
size_t spdy_headers_frame_len;
return client_maker_.MakeRequestHeadersPacket(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(headers), &spdy_headers_frame_len, offset);
+ std::move(headers), 0, &spdy_headers_frame_len, offset);
}
std::unique_ptr<QuicEncryptedPacket> ConstructOkResponsePacket(
@@ -499,8 +517,9 @@ class QuicStreamFactoryTestBase {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
- net_log_, CompletionCallback()));
+ EXPECT_EQ(OK,
+ stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
// Ensure that session is alive and active.
QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
@@ -759,7 +778,8 @@ class QuicStreamFactoryTestBase {
MockRandom random_generator_;
MockClock clock_;
scoped_refptr<TestTaskRunner> runner_;
- QuicTransportVersion version_;
+ const QuicTransportVersion version_;
+ const bool client_headers_include_h2_stream_dependency_;
QuicTestPacketMaker client_maker_;
QuicTestPacketMaker server_maker_;
HttpServerPropertiesImpl http_server_properties_;
@@ -803,10 +823,13 @@ class QuicStreamFactoryTestBase {
class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
public ::testing::TestWithParam<TestParams> {
protected:
- QuicStreamFactoryTest() : QuicStreamFactoryTestBase(GetParam().version) {}
+ QuicStreamFactoryTest()
+ : QuicStreamFactoryTestBase(
+ GetParam().version,
+ GetParam().client_headers_include_h2_stream_dependency) {}
};
-INSTANTIATE_TEST_CASE_P(Version,
+INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequnece,
QuicStreamFactoryTest,
::testing::ValuesIn(GetTestParams()));
@@ -1569,8 +1592,9 @@ TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
}
std::unique_ptr<HttpStream> stream = CreateStream(&request);
EXPECT_TRUE(stream);
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
- net_log_, CompletionCallback()));
+ EXPECT_EQ(OK,
+ stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
streams.push_back(std::move(stream));
}
@@ -1582,8 +1606,8 @@ TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
std::unique_ptr<HttpStream> stream = CreateStream(&request);
EXPECT_TRUE(stream);
EXPECT_EQ(ERR_IO_PENDING,
- stream->InitializeStream(&request_info, DEFAULT_PRIORITY, net_log_,
- callback_.callback()));
+ stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
+ net_log_, callback_.callback()));
// Close the first stream.
streams.front()->Close(false);
@@ -1700,7 +1724,7 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
std::unique_ptr<HttpStream> stream = CreateStream(&request);
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Close the session and verify that stream saw the error.
@@ -1884,7 +1908,7 @@ TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
std::unique_ptr<HttpStream> stream = CreateStream(&request);
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
IPAddress last_address;
@@ -1939,7 +1963,7 @@ TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
std::unique_ptr<HttpStream> stream = CreateStream(&request);
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
IPAddress last_address;
@@ -2008,7 +2032,7 @@ void QuicStreamFactoryTestBase::OnNetworkMadeDefault(bool async_write_before) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2140,7 +2164,7 @@ void QuicStreamFactoryTestBase::OnNetworkDisconnected(bool async_write_before) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2250,7 +2274,7 @@ void QuicStreamFactoryTestBase::OnNetworkDisconnectedWithNetworkList(
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2310,7 +2334,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNonMigratableStream) {
// Cause QUIC stream to be created, but marked as non-migratable.
HttpRequestInfo request_info;
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2360,7 +2384,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNonMigratableStreamV2) {
// Cause QUIC stream to be created, but marked as non-migratable.
HttpRequestInfo request_info;
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2409,7 +2433,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2463,7 +2487,7 @@ TEST_P(QuicStreamFactoryTest,
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2517,7 +2541,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNonMigratableStream) {
// Cause QUIC stream to be created, but marked as non-migratable.
HttpRequestInfo request_info;
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2565,7 +2589,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNonMigratableStreamV2) {
// Cause QUIC stream to be created, but marked as non-migratable.
HttpRequestInfo request_info;
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2613,7 +2637,7 @@ TEST_P(QuicStreamFactoryTest,
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2665,7 +2689,7 @@ TEST_P(QuicStreamFactoryTest,
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2882,7 +2906,7 @@ TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -2989,7 +3013,7 @@ TEST_P(QuicStreamFactoryTest, OnNetworkChangeDisconnectedPauseBeforeConnected) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3128,8 +3152,9 @@ TEST_P(QuicStreamFactoryTest,
HttpRequestInfo request_info1;
request_info1.method = "GET";
request_info1.url = url_;
- EXPECT_EQ(OK, stream1->InitializeStream(&request_info1, DEFAULT_PRIORITY,
- net_log_, CompletionCallback()));
+ EXPECT_EQ(OK,
+ stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
HttpResponseInfo response1;
HttpRequestHeaders request_headers1;
EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
@@ -3140,8 +3165,9 @@ TEST_P(QuicStreamFactoryTest,
HttpRequestInfo request_info2;
request_info2.method = "GET";
request_info2.url = url_;
- EXPECT_EQ(OK, stream2->InitializeStream(&request_info2, DEFAULT_PRIORITY,
- net_log_, CompletionCallback()));
+ EXPECT_EQ(OK,
+ stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
HttpResponseInfo response2;
HttpRequestHeaders request_headers2;
EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
@@ -3210,7 +3236,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarly) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3337,7 +3363,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyWithAsyncWrites) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3456,7 +3482,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNoNewNetwork) {
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3510,7 +3536,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNonMigratableStream) {
// Cause QUIC stream to be created, but marked as non-migratable.
HttpRequestInfo request_info;
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3562,7 +3588,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
// Cause QUIC stream to be created.
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3623,7 +3649,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3713,7 +3739,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3804,7 +3830,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3868,7 +3894,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -3948,7 +3974,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4029,7 +4055,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithNotificationQueued(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4128,7 +4154,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnNotificationWithWriteErrorQueued(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4228,7 +4254,7 @@ void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4363,7 +4389,7 @@ void QuicStreamFactoryTestBase::
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4519,7 +4545,7 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyToBadSocket) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = url_;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4583,7 +4609,7 @@ TEST_P(QuicStreamFactoryTest, ServerMigration) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4727,7 +4753,7 @@ TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("https://www.example.org/");
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Ensure that session is alive and active.
@@ -4778,7 +4804,7 @@ TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
std::unique_ptr<HttpStream> stream = CreateStream(&request);
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
ssl_config_service_->NotifySSLConfigChange();
@@ -4833,7 +4859,7 @@ TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
EXPECT_THAT(callback_.WaitForResult(), IsOk());
std::unique_ptr<HttpStream> stream = CreateStream(&request);
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
// Change the CA cert and verify that stream saw the event.
@@ -5013,7 +5039,7 @@ TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
std::unique_ptr<HttpStream> stream = CreateStream(&request);
EXPECT_TRUE(stream.get());
HttpRequestInfo request_info;
- EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
net_log_, CompletionCallback()));
DVLOG(1)
@@ -5044,8 +5070,9 @@ TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
EXPECT_TRUE(stream2.get());
- EXPECT_EQ(OK, stream2->InitializeStream(&request_info, DEFAULT_PRIORITY,
- net_log_, CompletionCallback()));
+ EXPECT_EQ(OK,
+ stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
session2->connection()->CloseConnection(
QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
// Need to spin the loop now to ensure that
@@ -5376,7 +5403,9 @@ class QuicStreamFactoryWithDestinationTest
public ::testing::TestWithParam<PoolingTestParams> {
protected:
QuicStreamFactoryWithDestinationTest()
- : QuicStreamFactoryTestBase(GetParam().version),
+ : QuicStreamFactoryTestBase(
+ GetParam().version,
+ GetParam().client_headers_include_h2_stream_dependency),
destination_type_(GetParam().destination_type),
hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
@@ -5419,7 +5448,7 @@ class QuicStreamFactoryWithDestinationTest
sequenced_socket_data_vector_;
};
-INSTANTIATE_TEST_CASE_P(Version,
+INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequnece,
QuicStreamFactoryWithDestinationTest,
::testing::ValuesIn(GetPoolingTestParams()));
@@ -5804,5 +5833,239 @@ TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
config->max_idle_time_before_crypto_handshake());
}
+// Verify ResultAfterHostResolutionCallback behavior when host resolution
+// succeeds asynchronously, then crypto handshake fails synchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ host_resolver_.set_ondemand_mode(true);
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
+ socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
+ socket_data.AddSocketDataToFactory(socket_factory_.get());
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY,
+ /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_TRUE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+
+ // |host_resolver_| has not finished host resolution at this point, so
+ // |host_resolution_callback| should not have a result.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(host_resolution_callback.have_result());
+
+ // Allow |host_resolver_| to finish host resolution.
+ // Since the request fails immediately after host resolution (getting
+ // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
+ // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
+ // forming the connection.
+ host_resolver_.ResolveAllPending();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(host_resolution_callback.have_result());
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
+
+ // Calling WaitForHostResolution() a second time should return
+ // false since host resolution has finished already.
+ EXPECT_FALSE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+
+ EXPECT_TRUE(callback_.have_result());
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
+}
+
+// Verify ResultAfterHostResolutionCallback behavior when host resolution
+// succeeds asynchronously, then crypto handshake fails asynchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ host_resolver_.set_ondemand_mode(true);
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::ZERO_RTT);
+ factory_->set_require_confirmation(true);
+
+ MockQuicData socket_data;
+ socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ socket_data.AddRead(ASYNC, ERR_FAILED);
+ socket_data.AddWrite(ASYNC, ERR_FAILED);
+ socket_data.AddSocketDataToFactory(socket_factory_.get());
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY,
+ /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_TRUE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+
+ // |host_resolver_| has not finished host resolution at this point, so
+ // |host_resolution_callback| should not have a result.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(host_resolution_callback.have_result());
+
+ // Allow |host_resolver_| to finish host resolution. Since crypto handshake
+ // will hang after host resolution, |host_resolution_callback| should run with
+ // ERR_IO_PENDING since that's the next result in forming the connection.
+ host_resolver_.ResolveAllPending();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(host_resolution_callback.have_result());
+ EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
+
+ // Calling WaitForHostResolution() a second time should return
+ // false since host resolution has finished already.
+ EXPECT_FALSE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+
+ EXPECT_FALSE(callback_.have_result());
+ socket_data.GetSequencedSocketData()->Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(callback_.have_result());
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
+}
+
+// Verify ResultAfterHostResolutionCallback behavior when host resolution
+// succeeds synchronously, then crypto handshake fails synchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ host_resolver_.set_synchronous_mode(true);
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
+ socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
+ socket_data.AddSocketDataToFactory(socket_factory_.get());
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_QUIC_PROTOCOL_ERROR,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY, /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ // WaitForHostResolution() should return false since host
+ // resolution has finished already.
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_FALSE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(host_resolution_callback.have_result());
+ EXPECT_FALSE(callback_.have_result());
+}
+
+// Verify ResultAfterHostResolutionCallback behavior when host resolution
+// succeeds synchronously, then crypto handshake fails asynchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ // Host resolution will succeed synchronously, but Request() as a whole
+ // will fail asynchronously.
+ host_resolver_.set_synchronous_mode(true);
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::ZERO_RTT);
+ factory_->set_require_confirmation(true);
+
+ MockQuicData socket_data;
+ socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
+ socket_data.AddRead(ASYNC, ERR_FAILED);
+ socket_data.AddWrite(ASYNC, ERR_FAILED);
+ socket_data.AddSocketDataToFactory(socket_factory_.get());
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY, /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ // WaitForHostResolution() should return false since host
+ // resolution has finished already.
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_FALSE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(host_resolution_callback.have_result());
+
+ EXPECT_FALSE(callback_.have_result());
+ socket_data.GetSequencedSocketData()->Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(callback_.have_result());
+ EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
+}
+
+// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
+// synchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ // Host resolution will fail synchronously.
+ host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
+ host_resolver_.set_synchronous_mode(true);
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_NAME_NOT_RESOLVED,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY, /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ // WaitForHostResolution() should return false since host
+ // resolution has failed already.
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_FALSE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(host_resolution_callback.have_result());
+}
+
+// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
+// asynchronously.
+TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ request.Request(host_port_pair_, version_, privacy_mode_,
+ DEFAULT_PRIORITY, /*cert_verify_flags=*/0, url_, net_log_,
+ &net_error_details_, callback_.callback()));
+
+ TestCompletionCallback host_resolution_callback;
+ EXPECT_TRUE(
+ request.WaitForHostResolution(host_resolution_callback.callback()));
+
+ // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
+ // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
+ // resolution failed with.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(host_resolution_callback.have_result());
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
+
+ EXPECT_TRUE(callback_.have_result());
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/chromium/quic_test_packet_maker.cc b/chromium/net/quic/chromium/quic_test_packet_maker.cc
index c39b2073f4f..435250f978f 100644
--- a/chromium/net/quic/chromium/quic_test_packet_maker.cc
+++ b/chromium/net/quic/chromium/quic_test_packet_maker.cc
@@ -18,24 +18,31 @@ namespace {
QuicAckFrame MakeAckFrame(QuicPacketNumber largest_observed) {
QuicAckFrame ack;
- ack.deprecated_largest_observed = largest_observed;
+ ack.largest_acked = largest_observed;
return ack;
}
} // namespace
-QuicTestPacketMaker::QuicTestPacketMaker(QuicTransportVersion version,
- QuicConnectionId connection_id,
- MockClock* clock,
- const std::string& host,
- Perspective perspective)
+QuicTestPacketMaker::QuicTestPacketMaker(
+ QuicTransportVersion version,
+ QuicConnectionId connection_id,
+ MockClock* clock,
+ const std::string& host,
+ Perspective perspective,
+ bool client_headers_include_h2_stream_dependency)
: version_(version),
connection_id_(connection_id),
clock_(clock),
host_(host),
spdy_request_framer_(SpdyFramer::ENABLE_COMPRESSION),
spdy_response_framer_(SpdyFramer::ENABLE_COMPRESSION),
- perspective_(perspective) {}
+ perspective_(perspective),
+ client_headers_include_h2_stream_dependency_(
+ client_headers_include_h2_stream_dependency) {
+ DCHECK(!(perspective_ == Perspective::IS_SERVER &&
+ client_headers_include_h2_stream_dependency_));
+}
QuicTestPacketMaker::~QuicTestPacketMaker() {}
@@ -137,8 +144,9 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakeAckAndRstPacket(
frames.push_back(QuicFrame(&rst));
DVLOG(1) << "Adding frame: " << frames[2];
- QuicFramer framer(SupportedTransportVersions(version_), clock_->Now(),
- perspective_);
+ QuicFramer framer(
+ SupportedVersions(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version_)),
+ clock_->Now(), perspective_);
std::unique_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
@@ -190,8 +198,10 @@ QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
frames.push_back(QuicFrame(&close));
DVLOG(1) << "Adding frame: " << frames[2];
- QuicFramer framer(SupportedTransportVersions(version_), clock_->Now(),
- perspective_);
+ QuicFramer framer(
+ SupportedVersions(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version_)),
+ clock_->Now(), perspective_);
+
std::unique_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
@@ -269,9 +279,9 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
if (largest_received > 0) {
ack.packets.AddRange(1, largest_received + 1);
}
-
- QuicFramer framer(SupportedTransportVersions(version_), clock_->Now(),
- perspective_);
+ QuicFramer framer(
+ SupportedVersions(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version_)),
+ clock_->Now(), perspective_);
QuicFrames frames;
QuicFrame ack_frame(&ack);
DVLOG(1) << "Adding frame: " << ack_frame;
@@ -373,16 +383,13 @@ QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
QuicStreamOffset* header_stream_offset,
size_t* spdy_headers_frame_length,
const std::vector<std::string>& data_writes) {
InitializeHeader(packet_number, should_include_version);
- SpdySerializedFrame spdy_frame;
- SpdyHeadersIR headers_frame(stream_id, std::move(headers));
- headers_frame.set_fin(fin);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority));
- headers_frame.set_has_priority(true);
- spdy_frame = spdy_request_framer_.SerializeFrame(headers_frame);
+ SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
+ stream_id, fin, priority, std::move(headers), parent_stream_id);
if (spdy_headers_frame_length) {
*spdy_headers_frame_length = spdy_frame.size();
@@ -423,10 +430,11 @@ QuicTestPacketMaker::MakeRequestHeadersPacket(
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length) {
return MakeRequestHeadersPacket(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(headers), spdy_headers_frame_length, nullptr);
+ std::move(headers), parent_stream_id, spdy_headers_frame_length, nullptr);
}
// If |offset| is provided, will use the value when creating the packet.
@@ -438,12 +446,13 @@ QuicTestPacketMaker::MakeRequestHeadersPacket(QuicPacketNumber packet_number,
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset) {
std::string unused_stream_data;
return MakeRequestHeadersPacketAndSaveData(
packet_number, stream_id, should_include_version, fin, priority,
- std::move(headers), spdy_headers_frame_length, offset,
+ std::move(headers), parent_stream_id, spdy_headers_frame_length, offset,
&unused_stream_data);
}
@@ -455,16 +464,13 @@ QuicTestPacketMaker::MakeRequestHeadersPacketAndSaveData(
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset,
std::string* stream_data) {
InitializeHeader(packet_number, should_include_version);
- SpdySerializedFrame spdy_frame;
- SpdyHeadersIR headers_frame(stream_id, std::move(headers));
- headers_frame.set_fin(fin);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority));
- headers_frame.set_has_priority(true);
- spdy_frame = spdy_request_framer_.SerializeFrame(headers_frame);
+ SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
+ stream_id, fin, priority, std::move(headers), parent_stream_id);
*stream_data = std::string(spdy_frame.data(), spdy_frame.size());
if (spdy_headers_frame_length)
@@ -485,6 +491,28 @@ QuicTestPacketMaker::MakeRequestHeadersPacketAndSaveData(
}
}
+SpdySerializedFrame QuicTestPacketMaker::MakeSpdyHeadersFrame(
+ QuicStreamId stream_id,
+ bool fin,
+ SpdyPriority priority,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id) {
+ SpdyHeadersIR headers_frame(stream_id, std::move(headers));
+ headers_frame.set_fin(fin);
+ headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority));
+ headers_frame.set_has_priority(true);
+
+ if (client_headers_include_h2_stream_dependency_) {
+ headers_frame.set_parent_stream_id(parent_stream_id);
+ headers_frame.set_exclusive(true);
+ } else {
+ headers_frame.set_parent_stream_id(0);
+ headers_frame.set_exclusive(false);
+ }
+
+ return spdy_request_framer_.SerializeFrame(headers_frame);
+}
+
// Convenience method for calling MakeRequestHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
std::unique_ptr<QuicReceivedPacket>
@@ -495,10 +523,11 @@ QuicTestPacketMaker::MakeRequestHeadersPacketWithOffsetTracking(
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
QuicStreamOffset* offset) {
- return MakeRequestHeadersPacket(packet_number, stream_id,
- should_include_version, fin, priority,
- std::move(headers), nullptr, offset);
+ return MakeRequestHeadersPacket(
+ packet_number, stream_id, should_include_version, fin, priority,
+ std::move(headers), parent_stream_id, nullptr, offset);
}
// If |offset| is provided, will use the value when creating the packet.
@@ -657,8 +686,9 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakePacket(
std::unique_ptr<QuicReceivedPacket>
QuicTestPacketMaker::MakeMultipleFramesPacket(const QuicPacketHeader& header,
const QuicFrames& frames) {
- QuicFramer framer(SupportedTransportVersions(version_), clock_->Now(),
- perspective_);
+ QuicFramer framer(
+ SupportedVersions(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version_)),
+ clock_->Now(), perspective_);
std::unique_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
char buffer[kMaxPacketSize];
diff --git a/chromium/net/quic/chromium/quic_test_packet_maker.h b/chromium/net/quic/chromium/quic_test_packet_maker.h
index c476d828c04..201f5fdb0ca 100644
--- a/chromium/net/quic/chromium/quic_test_packet_maker.h
+++ b/chromium/net/quic/chromium/quic_test_packet_maker.h
@@ -27,11 +27,18 @@ namespace test {
class QuicTestPacketMaker {
public:
+ // |client_headers_include_h2_stream_dependency| affects the output of
+ // the MakeRequestHeaders...() methods. If its value is true, then request
+ // headers are constructed with the exclusive flag set to true and the parent
+ // stream id set to the |parent_stream_id| param of MakeRequestHeaders...().
+ // Otherwise, headers are constructed with the exclusive flag set to false and
+ // the parent stream ID set to 0 (ignoring the |parent_stream_id| param).
QuicTestPacketMaker(QuicTransportVersion version,
QuicConnectionId connection_id,
MockClock* clock,
const std::string& host,
- Perspective perspective);
+ Perspective perspective,
+ bool client_headers_include_h2_stream_dependency);
~QuicTestPacketMaker();
void set_hostname(const std::string& host);
@@ -137,6 +144,7 @@ class QuicTestPacketMaker {
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
QuicStreamOffset* header_stream_offset,
size_t* spdy_headers_frame_length,
const std::vector<std::string>& data_writes);
@@ -150,6 +158,7 @@ class QuicTestPacketMaker {
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length);
std::unique_ptr<QuicReceivedPacket> MakeRequestHeadersPacket(
@@ -159,6 +168,7 @@ class QuicTestPacketMaker {
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset);
@@ -170,6 +180,7 @@ class QuicTestPacketMaker {
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
size_t* spdy_headers_frame_length,
QuicStreamOffset* offset,
std::string* stream_data);
@@ -183,6 +194,7 @@ class QuicTestPacketMaker {
bool fin,
SpdyPriority priority,
SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
QuicStreamOffset* offset);
// If |spdy_headers_frame_length| is non-null, it will be set to the size of
@@ -257,6 +269,12 @@ class QuicTestPacketMaker {
void InitializeHeader(QuicPacketNumber packet_number,
bool should_include_version);
+ SpdySerializedFrame MakeSpdyHeadersFrame(QuicStreamId stream_id,
+ bool fin,
+ SpdyPriority priority,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id);
+
QuicTransportVersion version_;
QuicConnectionId connection_id_;
MockClock* clock_; // Owned by QuicStreamFactory.
@@ -267,6 +285,10 @@ class QuicTestPacketMaker {
QuicPacketHeader header_;
Perspective perspective_;
+ // If true, generated request headers will include non-default HTTP2 stream
+ // dependency info.
+ bool client_headers_include_h2_stream_dependency_;
+
DISALLOW_COPY_AND_ASSIGN(QuicTestPacketMaker);
};
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.cc b/chromium/net/quic/core/congestion_control/bbr_sender.cc
index 6f2f5a01da0..4da5df3d93f 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender.cc
+++ b/chromium/net/quic/core/congestion_control/bbr_sender.cc
@@ -9,7 +9,6 @@
#include "net/quic/core/congestion_control/rtt_stats.h"
#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
@@ -22,7 +21,7 @@ namespace {
const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
// Does not inflate the pacing rate.
-const QuicByteCount kMinimumCongestionWindow = 4 * kMaxSegmentSize;
+const QuicByteCount kDefaultMinimumCongestionWindow = 4 * kMaxSegmentSize;
// The gain used for the slow start, equal to 2/ln(2).
const float kHighGain = 2.885f;
@@ -100,6 +99,7 @@ BbrSender::BbrSender(const RttStats* rtt_stats,
initial_congestion_window_(initial_tcp_congestion_window *
kDefaultTCPMSS),
max_congestion_window_(max_tcp_congestion_window * kDefaultTCPMSS),
+ min_congestion_window_(kDefaultMinimumCongestionWindow),
pacing_rate_(QuicBandwidth::Zero()),
pacing_gain_(1),
congestion_window_gain_(1),
@@ -211,7 +211,7 @@ void BbrSender::SetFromConfig(const QuicConfig& config,
if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
num_startup_rtts_ = 2;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_rate_recovery &&
+ if (GetQuicReloadableFlag(quic_bbr_rate_recovery) &&
config.HasClientRequestedIndependentOption(kBBRR, perspective)) {
rate_based_recovery_ = true;
}
@@ -221,61 +221,47 @@ void BbrSender::SetFromConfig(const QuicConfig& config,
if (config.HasClientRequestedIndependentOption(kBBR2, perspective)) {
max_aggregation_bytes_multiplier_ = 2;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_slower_startup &&
- config.HasClientRequestedIndependentOption(kBBRS, perspective)) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_slower_startup);
+ if (config.HasClientRequestedIndependentOption(kBBRS, perspective)) {
slower_startup_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_fully_drain_queue &&
- config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_bbr_fully_drain_queue);
+ if (config.HasClientRequestedIndependentOption(kBBR3, perspective)) {
fully_drain_queue_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup &&
- config.HasClientRequestedIndependentOption(kBBS1, perspective)) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_conservation_in_startup, 1,
- 3);
+ if (config.HasClientRequestedIndependentOption(kBBS1, perspective)) {
rate_based_startup_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup &&
- config.HasClientRequestedIndependentOption(kBBS2, perspective)) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_conservation_in_startup, 2,
- 3);
+ if (config.HasClientRequestedIndependentOption(kBBS2, perspective)) {
initial_conservation_in_startup_ = MEDIUM_GROWTH;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup &&
- config.HasClientRequestedIndependentOption(kBBS3, perspective)) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_conservation_in_startup, 3,
- 3);
+ if (config.HasClientRequestedIndependentOption(kBBS3, perspective)) {
initial_conservation_in_startup_ = GROWTH;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_window &&
- config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_window, 1,
- 2);
+ if (config.HasClientRequestedIndependentOption(kBBR4, perspective)) {
max_ack_height_.SetWindowLength(2 * kBandwidthWindowSize);
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_window &&
- config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_ack_aggregation_window, 2,
- 2);
+ if (config.HasClientRequestedIndependentOption(kBBR5, perspective)) {
max_ack_height_.SetWindowLength(4 * kBandwidthWindowSize);
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt &&
+ if (GetQuicReloadableFlag(quic_bbr_less_probe_rtt) &&
config.HasClientRequestedIndependentOption(kBBR6, perspective)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_less_probe_rtt, 1, 3);
probe_rtt_based_on_bdp_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt &&
+ if (GetQuicReloadableFlag(quic_bbr_less_probe_rtt) &&
config.HasClientRequestedIndependentOption(kBBR7, perspective)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_less_probe_rtt, 2, 3);
probe_rtt_skipped_if_similar_rtt_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt &&
+ if (GetQuicReloadableFlag(quic_bbr_less_probe_rtt) &&
config.HasClientRequestedIndependentOption(kBBR8, perspective)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_bbr_less_probe_rtt, 3, 3);
probe_rtt_disabled_if_app_limited_ = true;
}
+ if (GetQuicReloadableFlag(quic_one_tlp) &&
+ config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_one_tlp, 2, 2);
+ min_congestion_window_ = kMaxSegmentSize;
+ }
}
void BbrSender::AdjustNetworkParameters(QuicBandwidth bandwidth,
@@ -373,14 +359,14 @@ QuicByteCount BbrSender::GetTargetCongestionWindow(float gain) const {
congestion_window = gain * initial_congestion_window_;
}
- return std::max(congestion_window, kMinimumCongestionWindow);
+ return std::max(congestion_window, min_congestion_window_);
}
QuicByteCount BbrSender::ProbeRttCongestionWindow() const {
if (probe_rtt_based_on_bdp_) {
return GetTargetCongestionWindow(kModerateProbeRttMultiplier);
}
- return kMinimumCongestionWindow;
+ return min_congestion_window_;
}
void BbrSender::EnterStartupMode() {
@@ -719,7 +705,7 @@ void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked) {
target_window += max_ack_height_.GetBest();
}
- if (FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd) {
+ if (GetQuicReloadableFlag(quic_bbr_add_tso_cwnd)) {
// QUIC doesn't have TSO, but it does have similarly quantized pacing, so
// allow extra CWND to make QUIC's BBR CWND identical to TCP's.
QuicByteCount tso_segs_goal = 0;
@@ -749,7 +735,7 @@ void BbrSender::CalculateCongestionWindow(QuicByteCount bytes_acked) {
}
// Enforce the limits on the congestion window.
- congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow);
+ congestion_window_ = std::max(congestion_window_, min_congestion_window_);
congestion_window_ = std::min(congestion_window_, max_congestion_window_);
}
@@ -766,7 +752,7 @@ void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
// Set up the initial recovery window.
if (recovery_window_ == 0) {
recovery_window_ = unacked_packets_->bytes_in_flight() + bytes_acked;
- recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
+ recovery_window_ = std::max(min_congestion_window_, recovery_window_);
return;
}
@@ -789,7 +775,7 @@ void BbrSender::CalculateRecoveryWindow(QuicByteCount bytes_acked,
// |bytes_acked| in response.
recovery_window_ = std::max(
recovery_window_, unacked_packets_->bytes_in_flight() + bytes_acked);
- recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
+ recovery_window_ = std::max(min_congestion_window_, recovery_window_);
}
std::string BbrSender::GetDebugState() const {
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.h b/chromium/net/quic/core/congestion_control/bbr_sender.h
index 149bc06c811..122abe35db1 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender.h
+++ b/chromium/net/quic/core/congestion_control/bbr_sender.h
@@ -268,6 +268,9 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
// The largest value the |congestion_window_| can achieve.
QuicByteCount max_congestion_window_;
+ // The smallest value the |congestion_window_| can achieve.
+ QuicByteCount min_congestion_window_;
+
// The current pacing rate of the connection.
QuicBandwidth pacing_rate_;
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
index 450f610d8d5..a229e8ac06f 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
+++ b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
@@ -92,7 +92,7 @@ class BbrSenderTest : public QuicTest {
receiver_multiplexer_("Receiver multiplexer",
{&receiver_, &competing_receiver_}) {
// These will be changed by the appropriate tests as necessary.
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats();
sender_ = SetupBbrSender(&bbr_sender_);
@@ -253,7 +253,7 @@ class BbrSenderTest : public QuicTest {
// Test a simple long data transfer in the default setup.
TEST_F(BbrSenderTest, SimpleTransfer) {
// Adding TSO CWND causes packet loss before exiting startup.
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
// At startup make sure we are at the default.
@@ -301,7 +301,7 @@ TEST_F(BbrSenderTest, SimpleTransferSmallBuffer) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes) {
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
// 2 RTTs of aggregation, with a max of 10kb.
EnableAggregation(10 * 1024, 2 * kTestRtt);
@@ -361,7 +361,7 @@ TEST_F(BbrSenderTest, SimpleTransferAckDecimation) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes4) {
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
// Enable ack aggregation that forces the queue to be drained.
@@ -427,8 +427,7 @@ TEST_F(BbrSenderTest, SimpleTransferAckDecimation4) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) {
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
- FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_window = true;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
SetConnectionOption(kBBR4);
// 2 RTTs of aggregation, with a max of 10kb.
@@ -454,8 +453,7 @@ TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes20RTTWindow) {
// Test a simple long data transfer with 2 rtts of aggregation.
TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationBytes40RTTWindow) {
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
- FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_window = true;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
SetConnectionOption(kBBR5);
// 2 RTTs of aggregation, with a max of 10kb.
@@ -552,7 +550,6 @@ TEST_F(BbrSenderTest, StartupMediumRecoveryStates) {
const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
bool simulator_result;
CreateSmallBufferSetup();
- FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup = true;
SetConnectionOption(kBBS2);
bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
@@ -603,7 +600,6 @@ TEST_F(BbrSenderTest, StartupGrowthRecoveryStates) {
const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
bool simulator_result;
CreateSmallBufferSetup();
- FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup = true;
SetConnectionOption(kBBS3);
bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
@@ -748,7 +744,7 @@ TEST_F(BbrSenderTest, ProbeRtt) {
// Verify that the connection enters and exits PROBE_RTT correctly.
TEST_F(BbrSenderTest, ProbeRttBDPBasedCWNDTarget) {
CreateDefaultSetup();
- FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt = true;
+ SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true);
SetConnectionOption(kBBR6);
DriveOutOfStartup();
@@ -777,7 +773,7 @@ TEST_F(BbrSenderTest, ProbeRttBDPBasedCWNDTarget) {
// Verify that the connection enters does not enter PROBE_RTT.
TEST_F(BbrSenderTest, ProbeRttSkippedAfterAppLimitedAndStableRtt) {
CreateDefaultSetup();
- FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt = true;
+ SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true);
SetConnectionOption(kBBR7);
DriveOutOfStartup();
@@ -798,7 +794,7 @@ TEST_F(BbrSenderTest, ProbeRttSkippedAfterAppLimitedAndStableRtt) {
// Verify that the connection enters does not enter PROBE_RTT.
TEST_F(BbrSenderTest, ProbeRttSkippedAfterAppLimited) {
CreateDefaultSetup();
- FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt = true;
+ SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true);
SetConnectionOption(kBBR8);
DriveOutOfStartup();
@@ -919,7 +915,7 @@ TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
// Test exiting STARTUP earlier due to the 2RTT connection option.
TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
// Adding TSO CWND causes packet loss before exiting startup.
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateDefaultSetup();
SetConnectionOption(k2RTT);
@@ -1005,8 +1001,7 @@ TEST_F(BbrSenderTest, SimpleTransferLRTTStartupSmallBuffer) {
// Test slower pacing after loss in STARTUP due to the BBRS connection option.
TEST_F(BbrSenderTest, SimpleTransferSlowerStartup) {
// Adding TSO CWND causes packet loss before exiting startup.
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
- FLAGS_quic_reloadable_flag_quic_bbr_slower_startup = true;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateSmallBufferSetup();
SetConnectionOption(kBBRS);
@@ -1042,8 +1037,7 @@ TEST_F(BbrSenderTest, SimpleTransferSlowerStartup) {
// Ensures no change in congestion window in STARTUP after loss.
TEST_F(BbrSenderTest, SimpleTransferNoConservationInStartup) {
// Adding TSO CWND causes packet loss before exiting startup.
- FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false;
- FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup = true;
+ SetQuicReloadableFlag(quic_bbr_add_tso_cwnd, false);
CreateSmallBufferSetup();
SetConnectionOption(kBBS1);
@@ -1108,5 +1102,36 @@ TEST_F(BbrSenderTest, ResumeConnectionState) {
DriveOutOfStartup();
}
+// Test with a min CWND of 1 instead of 4 packets.
+TEST_F(BbrSenderTest, ProbeRTTMinCWND1) {
+ SetQuicReloadableFlag(quic_one_tlp, true);
+ CreateDefaultSetup();
+ SetConnectionOption(kMIN1);
+ DriveOutOfStartup();
+
+ // We have no intention of ever finishing this transfer.
+ bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024);
+
+ // Wait until the connection enters PROBE_RTT.
+ const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(12);
+ bool simulator_result = simulator_.RunUntilOrTimeout(
+ [this]() {
+ return sender_->ExportDebugState().mode == BbrSender::PROBE_RTT;
+ },
+ timeout);
+ ASSERT_TRUE(simulator_result);
+ ASSERT_EQ(BbrSender::PROBE_RTT, sender_->ExportDebugState().mode);
+ // The PROBE_RTT CWND should be 1 if the min CWND is 1.
+ EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
+
+ // Exit PROBE_RTT.
+ const QuicTime probe_rtt_start = clock_->Now();
+ const QuicTime::Delta time_to_exit_probe_rtt =
+ kTestRtt + QuicTime::Delta::FromMilliseconds(200);
+ simulator_.RunFor(1.5 * time_to_exit_probe_rtt);
+ EXPECT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode);
+ EXPECT_GE(sender_->ExportDebugState().min_rtt_timestamp, probe_rtt_start);
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/congestion_control/cubic.cc b/chromium/net/quic/core/congestion_control/cubic.cc
deleted file mode 100644
index 37d0aafb712..00000000000
--- a/chromium/net/quic/core/congestion_control/cubic.cc
+++ /dev/null
@@ -1,227 +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/quic/core/congestion_control/cubic.h"
-
-#include <algorithm>
-#include <cmath>
-#include <cstdint>
-
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/platform/api/quic_flag_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_logging.h"
-
-namespace net {
-
-namespace {
-
-// Constants based on TCP defaults.
-// The following constants are in 2^10 fractions of a second instead of ms to
-// allow a 10 shift right to divide.
-const int kCubeScale = 40; // 1024*1024^3 (first 1024 is from 0.100^3)
- // where 0.100 is 100 ms which is the scaling
- // round trip time.
-const int kCubeCongestionWindowScale = 410;
-const uint64_t kCubeFactor =
- (UINT64_C(1) << kCubeScale) / kCubeCongestionWindowScale;
-
-const uint32_t kDefaultNumConnections = 2;
-const float kBeta = 0.7f; // Default Cubic backoff factor.
-// Additional backoff factor when loss occurs in the concave part of the Cubic
-// curve. This additional backoff factor is expected to give up bandwidth to
-// new concurrent flows and speed up convergence.
-const float kBetaLastMax = 0.85f;
-
-} // namespace
-
-Cubic::Cubic(const QuicClock* clock)
- : clock_(clock),
- num_connections_(kDefaultNumConnections),
- epoch_(QuicTime::Zero()),
- app_limited_start_time_(QuicTime::Zero()),
- last_update_time_(QuicTime::Zero()),
- fix_convex_mode_(FLAGS_quic_reloadable_flag_quic_enable_cubic_fixes),
- fix_beta_last_max_(fix_convex_mode_),
- allow_per_ack_updates_(fix_convex_mode_) {
- ResetCubicState();
- if (fix_convex_mode_) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_enable_cubic_fixes, 1, 2);
- }
-}
-
-void Cubic::SetNumConnections(int num_connections) {
- num_connections_ = num_connections;
-}
-
-float Cubic::Alpha() const {
- // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
- // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
- // We derive the equivalent alpha for an N-connection emulation as:
- const float beta = Beta();
- return 3 * num_connections_ * num_connections_ * (1 - beta) / (1 + beta);
-}
-
-float Cubic::Beta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kBeta) / num_connections_;
-}
-
-float Cubic::BetaLastMax() const {
- // BetaLastMax is the additional backoff factor after loss for our
- // N-connection emulation, which emulates the additional backoff of
- // an ensemble of N TCP-Reno connections on a single loss event. The
- // effective multiplier is computed as:
- return fix_beta_last_max_
- ? (num_connections_ - 1 + kBetaLastMax) / num_connections_
- : kBetaLastMax;
-}
-
-void Cubic::ResetCubicState() {
- epoch_ = QuicTime::Zero(); // Reset time.
- app_limited_start_time_ = QuicTime::Zero();
- last_update_time_ = QuicTime::Zero(); // Reset time.
- last_congestion_window_ = 0;
- last_max_congestion_window_ = 0;
- acked_packets_count_ = 0;
- epoch_packets_count_ = 0;
- estimated_tcp_congestion_window_ = 0;
- origin_point_congestion_window_ = 0;
- time_to_origin_point_ = 0;
- last_target_congestion_window_ = 0;
-}
-
-void Cubic::OnApplicationLimited() {
- // When sender is not using the available congestion window, Cubic's epoch
- // should not continue growing. Reset the epoch when in such a period.
- epoch_ = QuicTime::Zero();
-}
-
-void Cubic::SetFixConvexMode(bool fix_convex_mode) {
- fix_convex_mode_ = fix_convex_mode;
-}
-
-void Cubic::SetFixBetaLastMax(bool fix_beta_last_max) {
- fix_beta_last_max_ = fix_beta_last_max;
-}
-
-void Cubic::SetAllowPerAckUpdates(bool allow_per_ack_updates) {
- allow_per_ack_updates_ = allow_per_ack_updates;
-}
-
-QuicPacketCount Cubic::CongestionWindowAfterPacketLoss(
- QuicPacketCount current_congestion_window) {
- if (current_congestion_window < last_max_congestion_window_) {
- // We never reached the old max, so assume we are competing with another
- // flow. Use our extra back off factor to allow the other flow to go up.
- last_max_congestion_window_ =
- static_cast<int>(BetaLastMax() * current_congestion_window);
- } else {
- last_max_congestion_window_ = current_congestion_window;
- }
- epoch_ = QuicTime::Zero(); // Reset time.
- return static_cast<int>(current_congestion_window * Beta());
-}
-
-QuicPacketCount Cubic::CongestionWindowAfterAck(
- QuicPacketCount current_congestion_window,
- QuicTime::Delta delay_min,
- QuicTime event_time) {
- acked_packets_count_ += 1; // Packets acked.
- epoch_packets_count_ += 1;
- // Cubic is "independent" of RTT, the update is limited by the time elapsed.
- if (!allow_per_ack_updates_ &&
- last_congestion_window_ == current_congestion_window &&
- (event_time - last_update_time_ <= MaxCubicTimeInterval())) {
- return std::max(last_target_congestion_window_,
- estimated_tcp_congestion_window_);
- }
- last_congestion_window_ = current_congestion_window;
- last_update_time_ = event_time;
-
- if (!epoch_.IsInitialized()) {
- // First ACK after a loss event.
- epoch_ = event_time; // Start of epoch.
- acked_packets_count_ = 1; // Reset count.
- epoch_packets_count_ = 1;
- // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
- estimated_tcp_congestion_window_ = current_congestion_window;
- if (last_max_congestion_window_ <= current_congestion_window) {
- time_to_origin_point_ = 0;
- origin_point_congestion_window_ = current_congestion_window;
- } else {
- time_to_origin_point_ = static_cast<uint32_t>(
- cbrt(kCubeFactor *
- (last_max_congestion_window_ - current_congestion_window)));
- origin_point_congestion_window_ = last_max_congestion_window_;
- }
- }
-
- // Change the time unit from microseconds to 2^10 fractions per second. Take
- // the round trip time in account. This is done to allow us to use shift as a
- // divide operator.
- const int64_t elapsed_time =
- ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
- kNumMicrosPerSecond;
- DCHECK_GE(elapsed_time, 0);
-
- int64_t offset = time_to_origin_point_ - elapsed_time;
- if (fix_convex_mode_) {
- // Right-shifts of negative, signed numbers have
- // implementation-dependent behavior. Force the offset to be
- // positive, similar to the kernel implementation.
- offset = std::abs(time_to_origin_point_ - elapsed_time);
- }
-
- QuicPacketCount delta_congestion_window =
- (kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale;
-
- const bool add_delta = elapsed_time > time_to_origin_point_;
- DCHECK(add_delta ||
- (origin_point_congestion_window_ > delta_congestion_window));
- QuicPacketCount target_congestion_window =
- (fix_convex_mode_ && add_delta)
- ? origin_point_congestion_window_ + delta_congestion_window
- : origin_point_congestion_window_ - delta_congestion_window;
-
- // Limit the CWND increase to half the acked packets rounded up to the
- // nearest packet.
- target_congestion_window =
- std::min(target_congestion_window,
- current_congestion_window + (epoch_packets_count_ + 1) / 2);
-
- DCHECK_LT(0u, estimated_tcp_congestion_window_);
- // With dynamic beta/alpha based on number of active streams, it is possible
- // for the required_ack_count to become much lower than acked_packets_count_
- // suddenly, leading to more than one iteration through the following loop.
- while (true) {
- // Update estimated TCP congestion_window.
- QuicPacketCount required_ack_count = static_cast<QuicPacketCount>(
- estimated_tcp_congestion_window_ / Alpha());
- if (acked_packets_count_ < required_ack_count) {
- break;
- }
- acked_packets_count_ -= required_ack_count;
- estimated_tcp_congestion_window_++;
- }
- epoch_packets_count_ = 0;
-
- // We have a new cubic congestion window.
- last_target_congestion_window_ = target_congestion_window;
-
- // Compute target congestion_window based on cubic target and estimated TCP
- // congestion_window, use highest (fastest).
- if (target_congestion_window < estimated_tcp_congestion_window_) {
- target_congestion_window = estimated_tcp_congestion_window_;
- }
-
- QUIC_DVLOG(1) << "Final target congestion_window: "
- << target_congestion_window;
- return target_congestion_window;
-}
-
-} // namespace net
diff --git a/chromium/net/quic/core/congestion_control/cubic.h b/chromium/net/quic/core/congestion_control/cubic.h
deleted file mode 100644
index a2f99463032..00000000000
--- a/chromium/net/quic/core/congestion_control/cubic.h
+++ /dev/null
@@ -1,144 +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.
-//
-// Cubic algorithm, helper class to TCP cubic.
-// For details see http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf.
-
-#ifndef NET_QUIC_CORE_CONGESTION_CONTROL_CUBIC_H_
-#define NET_QUIC_CORE_CONGESTION_CONTROL_CUBIC_H_
-
-#include <cstdint>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_bandwidth.h"
-#include "net/quic/core/quic_connection_stats.h"
-#include "net/quic/core/quic_time.h"
-#include "net/quic/platform/api/quic_clock.h"
-#include "net/quic/platform/api/quic_export.h"
-
-namespace net {
-
-namespace test {
-class CubicTest;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE Cubic {
- public:
- explicit Cubic(const QuicClock* clock);
-
- void SetNumConnections(int num_connections);
-
- // Call after a timeout to reset the cubic state.
- void ResetCubicState();
-
- // Compute a new congestion window to use after a loss event.
- // Returns the new congestion window in packets. The new congestion window is
- // a multiplicative decrease of our current window.
- QuicPacketCount CongestionWindowAfterPacketLoss(QuicPacketCount current);
-
- // Compute a new congestion window to use after a received ACK.
- // Returns the new congestion window in packets. The new congestion
- // window follows a cubic function that depends on the time passed
- // since last packet loss.
- QuicPacketCount CongestionWindowAfterAck(QuicPacketCount current,
- QuicTime::Delta delay_min,
- QuicTime event_time);
-
- // Call on ack arrival when sender is unable to use the available congestion
- // window. Resets Cubic state during quiescence.
- void OnApplicationLimited();
-
- // Methods for enabling experimental modes.
- // If true, enable the fix for the convex-mode signing bug. See
- // b/32170105 for more information about the bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetFixConvexMode(bool fix_convex_mode);
- // If true, enable per-ack updates. See b/32170105 for more
- // information about the bug. TODO(jokulik): Remove once this
- // change is enabled by default.
- void SetAllowPerAckUpdates(bool allow_per_ack_updates);
-
- // If true, enable the fix for scaling BetaLastMax for n-nonnection
- // emulation. See b/33272010 for more information about the bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetFixBetaLastMax(bool fix_bet_last_max);
-
- private:
- friend class test::CubicTest;
-
- static const QuicTime::Delta MaxCubicTimeInterval() {
- return QuicTime::Delta::FromMilliseconds(30);
- }
-
- // Compute the TCP Cubic alpha, beta, and beta-last-max based on the
- // current number of connections.
- float Alpha() const;
- float Beta() const;
- float BetaLastMax() const;
-
- QuicByteCount last_max_congestion_window() const {
- return last_max_congestion_window_;
- }
-
- const QuicClock* clock_;
-
- // Number of connections to simulate.
- int num_connections_;
-
- // Time when this cycle started, after last loss event.
- QuicTime epoch_;
-
- // Time when sender went into application-limited period. Zero if not in
- // application-limited period.
- QuicTime app_limited_start_time_;
-
- // Time when we updated last_congestion_window.
- QuicTime last_update_time_;
-
- // Last congestion window (in packets) used.
- QuicPacketCount last_congestion_window_;
-
- // Max congestion window (in packets) used just before last loss event.
- // Note: to improve fairness to other streams an additional back off is
- // applied to this value if the new value is below our latest value.
- QuicPacketCount last_max_congestion_window_;
-
- // Number of acked packets accumulated to increase the CWND via Reno
- // 'tcp friendly' mode.
- QuicPacketCount acked_packets_count_;
-
- // Number of acked packets since the cycle started (epoch).
- // Used to limit CWND increases to 1/2 the number of acked packets.
- QuicPacketCount epoch_packets_count_;
-
- // TCP Reno equivalent congestion window in packets.
- QuicPacketCount estimated_tcp_congestion_window_;
-
- // Origin point of cubic function.
- QuicPacketCount origin_point_congestion_window_;
-
- // Time to origin point of cubic function in 2^10 fractions of a second.
- uint32_t time_to_origin_point_;
-
- // Last congestion window in packets computed by cubic function.
- QuicPacketCount last_target_congestion_window_;
-
- // Fix convex mode for cubic.
- // TODO(jokulik): Remove once the cubic convex experiment is done.
- bool fix_convex_mode_;
-
- // Fix beta last max for n-connection-emulation.
- // TODO(jokulik): Remove once the corresponding experiment is done.
- bool fix_beta_last_max_;
-
- // Allow cubic per ack updates.
- // TODO(jokulik): Remove once the per ack update experiment is done.
- bool allow_per_ack_updates_;
-
- DISALLOW_COPY_AND_ASSIGN(Cubic);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_CORE_CONGESTION_CONTROL_CUBIC_H_
diff --git a/chromium/net/quic/core/congestion_control/cubic_bytes.cc b/chromium/net/quic/core/congestion_control/cubic_bytes.cc
index 33dc0de7e60..1df0fd44da1 100644
--- a/chromium/net/quic/core/congestion_control/cubic_bytes.cc
+++ b/chromium/net/quic/core/congestion_control/cubic_bytes.cc
@@ -40,16 +40,8 @@ const float kBetaLastMax = 0.85f;
CubicBytes::CubicBytes(const QuicClock* clock)
: clock_(clock),
num_connections_(kDefaultNumConnections),
- epoch_(QuicTime::Zero()),
- last_update_time_(QuicTime::Zero()),
- fix_convex_mode_(FLAGS_quic_reloadable_flag_quic_enable_cubic_fixes),
- fix_cubic_quantization_(fix_convex_mode_),
- fix_beta_last_max_(fix_convex_mode_),
- allow_per_ack_updates_(fix_convex_mode_) {
+ epoch_(QuicTime::Zero()) {
ResetCubicState();
- if (fix_convex_mode_) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_enable_cubic_fixes, 2, 2);
- }
}
void CubicBytes::SetNumConnections(int num_connections) {
@@ -77,15 +69,11 @@ float CubicBytes::BetaLastMax() const {
// N-connection emulation, which emulates the additional backoff of
// an ensemble of N TCP-Reno connections on a single loss event. The
// effective multiplier is computed as:
- return fix_beta_last_max_
- ? (num_connections_ - 1 + kBetaLastMax) / num_connections_
- : kBetaLastMax;
+ return (num_connections_ - 1 + kBetaLastMax) / num_connections_;
}
void CubicBytes::ResetCubicState() {
epoch_ = QuicTime::Zero(); // Reset time.
- last_update_time_ = QuicTime::Zero(); // Reset time.
- last_congestion_window_ = 0;
last_max_congestion_window_ = 0;
acked_bytes_count_ = 0;
estimated_tcp_congestion_window_ = 0;
@@ -94,22 +82,6 @@ void CubicBytes::ResetCubicState() {
last_target_congestion_window_ = 0;
}
-void CubicBytes::SetFixConvexMode(bool fix_convex_mode) {
- fix_convex_mode_ = fix_convex_mode;
-}
-
-void CubicBytes::SetFixCubicQuantization(bool fix_cubic_quantization) {
- fix_cubic_quantization_ = fix_cubic_quantization;
-}
-
-void CubicBytes::SetFixBetaLastMax(bool fix_beta_last_max) {
- fix_beta_last_max_ = fix_beta_last_max;
-}
-
-void CubicBytes::SetAllowPerAckUpdates(bool allow_per_ack_updates) {
- allow_per_ack_updates_ = allow_per_ack_updates;
-}
-
void CubicBytes::OnApplicationLimited() {
// When sender is not using the available congestion window, the window does
// not grow. But to be RTT-independent, Cubic assumes that the sender has been
@@ -127,9 +99,7 @@ QuicByteCount CubicBytes::CongestionWindowAfterPacketLoss(
// Since bytes-mode Reno mode slightly under-estimates the cwnd, we
// may never reach precisely the last cwnd over the course of an
// RTT. Do not interpret a slight under-estimation as competing traffic.
- const QuicByteCount last_window_delta =
- fix_beta_last_max_ ? kDefaultTCPMSS : 0;
- if (current_congestion_window + last_window_delta <
+ if (current_congestion_window + kDefaultTCPMSS <
last_max_congestion_window_) {
// We never reached the old max, so assume we are competing with
// another flow. Use our extra back off factor to allow the other
@@ -149,15 +119,6 @@ QuicByteCount CubicBytes::CongestionWindowAfterAck(
QuicTime::Delta delay_min,
QuicTime event_time) {
acked_bytes_count_ += acked_bytes;
- // Cubic is "independent" of RTT, the update is limited by the time elapsed.
- if (!allow_per_ack_updates_ &&
- (last_congestion_window_ == current_congestion_window &&
- (event_time - last_update_time_ <= MaxCubicTimeInterval()))) {
- return std::max(last_target_congestion_window_,
- estimated_tcp_congestion_window_);
- }
- last_congestion_window_ = current_congestion_window;
- last_update_time_ = event_time;
if (!epoch_.IsInitialized()) {
// First ACK after a loss event.
@@ -183,32 +144,20 @@ QuicByteCount CubicBytes::CongestionWindowAfterAck(
((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
kNumMicrosPerSecond;
- // TODO(ianswett): Change to uint64_t once fix_convex_mode_ is always enabled.
- int64_t offset = time_to_origin_point_ - elapsed_time;
- if (fix_convex_mode_) {
- // Right-shifts of negative, signed numbers have
- // implementation-dependent behavior. In the fix, force the
- // offset to be positive, as is done in the kernel.
- const int64_t positive_offset =
- std::abs(time_to_origin_point_ - elapsed_time);
- offset = positive_offset;
- }
- QuicByteCount delta_congestion_window =
- fix_cubic_quantization_
- ? (kCubeCongestionWindowScale * offset * offset * offset *
- kDefaultTCPMSS) >>
- kCubeScale
- : ((kCubeCongestionWindowScale * offset * offset * offset) >>
- kCubeScale) *
- kDefaultTCPMSS;
+ // Right-shifts of negative, signed numbers have implementation-dependent
+ // behavior, so force the offset to be positive, as is done in the kernel.
+ uint64_t offset = std::abs(time_to_origin_point_ - elapsed_time);
+
+ QuicByteCount delta_congestion_window = (kCubeCongestionWindowScale * offset *
+ offset * offset * kDefaultTCPMSS) >>
+ kCubeScale;
const bool add_delta = elapsed_time > time_to_origin_point_;
DCHECK(add_delta ||
(origin_point_congestion_window_ > delta_congestion_window));
QuicByteCount target_congestion_window =
- (fix_convex_mode_ && add_delta)
- ? origin_point_congestion_window_ + delta_congestion_window
- : origin_point_congestion_window_ - delta_congestion_window;
+ add_delta ? origin_point_congestion_window_ + delta_congestion_window
+ : origin_point_congestion_window_ - delta_congestion_window;
// Limit the CWND increase to half the acked bytes.
target_congestion_window =
std::min(target_congestion_window,
diff --git a/chromium/net/quic/core/congestion_control/cubic_bytes.h b/chromium/net/quic/core/congestion_control/cubic_bytes.h
index 55f55591369..8c31b95cb7d 100644
--- a/chromium/net/quic/core/congestion_control/cubic_bytes.h
+++ b/chromium/net/quic/core/congestion_control/cubic_bytes.h
@@ -50,23 +50,6 @@ class QUIC_EXPORT_PRIVATE CubicBytes {
// window. Resets Cubic state during quiescence.
void OnApplicationLimited();
- // If true, enable the fix for the convex-mode signing bug. See
- // b/32170105 for more information about the bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetFixConvexMode(bool fix_convex_mode);
- // If true, fix CubicBytes quantization bug. See b/33273459 for
- // more information about the bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetFixCubicQuantization(bool fix_cubic_quantization);
- // If true, enable the fix for scaling BetaLastMax for n-nonnection
- // emulation. See b/33272010 for more information about the bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetFixBetaLastMax(bool fix_beta_last_max);
- // If true, unconditionally enable each ack to update the congestion
- // window. See b/33410956 for further information about this bug.
- // TODO(jokulik): Remove once the fix is enabled by default.
- void SetAllowPerAckUpdates(bool allow_per_ack_updates);
-
private:
friend class test::CubicBytesTest;
@@ -92,12 +75,6 @@ class QUIC_EXPORT_PRIVATE CubicBytes {
// Time when this cycle started, after last loss event.
QuicTime epoch_;
- // Time when we updated last_congestion_window.
- QuicTime last_update_time_;
-
- // Last congestion window used.
- QuicByteCount last_congestion_window_;
-
// Max congestion window used just before last loss event.
// Note: to improve fairness to other streams an additional back off is
// applied to this value if the new value is below our latest value.
@@ -118,23 +95,6 @@ class QUIC_EXPORT_PRIVATE CubicBytes {
// Last congestion window in packets computed by cubic function.
QuicByteCount last_target_congestion_window_;
- // Fix convex mode for cubic.
- // TODO(jokulik): Remove once the cubic convex experiment is done.
- bool fix_convex_mode_;
-
- // Fix for quantization in cubic mode.
- // TODO(jokulik): Remove once the experiment is done.
- bool fix_cubic_quantization_;
-
- // Fix beta last max for n-connection-emulation.
- // TODO(jokulik): Remove once the corresponding experiment is done.
- bool fix_beta_last_max_;
-
- // Allow per ack updates, rather than limiting the frequency of
- // updates when in cubic-mode.
- // TODO(jokulik): Remove once the experiment is done.
- bool allow_per_ack_updates_;
-
DISALLOW_COPY_AND_ASSIGN(CubicBytes);
};
diff --git a/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc b/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc
index b009b1d258d..6d6468e5ebe 100644
--- a/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc
+++ b/chromium/net/quic/core/congestion_control/cubic_bytes_test.cc
@@ -26,67 +26,14 @@ const float kNConnectionBetaLastMax =
const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
(1 - kNConnectionBeta) / (1 + kNConnectionBeta);
-struct TestParams {
- TestParams(bool fix_convex_mode,
- bool fix_cubic_quantization,
- bool fix_beta_last_max,
- bool allow_per_ack_updates)
- : fix_convex_mode(fix_convex_mode),
- fix_cubic_quantization(fix_cubic_quantization),
- fix_beta_last_max(fix_beta_last_max),
- allow_per_ack_updates(allow_per_ack_updates) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ fix_convex_mode: " << p.fix_convex_mode
- << " fix_cubic_quantization: " << p.fix_cubic_quantization
- << " fix_beta_last_max: " << p.fix_beta_last_max
- << " allow_per_ack_updates: " << p.allow_per_ack_updates << " }";
- return os;
- }
-
- bool fix_convex_mode;
- bool fix_cubic_quantization;
- bool fix_beta_last_max;
- bool allow_per_ack_updates;
-};
-
-string TestParamToString(const testing::TestParamInfo<TestParams>& params) {
- return QuicStrCat("convex_mode_", params.param.fix_convex_mode, "_",
- "cubic_quantization_", params.param.fix_cubic_quantization,
- "_", "beta_last_max_", params.param.fix_beta_last_max, "_",
- "allow_per_ack_updates_",
- params.param.allow_per_ack_updates);
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (bool fix_convex_mode : {true, false}) {
- for (bool fix_cubic_quantization : {true, false}) {
- for (bool fix_beta_last_max : {true, false}) {
- for (bool allow_per_ack_updates : {true, false}) {
- TestParams param(fix_convex_mode, fix_cubic_quantization,
- fix_beta_last_max, allow_per_ack_updates);
- params.push_back(param);
- }
- }
- }
- }
- return params;
-}
-
} // namespace
-class CubicBytesTest : public QuicTestWithParam<TestParams> {
+class CubicBytesTest : public QuicTest {
protected:
CubicBytesTest()
: one_ms_(QuicTime::Delta::FromMilliseconds(1)),
hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
- cubic_(&clock_) {
- cubic_.SetFixConvexMode(GetParam().fix_convex_mode);
- cubic_.SetFixCubicQuantization(GetParam().fix_cubic_quantization);
- cubic_.SetFixBetaLastMax(GetParam().fix_beta_last_max);
- cubic_.SetAllowPerAckUpdates(GetParam().allow_per_ack_updates);
- }
+ cubic_(&clock_) {}
QuicByteCount RenoCwndInBytes(QuicByteCount current_cwnd) {
QuicByteCount reno_estimated_cwnd =
@@ -106,9 +53,7 @@ class CubicBytesTest : public QuicTestWithParam<TestParams> {
const int64_t offset =
((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
const QuicByteCount delta_congestion_window =
- GetParam().fix_cubic_quantization
- ? ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40)
- : ((410 * offset * offset * offset) >> 40) * kDefaultTCPMSS;
+ ((410 * offset * offset * offset) * kDefaultTCPMSS >> 40);
const QuicByteCount cubic_cwnd = initial_cwnd + delta_congestion_window;
return cubic_cwnd;
}
@@ -127,27 +72,11 @@ class CubicBytesTest : public QuicTestWithParam<TestParams> {
CubicBytes cubic_;
};
-INSTANTIATE_TEST_CASE_P(CubicBytesTests,
- CubicBytesTest,
- ::testing::ValuesIn(GetTestParams()),
- TestParamToString);
-
// TODO(jokulik): The original "AboveOrigin" test, below, is very
// loose. It's nearly impossible to make the test tighter without
// deploying the fix for convex mode. Once cubic convex is deployed,
// replace "AboveOrigin" with this test.
-TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) {
- if (!GetParam().fix_convex_mode) {
- // Without convex mode fixed, the behavior of the algorithm is so
- // far from expected, there's no point in doing a tighter test.
- return;
- }
- if (!GetParam().fix_cubic_quantization && GetParam().allow_per_ack_updates) {
- // Without quantization mode fixed, the behavior of per ack
- // updates is so far from expected, there is no point of a tighter
- // test.
- return;
- }
+TEST_F(CubicBytesTest, AboveOriginWithTighterBounds) {
// Convex growth.
const QuicTime::Delta rtt_min = hundred_ms_;
int64_t rtt_min_ms = rtt_min.ToMilliseconds();
@@ -166,13 +95,8 @@ TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) {
// The maximum number of expected Reno RTTs is calculated by
// finding the point where the cubic curve and the reno curve meet.
const int max_reno_rtts =
- GetParam().fix_cubic_quantization
- ? std::sqrt(kNConnectionAlpha /
- (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
- 2
- : std::sqrt(kNConnectionAlpha /
- (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
- 1;
+ std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
+ 2;
for (int i = 0; i < max_reno_rtts; ++i) {
// Alternatively, we expect it to increase by one, every time we
// receive current_cwnd/Alpha acks back. (This is another way of
@@ -198,19 +122,6 @@ TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) {
clock_.AdvanceTime(hundred_ms_);
}
- if (!GetParam().fix_cubic_quantization) {
- // Because our byte-wise Reno under-estimates the cwnd, we switch to
- // conservative increases for a few acks before switching to true
- // cubic increases.
- for (int i = 0; i < 3; ++i) {
- const QuicByteCount next_expected_cwnd =
- ConservativeCwndInBytes(current_cwnd);
- current_cwnd = cubic_.CongestionWindowAfterAck(
- kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- ASSERT_EQ(next_expected_cwnd, current_cwnd);
- }
- }
-
for (int i = 0; i < 54; ++i) {
const uint64_t max_acks_this_epoch = current_cwnd / kDefaultTCPMSS;
const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
@@ -221,20 +132,10 @@ TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) {
kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
- if (GetParam().allow_per_ack_updates) {
- // If we allow per-ack updates, every update is a small cubic update.
- ASSERT_EQ(expected_cwnd, current_cwnd);
- } else {
- // If we do not allow per-ack updates, we get sporadic cubic updates.
- ASSERT_GE(expected_cwnd, current_cwnd);
- }
+ // If we allow per-ack updates, every update is a small cubic update.
+ ASSERT_EQ(expected_cwnd, current_cwnd);
}
}
- if (!GetParam().allow_per_ack_updates) {
- // If we don't allow per-ack updates, we need to artificially
- // advance the clock to make the cwnd increase.
- clock_.AdvanceTime(MaxCubicTimeInterval());
- }
const QuicByteCount expected_cwnd = CubicConvexCwndInBytes(
initial_cwnd, rtt_min, (clock_.ApproximateNow() - initial_time));
current_cwnd = cubic_.CongestionWindowAfterAck(
@@ -242,24 +143,15 @@ TEST_P(CubicBytesTest, AboveOriginWithTighterBounds) {
ASSERT_EQ(expected_cwnd, current_cwnd);
}
-TEST_P(CubicBytesTest, AboveOrigin) {
- if ((!GetParam().fix_convex_mode && GetParam().fix_cubic_quantization) ||
- GetParam().allow_per_ack_updates) {
- // Without convex mode fixed, the behavior of the algorithm does
- // not fit the exact pattern of this test.
- // TODO(jokulik): Once the convex mode fix becomes default, this
- // test can be replaced with the better AboveOriginTighterBounds
- // test.
- return;
- }
+// TODO(ianswett): This test was disabled when all fixes were enabled, but it
+// may be worth fixing.
+TEST_F(CubicBytesTest, DISABLED_AboveOrigin) {
// Convex growth.
const QuicTime::Delta rtt_min = hundred_ms_;
QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
// Without the signed-integer, cubic-convex fix, we start out in the
// wrong mode.
- QuicPacketCount expected_cwnd = GetParam().fix_convex_mode
- ? RenoCwndInBytes(current_cwnd)
- : ConservativeCwndInBytes(current_cwnd);
+ QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
// Initialize the state.
clock_.AdvanceTime(one_ms_);
ASSERT_EQ(expected_cwnd,
@@ -280,16 +172,11 @@ TEST_P(CubicBytesTest, AboveOrigin) {
clock_.AdvanceTime(hundred_ms_);
current_cwnd = cubic_.CongestionWindowAfterAck(
kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- if (GetParam().fix_convex_mode) {
- // When we fix convex mode and the uint64 arithmetic, we
- // increase the expected_cwnd only after after the first 100ms,
- // rather than after the initial 1ms.
- expected_cwnd += kDefaultTCPMSS;
- ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
- } else {
- ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
- expected_cwnd += kDefaultTCPMSS;
- }
+ // When we fix convex mode and the uint64 arithmetic, we
+ // increase the expected_cwnd only after after the first 100ms,
+ // rather than after the initial 1ms.
+ expected_cwnd += kDefaultTCPMSS;
+ ASSERT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
}
// Cubic phase.
for (int i = 0; i < 52; ++i) {
@@ -310,10 +197,6 @@ TEST_P(CubicBytesTest, AboveOrigin) {
expected_cwnd =
initial_cwnd / kDefaultTCPMSS +
(elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
- // Without the convex mode fix, the result is off by one.
- if (!GetParam().fix_convex_mode) {
- ++expected_cwnd;
- }
EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
}
@@ -326,12 +209,7 @@ TEST_P(CubicBytesTest, AboveOrigin) {
//
// - Sets an artificially large initial cwnd to prevent Reno from the
// convex increases on every ack.
-TEST_P(CubicBytesTest, AboveOriginFineGrainedCubing) {
- if (!GetParam().fix_convex_mode || !GetParam().fix_cubic_quantization) {
- // Without these two fixes, this test cannot pass.
- return;
- }
-
+TEST_F(CubicBytesTest, AboveOriginFineGrainedCubing) {
// Start the test with an artificially large cwnd to prevent Reno
// from over-taking cubic.
QuicByteCount current_cwnd = 1000 * kDefaultTCPMSS;
@@ -373,13 +251,7 @@ TEST_P(CubicBytesTest, AboveOriginFineGrainedCubing) {
// cwnd. When we limit per-ack updates, this would cause the
// cessation of cubic updates for 30ms. When we allow per-ack
// updates, the window continues to grow on every ack.
-TEST_P(CubicBytesTest, PerAckUpdates) {
- if (!GetParam().fix_convex_mode || !GetParam().fix_cubic_quantization ||
- !GetParam().allow_per_ack_updates) {
- // Without these fixes, this test will fail.
- return;
- }
-
+TEST_F(CubicBytesTest, PerAckUpdates) {
// Start the test with a large cwnd and RTT, to force the first
// increase to be a cubic increase.
QuicPacketCount initial_cwnd_packets = 150;
@@ -431,14 +303,12 @@ TEST_P(CubicBytesTest, PerAckUpdates) {
EXPECT_LT(minimum_expected_increase + initial_cwnd, current_cwnd);
}
-TEST_P(CubicBytesTest, LossEvents) {
+TEST_F(CubicBytesTest, LossEvents) {
const QuicTime::Delta rtt_min = hundred_ms_;
QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
// Without the signed-integer, cubic-convex fix, we mistakenly
// increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd = GetParam().fix_convex_mode
- ? RenoCwndInBytes(current_cwnd)
- : current_cwnd + kDefaultTCPMSS / 2;
+ QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
// Initialize the state.
clock_.AdvanceTime(one_ms_);
EXPECT_EQ(expected_cwnd,
@@ -466,27 +336,13 @@ TEST_P(CubicBytesTest, LossEvents) {
current_cwnd = expected_cwnd;
EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
QuicByteCount expected_last_max =
- GetParam().fix_beta_last_max
- ? static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax)
- : static_cast<QuicByteCount>(pre_loss_cwnd * kBetaLastMax);
+ static_cast<QuicByteCount>(pre_loss_cwnd * kNConnectionBetaLastMax);
EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
- if (GetParam().fix_beta_last_max) {
- EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
- } else {
- // If we don't scale kLastBetaMax, the current window is exactly
- // equal to the last max congestion window, which would cause us
- // to land above the origin on the next increase.
- EXPECT_EQ(expected_cwnd, LastMaxCongestionWindow());
- }
+ EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
// Simulate an increase, and check that we are below the origin.
current_cwnd = cubic_.CongestionWindowAfterAck(
kDefaultTCPMSS, current_cwnd, rtt_min, clock_.ApproximateNow());
- if (GetParam().fix_beta_last_max) {
- EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
- } else {
- // Without the bug fix, we will be at or above the origin.
- EXPECT_LE(LastMaxCongestionWindow(), current_cwnd);
- }
+ EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
// On the final loss, simulate the condition where the congestion
// window had a chance to grow nearly to the last congestion window.
@@ -495,22 +351,17 @@ TEST_P(CubicBytesTest, LossEvents) {
expected_cwnd = static_cast<QuicByteCount>(current_cwnd * kNConnectionBeta);
EXPECT_EQ(expected_cwnd,
cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- expected_last_max =
- GetParam().fix_beta_last_max
- ? pre_loss_cwnd
- : static_cast<QuicByteCount>(pre_loss_cwnd * kBetaLastMax);
+ expected_last_max = pre_loss_cwnd;
ASSERT_EQ(expected_last_max, LastMaxCongestionWindow());
}
-TEST_P(CubicBytesTest, BelowOrigin) {
+TEST_F(CubicBytesTest, BelowOrigin) {
// Concave growth.
const QuicTime::Delta rtt_min = hundred_ms_;
QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
// Without the signed-integer, cubic-convex fix, we mistakenly
// increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd = GetParam().fix_convex_mode
- ? RenoCwndInBytes(current_cwnd)
- : current_cwnd + kDefaultTCPMSS / 2;
+ QuicPacketCount expected_cwnd = RenoCwndInBytes(current_cwnd);
// Initialize the state.
clock_.AdvanceTime(one_ms_);
EXPECT_EQ(expected_cwnd,
diff --git a/chromium/net/quic/core/congestion_control/cubic_test.cc b/chromium/net/quic/core/congestion_control/cubic_test.cc
deleted file mode 100644
index 47733b7d087..00000000000
--- a/chromium/net/quic/core/congestion_control/cubic_test.cc
+++ /dev/null
@@ -1,367 +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/quic/core/congestion_control/cubic.h"
-
-#include <cstdint>
-
-#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/api/quic_str_cat.h"
-#include "net/quic/platform/api/quic_test.h"
-#include "net/quic/test_tools/mock_clock.h"
-
-using std::string;
-
-namespace net {
-namespace test {
-namespace {
-
-const float kBeta = 0.7f; // Default Cubic backoff factor.
-const float kBetaLastMax = 0.85f; // Default Cubic backoff factor.
-const uint32_t kNumConnections = 2;
-const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
-const float kNConnectionBetaLastMax =
- (kNumConnections - 1 + kBetaLastMax) / kNumConnections;
-const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
- (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
-
-struct TestParams {
- TestParams(bool fix_convex_mode,
- bool fix_beta_last_max,
- bool allow_per_ack_updates)
- : fix_convex_mode(fix_convex_mode),
- fix_beta_last_max(fix_beta_last_max),
- allow_per_ack_updates(allow_per_ack_updates) {}
-
- friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ fix_convex_mode: " << p.fix_convex_mode
- << " fix_beta_last_max: " << p.fix_beta_last_max
- << " allow_per_ack_updates: " << p.allow_per_ack_updates << " }";
- return os;
- }
-
- bool fix_convex_mode;
- bool fix_beta_last_max;
- bool allow_per_ack_updates;
-};
-
-string TestParamToString(const testing::TestParamInfo<TestParams>& params) {
- return QuicStrCat("convex_mode_", params.param.fix_convex_mode, "_",
- "beta_last_max_", params.param.fix_beta_last_max, "_",
- "allow_per_ack_updates_",
- params.param.allow_per_ack_updates);
-}
-
-std::vector<TestParams> GetTestParams() {
- std::vector<TestParams> params;
- for (bool fix_convex_mode : {true, false}) {
- for (bool fix_beta_last_max : {true, false}) {
- for (bool allow_per_ack_updates : {true, false}) {
- TestParams param(fix_convex_mode, fix_beta_last_max,
- allow_per_ack_updates);
- params.push_back(param);
- }
- }
- }
- return params;
-}
-
-} // namespace
-
-// TODO(jokulik): Once we've rolled out the cubic convex fix, we will
-// no longer need a parameterized test.
-class CubicTest : public QuicTestWithParam<TestParams> {
- protected:
- CubicTest()
- : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
- cubic_(&clock_) {
- cubic_.SetFixConvexMode(GetParam().fix_convex_mode);
- cubic_.SetFixBetaLastMax(GetParam().fix_beta_last_max);
- cubic_.SetAllowPerAckUpdates(GetParam().allow_per_ack_updates);
- }
-
- QuicByteCount LastMaxCongestionWindow() {
- return cubic_.last_max_congestion_window();
- }
-
- QuicPacketCount CubicConvexCwnd(QuicByteCount initial_cwnd,
- QuicTime::Delta rtt,
- QuicTime::Delta elapsed_time) {
- const int64_t offset =
- ((elapsed_time + rtt).ToMicroseconds() << 10) / 1000000;
- const QuicPacketCount delta_congestion_window =
- (410 * offset * offset * offset) >> 40;
- const QuicPacketCount cubic_cwnd = initial_cwnd + delta_congestion_window;
- return cubic_cwnd;
- }
-
- QuicTime::Delta MaxCubicTimeInterval() {
- return cubic_.MaxCubicTimeInterval();
- }
-
- const QuicTime::Delta one_ms_;
- const QuicTime::Delta hundred_ms_;
- MockClock clock_;
- Cubic cubic_;
-};
-
-INSTANTIATE_TEST_CASE_P(CubicTests,
- CubicTest,
- ::testing::ValuesIn(GetTestParams()),
- TestParamToString);
-
-TEST_P(CubicTest, AboveOrigin) {
- if (GetParam().allow_per_ack_updates) {
- // Don't even test a scenario where we fix per ack updates without
- // the signing bug fix.
- return;
- }
-
- // Convex growth.
- const QuicTime::Delta rtt_min = hundred_ms_;
- const float rtt_min_s = rtt_min.ToMilliseconds() / 1000.0;
- QuicPacketCount current_cwnd = 10;
- // Without the signed-integer, cubic-convex fix, we mistakenly
- // increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd =
- GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1;
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- const QuicTime initial_time = clock_.ApproximateNow();
- current_cwnd =
- cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min, initial_time);
- ASSERT_EQ(expected_cwnd, current_cwnd);
- const QuicPacketCount initial_cwnd = current_cwnd;
- // Normal TCP phase.
- // The maximum number of expected reno RTTs can be calculated by
- // finding the point where the cubic curve and the reno curve meet.
- int max_reno_rtts =
- std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
- 1;
- QuicPacketCount reno_acked_packet_count = 1;
- for (int i = 0; i < max_reno_rtts; ++i) {
- const QuicPacketCount max_acks_before_increase =
- current_cwnd / kNConnectionAlpha;
- while (reno_acked_packet_count < max_acks_before_increase - 1) {
- // Call once per ACK.
- const QuicByteCount next_cwnd = cubic_.CongestionWindowAfterAck(
- current_cwnd, rtt_min, clock_.ApproximateNow());
- ASSERT_EQ(current_cwnd, next_cwnd);
- ++reno_acked_packet_count;
- }
- if (!GetParam().allow_per_ack_updates) {
- // If we do not allow per-ack updates, the clock must be
- // advanced in order for the window updates to take affect.
- clock_.AdvanceTime(hundred_ms_);
- }
- // If we allow per-ack updates, the window can increase even
- // before the clock has.
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- if (GetParam().fix_convex_mode) {
- if (GetParam().allow_per_ack_updates) {
- // If we allow per-ack updates, the cwnd can increase even after
- // the ack.
- clock_.AdvanceTime(hundred_ms_);
- }
- // When we fix convex mode and the uint64 arithmetic, we
- // increase the expected_cwnd only after the first 100ms, rather
- // than after the initial 1ms.
- expected_cwnd++;
- ASSERT_EQ(expected_cwnd, current_cwnd);
- } else {
- ASSERT_EQ(expected_cwnd, current_cwnd);
- expected_cwnd++;
- }
- reno_acked_packet_count = 0;
- }
- // Cubic phase.
- for (int i = 0; i < 52; ++i) {
- for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
- // Call once per ACK.
- const QuicPacketCount next_cwnd = cubic_.CongestionWindowAfterAck(
- current_cwnd, rtt_min, clock_.ApproximateNow());
- ;
- if (GetParam().allow_per_ack_updates) {
- // If we allow per-ack increases, the cwnd may gently increase
- // up to the cubic value, rather than jumping up after a 30ms
- // delay.
- ASSERT_LE(current_cwnd, next_cwnd);
- current_cwnd = next_cwnd;
- } else {
- ASSERT_EQ(current_cwnd, next_cwnd);
- }
- }
- if (!GetParam().allow_per_ack_updates) {
- // If we do not allow per-ack increases, we have to artificially
- // move the clock past the MaxCubicTimeInterval() in order for
- // the increases to take effect.
- clock_.AdvanceTime(hundred_ms_);
- }
- const QuicTime::Delta elapsed_time = clock_.ApproximateNow() - initial_time;
- const QuicPacketCount expected_cwnd =
- CubicConvexCwnd(initial_cwnd, rtt_min, elapsed_time);
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- if (GetParam().allow_per_ack_updates) {
- ASSERT_EQ(expected_cwnd, current_cwnd);
- clock_.AdvanceTime(hundred_ms_);
- }
- }
- if (!GetParam().allow_per_ack_updates) {
- QuicTime::Delta elapsed_time = clock_.ApproximateNow() - initial_time;
- const QuicPacketCount final_cwnd =
- CubicConvexCwnd(initial_cwnd, rtt_min, elapsed_time);
- ASSERT_EQ(final_cwnd, current_cwnd);
- }
-}
-
-// Constructs an artificial scenario to show what happens when we
-// allow per-ack updates, rather than limiting update freqency. In
-// this scenario, the first two acks of the epoch produce the same
-// cwnd. When we limit per-ack updates, this would cause the
-// cessation of cubic updates for 30ms, which is longer than an RTT.
-// When we allow per-ack updates, the window continues to grow on
-// every ack.
-TEST_P(CubicTest, PerAckUpdates) {
- if (!GetParam().fix_convex_mode) {
- // Without this fix, this test cannot pass.
- return;
- }
-
- // Pick an RTT smaller than the MaxCubicTimeInterval()
- QuicPacketCount current_cwnd = 5;
- const QuicTime::Delta rtt_min = 20 * one_ms_;
- ASSERT_LT(rtt_min, MaxCubicTimeInterval());
-
- // Initialize the epoch
- clock_.AdvanceTime(one_ms_);
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- const QuicPacketCount initial_cwnd = current_cwnd;
-
- // Simulate the return of cwnd packets over the course of an RTT,
- // which is less than the MaxCubicTimeInterval()
- const QuicPacketCount max_acks = current_cwnd / kNConnectionAlpha - 1;
- const QuicTime::Delta interval = QuicTime::Delta::FromMicroseconds(
- rtt_min.ToMicroseconds() / (max_acks + 2));
- for (QuicPacketCount n = 1; n < max_acks; ++n) {
- clock_.AdvanceTime(interval);
- ASSERT_EQ(current_cwnd,
- cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow()));
- }
- clock_.AdvanceTime(interval);
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
-
- if (GetParam().allow_per_ack_updates) {
- // After all the acks are returned from the epoch, we expect the
- // cwnd to have increased by one.
- EXPECT_EQ(initial_cwnd + 1, current_cwnd);
- } else {
- // If we do not allow per-ack updates, no increases occur at all
- // because we have not moved pass the MaxCubicTimeInterval()
- EXPECT_EQ(initial_cwnd, current_cwnd);
- }
-}
-
-TEST_P(CubicTest, LossEvents) {
- const QuicTime::Delta rtt_min = hundred_ms_;
- QuicPacketCount current_cwnd = 422;
- // Without the signed-integer, cubic-convex fix, we mistakenly
- // increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd =
- GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1;
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck(
- current_cwnd, rtt_min, clock_.ApproximateNow()));
-
- // On the first loss, the last max congestion window is set to the
- // congestion window before the loss.
- QuicByteCount pre_loss_cwnd = current_cwnd;
- expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
- ASSERT_EQ(0u, LastMaxCongestionWindow());
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
- current_cwnd = expected_cwnd;
-
- // On the second loss, the current congestion window is
- // significantly lower than the last max congestion window. The
- // last max congestion window will be reduced by an additional
- // backoff factor to allow for competition.
- pre_loss_cwnd = current_cwnd;
- expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
- ASSERT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- current_cwnd = expected_cwnd;
- EXPECT_GT(pre_loss_cwnd, LastMaxCongestionWindow());
- QuicByteCount expected_last_max =
- GetParam().fix_beta_last_max
- ? static_cast<QuicPacketCount>(pre_loss_cwnd *
- kNConnectionBetaLastMax)
- : static_cast<QuicPacketCount>(pre_loss_cwnd * kBetaLastMax);
- EXPECT_EQ(expected_last_max, LastMaxCongestionWindow());
- if (GetParam().fix_beta_last_max) {
- EXPECT_LT(expected_cwnd, LastMaxCongestionWindow());
- } else {
- // If we don't scale kLastBetaMax, the current window is exactly
- // equal to the last max congestion window, which would cause us
- // to land above the origin on the next increase.
- EXPECT_EQ(expected_cwnd, LastMaxCongestionWindow());
- }
- // Simulate an increase, and check that we are below the origin.
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- if (GetParam().fix_beta_last_max) {
- EXPECT_GT(LastMaxCongestionWindow(), current_cwnd);
- } else {
- // Without the bug fix, we will be at or above the origin.
- EXPECT_LE(LastMaxCongestionWindow(), current_cwnd);
- }
-
- // On the final loss, simulate the condition where the congestion
- // window had a chance to grow back to the last congestion window.
- current_cwnd = LastMaxCongestionWindow();
- pre_loss_cwnd = current_cwnd;
- expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- ASSERT_EQ(pre_loss_cwnd, LastMaxCongestionWindow());
-}
-
-TEST_P(CubicTest, BelowOrigin) {
- // Concave growth.
- const QuicTime::Delta rtt_min = hundred_ms_;
- QuicPacketCount current_cwnd = 422;
- // Without the signed-integer, cubic-convex fix, we mistakenly
- // increment cwnd after only one_ms_ and a single ack.
- QuicPacketCount expected_cwnd =
- GetParam().fix_convex_mode ? current_cwnd : current_cwnd + 1;
- // Initialize the state.
- clock_.AdvanceTime(one_ms_);
- EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck(
- current_cwnd, rtt_min, clock_.ApproximateNow()));
- expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
- EXPECT_EQ(expected_cwnd,
- cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
- current_cwnd = expected_cwnd;
- // First update after loss to initialize the epoch.
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- // Cubic phase.
- for (int i = 0; i < 40; ++i) {
- clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min,
- clock_.ApproximateNow());
- }
- expected_cwnd = 399;
- EXPECT_EQ(expected_cwnd, current_cwnd);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc b/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc
index 8833ddffdd2..b6f54e92e92 100644
--- a/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc
+++ b/chromium/net/quic/core/congestion_control/general_loss_algorithm.cc
@@ -144,7 +144,7 @@ void GeneralLossAlgorithm::SpuriousRetransmitDetected(
// Increase the reordering fraction until enough time would be allowed.
QuicTime::Delta max_rtt =
std::max(rtt_stats.previous_srtt(), rtt_stats.latest_rtt());
- if (FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss) {
+ if (GetQuicReloadableFlag(quic_fix_adaptive_time_loss)) {
QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fix_adaptive_time_loss);
while ((max_rtt >> reordering_shift_) <= extra_time_needed &&
reordering_shift_ > 0) {
diff --git a/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc b/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc
index 7a90f9bbd92..b3d0e717e28 100644
--- a/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc
+++ b/chromium/net/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -420,7 +420,7 @@ TEST_F(GeneralLossAlgorithmTest, IncreaseThresholdUponSpuriousLoss) {
// Advance the time 1/4 RTT and indicate the loss was spurious.
// The new threshold should be 1/2 RTT.
clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
- if (FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss) {
+ if (GetQuicReloadableFlag(quic_fix_adaptive_time_loss)) {
// The flag fixes an issue where adaptive time loss would increase the
// reordering threshold by an extra factor of two.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
diff --git a/chromium/net/quic/core/congestion_control/send_algorithm_interface.cc b/chromium/net/quic/core/congestion_control/send_algorithm_interface.cc
index b74d299cc5e..305811cd29b 100644
--- a/chromium/net/quic/core/congestion_control/send_algorithm_interface.cc
+++ b/chromium/net/quic/core/congestion_control/send_algorithm_interface.cc
@@ -32,7 +32,7 @@ SendAlgorithmInterface* SendAlgorithmInterface::Create(
initial_congestion_window, max_congestion_window,
random);
case kPCC:
- if (FLAGS_quic_reloadable_flag_quic_enable_pcc) {
+ if (GetQuicReloadableFlag(quic_enable_pcc)) {
return CreatePccSender(clock, rtt_stats, unacked_packets, random, stats,
initial_congestion_window,
max_congestion_window);
diff --git a/chromium/net/quic/core/congestion_control/send_algorithm_test.cc b/chromium/net/quic/core/congestion_control/send_algorithm_test.cc
index ca83556773f..59cd51d1fa7 100644
--- a/chromium/net/quic/core/congestion_control/send_algorithm_test.cc
+++ b/chromium/net/quic/core/congestion_control/send_algorithm_test.cc
@@ -120,42 +120,22 @@ const char* CongestionControlTypeToString(CongestionControlType cc_type) {
}
struct TestParams {
- explicit TestParams(CongestionControlType congestion_control_type,
- bool fix_convex_mode,
- bool fix_cubic_quantization,
- bool fix_beta_last_max,
- bool allow_per_ack_updates)
- : congestion_control_type(congestion_control_type),
- fix_convex_mode(fix_convex_mode),
- fix_cubic_quantization(fix_cubic_quantization),
- fix_beta_last_max(fix_beta_last_max),
- allow_per_ack_updates(allow_per_ack_updates) {}
+ explicit TestParams(CongestionControlType congestion_control_type)
+ : congestion_control_type(congestion_control_type) {}
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
os << "{ congestion_control_type: "
<< CongestionControlTypeToString(p.congestion_control_type);
- os << " fix_convex_mode: " << p.fix_convex_mode
- << " fix_cubic_quantization: " << p.fix_cubic_quantization
- << " fix_beta_last_max: " << p.fix_beta_last_max;
- os << " allow_per_ack_updates: " << p.allow_per_ack_updates;
os << " }";
return os;
}
- CongestionControlType congestion_control_type;
- bool fix_convex_mode;
- bool fix_cubic_quantization;
- bool fix_beta_last_max;
- bool allow_per_ack_updates;
+ const CongestionControlType congestion_control_type;
};
string TestParamToString(const testing::TestParamInfo<TestParams>& params) {
return QuicStrCat(
- CongestionControlTypeToString(params.param.congestion_control_type), "_",
- "convex_mode_", params.param.fix_convex_mode, "_", "cubic_quantization_",
- params.param.fix_cubic_quantization, "_", "beta_last_max_",
- params.param.fix_beta_last_max, "_", "allow_per_ack_updates_",
- params.param.allow_per_ack_updates);
+ CongestionControlTypeToString(params.param.congestion_control_type), "_");
}
// Constructs various test permutations.
@@ -163,13 +143,7 @@ std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
for (const CongestionControlType congestion_control_type :
{kBBR, kCubicBytes, kRenoBytes, kPCC}) {
- params.push_back(
- TestParams(congestion_control_type, false, false, false, false));
- if (congestion_control_type != kCubicBytes) {
- continue;
- }
- params.push_back(
- TestParams(congestion_control_type, true, true, true, true));
+ params.push_back(TestParams(congestion_control_type));
}
return params;
}
@@ -199,8 +173,6 @@ class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
GetParam().congestion_control_type, &random_, &stats_,
kInitialCongestionWindowPackets);
- SetExperimentalOptionsInServerConfig();
-
QuicConnectionPeer::SetSendAlgorithm(quic_sender_.connection(), sender_);
// TODO(jokulik): Remove once b/38032710 is fixed.
// Disable pacing for PCC.
@@ -217,30 +189,6 @@ class SendAlgorithmTest : public QuicTestWithParam<TestParams> {
QUIC_LOG(INFO) << "SendAlgorithmTest simulator set up. Seed: " << seed;
}
- // Sets experimental options in the server config, as if they had
- // been sent by the client.
- void SetExperimentalOptionsInServerConfig() {
- QuicConfig client_config;
- QuicTagVector options;
- if (GetParam().fix_convex_mode) {
- options.push_back(kCCVX);
- }
- if (GetParam().fix_cubic_quantization) {
- options.push_back(kCBQT);
- }
- if (GetParam().fix_beta_last_max) {
- options.push_back(kBLMX);
- }
- if (GetParam().allow_per_ack_updates) {
- options.push_back(kCPAU);
- }
-
- if (!options.empty()) {
- client_config.SetInitialReceivedConnectionOptions(options);
- sender_->SetFromConfig(client_config, Perspective::IS_SERVER);
- }
- }
-
// Creates a simulated network, with default settings between the
// sender and the switch and the given settings from the switch to
// the receiver.
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.cc b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.cc
deleted file mode 100644
index f76b0efceb5..00000000000
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.cc
+++ /dev/null
@@ -1,262 +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/quic/core/congestion_control/tcp_cubic_sender_base.h"
-
-#include <algorithm>
-
-#include "net/quic/core/congestion_control/prr_sender.h"
-#include "net/quic/core/congestion_control/rtt_stats.h"
-#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
-#include "net/quic/platform/api/quic_bug_tracker.h"
-
-namespace net {
-
-namespace {
-// Constants based on TCP defaults.
-// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
-// fast retransmission. The cwnd after a timeout is still 1.
-const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
-const float kRenoBeta = 0.7f; // Reno backoff factor.
-const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
-} // namespace
-
-TcpCubicSenderBase::TcpCubicSenderBase(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicConnectionStats* stats)
- : rtt_stats_(rtt_stats),
- stats_(stats),
- reno_(reno),
- num_connections_(kDefaultNumConnections),
- largest_sent_packet_number_(0),
- largest_acked_packet_number_(0),
- largest_sent_at_last_cutback_(0),
- min4_mode_(false),
- last_cutback_exited_slowstart_(false),
- slow_start_large_reduction_(false),
- no_prr_(false) {}
-
-TcpCubicSenderBase::~TcpCubicSenderBase() {}
-
-void TcpCubicSenderBase::SetFromConfig(const QuicConfig& config,
- Perspective perspective) {
- if (perspective == Perspective::IS_SERVER) {
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(3);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(10);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(20);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(50);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
- // Min CWND experiment.
- SetMinCongestionWindowInPackets(1);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
- // Min CWND of 4 experiment.
- min4_mode_ = true;
- SetMinCongestionWindowInPackets(1);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
- // Slow Start Fast Exit experiment.
- slow_start_large_reduction_ = true;
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
- // Use unity pacing instead of PRR.
- no_prr_ = true;
- }
- }
-}
-
-void TcpCubicSenderBase::AdjustNetworkParameters(QuicBandwidth bandwidth,
- QuicTime::Delta rtt) {
- if (bandwidth.IsZero() || rtt.IsZero()) {
- return;
- }
-
- SetCongestionWindowFromBandwidthAndRtt(bandwidth, rtt);
-}
-
-void TcpCubicSenderBase::SetNumEmulatedConnections(int num_connections) {
- num_connections_ = std::max(1, num_connections);
-}
-
-float TcpCubicSenderBase::RenoBeta() const {
- // kNConnectionBeta is the backoff factor after loss for our N-connection
- // emulation, which emulates the effective backoff of an ensemble of N
- // TCP-Reno connections on a single loss event. The effective multiplier is
- // computed as:
- return (num_connections_ - 1 + kRenoBeta) / num_connections_;
-}
-
-void TcpCubicSenderBase::OnCongestionEvent(
- bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) {
- if (rtt_updated && InSlowStart() &&
- hybrid_slow_start_.ShouldExitSlowStart(
- rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
- GetCongestionWindow() / kDefaultTCPMSS)) {
- ExitSlowstart();
- }
- for (const LostPacket& lost_packet : lost_packets) {
- OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
- prior_in_flight);
- }
- for (const AckedPacket acked_packet : acked_packets) {
- OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
- prior_in_flight, event_time);
- }
-}
-
-void TcpCubicSenderBase::OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time) {
- largest_acked_packet_number_ =
- std::max(acked_packet_number, largest_acked_packet_number_);
- if (InRecovery()) {
- if (!no_prr_) {
- // PRR is used when in recovery.
- prr_.OnPacketAcked(acked_bytes);
- }
- return;
- }
- MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
- event_time);
- if (InSlowStart()) {
- hybrid_slow_start_.OnPacketAcked(acked_packet_number);
- }
-}
-
-void TcpCubicSenderBase::OnPacketSent(
- QuicTime /*sent_time*/,
- QuicByteCount /*bytes_in_flight*/,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) {
- if (InSlowStart()) {
- ++(stats_->slowstart_packets_sent);
- }
-
- if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
- return;
- }
- if (InRecovery()) {
- // PRR is used when in recovery.
- prr_.OnPacketSent(bytes);
- }
- DCHECK_LT(largest_sent_packet_number_, packet_number);
- largest_sent_packet_number_ = packet_number;
- hybrid_slow_start_.OnPacketSent(packet_number);
-}
-
-bool TcpCubicSenderBase::CanSend(QuicByteCount bytes_in_flight) {
- if (!no_prr_ && InRecovery()) {
- // PRR is used when in recovery.
- return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
- GetSlowStartThreshold());
- }
- if (GetCongestionWindow() > bytes_in_flight) {
- return true;
- }
- if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
- return true;
- }
- return false;
-}
-
-QuicBandwidth TcpCubicSenderBase::PacingRate(
- QuicByteCount /* bytes_in_flight */) const {
- // We pace at twice the rate of the underlying sender's bandwidth estimate
- // during slow start and 1.25x during congestion avoidance to ensure pacing
- // doesn't prevent us from filling the window.
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us());
- }
- const QuicBandwidth bandwidth =
- QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
- return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
-}
-
-QuicBandwidth TcpCubicSenderBase::BandwidthEstimate() const {
- QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
- if (srtt.IsZero()) {
- // If we haven't measured an rtt, the bandwidth estimate is unknown.
- return QuicBandwidth::Zero();
- }
- return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
-}
-
-bool TcpCubicSenderBase::InSlowStart() const {
- return GetCongestionWindow() < GetSlowStartThreshold();
-}
-
-bool TcpCubicSenderBase::IsCwndLimited(QuicByteCount bytes_in_flight) const {
- const QuicByteCount congestion_window = GetCongestionWindow();
- if (bytes_in_flight >= congestion_window) {
- return true;
- }
- const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
- const bool slow_start_limited =
- InSlowStart() && bytes_in_flight > congestion_window / 2;
- return slow_start_limited || available_bytes <= kMaxBurstBytes;
-}
-
-bool TcpCubicSenderBase::InRecovery() const {
- return largest_acked_packet_number_ <= largest_sent_at_last_cutback_ &&
- largest_acked_packet_number_ != 0;
-}
-
-bool TcpCubicSenderBase::IsProbingForMoreBandwidth() const {
- return false;
-}
-
-void TcpCubicSenderBase::OnRetransmissionTimeout(bool packets_retransmitted) {
- largest_sent_at_last_cutback_ = 0;
- if (!packets_retransmitted) {
- return;
- }
- hybrid_slow_start_.Restart();
- HandleRetransmissionTimeout();
-}
-
-void TcpCubicSenderBase::OnConnectionMigration() {
- hybrid_slow_start_.Restart();
- prr_ = PrrSender();
- largest_sent_packet_number_ = 0;
- largest_acked_packet_number_ = 0;
- largest_sent_at_last_cutback_ = 0;
- last_cutback_exited_slowstart_ = false;
-}
-
-std::string TcpCubicSenderBase::GetDebugState() const {
- return "";
-}
-
-void TcpCubicSenderBase::OnApplicationLimited(QuicByteCount bytes_in_flight) {}
-
-} // namespace net
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.h b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.h
deleted file mode 100644
index 721662c50fe..00000000000
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_base.h
+++ /dev/null
@@ -1,158 +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.
-//
-// TCP cubic send side congestion algorithm, emulates the behavior of TCP cubic.
-
-#ifndef NET_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BASE_H_
-#define NET_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BASE_H_
-
-#include <cstdint>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "net/quic/core/congestion_control/hybrid_slow_start.h"
-#include "net/quic/core/congestion_control/prr_sender.h"
-#include "net/quic/core/congestion_control/send_algorithm_interface.h"
-#include "net/quic/core/quic_bandwidth.h"
-#include "net/quic/core/quic_connection_stats.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_time.h"
-#include "net/quic/platform/api/quic_export.h"
-
-namespace net {
-
-class RttStats;
-
-// Maximum window to allow when doing bandwidth resumption.
-const QuicPacketCount kMaxResumptionCongestionWindow = 200;
-
-namespace test {
-class TcpCubicSenderBasePeer;
-} // namespace test
-
-class QUIC_EXPORT_PRIVATE TcpCubicSenderBase : public SendAlgorithmInterface {
- public:
- // Reno option and max_tcp_congestion_window are provided for testing.
- TcpCubicSenderBase(const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicConnectionStats* stats);
-
- ~TcpCubicSenderBase() override;
-
- // Start implementation of SendAlgorithmInterface.
- void SetFromConfig(const QuicConfig& config,
- Perspective perspective) override;
- void AdjustNetworkParameters(QuicBandwidth bandwidth,
- QuicTime::Delta rtt) override;
- void SetNumEmulatedConnections(int num_connections) override;
- void OnCongestionEvent(bool rtt_updated,
- QuicByteCount prior_in_flight,
- QuicTime event_time,
- const AckedPacketVector& acked_packets,
- const LostPacketVector& lost_packets) override;
- void OnPacketSent(QuicTime sent_time,
- QuicByteCount bytes_in_flight,
- QuicPacketNumber packet_number,
- QuicByteCount bytes,
- HasRetransmittableData is_retransmittable) override;
- void OnRetransmissionTimeout(bool packets_retransmitted) override;
- void OnConnectionMigration() override;
- bool CanSend(QuicByteCount bytes_in_flight) override;
- QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
- QuicBandwidth BandwidthEstimate() const override;
- bool InSlowStart() const override;
- bool InRecovery() const override;
- bool IsProbingForMoreBandwidth() const override;
- std::string GetDebugState() const override;
- void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
-
- protected:
- // Called when resuming a previous bandwidth.
- virtual void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
- QuicTime::Delta rtt) = 0;
-
- // Called when initializing the congestion window.
- virtual void SetCongestionWindowInPackets(
- QuicPacketCount congestion_window) = 0;
-
- // Called when initializing the minimum congestion window.
- virtual void SetMinCongestionWindowInPackets(
- QuicPacketCount congestion_window) = 0;
-
- // Called when slow start is exited to set SSTHRESH.
- virtual void ExitSlowstart() = 0;
-
- // Called when a packet is lost.
- virtual void OnPacketLost(QuicPacketNumber largest_loss,
- QuicByteCount lost_bytes,
- QuicByteCount prior_in_flight) = 0;
-
- // Called when a packet has been acked to possibly increase the congestion
- // window.
- virtual void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time) = 0;
-
- // Called when a retransmission has occured which resulted in packets
- // being retransmitted.
- virtual void HandleRetransmissionTimeout() = 0;
-
- // Compute the TCP Reno beta based on the current number of connections.
- float RenoBeta() const;
-
- bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
-
- private:
- friend class test::TcpCubicSenderBasePeer;
-
- // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
- void OnPacketAcked(QuicPacketNumber acked_packet_number,
- QuicByteCount acked_bytes,
- QuicByteCount prior_in_flight,
- QuicTime event_time);
-
- protected:
- // TODO(rch): Make these private and clean up subclass access to them.
- HybridSlowStart hybrid_slow_start_;
- PrrSender prr_;
- const RttStats* rtt_stats_;
- QuicConnectionStats* stats_;
-
- // If true, Reno congestion control is used instead of Cubic.
- const bool reno_;
-
- // Number of connections to simulate.
- uint32_t num_connections_;
-
- // Track the largest packet that has been sent.
- QuicPacketNumber largest_sent_packet_number_;
-
- // Track the largest packet that has been acked.
- QuicPacketNumber largest_acked_packet_number_;
-
- // Track the largest packet number outstanding when a CWND cutback occurs.
- QuicPacketNumber largest_sent_at_last_cutback_;
-
- // Whether to use 4 packets as the actual min, but pace lower.
- bool min4_mode_;
-
- // Whether the last loss event caused us to exit slowstart.
- // Used for stats collection of slowstart_packets_lost
- bool last_cutback_exited_slowstart_;
-
- // When true, exit slow start with large cutback of congestion window.
- bool slow_start_large_reduction_;
-
- // When true, use unity pacing instead of PRR.
- bool no_prr_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TcpCubicSenderBase);
-};
-
-} // namespace net
-
-#endif // NET_QUIC_CORE_CONGESTION_CONTROL_TCP_CUBIC_SENDER_BASE_H_
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
index 60063a4fcda..1cb6e772ceb 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -18,6 +18,9 @@ namespace net {
namespace {
// Constants based on TCP defaults.
+const QuicByteCount kMaxBurstBytes = 3 * kDefaultTCPMSS;
+const float kRenoBeta = 0.7f; // Reno backoff factor.
+const uint32_t kDefaultNumConnections = 2; // N-connection emulation.
// The minimum cwnd based on RFC 3782 (TCP NewReno) for cwnd reductions on a
// fast retransmission.
const QuicByteCount kDefaultMinimumCongestionWindow = 2 * kDefaultTCPMSS;
@@ -30,7 +33,17 @@ TcpCubicSenderBytes::TcpCubicSenderBytes(
QuicPacketCount initial_tcp_congestion_window,
QuicPacketCount max_congestion_window,
QuicConnectionStats* stats)
- : TcpCubicSenderBase(clock, rtt_stats, reno, stats),
+ : rtt_stats_(rtt_stats),
+ stats_(stats),
+ reno_(reno),
+ num_connections_(kDefaultNumConnections),
+ largest_sent_packet_number_(0),
+ largest_acked_packet_number_(0),
+ largest_sent_at_last_cutback_(0),
+ min4_mode_(false),
+ last_cutback_exited_slowstart_(false),
+ slow_start_large_reduction_(false),
+ no_prr_(false),
cubic_(clock),
num_acked_packets_(0),
congestion_window_(initial_tcp_congestion_window * kDefaultTCPMSS),
@@ -47,25 +60,209 @@ TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
- TcpCubicSenderBase::SetFromConfig(config, perspective);
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kCCVX)) {
- cubic_.SetFixConvexMode(true);
+ if (perspective == Perspective::IS_SERVER) {
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
+ // Initial window experiment.
+ SetCongestionWindowInPackets(3);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
+ // Initial window experiment.
+ SetCongestionWindowInPackets(10);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
+ // Initial window experiment.
+ SetCongestionWindowInPackets(20);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
+ // Initial window experiment.
+ SetCongestionWindowInPackets(50);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
+ // Min CWND experiment.
+ SetMinCongestionWindowInPackets(1);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
+ // Min CWND of 4 experiment.
+ min4_mode_ = true;
+ SetMinCongestionWindowInPackets(1);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kSSLR)) {
+ // Slow Start Fast Exit experiment.
+ slow_start_large_reduction_ = true;
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kNPRR)) {
+ // Use unity pacing instead of PRR.
+ no_prr_ = true;
+ }
+ }
+}
+
+void TcpCubicSenderBytes::AdjustNetworkParameters(QuicBandwidth bandwidth,
+ QuicTime::Delta rtt) {
+ if (bandwidth.IsZero() || rtt.IsZero()) {
+ return;
+ }
+
+ SetCongestionWindowFromBandwidthAndRtt(bandwidth, rtt);
+}
+
+float TcpCubicSenderBytes::RenoBeta() const {
+ // kNConnectionBeta is the backoff factor after loss for our N-connection
+ // emulation, which emulates the effective backoff of an ensemble of N
+ // TCP-Reno connections on a single loss event. The effective multiplier is
+ // computed as:
+ return (num_connections_ - 1 + kRenoBeta) / num_connections_;
+}
+
+void TcpCubicSenderBytes::OnCongestionEvent(
+ bool rtt_updated,
+ QuicByteCount prior_in_flight,
+ QuicTime event_time,
+ const AckedPacketVector& acked_packets,
+ const LostPacketVector& lost_packets) {
+ if (rtt_updated && InSlowStart() &&
+ hybrid_slow_start_.ShouldExitSlowStart(
+ rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
+ GetCongestionWindow() / kDefaultTCPMSS)) {
+ ExitSlowstart();
+ }
+ for (const LostPacket& lost_packet : lost_packets) {
+ OnPacketLost(lost_packet.packet_number, lost_packet.bytes_lost,
+ prior_in_flight);
+ }
+ for (const AckedPacket acked_packet : acked_packets) {
+ OnPacketAcked(acked_packet.packet_number, acked_packet.bytes_acked,
+ prior_in_flight, event_time);
+ }
+}
+
+void TcpCubicSenderBytes::OnPacketAcked(QuicPacketNumber acked_packet_number,
+ QuicByteCount acked_bytes,
+ QuicByteCount prior_in_flight,
+ QuicTime event_time) {
+ largest_acked_packet_number_ =
+ std::max(acked_packet_number, largest_acked_packet_number_);
+ if (InRecovery()) {
+ if (!no_prr_) {
+ // PRR is used when in recovery.
+ prr_.OnPacketAcked(acked_bytes);
+ }
+ return;
+ }
+ MaybeIncreaseCwnd(acked_packet_number, acked_bytes, prior_in_flight,
+ event_time);
+ if (InSlowStart()) {
+ hybrid_slow_start_.OnPacketAcked(acked_packet_number);
+ }
+}
+
+void TcpCubicSenderBytes::OnPacketSent(
+ QuicTime /*sent_time*/,
+ QuicByteCount /*bytes_in_flight*/,
+ QuicPacketNumber packet_number,
+ QuicByteCount bytes,
+ HasRetransmittableData is_retransmittable) {
+ if (InSlowStart()) {
+ ++(stats_->slowstart_packets_sent);
+ }
+
+ if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) {
+ return;
+ }
+ if (InRecovery()) {
+ // PRR is used when in recovery.
+ prr_.OnPacketSent(bytes);
}
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kCBQT)) {
- cubic_.SetFixCubicQuantization(true);
+ DCHECK_LT(largest_sent_packet_number_, packet_number);
+ largest_sent_packet_number_ = packet_number;
+ hybrid_slow_start_.OnPacketSent(packet_number);
+}
+
+bool TcpCubicSenderBytes::CanSend(QuicByteCount bytes_in_flight) {
+ if (!no_prr_ && InRecovery()) {
+ // PRR is used when in recovery.
+ return prr_.CanSend(GetCongestionWindow(), bytes_in_flight,
+ GetSlowStartThreshold());
+ }
+ if (GetCongestionWindow() > bytes_in_flight) {
+ return true;
+ }
+ if (min4_mode_ && bytes_in_flight < 4 * kDefaultTCPMSS) {
+ return true;
+ }
+ return false;
+}
+
+QuicBandwidth TcpCubicSenderBytes::PacingRate(
+ QuicByteCount /* bytes_in_flight */) const {
+ // We pace at twice the rate of the underlying sender's bandwidth estimate
+ // during slow start and 1.25x during congestion avoidance to ensure pacing
+ // doesn't prevent us from filling the window.
+ QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
+ if (srtt.IsZero()) {
+ srtt = QuicTime::Delta::FromMicroseconds(rtt_stats_->initial_rtt_us());
+ }
+ const QuicBandwidth bandwidth =
+ QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+ return bandwidth * (InSlowStart() ? 2 : (no_prr_ && InRecovery() ? 1 : 1.25));
+}
+
+QuicBandwidth TcpCubicSenderBytes::BandwidthEstimate() const {
+ QuicTime::Delta srtt = rtt_stats_->smoothed_rtt();
+ if (srtt.IsZero()) {
+ // If we haven't measured an rtt, the bandwidth estimate is unknown.
+ return QuicBandwidth::Zero();
}
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kBLMX)) {
- cubic_.SetFixBetaLastMax(true);
+ return QuicBandwidth::FromBytesAndTimeDelta(GetCongestionWindow(), srtt);
+}
+
+bool TcpCubicSenderBytes::InSlowStart() const {
+ return GetCongestionWindow() < GetSlowStartThreshold();
+}
+
+bool TcpCubicSenderBytes::IsCwndLimited(QuicByteCount bytes_in_flight) const {
+ const QuicByteCount congestion_window = GetCongestionWindow();
+ if (bytes_in_flight >= congestion_window) {
+ return true;
}
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kCPAU)) {
- cubic_.SetAllowPerAckUpdates(true);
+ const QuicByteCount available_bytes = congestion_window - bytes_in_flight;
+ const bool slow_start_limited =
+ InSlowStart() && bytes_in_flight > congestion_window / 2;
+ return slow_start_limited || available_bytes <= kMaxBurstBytes;
+}
+
+bool TcpCubicSenderBytes::InRecovery() const {
+ return largest_acked_packet_number_ <= largest_sent_at_last_cutback_ &&
+ largest_acked_packet_number_ != 0;
+}
+
+bool TcpCubicSenderBytes::IsProbingForMoreBandwidth() const {
+ return false;
+}
+
+void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
+ largest_sent_at_last_cutback_ = 0;
+ if (!packets_retransmitted) {
+ return;
}
+ hybrid_slow_start_.Restart();
+ HandleRetransmissionTimeout();
}
+std::string TcpCubicSenderBytes::GetDebugState() const {
+ return "";
+}
+
+void TcpCubicSenderBytes::OnApplicationLimited(QuicByteCount bytes_in_flight) {}
+
void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
QuicBandwidth bandwidth,
QuicTime::Delta rtt) {
@@ -88,7 +285,7 @@ void TcpCubicSenderBytes::SetMinCongestionWindowInPackets(
}
void TcpCubicSenderBytes::SetNumEmulatedConnections(int num_connections) {
- TcpCubicSenderBase::SetNumEmulatedConnections(num_connections);
+ num_connections_ = std::max(1, num_connections);
cubic_.SetNumConnections(num_connections_);
}
@@ -215,7 +412,12 @@ void TcpCubicSenderBytes::HandleRetransmissionTimeout() {
}
void TcpCubicSenderBytes::OnConnectionMigration() {
- TcpCubicSenderBase::OnConnectionMigration();
+ hybrid_slow_start_.Restart();
+ prr_ = PrrSender();
+ largest_sent_packet_number_ = 0;
+ largest_acked_packet_number_ = 0;
+ largest_sent_at_last_cutback_ = 0;
+ last_cutback_exited_slowstart_ = false;
cubic_.ResetCubicState();
num_acked_packets_ = 0;
congestion_window_ = initial_tcp_congestion_window_;
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index d49543f71a9..83189bfcf14 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -13,7 +13,7 @@
#include "net/quic/core/congestion_control/cubic_bytes.h"
#include "net/quic/core/congestion_control/hybrid_slow_start.h"
#include "net/quic/core/congestion_control/prr_sender.h"
-#include "net/quic/core/congestion_control/tcp_cubic_sender_base.h"
+#include "net/quic/core/congestion_control/send_algorithm_interface.h"
#include "net/quic/core/quic_bandwidth.h"
#include "net/quic/core/quic_connection_stats.h"
#include "net/quic/core/quic_packets.h"
@@ -24,11 +24,14 @@ namespace net {
class RttStats;
+// Maximum window to allow when doing bandwidth resumption.
+const QuicPacketCount kMaxResumptionCongestionWindow = 200;
+
namespace test {
class TcpCubicSenderBytesPeer;
} // namespace test
-class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public TcpCubicSenderBase {
+class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
public:
TcpCubicSenderBytes(const QuicClock* clock,
const RttStats* rtt_stats,
@@ -41,35 +44,97 @@ class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public TcpCubicSenderBase {
// Start implementation of SendAlgorithmInterface.
void SetFromConfig(const QuicConfig& config,
Perspective perspective) override;
+ void AdjustNetworkParameters(QuicBandwidth bandwidth,
+ QuicTime::Delta rtt) override;
void SetNumEmulatedConnections(int num_connections) override;
void OnConnectionMigration() override;
+ void OnCongestionEvent(bool rtt_updated,
+ QuicByteCount prior_in_flight,
+ QuicTime event_time,
+ const AckedPacketVector& acked_packets,
+ const LostPacketVector& lost_packets) override;
+ void OnPacketSent(QuicTime sent_time,
+ QuicByteCount bytes_in_flight,
+ QuicPacketNumber packet_number,
+ QuicByteCount bytes,
+ HasRetransmittableData is_retransmittable) override;
+ void OnRetransmissionTimeout(bool packets_retransmitted) override;
+ bool CanSend(QuicByteCount bytes_in_flight) override;
+ QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;
+ QuicBandwidth BandwidthEstimate() const override;
QuicByteCount GetCongestionWindow() const override;
QuicByteCount GetSlowStartThreshold() const override;
CongestionControlType GetCongestionControlType() const override;
+ bool InSlowStart() const override;
+ bool InRecovery() const override;
+ bool IsProbingForMoreBandwidth() const override;
+ std::string GetDebugState() const override;
+ void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
// End implementation of SendAlgorithmInterface.
QuicByteCount min_congestion_window() const { return min_congestion_window_; }
protected:
- // TcpCubicSenderBase methods
+ // Compute the TCP Reno beta based on the current number of connections.
+ float RenoBeta() const;
+
+ bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
+
+ // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
+ void OnPacketAcked(QuicPacketNumber acked_packet_number,
+ QuicByteCount acked_bytes,
+ QuicByteCount prior_in_flight,
+ QuicTime event_time);
void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
- QuicTime::Delta rtt) override;
- void SetCongestionWindowInPackets(QuicPacketCount congestion_window) override;
- void SetMinCongestionWindowInPackets(
- QuicPacketCount congestion_window) override;
- void ExitSlowstart() override;
+ QuicTime::Delta rtt);
+ void SetCongestionWindowInPackets(QuicPacketCount congestion_window);
+ void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
+ void ExitSlowstart();
void OnPacketLost(QuicPacketNumber largest_loss,
QuicByteCount lost_bytes,
- QuicByteCount prior_in_flight) override;
+ QuicByteCount prior_in_flight);
void MaybeIncreaseCwnd(QuicPacketNumber acked_packet_number,
QuicByteCount acked_bytes,
QuicByteCount prior_in_flight,
- QuicTime event_time) override;
- void HandleRetransmissionTimeout() override;
+ QuicTime event_time);
+ void HandleRetransmissionTimeout();
private:
friend class test::TcpCubicSenderBytesPeer;
+ HybridSlowStart hybrid_slow_start_;
+ PrrSender prr_;
+ const RttStats* rtt_stats_;
+ QuicConnectionStats* stats_;
+
+ // If true, Reno congestion control is used instead of Cubic.
+ const bool reno_;
+
+ // Number of connections to simulate.
+ uint32_t num_connections_;
+
+ // Track the largest packet that has been sent.
+ QuicPacketNumber largest_sent_packet_number_;
+
+ // Track the largest packet that has been acked.
+ QuicPacketNumber largest_acked_packet_number_;
+
+ // Track the largest packet number outstanding when a CWND cutback occurs.
+ QuicPacketNumber largest_sent_at_last_cutback_;
+
+ // Whether to use 4 packets as the actual min, but pace lower.
+ bool min4_mode_;
+
+ // Whether the last loss event caused us to exit slowstart.
+ // Used for stats collection of slowstart_packets_lost
+ bool last_cutback_exited_slowstart_;
+
+ // When true, exit slow start with large cutback of congestion window.
+ bool slow_start_large_reduction_;
+
+ // When true, use unity pacing instead of PRR.
+ bool no_prr_;
+
CubicBytes cubic_;
// ACK counter for the Reno implementation.
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
index 1cd69ab1c7b..4bdcf440b12 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -11,7 +11,6 @@
#include "net/quic/core/congestion_control/rtt_stats.h"
#include "net/quic/core/congestion_control/send_algorithm_interface.h"
#include "net/quic/core/crypto/crypto_protocol.h"
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_logging.h"
@@ -805,13 +804,9 @@ TEST_F(TcpCubicSenderBytesTest, LimitCwndIncreaseInCongestionAvoidance) {
AckNPackets(1);
SendAvailableSendWindow();
}
- if (FLAGS_quic_reloadable_flag_quic_enable_cubic_fixes) {
- // Bytes in flight may be larger than the CWND if the CWND isn't an exact
- // multiple of the packet sizes being sent.
- EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
- } else {
- EXPECT_EQ(bytes_in_flight_, sender_->GetCongestionWindow());
- }
+ // Bytes in flight may be larger than the CWND if the CWND isn't an exact
+ // multiple of the packet sizes being sent.
+ EXPECT_GE(bytes_in_flight_, sender_->GetCongestionWindow());
saved_cwnd = sender_->GetCongestionWindow();
// Advance time 2 seconds waiting for an ack.
diff --git a/chromium/net/quic/core/crypto/aead_base_decrypter.cc b/chromium/net/quic/core/crypto/aead_base_decrypter.cc
index 7fa1f692d0d..c036441c778 100644
--- a/chromium/net/quic/core/crypto/aead_base_decrypter.cc
+++ b/chromium/net/quic/core/crypto/aead_base_decrypter.cc
@@ -7,6 +7,7 @@
#include <cstdint>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
#include "third_party/boringssl/src/include/openssl/err.h"
@@ -32,7 +33,7 @@ void DLogOpenSslErrors() {
#else
while (uint32_t error = ERR_get_error()) {
char buf[120];
- ERR_error_string_n(error, buf, arraysize(buf));
+ ERR_error_string_n(error, buf, QUIC_ARRAYSIZE(buf));
QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
}
#endif
@@ -175,6 +176,14 @@ bool AeadBaseDecrypter::DecryptPacket(QuicTransportVersion /*version*/,
return true;
}
+size_t AeadBaseDecrypter::GetKeySize() const {
+ return key_size_;
+}
+
+size_t AeadBaseDecrypter::GetIVSize() const {
+ return nonce_size_;
+}
+
QuicStringPiece AeadBaseDecrypter::GetKey() const {
return QuicStringPiece(reinterpret_cast<const char*>(key_), key_size_);
}
diff --git a/chromium/net/quic/core/crypto/aead_base_decrypter.h b/chromium/net/quic/core/crypto/aead_base_decrypter.h
index 5e983007b8c..66c5b3499df 100644
--- a/chromium/net/quic/core/crypto/aead_base_decrypter.h
+++ b/chromium/net/quic/core/crypto/aead_base_decrypter.h
@@ -39,6 +39,8 @@ class QUIC_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
char* output,
size_t* output_length,
size_t max_output_length) override;
+ size_t GetKeySize() const override;
+ size_t GetIVSize() const override;
QuicStringPiece GetKey() const override;
QuicStringPiece GetNoncePrefix() const override;
diff --git a/chromium/net/quic/core/crypto/aead_base_encrypter.cc b/chromium/net/quic/core/crypto/aead_base_encrypter.cc
index c7303165a7a..50a66166ace 100644
--- a/chromium/net/quic/core/crypto/aead_base_encrypter.cc
+++ b/chromium/net/quic/core/crypto/aead_base_encrypter.cc
@@ -8,6 +8,7 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_aligned.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
#include "third_party/boringssl/src/include/openssl/err.h"
@@ -26,7 +27,7 @@ void DLogOpenSslErrors() {
#else
while (unsigned long error = ERR_get_error()) {
char buf[120];
- ERR_error_string_n(error, buf, arraysize(buf));
+ ERR_error_string_n(error, buf, QUIC_ARRAYSIZE(buf));
QUIC_DLOG(ERROR) << "OpenSSL error: " << buf;
}
#endif
@@ -157,6 +158,10 @@ size_t AeadBaseEncrypter::GetNoncePrefixSize() const {
return nonce_size_ - sizeof(QuicPacketNumber);
}
+size_t AeadBaseEncrypter::GetIVSize() const {
+ return nonce_size_;
+}
+
size_t AeadBaseEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
return ciphertext_size - auth_tag_size_;
}
diff --git a/chromium/net/quic/core/crypto/aead_base_encrypter.h b/chromium/net/quic/core/crypto/aead_base_encrypter.h
index 748bc461158..c9cadd987a7 100644
--- a/chromium/net/quic/core/crypto/aead_base_encrypter.h
+++ b/chromium/net/quic/core/crypto/aead_base_encrypter.h
@@ -39,6 +39,7 @@ class QUIC_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
size_t max_output_length) override;
size_t GetKeySize() const override;
size_t GetNoncePrefixSize() const override;
+ size_t GetIVSize() const override;
size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
size_t GetCiphertextSize(size_t plaintext_size) const override;
QuicStringPiece GetKey() const override;
diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter.cc b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter.cc
index 7bad0551d38..a8910b1d49c 100644
--- a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter.cc
+++ b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter.cc
@@ -4,8 +4,6 @@
#include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h"
-#include "net/quic/platform/api/quic_flag_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
#include "third_party/boringssl/src/include/openssl/aead.h"
#include "third_party/boringssl/src/include/openssl/tls1.h"
@@ -31,11 +29,7 @@ Aes128Gcm12Decrypter::Aes128Gcm12Decrypter()
Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {}
uint32_t Aes128Gcm12Decrypter::cipher_id() const {
- if (FLAGS_quic_reloadable_flag_quic_use_tls13_cipher_suites) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_tls13_cipher_suites);
- return TLS1_CK_AES_128_GCM_SHA256;
- }
- return TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
+ return TLS1_CK_AES_128_GCM_SHA256;
}
} // namespace net
diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
index 3f439767bc5..44aa748e475 100644
--- a/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -212,7 +213,7 @@ QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
std::unique_ptr<char[]> output(new char[ciphertext.length()]);
size_t output_length = 0;
const bool success = decrypter->DecryptPacket(
- QuicVersionMax(), packet_number, associated_data, ciphertext,
+ QuicTransportVersionMax(), packet_number, associated_data, ciphertext,
output.get(), &output_length, ciphertext.length());
if (!success) {
return nullptr;
@@ -223,7 +224,7 @@ QuicData* DecryptWithNonce(Aes128Gcm12Decrypter* decrypter,
class Aes128Gcm12DecrypterTest : public QuicTest {};
TEST_F(Aes128Gcm12DecrypterTest, Decrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/chromium/net/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
index 029a278b36c..e51e376c8e7 100644
--- a/chromium/net/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -175,7 +176,7 @@ QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter,
class Aes128Gcm12EncrypterTest : public QuicTest {};
TEST_F(Aes128Gcm12EncrypterTest, Encrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/chromium/net/quic/core/crypto/aes_128_gcm_decrypter_test.cc
index 336d5d800b4..86474c986ba 100644
--- a/chromium/net/quic/core/crypto/aes_128_gcm_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_128_gcm_decrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -207,7 +208,7 @@ QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
std::unique_ptr<char[]> output(new char[ciphertext.length()]);
size_t output_length = 0;
const bool success = decrypter->DecryptPacket(
- QuicVersionMax(), 0, associated_data, ciphertext, output.get(),
+ QuicTransportVersionMax(), 0, associated_data, ciphertext, output.get(),
&output_length, ciphertext.length());
if (!success) {
return nullptr;
@@ -218,7 +219,7 @@ QuicData* DecryptWithNonce(Aes128GcmDecrypter* decrypter,
class Aes128GcmDecrypterTest : public QuicTest {};
TEST_F(Aes128GcmDecrypterTest, Decrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/chromium/net/quic/core/crypto/aes_128_gcm_encrypter_test.cc
index 7d770fad0fb..fb752f79d1e 100644
--- a/chromium/net/quic/core/crypto/aes_128_gcm_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_128_gcm_encrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -175,7 +176,7 @@ QuicData* EncryptWithNonce(Aes128GcmEncrypter* encrypter,
class Aes128GcmEncrypterTest : public QuicTest {};
TEST_F(Aes128GcmEncrypterTest, Encrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/chromium/net/quic/core/crypto/aes_256_gcm_decrypter_test.cc
index 90adceee721..c52767bbd53 100644
--- a/chromium/net/quic/core/crypto/aes_256_gcm_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_256_gcm_decrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -211,7 +212,7 @@ QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
std::unique_ptr<char[]> output(new char[ciphertext.length()]);
size_t output_length = 0;
const bool success = decrypter->DecryptPacket(
- QuicVersionMax(), 0, associated_data, ciphertext, output.get(),
+ QuicTransportVersionMax(), 0, associated_data, ciphertext, output.get(),
&output_length, ciphertext.length());
if (!success) {
return nullptr;
@@ -222,7 +223,7 @@ QuicData* DecryptWithNonce(Aes256GcmDecrypter* decrypter,
class Aes256GcmDecrypterTest : public QuicTest {};
TEST_F(Aes256GcmDecrypterTest, Decrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/chromium/net/quic/core/crypto/aes_256_gcm_encrypter_test.cc
index 16683cc5cd2..cea40bd777f 100644
--- a/chromium/net/quic/core/crypto/aes_256_gcm_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/aes_256_gcm_encrypter_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -182,7 +183,7 @@ QuicData* EncryptWithNonce(Aes256GcmEncrypter* encrypter,
class Aes256GcmEncrypterTest : public QuicTest {};
TEST_F(Aes256GcmEncrypterTest, Encrypt) {
- for (size_t i = 0; i < arraysize(test_group_array); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_group_array); i++) {
SCOPED_TRACE(i);
const TestVector* test_vectors = test_group_array[i];
const TestGroupInfo& test_info = test_group_info[i];
diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc
index f28b1b6a8db..ec37f86d269 100644
--- a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc
+++ b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter.cc
@@ -4,8 +4,6 @@
#include "net/quic/core/crypto/chacha20_poly1305_decrypter.h"
-#include "net/quic/platform/api/quic_flag_utils.h"
-#include "net/quic/platform/api/quic_flags.h"
#include "third_party/boringssl/src/include/openssl/aead.h"
#include "third_party/boringssl/src/include/openssl/tls1.h"
@@ -31,11 +29,7 @@ ChaCha20Poly1305Decrypter::ChaCha20Poly1305Decrypter()
ChaCha20Poly1305Decrypter::~ChaCha20Poly1305Decrypter() {}
uint32_t ChaCha20Poly1305Decrypter::cipher_id() const {
- if (FLAGS_quic_reloadable_flag_quic_use_tls13_cipher_suites) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_tls13_cipher_suites);
- return TLS1_CK_CHACHA20_POLY1305_SHA256;
- }
- return TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
+ return TLS1_CK_CHACHA20_POLY1305_SHA256;
}
} // namespace net
diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
index c9307450890..2a02280f5e8 100644
--- a/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
@@ -126,7 +126,7 @@ QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter,
std::unique_ptr<char[]> output(new char[ciphertext.length()]);
size_t output_length = 0;
const bool success = decrypter->DecryptPacket(
- QuicVersionMax(), packet_number, associated_data, ciphertext,
+ QuicTransportVersionMax(), packet_number, associated_data, ciphertext,
output.get(), &output_length, ciphertext.length());
if (!success) {
return nullptr;
diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
index 544ad0a6a22..e92e407f3c0 100644
--- a/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
@@ -8,6 +8,7 @@
#include "net/quic/core/crypto/chacha20_poly1305_decrypter.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -101,14 +102,14 @@ TEST_F(ChaCha20Poly1305EncrypterTest, EncryptThenDecrypt) {
string plaintext = "plaintext";
char encrypted[1024];
size_t len;
- ASSERT_TRUE(encrypter.EncryptPacket(QuicVersionMax(), packet_number,
+ ASSERT_TRUE(encrypter.EncryptPacket(QuicTransportVersionMax(), packet_number,
associated_data, plaintext, encrypted,
- &len, arraysize(encrypted)));
+ &len, QUIC_ARRAYSIZE(encrypted)));
QuicStringPiece ciphertext(encrypted, len);
char decrypted[1024];
- ASSERT_TRUE(decrypter.DecryptPacket(QuicVersionMax(), packet_number,
+ ASSERT_TRUE(decrypter.DecryptPacket(QuicTransportVersionMax(), packet_number,
associated_data, ciphertext, decrypted,
- &len, arraysize(decrypted)));
+ &len, QUIC_ARRAYSIZE(decrypted)));
}
TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
index 910f53ea3f3..4b2af650e0e 100644
--- a/chromium/net/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
@@ -121,7 +121,7 @@ QuicData* DecryptWithNonce(ChaCha20Poly1305TlsDecrypter* decrypter,
std::unique_ptr<char[]> output(new char[ciphertext.length()]);
size_t output_length = 0;
const bool success = decrypter->DecryptPacket(
- QuicVersionMax(), 0, associated_data, ciphertext, output.get(),
+ QuicTransportVersionMax(), 0, associated_data, ciphertext, output.get(),
&output_length, ciphertext.length());
if (!success) {
return nullptr;
diff --git a/chromium/net/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/chromium/net/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
index c4751763494..800b400cfe5 100644
--- a/chromium/net/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
@@ -8,6 +8,7 @@
#include "net/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -100,14 +101,14 @@ TEST_F(ChaCha20Poly1305TlsEncrypterTest, EncryptThenDecrypt) {
string plaintext = "plaintext";
char encrypted[1024];
size_t len;
- ASSERT_TRUE(encrypter.EncryptPacket(QuicVersionMax(), packet_number,
+ ASSERT_TRUE(encrypter.EncryptPacket(QuicTransportVersionMax(), packet_number,
associated_data, plaintext, encrypted,
- &len, arraysize(encrypted)));
+ &len, QUIC_ARRAYSIZE(encrypted)));
QuicStringPiece ciphertext(encrypted, len);
char decrypted[1024];
- ASSERT_TRUE(decrypter.DecryptPacket(QuicVersionMax(), packet_number,
+ ASSERT_TRUE(decrypter.DecryptPacket(QuicTransportVersionMax(), packet_number,
associated_data, ciphertext, decrypted,
- &len, arraysize(decrypted)));
+ &len, QUIC_ARRAYSIZE(decrypted)));
}
TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
diff --git a/chromium/net/quic/core/crypto/common_cert_set.cc b/chromium/net/quic/core/crypto/common_cert_set.cc
index 9ef68d8cc00..83c3e976706 100644
--- a/chromium/net/quic/core/crypto/common_cert_set.cc
+++ b/chromium/net/quic/core/crypto/common_cert_set.cc
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "net/quic/core/quic_utils.h"
-
+#include "net/quic/platform/api/quic_arraysize.h"
namespace net {
@@ -77,11 +77,11 @@ class CommonCertSetsQUIC : public CommonCertSets {
// CommonCertSets interface.
QuicStringPiece GetCommonHashes() const override {
return QuicStringPiece(reinterpret_cast<const char*>(kSetHashes),
- sizeof(uint64_t) * arraysize(kSetHashes));
+ sizeof(uint64_t) * QUIC_ARRAYSIZE(kSetHashes));
}
QuicStringPiece GetCert(uint64_t hash, uint32_t index) const override {
- for (size_t i = 0; i < arraysize(kSets); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kSets); i++) {
if (kSets[i].hash == hash) {
if (index < kSets[i].num_certs) {
return QuicStringPiece(
@@ -108,7 +108,7 @@ class CommonCertSetsQUIC : public CommonCertSets {
memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t),
sizeof(uint64_t));
- for (size_t j = 0; j < arraysize(kSets); j++) {
+ for (size_t j = 0; j < QUIC_ARRAYSIZE(kSets); j++) {
if (kSets[j].hash != hash) {
continue;
}
diff --git a/chromium/net/quic/core/crypto/crypto_framer_test.cc b/chromium/net/quic/core/crypto/crypto_framer_test.cc
index 9d61aa4ecf1..74691d0aab0 100644
--- a/chromium/net/quic/core/crypto/crypto_framer_test.cc
+++ b/chromium/net/quic/core/crypto/crypto_framer_test.cc
@@ -11,6 +11,7 @@
#include "net/quic/core/crypto/crypto_handshake.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -92,7 +93,7 @@ TEST_P(CryptoFramerTest, ConstructHandshakeMessage) {
ASSERT_TRUE(data.get() != nullptr);
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
@@ -129,7 +130,7 @@ TEST_P(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
@@ -157,7 +158,7 @@ TEST_P(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
@@ -209,7 +210,7 @@ TEST_P(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
@@ -246,7 +247,7 @@ TEST_P(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(CryptoFramerTest, ProcessInput) {
@@ -276,7 +277,7 @@ TEST_P(CryptoFramerTest, ProcessInput) {
};
EXPECT_TRUE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(0u, framer.InputBytesRemaining());
EXPECT_EQ(0, visitor.error_count_);
ASSERT_EQ(1u, visitor.messages_.size());
@@ -320,7 +321,7 @@ TEST_P(CryptoFramerTest, ProcessInputWithThreeKeys) {
};
EXPECT_TRUE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(0u, framer.InputBytesRemaining());
EXPECT_EQ(0, visitor.error_count_);
ASSERT_EQ(1u, visitor.messages_.size());
@@ -358,7 +359,7 @@ TEST_P(CryptoFramerTest, ProcessInputIncrementally) {
'g', 'h', 'i', 'j', 'k',
};
- for (size_t i = 0; i < arraysize(input); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(input); i++) {
EXPECT_TRUE(framer.ProcessInput(QuicStringPiece(AsChars(input) + i, 1),
GetParam()));
}
@@ -394,7 +395,7 @@ TEST_P(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
};
EXPECT_FALSE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error());
EXPECT_EQ(1, visitor.error_count_);
}
@@ -422,7 +423,7 @@ TEST_P(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
};
EXPECT_FALSE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error());
EXPECT_EQ(1, visitor.error_count_);
}
@@ -442,7 +443,7 @@ TEST_P(CryptoFramerTest, ProcessInputTooManyEntries) {
};
EXPECT_FALSE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(QUIC_CRYPTO_TOO_MANY_ENTRIES, framer.error());
EXPECT_EQ(1, visitor.error_count_);
}
@@ -470,7 +471,7 @@ TEST_P(CryptoFramerTest, ProcessInputZeroLength) {
};
EXPECT_TRUE(framer.ProcessInput(
- QuicStringPiece(AsChars(input), arraysize(input)), GetParam()));
+ QuicStringPiece(AsChars(input), QUIC_ARRAYSIZE(input)), GetParam()));
EXPECT_EQ(0, visitor.error_count_);
}
diff --git a/chromium/net/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/quic/core/crypto/crypto_handshake_message.cc
index 9081294bc98..037156a4d03 100644
--- a/chromium/net/quic/core/crypto/crypto_handshake_message.cc
+++ b/chromium/net/quic/core/crypto/crypto_handshake_message.cc
@@ -76,28 +76,16 @@ void CryptoHandshakeMessage::SetVersionVector(
QuicTransportVersionVector versions) {
QuicVersionLabelVector version_labels;
for (QuicTransportVersion version : versions) {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- version_labels.push_back(QuicVersionToQuicVersionLabel(version));
- } else {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 7, 10);
- version_labels.push_back(
- QuicEndian::HostToNet32(QuicVersionToQuicVersionLabel(version)));
- }
+ version_labels.push_back(
+ QuicEndian::HostToNet32(QuicVersionToQuicVersionLabel(version)));
}
SetVector(tag, version_labels);
}
void CryptoHandshakeMessage::SetVersion(QuicTag tag,
QuicTransportVersion version) {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- SetValue(tag, QuicVersionToQuicVersionLabel(version));
- } else {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 8, 10);
- SetValue(tag,
- QuicEndian::HostToNet32(QuicVersionToQuicVersionLabel(version)));
- }
+ SetValue(tag,
+ QuicEndian::HostToNet32(QuicVersionToQuicVersionLabel(version)));
}
void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
@@ -139,12 +127,6 @@ QuicErrorCode CryptoHandshakeMessage::GetTaglist(
QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
QuicTag tag,
QuicVersionLabelVector* out) const {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- return GetTaglist(tag, out);
- }
-
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_net_byte_order_version_label,
- 9, 10);
QuicErrorCode error = GetTaglist(tag, out);
if (error != QUIC_NO_ERROR) {
return error;
@@ -160,12 +142,6 @@ QuicErrorCode CryptoHandshakeMessage::GetVersionLabelList(
QuicErrorCode CryptoHandshakeMessage::GetVersionLabel(
QuicTag tag,
QuicVersionLabel* out) const {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- return GetUint32(tag, out);
- }
-
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_net_byte_order_version_label,
- 10, 10);
QuicErrorCode error = GetUint32(tag, out);
if (error != QUIC_NO_ERROR) {
return error;
diff --git a/chromium/net/quic/core/crypto/crypto_protocol.h b/chromium/net/quic/core/crypto/crypto_protocol.h
index e02a5c504cc..cec1e357433 100644
--- a/chromium/net/quic/core/crypto/crypto_protocol.h
+++ b/chromium/net/quic/core/crypto/crypto_protocol.h
@@ -113,6 +113,7 @@ const QuicTag kIW20 = TAG('I', 'W', '2', '0'); // Force ICWND to 20
const QuicTag kIW50 = TAG('I', 'W', '5', '0'); // Force ICWND to 50
const QuicTag k1CON = TAG('1', 'C', 'O', 'N'); // Emulate a single connection
const QuicTag kNTLP = TAG('N', 'T', 'L', 'P'); // No tail loss probe
+const QuicTag k1TLP = TAG('1', 'T', 'L', 'P'); // 1 tail loss probe
const QuicTag kNCON = TAG('N', 'C', 'O', 'N'); // N Connection Congestion Ctrl
const QuicTag kNRTO = TAG('N', 'R', 'T', 'O'); // CWND reduction on loss
const QuicTag kTIME = TAG('T', 'I', 'M', 'E'); // Time based loss detection
@@ -146,10 +147,6 @@ const QuicTag kLFAK = TAG('L', 'F', 'A', 'K'); // Don't invoke FACK on the
// MAX_HEADER_LIST_SIZE settings frame should be supported.
const QuicTag kSMHL = TAG('S', 'M', 'H', 'L'); // Support MAX_HEADER_LIST_SIZE
// settings frame.
-const QuicTag kCCVX = TAG('C', 'C', 'V', 'X'); // Fix Cubic convex bug.
-const QuicTag kCBQT = TAG('C', 'B', 'Q', 'T'); // Fix CubicBytes quantization.
-const QuicTag kBLMX = TAG('B', 'L', 'M', 'X'); // Fix Cubic BetaLastMax bug.
-const QuicTag kCPAU = TAG('C', 'P', 'A', 'U'); // Allow Cubic per-ack-updates.
const QuicTag kNSTP = TAG('N', 'S', 'T', 'P'); // No stop waiting frames.
// Optional support of truncated Connection IDs. If sent by a peer, the value
diff --git a/chromium/net/quic/core/crypto/crypto_server_test.cc b/chromium/net/quic/core/crypto/crypto_server_test.cc
index 346cc2a9990..0bf9d04355c 100644
--- a/chromium/net/quic/core/crypto/crypto_server_test.cc
+++ b/chromium/net/quic/core/crypto/crypto_server_test.cc
@@ -18,6 +18,8 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_socket_address_coder.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_string_piece.h"
@@ -108,7 +110,8 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> {
client_address_(QuicIpAddress::Loopback4(), 1234),
config_(QuicCryptoServerConfig::TESTING,
rand_,
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
peer_(&config_),
compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
@@ -122,8 +125,8 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> {
client_version_string_ = QuicVersionLabelToString(
QuicVersionToQuicVersionLabel(client_version_));
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support =
- GetParam().enable_stateless_rejects;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support,
+ GetParam().enable_stateless_rejects);
use_stateless_rejects_ = GetParam().use_stateless_rejects;
}
@@ -165,7 +168,7 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
CheckForServerDesignatedConnectionId();
QuicStringPiece srct;
@@ -347,7 +350,8 @@ class CryptoServerTest : public QuicTestWithParam<TestParams> {
EXPECT_EQ(expected_count, reject_reasons.size());
for (size_t i = 0; i < reject_reasons.size(); ++i) {
- EXPECT_EQ(expected_handshake_failures[i], reject_reasons[i]);
+ EXPECT_EQ(static_cast<QuicTag>(expected_handshake_failures[i]),
+ reject_reasons[i]);
}
}
@@ -430,7 +434,7 @@ TEST_P(CryptoServerTest, BadSNI) {
};
// clang-format on
- for (size_t i = 0; i < arraysize(kBadSNIs); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kBadSNIs); i++) {
CryptoHandshakeMessage msg =
crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
{"SNI", kBadSNIs[i]},
@@ -439,7 +443,7 @@ TEST_P(CryptoServerTest, BadSNI) {
ShouldFailMentioning("SNI", msg);
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
}
@@ -465,7 +469,7 @@ TEST_P(CryptoServerTest, DefaultCert) {
EXPECT_NE(0u, proof.size());
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
EXPECT_LT(0u, cert_sct.size());
}
@@ -492,7 +496,7 @@ TEST_P(CryptoServerTest, RejectTooLarge) {
EXPECT_FALSE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, RejectNotTooLarge) {
@@ -519,7 +523,7 @@ TEST_P(CryptoServerTest, RejectNotTooLarge) {
EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct));
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
@@ -548,7 +552,7 @@ TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) {
EXPECT_NE(0u, proof.size());
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, TooSmall) {
@@ -559,7 +563,7 @@ TEST_P(CryptoServerTest, TooSmall) {
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, BadSourceAddressToken) {
@@ -573,7 +577,7 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) {
};
// clang-format on
- for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kBadSourceAddressTokens); i++) {
CryptoHandshakeMessage msg =
crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
{"STK", kBadSourceAddressTokens[i]},
@@ -582,7 +586,7 @@ TEST_P(CryptoServerTest, BadSourceAddressToken) {
ShouldSucceed(msg);
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
}
@@ -595,7 +599,7 @@ TEST_P(CryptoServerTest, BadClientNonce) {
};
// clang-format on
- for (size_t i = 0; i < arraysize(kBadNonces); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kBadNonces); i++) {
// Invalid nonces should be ignored, in an inchoate CHLO.
CryptoHandshakeMessage msg =
@@ -607,7 +611,7 @@ TEST_P(CryptoServerTest, BadClientNonce) {
ShouldSucceed(msg);
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
// Invalid nonces should result in CLIENT_NONCE_INVALID_FAILURE.
CryptoHandshakeMessage msg1 =
@@ -628,7 +632,7 @@ TEST_P(CryptoServerTest, BadClientNonce) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons1[] = {
CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons1, arraysize(kRejectReasons1));
+ CheckRejectReasons(kRejectReasons1, QUIC_ARRAYSIZE(kRejectReasons1));
}
}
@@ -642,7 +646,7 @@ TEST_P(CryptoServerTest, NoClientNonce) {
ShouldSucceed(msg);
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
CryptoHandshakeMessage msg1 =
crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
@@ -659,7 +663,7 @@ TEST_P(CryptoServerTest, NoClientNonce) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons1[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons1, arraysize(kRejectReasons1));
+ CheckRejectReasons(kRejectReasons1, QUIC_ARRAYSIZE(kRejectReasons1));
}
TEST_P(CryptoServerTest, DowngradeAttack) {
@@ -678,7 +682,7 @@ TEST_P(CryptoServerTest, DowngradeAttack) {
ShouldFailMentioning("Downgrade", msg);
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, CorruptServerConfig) {
@@ -698,7 +702,7 @@ TEST_P(CryptoServerTest, CorruptServerConfig) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
@@ -719,7 +723,7 @@ TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons[] = {
SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
@@ -740,7 +744,7 @@ TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons[] = {
SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, CorruptMultipleTags) {
@@ -764,7 +768,7 @@ TEST_P(CryptoServerTest, CorruptMultipleTags) {
const HandshakeFailureReason kRejectReasons[] = {
SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, NoServerNonce) {
@@ -813,7 +817,7 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
CheckRejectTag();
const HandshakeFailureReason kRejectReasons[] = {
SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
QuicStringPiece cert, proof, scfg_str;
EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
@@ -874,7 +878,7 @@ TEST_P(CryptoServerTest, RejectInvalidXlct) {
const HandshakeFailureReason kRejectReasons[] = {
INVALID_EXPECTED_LEAF_CERTIFICATE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
TEST_P(CryptoServerTest, ValidXlct) {
@@ -942,6 +946,57 @@ TEST_P(CryptoServerTest, ProofSourceFailure) {
ShouldFailMentioning("", msg);
}
+// Regression test for crbug.com/723604
+// For 2RTT, if the first CHLO from the client contains hashes of cached
+// certs (stored in CCRT tag) but the second CHLO does not, then the second REJ
+// from the server should not contain hashes of cached certs.
+TEST_P(CryptoServerTest, TwoRttServerDropCachedCerts) {
+ // Send inchoate CHLO to get cert chain from server. This CHLO is only for
+ // the purpose of getting the server's certs; it is not part of the 2RTT
+ // handshake.
+ CryptoHandshakeMessage msg = crypto_test_utils::CreateCHLO(
+ {{"PDMD", "X509"}, {"VER\0", client_version_string_}},
+ kClientHelloMinimumSize);
+ ShouldSucceed(msg);
+
+ // Decompress cert chain from server to individual certs.
+ QuicStringPiece certs_compressed;
+ ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+ ASSERT_NE(0u, certs_compressed.size());
+ std::vector<string> certs;
+ ASSERT_TRUE(CertCompressor::DecompressChain(
+ certs_compressed, /*cached_certs=*/{}, /*common_sets=*/nullptr, &certs));
+
+ // Start 2-RTT. Client sends CHLO with bad source-address token and hashes of
+ // the certs, which tells the server that the client has cached those certs.
+ config_.set_chlo_multiplier(1);
+ const char kBadSourceAddressToken[] = "";
+ msg.SetStringPiece(kSourceAddressTokenTag, kBadSourceAddressToken);
+ std::vector<uint64_t> hashes(certs.size());
+ for (size_t i = 0; i < certs.size(); ++i) {
+ hashes[i] = QuicUtils::QuicUtils::FNV1a_64_Hash(certs[i]);
+ }
+ msg.SetVector(kCCRT, hashes);
+ ShouldSucceed(msg);
+
+ // Server responds with inchoate REJ containing valid source-address token.
+ QuicStringPiece srct;
+ ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
+
+ // Client now drops cached certs; sends CHLO with updated source-address
+ // token but no hashes of certs.
+ msg.SetStringPiece(kSourceAddressTokenTag, srct);
+ msg.Erase(kCCRT);
+ ShouldSucceed(msg);
+
+ // Server response's cert chain should not contain hashes of
+ // previously-cached certs.
+ ASSERT_TRUE(out_.GetStringPiece(kCertificateTag, &certs_compressed));
+ ASSERT_NE(0u, certs_compressed.size());
+ ASSERT_TRUE(CertCompressor::DecompressChain(
+ certs_compressed, /*cached_certs=*/{}, /*common_sets=*/nullptr, &certs));
+}
+
class CryptoServerConfigGenerationTest : public QuicTest {};
TEST_F(CryptoServerConfigGenerationTest, Determinism) {
@@ -953,9 +1008,11 @@ TEST_F(CryptoServerConfigGenerationTest, Determinism) {
MockClock clock;
QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
std::unique_ptr<CryptoHandshakeMessage> scfg_a(
a.AddDefaultConfig(&rand_a, &clock, options));
std::unique_ptr<CryptoHandshakeMessage> scfg_b(
@@ -974,10 +1031,12 @@ TEST_F(CryptoServerConfigGenerationTest, SCIDVaries) {
MockClock clock;
QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
rand_b.ChangeValue();
QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
std::unique_ptr<CryptoHandshakeMessage> scfg_a(
a.AddDefaultConfig(&rand_a, &clock, options));
std::unique_ptr<CryptoHandshakeMessage> scfg_b(
@@ -996,7 +1055,8 @@ TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
MockClock clock;
QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
std::unique_ptr<CryptoHandshakeMessage> scfg(
a.AddDefaultConfig(&rand_a, &clock, options));
@@ -1034,7 +1094,7 @@ TEST_P(CryptoServerTestNoConfig, DontCrash) {
const HandshakeFailureReason kRejectReasons[] = {
SERVER_CONFIG_INCHOATE_HELLO_FAILURE};
- CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+ CheckRejectReasons(kRejectReasons, QUIC_ARRAYSIZE(kRejectReasons));
}
class CryptoServerTestOldVersion : public CryptoServerTest {
diff --git a/chromium/net/quic/core/crypto/crypto_utils.cc b/chromium/net/quic/core/crypto/crypto_utils.cc
index 8cdda7a16b7..62668344158 100644
--- a/chromium/net/quic/core/crypto/crypto_utils.cc
+++ b/chromium/net/quic/core/crypto/crypto_utils.cc
@@ -14,8 +14,11 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_time.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/hkdf.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
using std::string;
@@ -23,6 +26,39 @@ using std::string;
namespace net {
// static
+std::vector<uint8_t> CryptoUtils::HkdfExpandLabel(
+ const EVP_MD* prf,
+ const std::vector<uint8_t>& secret,
+ const string& label,
+ size_t out_len) {
+ CBB hkdf_label, inner_label;
+ const char label_prefix[] = "tls13 ";
+ if (!CBB_init(&hkdf_label, 1) || !CBB_add_u16(&hkdf_label, out_len) ||
+ !CBB_add_u8_length_prefixed(&hkdf_label, &inner_label) ||
+ !CBB_add_bytes(&inner_label,
+ reinterpret_cast<const uint8_t*>(label_prefix),
+ QUIC_ARRAYSIZE(label_prefix) - 1) ||
+ !CBB_add_bytes(&inner_label,
+ reinterpret_cast<const uint8_t*>(label.data()),
+ label.size()) ||
+ !CBB_add_u8(&hkdf_label, 0) || !CBB_flush(&hkdf_label)) {
+ QUIC_LOG(ERROR) << "Building HKDF label failed";
+ CBB_cleanup(&hkdf_label);
+ std::vector<uint8_t>();
+ }
+ std::vector<uint8_t> out;
+ out.resize(out_len);
+ if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
+ CBB_data(&hkdf_label), CBB_len(&hkdf_label))) {
+ QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
+ CBB_cleanup(&hkdf_label);
+ std::vector<uint8_t>();
+ }
+ CBB_cleanup(&hkdf_label);
+ return out;
+}
+
+// static
void CryptoUtils::GenerateNonce(QuicWallTime now,
QuicRandom* random_generator,
QuicStringPiece orbit,
@@ -59,8 +95,8 @@ bool CryptoUtils::DeriveKeys(QuicStringPiece premaster_secret,
Diversification diversification,
CrypterPair* crypters,
string* subkey_secret) {
- crypters->encrypter.reset(QuicEncrypter::Create(aead));
- crypters->decrypter.reset(QuicDecrypter::Create(aead));
+ crypters->encrypter = QuicEncrypter::Create(aead);
+ crypters->decrypter = QuicDecrypter::Create(aead);
size_t key_bytes = crypters->encrypter->GetKeySize();
size_t nonce_prefix_bytes = crypters->encrypter->GetNoncePrefixSize();
size_t subkey_secret_bytes =
diff --git a/chromium/net/quic/core/crypto/crypto_utils.h b/chromium/net/quic/core/crypto/crypto_utils.h
index 537f15051af..ca42d901ba2 100644
--- a/chromium/net/quic/core/crypto/crypto_utils.h
+++ b/chromium/net/quic/core/crypto/crypto_utils.h
@@ -19,6 +19,7 @@
#include "net/quic/core/quic_time.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
namespace net {
@@ -68,6 +69,22 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
DiversificationNonce* nonce_;
};
+ // Implements the HKDF-Expand-Label function as defined in section 7.1 of TLS
+ // 1.3. The HKDF-Expand-Label definition assumes that the TLS connection's PRF
+ // will be used as the Hash function for HKDF; in this function it is
+ // explicitly passed in as |prf|. The inputs to HKDF-Expand-Label are as
+ // follows:
+ //
+ // Secret: |secret|
+ // Label: |label|
+ // Context: zero-length context
+ // Length: |out_len|
+ static std::vector<uint8_t> HkdfExpandLabel(
+ const EVP_MD* prf,
+ const std::vector<uint8_t>& secret,
+ const std::string& label,
+ size_t out_len);
+
// Generates the connection nonce. The nonce is formed as:
// <4 bytes> current time
// <8 bytes> |orbit| (or random if |orbit| is empty)
diff --git a/chromium/net/quic/core/crypto/crypto_utils_test.cc b/chromium/net/quic/core/crypto/crypto_utils_test.cc
index ef00ced4653..ad5ad9953ff 100644
--- a/chromium/net/quic/core/crypto/crypto_utils_test.cc
+++ b/chromium/net/quic/core/crypto/crypto_utils_test.cc
@@ -5,6 +5,7 @@
#include "net/quic/core/crypto/crypto_utils.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -17,6 +18,25 @@ namespace {
class CryptoUtilsTest : public QuicTest {};
+TEST_F(CryptoUtilsTest, TestHkdfExpandLabel) {
+ // This test vector is from
+ // https://github.com/quicwg/base-drafts/wiki/Test-Vector-for-the-Clear-Text-AEAD-key-derivation
+ const std::vector<uint8_t> secret = {
+ 0x8f, 0x01, 0x00, 0x67, 0x9c, 0x96, 0x5a, 0xc5, 0x9f, 0x28, 0x3a,
+ 0x02, 0x52, 0x2a, 0x6e, 0x43, 0xcf, 0xae, 0xf6, 0x3c, 0x45, 0x48,
+ 0xb0, 0xa6, 0x8f, 0x91, 0x91, 0x40, 0xee, 0x7d, 0x9a, 0x48};
+ const string label = "QUIC client cleartext Secret";
+ std::vector<uint8_t> out =
+ CryptoUtils::HkdfExpandLabel(EVP_sha256(), secret, label, 32);
+
+ std::vector<uint8_t> expected_out = {
+ 0x31, 0xba, 0x96, 0x68, 0x73, 0xf7, 0xf4, 0x53, 0xe6, 0xc8, 0xa1,
+ 0xbf, 0x78, 0xed, 0x70, 0x13, 0xfa, 0xd8, 0x3f, 0xfc, 0xee, 0xfc,
+ 0x95, 0x68, 0x81, 0xcd, 0x24, 0x1c, 0x0a, 0xe3, 0xa7, 0xa6};
+
+ EXPECT_EQ(out, expected_out);
+}
+
TEST_F(CryptoUtilsTest, TestExportKeyingMaterial) {
const struct TestVector {
// Input (strings of hexadecimal digits):
@@ -48,7 +68,7 @@ TEST_F(CryptoUtilsTest, TestExportKeyingMaterial) {
"c9a46ed0757bd1812f1f21b4d41e62125fec8364a21db7"},
};
- for (size_t i = 0; i < arraysize(test_vector); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_vector); i++) {
// Decode the test vector.
string subkey_secret =
QuicTextUtils::HexDecode(test_vector[i].subkey_secret);
diff --git a/chromium/net/quic/core/crypto/null_decrypter.cc b/chromium/net/quic/core/crypto/null_decrypter.cc
index 6dc7cad8667..8d76dfb7b0b 100644
--- a/chromium/net/quic/core/crypto/null_decrypter.cc
+++ b/chromium/net/quic/core/crypto/null_decrypter.cc
@@ -69,6 +69,14 @@ bool NullDecrypter::DecryptPacket(QuicTransportVersion version,
return true;
}
+size_t NullDecrypter::GetKeySize() const {
+ return 0;
+}
+
+size_t NullDecrypter::GetIVSize() const {
+ return 0;
+}
+
QuicStringPiece NullDecrypter::GetKey() const {
return QuicStringPiece();
}
diff --git a/chromium/net/quic/core/crypto/null_decrypter.h b/chromium/net/quic/core/crypto/null_decrypter.h
index 63d923b1b33..0ca74fe8cc0 100644
--- a/chromium/net/quic/core/crypto/null_decrypter.h
+++ b/chromium/net/quic/core/crypto/null_decrypter.h
@@ -41,6 +41,8 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
char* output,
size_t* output_length,
size_t max_output_length) override;
+ size_t GetKeySize() const override;
+ size_t GetIVSize() const override;
QuicStringPiece GetKey() const override;
QuicStringPiece GetNoncePrefix() const override;
diff --git a/chromium/net/quic/core/crypto/null_decrypter_test.cc b/chromium/net/quic/core/crypto/null_decrypter_test.cc
index fe6a252e2ea..3b83c20c2a2 100644
--- a/chromium/net/quic/core/crypto/null_decrypter_test.cc
+++ b/chromium/net/quic/core/crypto/null_decrypter_test.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "net/quic/core/crypto/null_decrypter.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -19,7 +20,7 @@ TEST_F(NullDecrypterTest, DecryptClient) {
'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_SERVER);
char buffer[256];
size_t length = 0;
@@ -38,7 +39,7 @@ TEST_F(NullDecrypterTest, DecryptServer) {
'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_CLIENT);
char buffer[256];
size_t length = 0;
@@ -57,7 +58,7 @@ TEST_F(NullDecrypterTest, DecryptClientPre37) {
'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_CLIENT);
char buffer[256];
size_t length = 0;
@@ -76,7 +77,7 @@ TEST_F(NullDecrypterTest, DecryptServerPre37) {
'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_SERVER);
char buffer[256];
size_t length = 0;
@@ -95,7 +96,7 @@ TEST_F(NullDecrypterTest, BadHash) {
'g', 'o', 'o', 'd', 'b', 'y', 'e', '!',
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_CLIENT);
char buffer[256];
size_t length = 0;
@@ -110,7 +111,7 @@ TEST_F(NullDecrypterTest, ShortInput) {
0x46, 0x11, 0xea, 0x5f, 0xcf, 0x1d, 0x66, 0x5b, 0xba, 0xf0, 0xbc,
};
const char* data = reinterpret_cast<const char*>(expected);
- size_t len = arraysize(expected);
+ size_t len = QUIC_ARRAYSIZE(expected);
NullDecrypter decrypter(Perspective::IS_CLIENT);
char buffer[256];
size_t length = 0;
diff --git a/chromium/net/quic/core/crypto/null_encrypter.cc b/chromium/net/quic/core/crypto/null_encrypter.cc
index 0cc7f3d8162..999d717c85b 100644
--- a/chromium/net/quic/core/crypto/null_encrypter.cc
+++ b/chromium/net/quic/core/crypto/null_encrypter.cc
@@ -68,6 +68,10 @@ size_t NullEncrypter::GetNoncePrefixSize() const {
return 0;
}
+size_t NullEncrypter::GetIVSize() const {
+ return 0;
+}
+
size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
return ciphertext_size - GetHashLength();
}
diff --git a/chromium/net/quic/core/crypto/null_encrypter.h b/chromium/net/quic/core/crypto/null_encrypter.h
index d6f114eb530..919a222737f 100644
--- a/chromium/net/quic/core/crypto/null_encrypter.h
+++ b/chromium/net/quic/core/crypto/null_encrypter.h
@@ -37,6 +37,7 @@ class QUIC_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
size_t max_output_length) override;
size_t GetKeySize() const override;
size_t GetNoncePrefixSize() const override;
+ size_t GetIVSize() const override;
size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
size_t GetCiphertextSize(size_t plaintext_size) const override;
QuicStringPiece GetKey() const override;
diff --git a/chromium/net/quic/core/crypto/null_encrypter_test.cc b/chromium/net/quic/core/crypto/null_encrypter_test.cc
index 00f24cdbe12..21aa85e5c56 100644
--- a/chromium/net/quic/core/crypto/null_encrypter_test.cc
+++ b/chromium/net/quic/core/crypto/null_encrypter_test.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "net/quic/core/crypto/null_encrypter.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -26,7 +27,7 @@ TEST_F(NullEncrypterTest, EncryptClient) {
256));
test::CompareCharArraysWithHexError(
"encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), arraysize(expected));
+ reinterpret_cast<const char*>(expected), QUIC_ARRAYSIZE(expected));
}
TEST_F(NullEncrypterTest, EncryptServer) {
@@ -44,7 +45,7 @@ TEST_F(NullEncrypterTest, EncryptServer) {
256));
test::CompareCharArraysWithHexError(
"encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), arraysize(expected));
+ reinterpret_cast<const char*>(expected), QUIC_ARRAYSIZE(expected));
}
TEST_F(NullEncrypterTest, EncryptClientPre37) {
@@ -62,7 +63,7 @@ TEST_F(NullEncrypterTest, EncryptClientPre37) {
256));
test::CompareCharArraysWithHexError(
"encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), arraysize(expected));
+ reinterpret_cast<const char*>(expected), QUIC_ARRAYSIZE(expected));
}
TEST_F(NullEncrypterTest, EncryptServerPre37) {
@@ -80,7 +81,7 @@ TEST_F(NullEncrypterTest, EncryptServerPre37) {
256));
test::CompareCharArraysWithHexError(
"encrypted data", encrypted, encrypted_len,
- reinterpret_cast<const char*>(expected), arraysize(expected));
+ reinterpret_cast<const char*>(expected), QUIC_ARRAYSIZE(expected));
}
TEST_F(NullEncrypterTest, GetMaxPlaintextSize) {
diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
index 9c77f54f02b..8f0f0fcd894 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -21,6 +21,7 @@
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_hostname_utils.h"
@@ -28,6 +29,7 @@
#include "net/quic/platform/api/quic_map_util.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_text_utils.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
using std::string;
@@ -55,8 +57,9 @@ void RecordDiskCacheServerConfigState(
} // namespace
QuicCryptoClientConfig::QuicCryptoClientConfig(
- std::unique_ptr<ProofVerifier> proof_verifier)
- : proof_verifier_(std::move(proof_verifier)) {
+ std::unique_ptr<ProofVerifier> proof_verifier,
+ bssl::UniquePtr<SSL_CTX> ssl_ctx)
+ : proof_verifier_(std::move(proof_verifier)), ssl_ctx_(std::move(ssl_ctx)) {
DCHECK(proof_verifier_.get());
SetDefaults();
}
@@ -466,9 +469,9 @@ void QuicCryptoClientConfig::FillInchoateClientHello(
}
char proof_nonce[32];
- rand->RandBytes(proof_nonce, arraysize(proof_nonce));
- out->SetStringPiece(kNONP,
- QuicStringPiece(proof_nonce, arraysize(proof_nonce)));
+ rand->RandBytes(proof_nonce, QUIC_ARRAYSIZE(proof_nonce));
+ out->SetStringPiece(
+ kNONP, QuicStringPiece(proof_nonce, QUIC_ARRAYSIZE(proof_nonce)));
out->SetVector(kPDMD, QuicTagVector{kX509});
@@ -923,6 +926,10 @@ ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const {
return channel_id_source_.get();
}
+SSL_CTX* QuicCryptoClientConfig::ssl_ctx() const {
+ return ssl_ctx_.get();
+}
+
void QuicCryptoClientConfig::SetChannelIDSource(ChannelIDSource* source) {
channel_id_source_.reset(source);
}
diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config.h b/chromium/net/quic/core/crypto/quic_crypto_client_config.h
index e5b413e4f7a..db8b23ef182 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_client_config.h
+++ b/chromium/net/quic/core/crypto/quic_crypto_client_config.h
@@ -18,6 +18,7 @@
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_reference_counted.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
namespace net {
@@ -206,8 +207,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
virtual bool Matches(const QuicServerId& server_id) const = 0;
};
- explicit QuicCryptoClientConfig(
- std::unique_ptr<ProofVerifier> proof_verifier);
+ QuicCryptoClientConfig(std::unique_ptr<ProofVerifier> proof_verifier,
+ bssl::UniquePtr<SSL_CTX> ssl_ctx);
~QuicCryptoClientConfig();
// LookupOrCreate returns a CachedState for the given |server_id|. If no such
@@ -313,6 +314,8 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
ChannelIDSource* channel_id_source() const;
+ SSL_CTX* ssl_ctx() const;
+
// SetChannelIDSource sets a ChannelIDSource that will be called, when the
// server supports channel IDs, to obtain a channel ID for signing a message
// proving possession of the channel ID. This object takes ownership of
@@ -385,6 +388,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
std::unique_ptr<ProofVerifier> proof_verifier_;
std::unique_ptr<ChannelIDSource> channel_id_source_;
+ bssl::UniquePtr<SSL_CTX> ssl_ctx_;
// The |user_agent_id_| passed in QUIC's CHLO message.
std::string user_agent_id_;
diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc b/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc
index 642e6a84719..d006c0f9ae7 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -7,6 +7,7 @@
#include "net/quic/core/crypto/proof_verifier.h"
#include "net/quic/core/quic_server_id.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -173,7 +174,8 @@ TEST_F(QuicCryptoClientConfigTest, CachedState_InitializeFrom) {
TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
config.set_user_agent_id("quic-tester");
config.set_alpn("hq");
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
@@ -181,12 +183,13 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
CryptoHandshakeMessage msg;
QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+ config.FillInchoateClientHello(server_id, QuicTransportVersionMax(), &state,
+ &rand,
/* demand_x509_proof= */ true, params, &msg);
QuicVersionLabel cver;
EXPECT_EQ(QUIC_NO_ERROR, msg.GetVersionLabel(kVER, &cver));
- EXPECT_EQ(QuicVersionToQuicVersionLabel(QuicVersionMax()), cver);
+ EXPECT_EQ(QuicVersionToQuicVersionLabel(QuicTransportVersionMax()), cver);
QuicStringPiece proof_nonce;
EXPECT_TRUE(msg.GetStringPiece(kNONP, &proof_nonce));
EXPECT_EQ(string(32, 'r'), proof_nonce);
@@ -199,7 +202,8 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChlo) {
}
TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
if (config.aead.size() > 1)
EXPECT_NE(kAESG, config.aead[0]);
config.PreferAesGcm();
@@ -208,13 +212,15 @@ TEST_F(QuicCryptoClientConfigTest, PreferAesGcm) {
TEST_F(QuicCryptoClientConfigTest, InchoateChloSecure) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
new QuicCryptoNegotiatedParameters);
CryptoHandshakeMessage msg;
QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+ config.FillInchoateClientHello(server_id, QuicTransportVersionMax(), &state,
+ &rand,
/* demand_x509_proof= */ true, params, &msg);
QuicTag pdmd;
@@ -238,13 +244,15 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCIDNoEXPY) {
scfg.GetSerialized(Perspective::IS_CLIENT).AsStringPiece(), now, expiry,
&details);
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
new QuicCryptoNegotiatedParameters);
CryptoHandshakeMessage msg;
QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+ config.FillInchoateClientHello(server_id, QuicTransportVersionMax(), &state,
+ &rand,
/* demand_x509_proof= */ true, params, &msg);
QuicStringPiece scid;
@@ -265,13 +273,15 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
QuicWallTime::FromUNIXSeconds(1), QuicWallTime::FromUNIXSeconds(0),
&details);
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
new QuicCryptoNegotiatedParameters);
CryptoHandshakeMessage msg;
QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
MockRandom rand;
- config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, &rand,
+ config.FillInchoateClientHello(server_id, QuicTransportVersionMax(), &state,
+ &rand,
/* demand_x509_proof= */ true, params, &msg);
QuicStringPiece scid;
@@ -281,7 +291,8 @@ TEST_F(QuicCryptoClientConfigTest, InchoateChloSecureWithSCID) {
TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
QuicCryptoClientConfig::CachedState state;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params(
new QuicCryptoNegotiatedParameters);
QuicConnectionId kConnectionId = 1234;
@@ -289,15 +300,15 @@ TEST_F(QuicCryptoClientConfigTest, FillClientHello) {
MockRandom rand;
CryptoHandshakeMessage chlo;
QuicServerId server_id("www.google.com", 443, PRIVACY_MODE_DISABLED);
- config.FillClientHello(server_id, kConnectionId, QuicVersionMax(), &state,
- QuicWallTime::Zero(), &rand,
+ config.FillClientHello(server_id, kConnectionId, QuicTransportVersionMax(),
+ &state, QuicWallTime::Zero(), &rand,
nullptr, // channel_id_key
params, &chlo, &error_details);
// Verify that the version label has been set correctly in the CHLO.
QuicVersionLabel cver;
EXPECT_EQ(QUIC_NO_ERROR, chlo.GetVersionLabel(kVER, &cver));
- EXPECT_EQ(QuicVersionToQuicVersionLabel(QuicVersionMax()), cver);
+ EXPECT_EQ(QuicVersionToQuicVersionLabel(QuicTransportVersionMax()), cver);
}
TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
@@ -321,7 +332,8 @@ TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
EXPECT_EQ(QUIC_VERSION_NEGOTIATION_MISMATCH,
config.ProcessServerHello(msg, 0, supported_versions.front(),
supported_versions, &cached, out_params,
@@ -330,7 +342,8 @@ TEST_F(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) {
}
TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicServerId canonical_server_id("www.google.com", 443,
PRIVACY_MODE_DISABLED);
QuicCryptoClientConfig::CachedState* state =
@@ -351,7 +364,8 @@ TEST_F(QuicCryptoClientConfigTest, InitializeFrom) {
}
TEST_F(QuicCryptoClientConfigTest, Canonical) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
config.AddCanonicalSuffix(".google.com");
QuicServerId canonical_id1("www.google.com", 443, PRIVACY_MODE_DISABLED);
QuicServerId canonical_id2("mail.google.com", 443, PRIVACY_MODE_DISABLED);
@@ -375,7 +389,8 @@ TEST_F(QuicCryptoClientConfigTest, Canonical) {
}
TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
config.AddCanonicalSuffix(".google.com");
QuicServerId canonical_id1("www.google.com", 443, PRIVACY_MODE_DISABLED);
QuicServerId canonical_id2("mail.google.com", 443, PRIVACY_MODE_DISABLED);
@@ -390,7 +405,8 @@ TEST_F(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) {
}
TEST_F(QuicCryptoClientConfigTest, ClearCachedStates) {
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
// Create two states on different origins.
struct TestCase {
@@ -486,7 +502,8 @@ TEST_F(QuicCryptoClientConfigTest, ProcessReject) {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
EXPECT_EQ(QUIC_NO_ERROR,
config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
AllSupportedTransportVersions().front(), "",
@@ -507,7 +524,8 @@ TEST_F(QuicCryptoClientConfigTest, ProcessRejectWithLongTTL) {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
EXPECT_EQ(QUIC_NO_ERROR,
config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
AllSupportedTransportVersions().front(), "",
@@ -534,7 +552,8 @@ TEST_F(QuicCryptoClientConfigTest, ProcessStatelessReject) {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
EXPECT_EQ(QUIC_NO_ERROR,
config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
AllSupportedTransportVersions().front(), "",
@@ -556,7 +575,8 @@ TEST_F(QuicCryptoClientConfigTest, BadlyFormattedStatelessReject) {
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
string error;
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND,
config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0),
AllSupportedTransportVersions().front(), "",
@@ -575,7 +595,8 @@ TEST_F(QuicCryptoClientConfigTest, ServerNonceinSHLO) {
supported_versions.push_back(version);
msg.SetVersionVector(kVER, supported_versions);
- QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting());
+ QuicCryptoClientConfig config(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
QuicCryptoClientConfig::CachedState cached;
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> out_params(
new QuicCryptoNegotiatedParameters);
diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
index 99a1655a53a..56c717e1999 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -35,12 +35,14 @@
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_clock.h"
#include "net/quic/platform/api/quic_endian.h"
+#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_hostname_utils.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_reference_counted.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
using std::string;
@@ -151,13 +153,15 @@ QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {}
QuicCryptoServerConfig::QuicCryptoServerConfig(
QuicStringPiece source_address_token_secret,
QuicRandom* server_nonce_entropy,
- std::unique_ptr<ProofSource> proof_source)
+ std::unique_ptr<ProofSource> proof_source,
+ bssl::UniquePtr<SSL_CTX> ssl_ctx)
: replay_protection_(true),
chlo_multiplier_(kMultiplier),
configs_lock_(),
primary_config_(nullptr),
next_config_promotion_time_(QuicWallTime::Zero()),
proof_source_(std::move(proof_source)),
+ ssl_ctx_(std::move(ssl_ctx)),
source_address_token_future_secs_(3600),
source_address_token_lifetime_secs_(86400),
enable_serving_sct_(false),
@@ -1313,7 +1317,7 @@ void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof(
QUIC_DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher.";
// If the server nonce is empty and we're requiring handshake confirmation
// for DoS reasons then we must reject the CHLO.
- if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation &&
+ if (GetQuicReloadableFlag(quic_require_handshake_confirmation) &&
info->server_nonce.empty()) {
info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE);
}
@@ -1451,7 +1455,7 @@ void QuicCryptoServerConfig::BuildRejection(
QuicByteCount total_framing_overhead,
QuicByteCount chlo_packet_size,
CryptoHandshakeMessage* out) const {
- if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support &&
+ if (GetQuicReloadableFlag(enable_quic_stateless_reject_support) &&
use_stateless_rejects) {
QUIC_DVLOG(1) << "QUIC Crypto server config returning stateless reject "
<< "with server-designated connection ID "
@@ -1490,6 +1494,12 @@ void QuicCryptoServerConfig::BuildRejection(
QuicStringPiece client_cached_cert_hashes;
if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
+ } else {
+ if (GetQuicReloadableFlag(quic_2rtt_drop_client_cached_certs)) {
+ params->client_cached_cert_hashes.clear();
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_2rtt_drop_client_cached_certs,
+ 1, 2);
+ }
}
const string compressed =
@@ -1553,9 +1563,18 @@ string QuicCryptoServerConfig::CompressChain(
return *cached_value;
}
- const string compressed =
- CertCompressor::CompressChain(chain->certs, client_common_set_hashes,
- client_common_set_hashes, common_sets);
+ string compressed;
+ if (GetQuicReloadableFlag(quic_2rtt_drop_client_cached_certs)) {
+ compressed =
+ CertCompressor::CompressChain(chain->certs, client_common_set_hashes,
+ client_cached_cert_hashes, common_sets);
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_2rtt_drop_client_cached_certs,
+ 2, 2);
+ } else {
+ compressed =
+ CertCompressor::CompressChain(chain->certs, client_common_set_hashes,
+ client_common_set_hashes, common_sets);
+ }
// Insert the newly compressed cert to cache.
compressed_certs_cache->Insert(chain, client_common_set_hashes,
@@ -1787,6 +1806,14 @@ int QuicCryptoServerConfig::NumberOfConfigs() const {
return configs_.size();
}
+ProofSource* QuicCryptoServerConfig::proof_source() const {
+ return proof_source_.get();
+}
+
+SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const {
+ return ssl_ctx_.get();
+}
+
HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
const Config& config,
QuicStringPiece token,
diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/quic/core/crypto/quic_crypto_server_config.h
index 861eae6b4d1..826c98c8743 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_server_config.h
+++ b/chromium/net/quic/core/crypto/quic_crypto_server_config.h
@@ -28,6 +28,7 @@
#include "net/quic/platform/api/quic_reference_counted.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
namespace net {
@@ -194,9 +195,11 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
// server. Not owned.
// |proof_source|: provides certificate chains and signatures. This class
// takes ownership of |proof_source|.
+ // |ssl_ctx|: The SSL_CTX used for doing TLS handshakes.
QuicCryptoServerConfig(QuicStringPiece source_address_token_secret,
QuicRandom* server_nonce_entropy,
- std::unique_ptr<ProofSource> proof_source);
+ std::unique_ptr<ProofSource> proof_source,
+ bssl::UniquePtr<SSL_CTX> ssl_ctx);
~QuicCryptoServerConfig();
// TESTING is a magic parameter for passing to the constructor in tests.
@@ -392,6 +395,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
rejection_observer_ = rejection_observer;
}
+ ProofSource* proof_source() const;
+
+ SSL_CTX* ssl_ctx() const;
+
private:
friend class test::QuicCryptoServerConfigPeer;
friend struct QuicSignedServerConfig;
@@ -740,6 +747,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
// signatures.
std::unique_ptr<ProofSource> proof_source_;
+ // ssl_ctx_ contains the server configuration for doing TLS handshakes.
+ bssl::UniquePtr<SSL_CTX> ssl_ctx_;
+
// ephemeral_key_source_ contains an object that caches ephemeral keys for a
// short period of time.
std::unique_ptr<EphemeralKeySource> ephemeral_key_source_;
diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
index 381c82b5cb8..437904eb824 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -15,6 +15,7 @@
#include "net/quic/core/crypto/crypto_server_config_protobuf.h"
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_time.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -31,7 +32,8 @@ class QuicCryptoServerConfigTest : public QuicTest {};
TEST_F(QuicCryptoServerConfigTest, ServerConfig) {
QuicRandom* rand = QuicRandom::GetInstance();
QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
MockClock clock;
std::unique_ptr<CryptoHandshakeMessage> message(server.AddDefaultConfig(
@@ -51,7 +53,8 @@ TEST_F(QuicCryptoServerConfigTest, CompressCerts) {
QuicRandom* rand = QuicRandom::GetInstance();
QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
QuicCryptoServerConfigPeer peer(&server);
std::vector<string> certs = {"testcert"};
@@ -70,7 +73,8 @@ TEST_F(QuicCryptoServerConfigTest, CompressSameCertsTwice) {
QuicRandom* rand = QuicRandom::GetInstance();
QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
QuicCryptoServerConfigPeer peer(&server);
// Compress the certs for the first time.
@@ -99,7 +103,8 @@ TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
QuicRandom* rand = QuicRandom::GetInstance();
QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand,
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
QuicCryptoServerConfigPeer peer(&server);
std::vector<string> certs = {"testcert"};
@@ -142,7 +147,8 @@ class SourceAddressTokenTest : public QuicTest {
rand_(QuicRandom::GetInstance()),
server_(QuicCryptoServerConfig::TESTING,
rand_,
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
peer_(&server_) {
// Advance the clock to some non-zero time.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
@@ -280,7 +286,8 @@ class CryptoServerConfigsTest : public QuicTest {
: rand_(QuicRandom::GetInstance()),
config_(QuicCryptoServerConfig::TESTING,
rand_,
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
test_peer_(&config_) {}
void SetUp() override {
diff --git a/chromium/net/quic/core/crypto/quic_decrypter.cc b/chromium/net/quic/core/crypto/quic_decrypter.cc
index 99c2a814d8b..924b07c46b6 100644
--- a/chromium/net/quic/core/crypto/quic_decrypter.cc
+++ b/chromium/net/quic/core/crypto/quic_decrypter.cc
@@ -6,22 +6,25 @@
#include "crypto/hkdf.h"
#include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h"
+#include "net/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "net/quic/core/crypto/aes_256_gcm_decrypter.h"
#include "net/quic/core/crypto/chacha20_poly1305_decrypter.h"
+#include "net/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "net/quic/core/crypto/null_decrypter.h"
+#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
-
-using std::string;
+#include "third_party/boringssl/src/include/openssl/tls1.h"
namespace net {
// static
-QuicDecrypter* QuicDecrypter::Create(QuicTag algorithm) {
+std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(QuicTag algorithm) {
switch (algorithm) {
case kAESG:
- return new Aes128Gcm12Decrypter();
+ return std::make_unique<Aes128Gcm12Decrypter>();
case kCC20:
- return new ChaCha20Poly1305Decrypter();
+ return std::make_unique<ChaCha20Poly1305Decrypter>();
default:
QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return nullptr;
@@ -29,13 +32,33 @@ QuicDecrypter* QuicDecrypter::Create(QuicTag algorithm) {
}
// static
+QuicDecrypter* QuicDecrypter::CreateFromCipherSuite(uint32_t cipher_suite) {
+ QuicDecrypter* decrypter;
+ switch (cipher_suite) {
+ case TLS1_CK_AES_128_GCM_SHA256:
+ decrypter = new Aes128GcmDecrypter();
+ break;
+ case TLS1_CK_AES_256_GCM_SHA384:
+ decrypter = new Aes256GcmDecrypter();
+ break;
+ case TLS1_CK_CHACHA20_POLY1305_SHA256:
+ decrypter = new ChaCha20Poly1305TlsDecrypter();
+ break;
+ default:
+ QUIC_BUG << "TLS cipher suite is unknown to QUIC";
+ return nullptr;
+ }
+ return decrypter;
+}
+
+// static
void QuicDecrypter::DiversifyPreliminaryKey(QuicStringPiece preliminary_key,
QuicStringPiece nonce_prefix,
const DiversificationNonce& nonce,
size_t key_size,
size_t nonce_prefix_size,
- string* out_key,
- string* out_nonce_prefix) {
+ std::string* out_key,
+ std::string* out_nonce_prefix) {
crypto::HKDF hkdf(preliminary_key.as_string() + nonce_prefix.as_string(),
QuicStringPiece(nonce.data(), nonce.size()),
"QUIC key diversification", 0, key_size, 0,
diff --git a/chromium/net/quic/core/crypto/quic_decrypter.h b/chromium/net/quic/core/crypto/quic_decrypter.h
index 5b6258f85d1..a5059097ea6 100644
--- a/chromium/net/quic/core/crypto/quic_decrypter.h
+++ b/chromium/net/quic/core/crypto/quic_decrypter.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <cstdint>
+#include <memory>
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_export.h"
@@ -18,7 +19,12 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter {
public:
virtual ~QuicDecrypter() {}
- static QuicDecrypter* Create(QuicTag algorithm);
+ static std::unique_ptr<QuicDecrypter> Create(QuicTag algorithm);
+
+ // Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
+ // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+ // ownership of the new QuicDecrypter.
+ static QuicDecrypter* CreateFromCipherSuite(uint32_t cipher_suite);
// Sets the encryption key. Returns true on success, false on failure.
//
@@ -102,6 +108,11 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter {
size_t* output_length,
size_t max_output_length) = 0;
+ // Returns the size in bytes of a key for the algorithm.
+ virtual size_t GetKeySize() const = 0;
+ // Returns the size in bytes of an IV to use with the algorithm.
+ virtual size_t GetIVSize() const = 0;
+
// The ID of the cipher. Return 0x03000000 ORed with the 'cryptographic suite
// selector'.
virtual uint32_t cipher_id() const = 0;
diff --git a/chromium/net/quic/core/crypto/quic_encrypter.cc b/chromium/net/quic/core/crypto/quic_encrypter.cc
index 377720b9db9..ef78336035e 100644
--- a/chromium/net/quic/core/crypto/quic_encrypter.cc
+++ b/chromium/net/quic/core/crypto/quic_encrypter.cc
@@ -5,24 +5,49 @@
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
+#include "net/quic/core/crypto/aes_128_gcm_encrypter.h"
+#include "net/quic/core/crypto/aes_256_gcm_encrypter.h"
#include "net/quic/core/crypto/chacha20_poly1305_encrypter.h"
+#include "net/quic/core/crypto/chacha20_poly1305_tls_encrypter.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "net/quic/core/crypto/null_encrypter.h"
+#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "third_party/boringssl/src/include/openssl/tls1.h"
namespace net {
// static
-QuicEncrypter* QuicEncrypter::Create(QuicTag algorithm) {
+std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(QuicTag algorithm) {
switch (algorithm) {
case kAESG:
- return new Aes128Gcm12Encrypter();
+ return std::make_unique<Aes128Gcm12Encrypter>();
case kCC20:
- return new ChaCha20Poly1305Encrypter();
+ return std::make_unique<ChaCha20Poly1305Encrypter>();
default:
QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return nullptr;
}
}
+// static
+QuicEncrypter* QuicEncrypter::CreateFromCipherSuite(uint32_t cipher_suite) {
+ QuicEncrypter* encrypter;
+ switch (cipher_suite) {
+ case TLS1_CK_AES_128_GCM_SHA256:
+ encrypter = new Aes128GcmEncrypter();
+ break;
+ case TLS1_CK_AES_256_GCM_SHA384:
+ encrypter = new Aes256GcmEncrypter();
+ break;
+ case TLS1_CK_CHACHA20_POLY1305_SHA256:
+ encrypter = new ChaCha20Poly1305TlsEncrypter();
+ break;
+ default:
+ QUIC_BUG << "TLS cipher suite is unknown to QUIC";
+ return nullptr;
+ }
+ return encrypter;
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/crypto/quic_encrypter.h b/chromium/net/quic/core/crypto/quic_encrypter.h
index c9e21f3a9b5..bc32213a1eb 100644
--- a/chromium/net/quic/core/crypto/quic_encrypter.h
+++ b/chromium/net/quic/core/crypto/quic_encrypter.h
@@ -6,6 +6,7 @@
#define NET_QUIC_CORE_CRYPTO_QUIC_ENCRYPTER_H_
#include <cstddef>
+#include <memory>
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_export.h"
@@ -17,7 +18,12 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter {
public:
virtual ~QuicEncrypter() {}
- static QuicEncrypter* Create(QuicTag algorithm);
+ static std::unique_ptr<QuicEncrypter> Create(QuicTag algorithm);
+
+ // Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
+ // returned by SSL_CIPHER_get_id. The caller is responsible for taking
+ // ownership of the new QuicEncrypter.
+ static QuicEncrypter* CreateFromCipherSuite(uint32_t cipher_suite);
// Sets the encryption key. Returns true on success, false on failure.
//
@@ -95,6 +101,9 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter {
// Returns the size in bytes of the fixed initial part of the nonce.
virtual size_t GetNoncePrefixSize() const = 0;
+ // Returns the size in bytes of an IV to use with the algorithm.
+ virtual size_t GetIVSize() const = 0;
+
// Returns the maximum length of plaintext that can be encrypted
// to ciphertext no larger than |ciphertext_size|.
virtual size_t GetMaxPlaintextSize(size_t ciphertext_size) const = 0;
diff --git a/chromium/net/quic/core/crypto/quic_tls_adapter_test.cc b/chromium/net/quic/core/crypto/quic_tls_adapter_test.cc
index 9a7c7cc32d8..614d14e8d05 100644
--- a/chromium/net/quic/core/crypto/quic_tls_adapter_test.cc
+++ b/chromium/net/quic/core/crypto/quic_tls_adapter_test.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "third_party/boringssl/src/include/openssl/bio.h"
@@ -56,7 +57,7 @@ TEST_P(QuicTlsAdapterTest, ProcessInput) {
char buf[4];
ASSERT_EQ(static_cast<int>(input.length()),
- BIO_read(bio_, buf, arraysize(buf)));
+ BIO_read(bio_, buf, QUIC_ARRAYSIZE(buf)));
EXPECT_EQ(input, string(buf, input.length()));
}
@@ -71,9 +72,9 @@ TEST_P(QuicTlsAdapterTest, BIORead) {
// Test that a call to BIO_read for less than what is in |adapter_|'s buffer
// still leaves more input remaining to read.
char buf1[3];
- ASSERT_EQ(static_cast<int>(arraysize(buf1)),
- BIO_read(bio_, buf1, arraysize(buf1)));
- EXPECT_EQ("abc", string(buf1, arraysize(buf1)));
+ ASSERT_EQ(static_cast<int>(QUIC_ARRAYSIZE(buf1)),
+ BIO_read(bio_, buf1, QUIC_ARRAYSIZE(buf1)));
+ EXPECT_EQ("abc", string(buf1, QUIC_ARRAYSIZE(buf1)));
EXPECT_EQ(1u, adapter_.InputBytesRemaining());
// Test that the bytes read by BIO_read can span input read in by
@@ -82,9 +83,9 @@ TEST_P(QuicTlsAdapterTest, BIORead) {
EXPECT_EQ(QUIC_NO_ERROR, adapter_.error());
EXPECT_EQ(2, visitor_.data_available_count());
char buf2[5];
- ASSERT_EQ(static_cast<int>(arraysize(buf2)),
- BIO_read(bio_, buf2, arraysize(buf2)));
- EXPECT_EQ("defgh", string(buf2, arraysize(buf2)));
+ ASSERT_EQ(static_cast<int>(QUIC_ARRAYSIZE(buf2)),
+ BIO_read(bio_, buf2, QUIC_ARRAYSIZE(buf2)));
+ EXPECT_EQ("defgh", string(buf2, QUIC_ARRAYSIZE(buf2)));
EXPECT_EQ(0u, adapter_.InputBytesRemaining());
}
diff --git a/chromium/net/quic/core/frames/quic_ack_frame.cc b/chromium/net/quic/core/frames/quic_ack_frame.cc
index e1b95b95b55..6e22672f9c7 100644
--- a/chromium/net/quic/core/frames/quic_ack_frame.cc
+++ b/chromium/net/quic/core/frames/quic_ack_frame.cc
@@ -19,36 +19,6 @@ namespace {
const QuicPacketNumber kMaxPrintRange = 128;
} // namespace
-PacketNumberQueue::const_iterator::const_iterator(const const_iterator& other) =
- default;
-PacketNumberQueue::const_iterator::const_iterator(const_iterator&& other) =
- default;
-PacketNumberQueue::const_iterator::~const_iterator() {}
-
-PacketNumberQueue::const_iterator::const_iterator(
- typename QuicIntervalSet<QuicPacketNumber>::const_iterator it)
- : vector_it_(it), use_deque_it_(false) {}
-
-PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
- const const_reverse_iterator& other) = default;
-PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
- const_reverse_iterator&& other) = default;
-PacketNumberQueue::const_reverse_iterator::~const_reverse_iterator() {}
-
-PacketNumberQueue::const_iterator::const_iterator(
- typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator it)
- : deque_it_(it), use_deque_it_(true) {}
-
-PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
- const typename QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator&
- it)
- : vector_it_(it), use_deque_it_(false) {}
-
-PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
- const typename QuicDeque<
- Interval<QuicPacketNumber>>::const_reverse_iterator& it)
- : deque_it_(it), use_deque_it_(true) {}
-
bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
QuicPacketNumber packet_number,
QuicPacketNumber peer_least_packet_awaiting_ack) {
@@ -57,8 +27,7 @@ bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
}
QuicAckFrame::QuicAckFrame()
- : deprecated_largest_observed(0),
- ack_delay_time(QuicTime::Delta::Infinite()) {}
+ : largest_acked(0), ack_delay_time(QuicTime::Delta::Infinite()) {}
QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
@@ -77,28 +46,7 @@ std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
return os;
}
-QuicPacketNumber LargestAcked(const QuicAckFrame& frame) {
- if (!FLAGS_quic_reloadable_flag_quic_deprecate_largest_observed) {
- return frame.deprecated_largest_observed;
- }
-
- if (!frame.packets.Empty() &&
- frame.packets.Max() != frame.deprecated_largest_observed) {
- QUIC_BUG << "Peer last received packet: " << frame.packets.Max()
- << " which is not equal to largest observed: "
- << frame.deprecated_largest_observed;
- }
-
- return frame.packets.Empty() ? 0 : frame.packets.Max();
-}
-
-PacketNumberQueue::PacketNumberQueue()
- : use_deque_(FLAGS_quic_reloadable_flag_quic_frames_deque3) {
- if (use_deque_) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_frames_deque3);
- }
-}
-
+PacketNumberQueue::PacketNumberQueue() {}
PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
PacketNumberQueue::~PacketNumberQueue() {}
@@ -109,80 +57,76 @@ PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
default;
void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
- if (use_deque_) {
- // Check if the deque is empty
- if (packet_number_deque_.empty()) {
- packet_number_deque_.push_front(
- Interval<QuicPacketNumber>(packet_number, packet_number + 1));
+ // Check if the deque is empty
+ if (packet_number_deque_.empty()) {
+ packet_number_deque_.push_front(
+ Interval<QuicPacketNumber>(packet_number, packet_number + 1));
+ return;
+ }
+ Interval<QuicPacketNumber> back = packet_number_deque_.back();
+
+ // Check for the typical case,
+ // when the next packet in order is acked
+ if (back.max() == packet_number) {
+ packet_number_deque_.back().SetMax(packet_number + 1);
+ return;
+ }
+ // Check if the next packet in order is skipped
+ if (back.max() < packet_number) {
+ packet_number_deque_.push_back(
+ Interval<QuicPacketNumber>(packet_number, packet_number + 1));
+ return;
+ }
+
+ Interval<QuicPacketNumber> front = packet_number_deque_.front();
+ // Check if the packet can be popped on the front
+ if (front.min() > packet_number + 1) {
+ packet_number_deque_.push_front(
+ Interval<QuicPacketNumber>(packet_number, packet_number + 1));
+ return;
+ }
+ if (front.min() == packet_number + 1) {
+ packet_number_deque_.front().SetMin(packet_number);
+ return;
+ }
+
+ int i = packet_number_deque_.size() - 1;
+ // Iterating through the queue backwards
+ // to find a proper place for the packet
+ while (i >= 0) {
+ Interval<QuicPacketNumber> packet_interval = packet_number_deque_[i];
+ DCHECK(packet_interval.min() < packet_interval.max());
+ // Check if the packet is contained in an interval already
+ if (packet_interval.Contains(packet_number)) {
return;
}
- Interval<QuicPacketNumber> back = packet_number_deque_.back();
- // Check for the typical case,
- // when the next packet in order is acked
- if (back.max() == packet_number) {
- packet_number_deque_.back().SetMax(packet_number + 1);
+ // Check if the packet can extend an interval.
+ if (packet_interval.max() == packet_number) {
+ packet_number_deque_[i].SetMax(packet_number + 1);
return;
}
- // Check if the next packet in order is skipped
- if (back.max() < packet_number) {
- packet_number_deque_.push_back(
- Interval<QuicPacketNumber>(packet_number, packet_number + 1));
+ // Check if the packet can extend an interval
+ // and merge two intervals if needed.
+ // There is no need to merge an interval in the previous
+ // if statement, as all merges will happen here.
+ if (packet_interval.min() == packet_number + 1) {
+ packet_number_deque_[i].SetMin(packet_number);
+ if (i > 0 && packet_number == packet_number_deque_[i - 1].max()) {
+ packet_number_deque_[i - 1].SetMax(packet_interval.max());
+ packet_number_deque_.erase(packet_number_deque_.begin() + i);
+ }
return;
}
- Interval<QuicPacketNumber> front = packet_number_deque_.front();
- // Check if the packet can be popped on the front
- if (front.min() > packet_number + 1) {
- packet_number_deque_.push_front(
+ // Check if we need to make a new interval for the packet
+ if (packet_interval.max() < packet_number + 1) {
+ packet_number_deque_.insert(
+ packet_number_deque_.begin() + i + 1,
Interval<QuicPacketNumber>(packet_number, packet_number + 1));
return;
}
- if (front.min() == packet_number + 1) {
- packet_number_deque_.front().SetMin(packet_number);
- return;
- }
-
- int i = packet_number_deque_.size() - 1;
- // Iterating through the queue backwards
- // to find a proper place for the packet
- while (i >= 0) {
- Interval<QuicPacketNumber> packet_interval = packet_number_deque_[i];
- DCHECK(packet_interval.min() < packet_interval.max());
- // Check if the packet is contained in an interval already
- if (packet_interval.Contains(packet_number)) {
- return;
- }
-
- // Check if the packet can extend an interval.
- if (packet_interval.max() == packet_number) {
- packet_number_deque_[i].SetMax(packet_number + 1);
- return;
- }
- // Check if the packet can extend an interval
- // and merge two intervals if needed.
- // There is no need to merge an interval in the previous
- // if statement, as all merges will happen here.
- if (packet_interval.min() == packet_number + 1) {
- packet_number_deque_[i].SetMin(packet_number);
- if (i > 0 && packet_number == packet_number_deque_[i - 1].max()) {
- packet_number_deque_[i - 1].SetMax(packet_interval.max());
- packet_number_deque_.erase(packet_number_deque_.begin() + i);
- }
- return;
- }
-
- // Check if we need to make a new interval for the packet
- if (packet_interval.max() < packet_number + 1) {
- packet_number_deque_.insert(
- packet_number_deque_.begin() + i + 1,
- Interval<QuicPacketNumber>(packet_number, packet_number + 1));
- return;
- }
- i--;
- }
- } else {
- packet_number_intervals_.Add(packet_number, packet_number + 1);
+ i--;
}
}
@@ -191,40 +135,34 @@ void PacketNumberQueue::AddRange(QuicPacketNumber lower,
if (lower >= higher) {
return;
}
- if (use_deque_) {
- if (packet_number_deque_.empty()) {
- packet_number_deque_.push_front(
- Interval<QuicPacketNumber>(lower, higher));
- return;
- }
- Interval<QuicPacketNumber> back = packet_number_deque_.back();
+ if (packet_number_deque_.empty()) {
+ packet_number_deque_.push_front(Interval<QuicPacketNumber>(lower, higher));
+ return;
+ }
+ Interval<QuicPacketNumber> back = packet_number_deque_.back();
- if (back.max() == lower) {
- // Check for the typical case,
- // when the next packet in order is acked
- packet_number_deque_.back().SetMax(higher);
- return;
- }
- if (back.max() < lower) {
- // Check if the next packet in order is skipped
- packet_number_deque_.push_back(Interval<QuicPacketNumber>(lower, higher));
- return;
- }
- Interval<QuicPacketNumber> front = packet_number_deque_.front();
- // Check if the packets are being added in reverse order
- if (front.min() == higher) {
- packet_number_deque_.front().SetMin(lower);
- } else if (front.min() > higher) {
- packet_number_deque_.push_front(
- Interval<QuicPacketNumber>(lower, higher));
+ if (back.max() == lower) {
+ // Check for the typical case,
+ // when the next packet in order is acked
+ packet_number_deque_.back().SetMax(higher);
+ return;
+ }
+ if (back.max() < lower) {
+ // Check if the next packet in order is skipped
+ packet_number_deque_.push_back(Interval<QuicPacketNumber>(lower, higher));
+ return;
+ }
+ Interval<QuicPacketNumber> front = packet_number_deque_.front();
+ // Check if the packets are being added in reverse order
+ if (front.min() == higher) {
+ packet_number_deque_.front().SetMin(lower);
+ } else if (front.min() > higher) {
+ packet_number_deque_.push_front(Interval<QuicPacketNumber>(lower, higher));
- } else {
- // Ranges must be above or below all existing ranges.
- QUIC_BUG << "AddRange only supports adding packets above or below the "
- << "current min:" << Min() << " and max:" << Max();
- }
} else {
- packet_number_intervals_.Add(lower, higher);
+ // Ranges must be above or below all existing ranges.
+ QUIC_BUG << "AddRange only supports adding packets above or below the "
+ << "current min:" << Min() << " and max:" << Max();
}
}
@@ -233,151 +171,92 @@ bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
return false;
}
const QuicPacketNumber old_min = Min();
- if (use_deque_) {
- while (!packet_number_deque_.empty()) {
- Interval<QuicPacketNumber> front = packet_number_deque_.front();
- if (front.max() < higher) {
+ while (!packet_number_deque_.empty()) {
+ Interval<QuicPacketNumber> front = packet_number_deque_.front();
+ if (front.max() < higher) {
+ packet_number_deque_.pop_front();
+ } else if (front.min() < higher && front.max() >= higher) {
+ packet_number_deque_.front().SetMin(higher);
+ if (front.max() == higher) {
packet_number_deque_.pop_front();
- } else if (front.min() < higher && front.max() >= higher) {
- packet_number_deque_.front().SetMin(higher);
- if (front.max() == higher) {
- packet_number_deque_.pop_front();
- }
- break;
- } else {
- break;
}
+ break;
+ } else {
+ break;
}
- } else {
- packet_number_intervals_.Difference(0, higher);
}
return Empty() || old_min != Min();
}
void PacketNumberQueue::RemoveSmallestInterval() {
- if (use_deque_) {
- QUIC_BUG_IF(packet_number_deque_.size() < 2)
- << (Empty() ? "No intervals to remove."
- : "Can't remove the last interval.");
- packet_number_deque_.pop_front();
- } else {
- QUIC_BUG_IF(packet_number_intervals_.Size() < 2)
- << (Empty() ? "No intervals to remove."
- : "Can't remove the last interval.");
- packet_number_intervals_.Difference(*packet_number_intervals_.begin());
- }
+ QUIC_BUG_IF(packet_number_deque_.size() < 2)
+ << (Empty() ? "No intervals to remove."
+ : "Can't remove the last interval.");
+ packet_number_deque_.pop_front();
}
bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
- if (use_deque_) {
- if (packet_number_deque_.empty()) {
- return false;
- }
- if (packet_number_deque_.front().min() > packet_number ||
- packet_number_deque_.back().max() <= packet_number) {
- return false;
- }
- for (Interval<QuicPacketNumber> interval : packet_number_deque_) {
- if (interval.Contains(packet_number)) {
- return true;
- }
- }
+ if (packet_number_deque_.empty()) {
return false;
- } else {
- return packet_number_intervals_.Contains(packet_number);
}
+ if (packet_number_deque_.front().min() > packet_number ||
+ packet_number_deque_.back().max() <= packet_number) {
+ return false;
+ }
+ for (Interval<QuicPacketNumber> interval : packet_number_deque_) {
+ if (interval.Contains(packet_number)) {
+ return true;
+ }
+ }
+ return false;
}
bool PacketNumberQueue::Empty() const {
- if (use_deque_) {
- return packet_number_deque_.empty();
- } else {
- return packet_number_intervals_.Empty();
- }
+ return packet_number_deque_.empty();
}
QuicPacketNumber PacketNumberQueue::Min() const {
DCHECK(!Empty());
- if (use_deque_) {
- return packet_number_deque_.front().min();
- } else {
- return packet_number_intervals_.begin()->min();
- }
+ return packet_number_deque_.front().min();
}
QuicPacketNumber PacketNumberQueue::Max() const {
DCHECK(!Empty());
- if (use_deque_) {
- return packet_number_deque_.back().max() - 1;
- } else {
- return packet_number_intervals_.rbegin()->max() - 1;
- }
+ return packet_number_deque_.back().max() - 1;
}
size_t PacketNumberQueue::NumPacketsSlow() const {
- if (use_deque_) {
- int n_packets = 0;
- for (Interval<QuicPacketNumber> interval : packet_number_deque_) {
- n_packets += interval.Length();
- }
- return n_packets;
- } else {
- size_t num_packets = 0;
- for (const auto& interval : packet_number_intervals_) {
- num_packets += interval.Length();
- }
- return num_packets;
+ int n_packets = 0;
+ for (Interval<QuicPacketNumber> interval : packet_number_deque_) {
+ n_packets += interval.Length();
}
+ return n_packets;
}
size_t PacketNumberQueue::NumIntervals() const {
- if (use_deque_) {
- return packet_number_deque_.size();
- } else {
- return packet_number_intervals_.Size();
- }
+ return packet_number_deque_.size();
}
PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
- if (use_deque_) {
- return PacketNumberQueue::const_iterator(packet_number_deque_.begin());
- } else {
- return PacketNumberQueue::const_iterator(packet_number_intervals_.begin());
- }
+ return packet_number_deque_.begin();
}
PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
- if (use_deque_) {
- return const_iterator(packet_number_deque_.end());
- } else {
- return const_iterator(packet_number_intervals_.end());
- }
+ return packet_number_deque_.end();
}
PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
- if (use_deque_) {
- return const_reverse_iterator(packet_number_deque_.rbegin());
- } else {
- return const_reverse_iterator(packet_number_intervals_.rbegin());
- }
+ return packet_number_deque_.rbegin();
}
PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
- if (use_deque_) {
- return const_reverse_iterator(packet_number_deque_.rend());
- } else {
- return const_reverse_iterator(packet_number_intervals_.rend());
- }
+ return packet_number_deque_.rend();
}
QuicPacketNumber PacketNumberQueue::LastIntervalLength() const {
DCHECK(!Empty());
- if (use_deque_) {
- return packet_number_deque_.back().Length();
- } else {
- return packet_number_intervals_.rbegin()->Length();
- }
+ return packet_number_deque_.back().Length();
}
// Largest min...max range for packet numbers where we print the numbers
diff --git a/chromium/net/quic/core/frames/quic_ack_frame.h b/chromium/net/quic/core/frames/quic_ack_frame.h
index c60610aacc9..98fe7012519 100644
--- a/chromium/net/quic/core/frames/quic_ack_frame.h
+++ b/chromium/net/quic/core/frames/quic_ack_frame.h
@@ -29,169 +29,9 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue {
PacketNumberQueue& operator=(const PacketNumberQueue& other);
PacketNumberQueue& operator=(PacketNumberQueue&& other);
- class QUIC_EXPORT_PRIVATE const_iterator {
- public:
- const_iterator(const const_iterator& other);
- const_iterator(const_iterator&& other);
- ~const_iterator();
-
- explicit const_iterator(
- typename QuicIntervalSet<QuicPacketNumber>::const_iterator it);
-
- explicit const_iterator(
- typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator it);
-
- typedef std::input_iterator_tag iterator_category;
- typedef Interval<QuicPacketNumber> value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef typename std::vector<value_type>::iterator::difference_type
- difference_type;
-
- inline const Interval<QuicPacketNumber>& operator*() {
- if (use_deque_it_) {
- return *deque_it_;
- } else {
- return *vector_it_;
- }
- }
-
- inline const_iterator& operator++() {
- if (use_deque_it_) {
- deque_it_++;
- } else {
- vector_it_++;
- }
- return *this;
- }
-
- inline const_iterator& operator--() {
- if (use_deque_it_) {
- deque_it_--;
- } else {
- vector_it_--;
- }
- return *this;
- }
-
- inline const_iterator& operator++(int) {
- if (use_deque_it_) {
- ++deque_it_;
- } else {
- ++vector_it_;
- }
- return *this;
- }
-
- inline bool operator==(const const_iterator& other) {
- if (use_deque_it_ != other.use_deque_it_) {
- return false;
- }
-
- if (use_deque_it_) {
- return deque_it_ == other.deque_it_;
- } else {
- return vector_it_ == other.vector_it_;
- }
- }
-
- inline bool operator!=(const const_iterator& other) {
- return !(*this == other);
- }
-
- private:
- typename QuicIntervalSet<QuicPacketNumber>::const_iterator vector_it_;
- typename QuicDeque<Interval<QuicPacketNumber>>::const_iterator deque_it_;
- const bool use_deque_it_;
- };
-
- class QUIC_EXPORT_PRIVATE const_reverse_iterator {
- public:
- const_reverse_iterator(const const_reverse_iterator& other);
- const_reverse_iterator(const_reverse_iterator&& other);
- ~const_reverse_iterator();
-
- explicit const_reverse_iterator(
- const typename QuicIntervalSet<
- QuicPacketNumber>::const_reverse_iterator& it);
-
- explicit const_reverse_iterator(
- const typename QuicDeque<
- Interval<QuicPacketNumber>>::const_reverse_iterator& it);
-
- typedef std::input_iterator_tag iterator_category;
- typedef Interval<QuicPacketNumber> value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef typename std::vector<value_type>::iterator::difference_type
- difference_type;
-
- inline const Interval<QuicPacketNumber>& operator*() {
- if (use_deque_it_) {
- return *deque_it_;
- } else {
- return *vector_it_;
- }
- }
-
- inline const Interval<QuicPacketNumber>* operator->() {
- if (use_deque_it_) {
- return &*deque_it_;
- } else {
- return &*vector_it_;
- }
- }
-
- inline const_reverse_iterator& operator++() {
- if (use_deque_it_) {
- deque_it_++;
- } else {
- vector_it_++;
- }
- return *this;
- }
-
- inline const_reverse_iterator& operator--() {
- if (use_deque_it_) {
- deque_it_--;
- } else {
- vector_it_--;
- }
- return *this;
- }
-
- inline const_reverse_iterator& operator++(int) {
- if (use_deque_it_) {
- ++deque_it_;
- } else {
- ++vector_it_;
- }
- return *this;
- }
-
- inline bool operator==(const const_reverse_iterator& other) {
- if (use_deque_it_ != other.use_deque_it_) {
- return false;
- }
-
- if (use_deque_it_) {
- return deque_it_ == other.deque_it_;
- } else {
- return vector_it_ == other.vector_it_;
- }
- }
-
- inline bool operator!=(const const_reverse_iterator& other) {
- return !(*this == other);
- }
-
- private:
- typename QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator
- vector_it_;
- typename QuicDeque<Interval<QuicPacketNumber>>::const_reverse_iterator
- deque_it_;
- const bool use_deque_it_;
- };
+ typedef QuicDeque<Interval<QuicPacketNumber>>::const_iterator const_iterator;
+ typedef QuicDeque<Interval<QuicPacketNumber>>::const_reverse_iterator
+ const_reverse_iterator;
// Adds |packet_number| to the set of packets in the queue.
void Add(QuicPacketNumber packet_number);
@@ -243,11 +83,7 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue {
const PacketNumberQueue& q);
private:
- // TODO(lilika): Remove QuicIntervalSet<QuicPacketNumber>
- // once FLAGS_quic_reloadable_flag_quic_frames_deque2 is removed
- QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
QuicDeque<Interval<QuicPacketNumber>> packet_number_deque_;
- bool use_deque_;
};
struct QUIC_EXPORT_PRIVATE QuicAckFrame {
@@ -259,9 +95,10 @@ struct QUIC_EXPORT_PRIVATE QuicAckFrame {
std::ostream& os,
const QuicAckFrame& ack_frame);
- // The highest packet number we've observed from the peer.
- // This is being deprecated.
- QuicPacketNumber deprecated_largest_observed;
+ // The highest packet number we've observed from the peer. When |packets| is
+ // not empty, it should always be equal to packets.Max(). The |LargestAcked|
+ // function ensures this invariant in debug mode.
+ QuicPacketNumber largest_acked;
// Time elapsed since largest_observed() was received until this Ack frame was
// sent.
@@ -276,7 +113,11 @@ struct QUIC_EXPORT_PRIVATE QuicAckFrame {
// The highest acked packet number we've observed from the peer. If no packets
// have been observed, return 0.
-QUIC_EXPORT_PRIVATE QuicPacketNumber LargestAcked(const QuicAckFrame& frame);
+inline QUIC_EXPORT_PRIVATE QuicPacketNumber
+LargestAcked(const QuicAckFrame& frame) {
+ DCHECK(frame.packets.Empty() || frame.packets.Max() == frame.largest_acked);
+ return frame.largest_acked;
+}
// True if the packet number is greater than largest_observed or is listed
// as missing.
diff --git a/chromium/net/quic/core/frames/quic_frame.cc b/chromium/net/quic/core/frames/quic_frame.cc
index 6007cb3fa25..be96ff00450 100644
--- a/chromium/net/quic/core/frames/quic_frame.cc
+++ b/chromium/net/quic/core/frames/quic_frame.cc
@@ -153,6 +153,32 @@ void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
}
}
+QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
+ QuicFrame copy;
+ switch (frame.type) {
+ case RST_STREAM_FRAME:
+ copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
+ break;
+ case GOAWAY_FRAME:
+ copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
+ break;
+ case WINDOW_UPDATE_FRAME:
+ copy = QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame));
+ break;
+ case BLOCKED_FRAME:
+ copy = QuicFrame(new QuicBlockedFrame(*frame.blocked_frame));
+ break;
+ case PING_FRAME:
+ copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
+ break;
+ default:
+ QUIC_BUG << "Try to copy a non-retransmittable control frame: " << frame;
+ copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
+ break;
+ }
+ return copy;
+}
+
std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
switch (frame.type) {
case PADDING_FRAME: {
diff --git a/chromium/net/quic/core/frames/quic_frame.h b/chromium/net/quic/core/frames/quic_frame.h
index 49f81eee263..b02ceaefc84 100644
--- a/chromium/net/quic/core/frames/quic_frame.h
+++ b/chromium/net/quic/core/frames/quic_frame.h
@@ -89,6 +89,10 @@ GetControlFrameId(const QuicFrame& frame);
QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id,
QuicFrame* frame);
+// Returns a copy of |frame|.
+QUIC_EXPORT_PRIVATE QuicFrame
+CopyRetransmittableControlFrame(const QuicFrame& frame);
+
} // namespace net
#endif // NET_QUIC_CORE_FRAMES_QUIC_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_frames_test.cc b/chromium/net/quic/core/frames/quic_frames_test.cc
index 87f9d2ad7d6..7e81b98d6da 100644
--- a/chromium/net/quic/core/frames/quic_frames_test.cc
+++ b/chromium/net/quic/core/frames/quic_frames_test.cc
@@ -25,7 +25,7 @@ class QuicFramesTest : public QuicTest {};
TEST_F(QuicFramesTest, AckFrameToString) {
QuicAckFrame frame;
- frame.deprecated_largest_observed = 5;
+ frame.largest_acked = 5;
frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
frame.packets.Add(4);
frame.packets.Add(5);
@@ -41,7 +41,7 @@ TEST_F(QuicFramesTest, AckFrameToString) {
TEST_F(QuicFramesTest, BigAckFrameToString) {
QuicAckFrame frame;
- frame.deprecated_largest_observed = 500;
+ frame.largest_acked = 500;
frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
frame.packets.AddRange(4, 501);
frame.received_packet_times = {
@@ -159,7 +159,7 @@ TEST_F(QuicFramesTest, StopWaitingFrameToString) {
TEST_F(QuicFramesTest, IsAwaitingPacket) {
QuicAckFrame ack_frame1;
- ack_frame1.deprecated_largest_observed = 10u;
+ ack_frame1.largest_acked = 10u;
ack_frame1.packets.AddRange(1, 11);
EXPECT_TRUE(IsAwaitingPacket(ack_frame1, 11u, 0u));
EXPECT_FALSE(IsAwaitingPacket(ack_frame1, 1u, 0u));
@@ -168,7 +168,7 @@ TEST_F(QuicFramesTest, IsAwaitingPacket) {
EXPECT_TRUE(IsAwaitingPacket(ack_frame1, 11u, 0u));
QuicAckFrame ack_frame2;
- ack_frame2.deprecated_largest_observed = 100u;
+ ack_frame2.largest_acked = 100u;
ack_frame2.packets.AddRange(21, 100);
EXPECT_FALSE(IsAwaitingPacket(ack_frame2, 11u, 20u));
EXPECT_FALSE(IsAwaitingPacket(ack_frame2, 80u, 20u));
@@ -266,78 +266,19 @@ TEST_F(QuicFramesTest, AddInterval) {
EXPECT_EQ(expected_intervals, actual_intervals);
- if (FLAGS_quic_reloadable_flag_quic_frames_deque3) {
- // Ensure adding a range within the existing ranges fails.
- EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(20, 30), "");
- } else {
- ack_frame1.packets.AddRange(20, 30);
- }
+ // Ensure adding a range within the existing ranges fails.
+ EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(20, 30), "");
const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals2;
expected_intervals2.emplace_back(Interval<QuicPacketNumber>(1, 10));
- if (!FLAGS_quic_reloadable_flag_quic_frames_deque3) {
- expected_intervals2.emplace_back(Interval<QuicPacketNumber>(20, 30));
- }
expected_intervals2.emplace_back(Interval<QuicPacketNumber>(50, 100));
EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
EXPECT_EQ(expected_intervals2, actual_intervals2);
- if (!FLAGS_quic_reloadable_flag_quic_frames_deque3) {
- ack_frame1.packets.AddRange(15, 20);
- ack_frame1.packets.AddRange(30, 35);
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals3(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals3;
- expected_intervals3.emplace_back(Interval<QuicPacketNumber>(1, 10));
- expected_intervals3.emplace_back(Interval<QuicPacketNumber>(15, 35));
- expected_intervals3.emplace_back(Interval<QuicPacketNumber>(50, 100));
-
- EXPECT_EQ(expected_intervals3, actual_intervals3);
-
- ack_frame1.packets.AddRange(20, 35);
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals4(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals3, actual_intervals4);
- ack_frame1.packets.AddRange(12, 20);
- ack_frame1.packets.AddRange(30, 38);
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals5(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals5;
- expected_intervals5.emplace_back(Interval<QuicPacketNumber>(1, 10));
- expected_intervals5.emplace_back(Interval<QuicPacketNumber>(12, 38));
- expected_intervals5.emplace_back(Interval<QuicPacketNumber>(50, 100));
-
- EXPECT_EQ(expected_intervals5, actual_intervals5);
- ack_frame1.packets.AddRange(8, 55);
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals6(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals6;
- expected_intervals6.emplace_back(Interval<QuicPacketNumber>(1, 100));
-
- EXPECT_EQ(expected_intervals6, actual_intervals6);
- ack_frame1.packets.AddRange(0, 200);
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals7(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals7;
- expected_intervals7.emplace_back(Interval<QuicPacketNumber>(0, 200));
-
- EXPECT_EQ(expected_intervals7, actual_intervals7);
- }
-
// Add ranges at both ends.
QuicAckFrame ack_frame2;
ack_frame2.packets.AddRange(20, 25);
@@ -391,91 +332,9 @@ TEST_F(QuicFramesTest, AddAdjacentReverse) {
EXPECT_EQ(expected_intervals, actual_intervals);
}
-TEST_F(QuicFramesTest, AddMerges) {
- FLAGS_quic_reloadable_flag_quic_frames_deque3 = false;
- QuicAckFrame ack_frame1;
- ack_frame1.packets.AddRange(110, 112);
- ack_frame1.packets.AddRange(106, 108);
- ack_frame1.packets.AddRange(102, 104);
- ack_frame1.packets.AddRange(1, 2);
- ack_frame1.packets.AddRange(4, 7);
- ack_frame1.packets.AddRange(10, 20);
- ack_frame1.packets.AddRange(21, 30);
- ack_frame1.packets.Add(20);
- ack_frame1.packets.AddRange(40, 50);
- ack_frame1.packets.AddRange(30, 35);
- ack_frame1.packets.AddRange(35, 40);
- ack_frame1.packets.AddRange(108, 110);
- ack_frame1.packets.AddRange(50, 106);
- ack_frame1.packets.AddRange(2, 4);
- ack_frame1.packets.AddRange(7, 11);
- std::vector<Interval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(1, 112));
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
-}
-
-TEST_F(QuicFramesTest, AddIntervalBig) {
- FLAGS_quic_reloadable_flag_quic_frames_deque3 = false;
- QuicAckFrame ack_frame1;
- ack_frame1.packets.AddRange(20, 30);
- ack_frame1.packets.AddRange(70, 100);
- ack_frame1.packets.AddRange(56, 58);
- ack_frame1.packets.AddRange(65, 69);
- ack_frame1.packets.AddRange(59, 64);
- ack_frame1.packets.AddRange(50, 55);
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals;
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(20, 30));
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(50, 55));
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(56, 58));
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(59, 64));
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(65, 69));
- expected_intervals.emplace_back(Interval<QuicPacketNumber>(70, 100));
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals, actual_intervals);
- ack_frame1.packets.AddRange(10, 60);
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals2;
- expected_intervals2.emplace_back(Interval<QuicPacketNumber>(10, 64));
- expected_intervals2.emplace_back(Interval<QuicPacketNumber>(65, 69));
- expected_intervals2.emplace_back(Interval<QuicPacketNumber>(70, 100));
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals2, actual_intervals2);
-
- ack_frame1.packets.AddRange(68, 1000);
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals3;
- expected_intervals3.emplace_back(Interval<QuicPacketNumber>(10, 64));
- expected_intervals3.emplace_back(Interval<QuicPacketNumber>(65, 1000));
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals3(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals3, actual_intervals3);
- ack_frame1.packets.AddRange(0, 10000);
-
- std::vector<Interval<QuicPacketNumber>> expected_intervals4;
- expected_intervals4.emplace_back(Interval<QuicPacketNumber>(0, 10000));
-
- const std::vector<Interval<QuicPacketNumber>> actual_intervals4(
- ack_frame1.packets.begin(), ack_frame1.packets.end());
-
- EXPECT_EQ(expected_intervals4, actual_intervals4);
-}
-
TEST_F(QuicFramesTest, RemoveSmallestInterval) {
QuicAckFrame ack_frame1;
- ack_frame1.deprecated_largest_observed = 100u;
+ ack_frame1.largest_acked = 100u;
ack_frame1.packets.AddRange(51, 60);
ack_frame1.packets.AddRange(71, 80);
ack_frame1.packets.AddRange(91, 100);
diff --git a/chromium/net/quic/core/quic_client_promised_info_test.cc b/chromium/net/quic/core/quic_client_promised_info_test.cc
index 9d5d758cdaa..f8bed9edf80 100644
--- a/chromium/net/quic/core/quic_client_promised_info_test.cc
+++ b/chromium/net/quic/core/quic_client_promised_info_test.cc
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_test.h"
@@ -35,7 +36,8 @@ class MockQuicSpdyClientSession : public QuicSpdyClientSession {
QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED),
&crypto_config_,
push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
authorized_(true) {}
~MockQuicSpdyClientSession() override {}
diff --git a/chromium/net/quic/core/quic_client_push_promise_index_test.cc b/chromium/net/quic/core/quic_client_push_promise_index_test.cc
index 9f980f14da5..3ab3a88e9f6 100644
--- a/chromium/net/quic/core/quic_client_push_promise_index_test.cc
+++ b/chromium/net/quic/core/quic_client_push_promise_index_test.cc
@@ -7,6 +7,7 @@
#include <string>
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_quic_client_promised_info.h"
@@ -34,7 +35,8 @@ class MockQuicSpdyClientSession : public QuicSpdyClientSession {
QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED),
&crypto_config_,
push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()) {}
~MockQuicSpdyClientSession() override {}
MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
diff --git a/chromium/net/quic/core/quic_config.cc b/chromium/net/quic/core/quic_config.cc
index 104333a48fe..593fb641391 100644
--- a/chromium/net/quic/core/quic_config.cc
+++ b/chromium/net/quic/core/quic_config.cc
@@ -668,7 +668,7 @@ void QuicConfig::SetDefaults() {
SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) {
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
SetSupportMaxHeaderListSize();
}
}
diff --git a/chromium/net/quic/core/quic_connection.cc b/chromium/net/quic/core/quic_connection.cc
index bbca3b58d57..027c90d35f5 100644
--- a/chromium/net/quic/core/quic_connection.cc
+++ b/chromium/net/quic/core/quic_connection.cc
@@ -178,12 +178,12 @@ QuicConnection::QuicConnection(
QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: framer_(supported_versions,
helper->GetClock()->ApproximateNow(),
perspective),
server_reply_to_connectivity_probes_(
- FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing),
+ GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)),
current_packet_content_(NO_FRAMES_RECEIVED),
current_peer_migration_type_(NO_CHANGE),
helper_(helper),
@@ -258,7 +258,7 @@ QuicConnection::QuicConnection(
perspective,
clock_,
&stats_,
- FLAGS_quic_reloadable_flag_quic_default_to_bbr ? kBBR : kCubicBytes,
+ GetQuicReloadableFlag(quic_default_to_bbr) ? kBBR : kCubicBytes,
kNack),
version_negotiation_state_(START_NEGOTIATION),
perspective_(perspective),
@@ -361,7 +361,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
close_connection_after_five_rtos_ = true;
}
- if (FLAGS_quic_reloadable_flag_quic_enable_3rtos &&
+ if (GetQuicReloadableFlag(quic_enable_3rtos) &&
config.HasClientSentConnectionOption(k3RTO, perspective_)) {
QUIC_FLAG_COUNT(quic_reloadable_flag_quic_enable_3rtos);
close_connection_after_three_rtos_ = true;
@@ -406,14 +406,14 @@ void QuicConnection::SetNumOpenStreams(size_t num_streams) {
}
bool QuicConnection::SelectMutualVersion(
- const QuicTransportVersionVector& available_versions) {
+ const ParsedQuicVersionVector& available_versions) {
// Try to find the highest mutual version by iterating over supported
// versions, starting with the highest, and breaking out of the loop once we
// find a matching version in the provided available_versions vector.
- const QuicTransportVersionVector& supported_versions =
+ const ParsedQuicVersionVector& supported_versions =
framer_.supported_versions();
for (size_t i = 0; i < supported_versions.size(); ++i) {
- const QuicTransportVersion& version = supported_versions[i];
+ const ParsedQuicVersion& version = supported_versions[i];
if (QuicContainsValue(available_versions, version)) {
framer_.set_version(version);
return true;
@@ -452,9 +452,9 @@ void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
}
bool QuicConnection::OnProtocolVersionMismatch(
- QuicTransportVersion received_version) {
+ ParsedQuicVersion received_version) {
QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
- << received_version;
+ << ParsedQuicVersionToString(received_version);
// TODO(satyamshekhar): Implement no server state in this mode.
if (perspective_ == Perspective::IS_CLIENT) {
const string error_details = "Protocol version mismatch.";
@@ -463,7 +463,7 @@ bool QuicConnection::OnProtocolVersionMismatch(
ConnectionCloseSource::FROM_SELF);
return false;
}
- DCHECK_NE(transport_version(), received_version);
+ DCHECK_NE(version(), received_version);
if (debug_visitor_ != nullptr) {
debug_visitor_->OnProtocolVersionMismatch(received_version);
@@ -495,11 +495,13 @@ bool QuicConnection::OnProtocolVersionMismatch(
}
version_negotiation_state_ = NEGOTIATED_VERSION;
- visitor_->OnSuccessfulVersionNegotiation(received_version);
+ visitor_->OnSuccessfulVersionNegotiation(received_version.transport_version);
if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(received_version);
+ debug_visitor_->OnSuccessfulVersionNegotiation(
+ received_version.transport_version);
}
- QUIC_DLOG(INFO) << ENDPOINT << "version negotiated " << received_version;
+ QUIC_DLOG(INFO) << ENDPOINT << "version negotiated "
+ << ParsedQuicVersionToString(received_version);
// Store the new version.
framer_.set_version(received_version);
@@ -533,7 +535,7 @@ void QuicConnection::OnVersionNegotiationPacket(
return;
}
- if (QuicContainsValue(packet.versions, transport_version())) {
+ if (QuicContainsValue(packet.versions, version())) {
const string error_details =
"Server already supports client's version and should have accepted the "
"connection.";
@@ -551,9 +553,9 @@ void QuicConnection::OnVersionNegotiationPacket(
QUIC_INVALID_VERSION,
QuicStrCat(
"No common version found. Supported versions: {",
- QuicTransportVersionVectorToString(framer_.supported_versions()),
+ ParsedQuicVersionVectorToString(framer_.supported_versions()),
"}, peer supported versions: {",
- QuicTransportVersionVectorToString(packet.versions), "}"),
+ ParsedQuicVersionVectorToString(packet.versions), "}"),
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return;
}
@@ -859,14 +861,12 @@ const char* QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
return "Largest observed too low.";
}
- // TODO(wub): Remove this check along with
- // FLAGS_quic_reloadable_flag_quic_deprecate_largest_observed.
if (!incoming_ack.packets.Empty() &&
incoming_ack.packets.Max() != LargestAcked(incoming_ack)) {
QUIC_BUG << ENDPOINT
<< "Peer last received packet: " << incoming_ack.packets.Max()
<< " which is not equal to largest observed: "
- << incoming_ack.deprecated_largest_observed;
+ << incoming_ack.largest_acked;
return "Last received packet not equal to largest observed.";
}
@@ -1161,7 +1161,7 @@ void QuicConnection::SendVersionNegotiationPacket() {
return;
}
QUIC_DLOG(INFO) << ENDPOINT << "Sending version negotiation packet: {"
- << QuicTransportVersionVectorToString(
+ << ParsedQuicVersionVectorToString(
framer_.supported_versions())
<< "}";
std::unique_ptr<QuicEncryptedPacket> version_packet(
@@ -1219,10 +1219,7 @@ void QuicConnection::SendRstStream(QuicStreamId id,
return;
}
// Flush stream frames of reset stream.
- if (FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded &&
- packet_generator_.HasPendingStreamFramesOfStream(id)) {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_remove_on_stream_frame_discarded, 2, 2);
+ if (packet_generator_.HasPendingStreamFramesOfStream(id)) {
packet_generator_.FlushAllQueuedFrames();
}
@@ -1414,7 +1411,7 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
if (self_address_.port() != last_packet_destination_address_.port() ||
self_address_.host().Normalized() !=
last_packet_destination_address_.host().Normalized()) {
- if (!FLAGS_quic_reloadable_flag_quic_allow_address_change_for_udp_proxy ||
+ if (!GetQuicReloadableFlag(quic_allow_address_change_for_udp_proxy) ||
!visitor_->AllowSelfAddressChange()) {
CloseConnection(
QUIC_ERROR_MIGRATING_ADDRESS,
@@ -1426,7 +1423,7 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
self_address_ = last_packet_destination_address_;
}
- if (FLAGS_quic_restart_flag_quic_enable_accept_random_ipn) {
+ if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
QUIC_FLAG_COUNT_N(quic_restart_flag_quic_enable_accept_random_ipn, 2, 2);
// Configured to accept any packet number in range 1...0x7fffffff
// as initial packet number.
@@ -1488,7 +1485,7 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return false;
} else {
- DCHECK_EQ(header.version, transport_version());
+ DCHECK_EQ(header.version, version());
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(transport_version());
if (debug_visitor_ != nullptr) {
@@ -2017,6 +2014,11 @@ void QuicConnection::SetDiversificationNonce(
}
void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
+ if (level != encryption_level_ && packet_generator_.HasQueuedFrames()) {
+ // Flush all queued frames when encryption level changes.
+ ScopedPacketFlusher flusher(this, NO_ACK);
+ packet_generator_.FlushAllQueuedFrames();
+ }
encryption_level_ = level;
packet_generator_.set_encryption_level(level);
}
@@ -2250,7 +2252,7 @@ void QuicConnection::CheckForTimeout() {
if (idle_duration >= idle_network_timeout_) {
const string error_details = "No recent network activity.";
QUIC_DVLOG(1) << ENDPOINT << error_details;
- if (FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp &&
+ if (GetQuicReloadableFlag(quic_explicit_close_after_tlp) &&
(sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
visitor_->HasOpenDynamicStreams())) {
@@ -2357,15 +2359,19 @@ QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
// If caller wants us to include an ack, check the delayed-ack timer to see if
// there's ack info to be sent.
if (ShouldSendAck(ack_mode)) {
- QUIC_DVLOG(1) << "Bundling ack with outgoing packet.";
- DCHECK(ack_mode == SEND_ACK || connection_->ack_frame_updated() ||
- connection_->stop_waiting_count_ > 1);
- connection_->SendAck();
+ if (!GetQuicReloadableFlag(quic_strict_ack_handling) ||
+ !connection_->GetUpdatedAckFrame().ack_frame->packets.Empty()) {
+ QUIC_DVLOG(1) << "Bundling ack with outgoing packet.";
+ connection_->SendAck();
+ }
}
}
bool QuicConnection::ScopedPacketFlusher::ShouldSendAck(
AckBundling ack_mode) const {
+ // If the ack alarm is set, make sure the ack has been updated.
+ DCHECK(!connection_->ack_alarm_->IsSet() || connection_->ack_frame_updated())
+ << "ack_mode:" << ack_mode;
switch (ack_mode) {
case SEND_ACK:
return true;
@@ -2588,8 +2594,13 @@ void QuicConnection::StartPeerMigration(
// TODO(jri): Move these calls to OnPeerMigrationValidated. Rename
// OnConnectionMigration methods to OnPeerMigration.
- visitor_->OnConnectionMigration(peer_migration_type);
- sent_packet_manager_.OnConnectionMigration(peer_migration_type);
+ OnConnectionMigration(peer_migration_type);
+}
+
+void QuicConnection::OnConnectionMigration(
+ PeerAddressChangeType addr_change_type) {
+ visitor_->OnConnectionMigration(addr_change_type);
+ sent_packet_manager_.OnConnectionMigration(addr_change_type);
}
bool QuicConnection::ack_frame_updated() const {
@@ -2730,9 +2741,9 @@ void QuicConnection::UpdatePacketContent(PacketContent type) {
current_peer_migration_type_ = NO_CHANGE;
}
-void QuicConnection::SetStreamNotifier(
- StreamNotifierInterface* stream_notifier) {
- sent_packet_manager_.SetStreamNotifier(stream_notifier);
+void QuicConnection::SetSessionNotifier(
+ SessionNotifierInterface* session_notifier) {
+ sent_packet_manager_.SetSessionNotifier(session_notifier);
}
void QuicConnection::SetDataProducer(
diff --git a/chromium/net/quic/core/quic_connection.h b/chromium/net/quic/core/quic_connection.h
index f45293a71d2..bdb90a91516 100644
--- a/chromium/net/quic/core/quic_connection.h
+++ b/chromium/net/quic/core/quic_connection.h
@@ -26,6 +26,7 @@
#include "base/macros.h"
#include "net/quic/core/crypto/quic_decrypter.h"
+#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/core/quic_alarm.h"
#include "net/quic/core/quic_alarm_factory.h"
#include "net/quic/core/quic_blocked_writer_interface.h"
@@ -55,7 +56,6 @@ class QuicEncrypter;
class QuicRandom;
namespace test {
-class PacketSavingConnection;
class QuicConnectionPeer;
} // namespace test
@@ -209,7 +209,7 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
// Called when the protocol version on the received packet doensn't match
// current protocol version of the connection.
- virtual void OnProtocolVersionMismatch(QuicTransportVersion version) {}
+ virtual void OnProtocolVersionMismatch(ParsedQuicVersion version) {}
// Called when the complete header of a packet has been parsed.
virtual void OnPacketHeader(const QuicPacketHeader& header) {}
@@ -265,7 +265,7 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
virtual void OnSendConnectionState(
const CachedNetworkParameters& cached_network_params) {}
- // Called when a CachedNetworkParameters are recieved from the client.
+ // Called when a CachedNetworkParameters are received from the client.
virtual void OnReceiveConnectionState(
const CachedNetworkParameters& cached_network_params) {}
@@ -325,7 +325,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
~QuicConnection() override;
// Sets connection parameters from the supplied |config|.
@@ -435,20 +435,16 @@ class QUIC_EXPORT_PRIVATE QuicConnection
return framer_.transport_version();
}
- // The QuicVersionLabel for the version this connection is using.
- QuicVersionLabel version_label() const {
- return framer_.last_version_label();
- }
+ ParsedQuicVersion version() const { return framer_.version(); }
// The versions of the protocol that this connection supports.
- const QuicTransportVersionVector& supported_versions() const {
+ const ParsedQuicVersionVector& supported_versions() const {
return framer_.supported_versions();
}
// From QuicFramerVisitorInterface
void OnError(QuicFramer* framer) override;
- bool OnProtocolVersionMismatch(
- QuicTransportVersion received_version) override;
+ bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
void OnPacket() override;
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
void OnVersionNegotiationPacket(
@@ -529,7 +525,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
bool goaway_received() const { return goaway_received_; }
// Must only be called on client connections.
- const QuicTransportVersionVector& server_supported_versions() const {
+ const ParsedQuicVersionVector& server_supported_versions() const {
DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
return server_supported_versions_;
}
@@ -683,8 +679,8 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// the MTU discovery alarm.
void DiscoverMtu();
- // Sets the stream notifer on the SentPacketManager.
- void SetStreamNotifier(StreamNotifierInterface* stream_notifier);
+ // Sets the session notifier on the SentPacketManager.
+ void SetSessionNotifier(SessionNotifierInterface* session_notifier);
// Set data producer in framer.
void SetDataProducer(QuicStreamFrameDataProducer* data_producer);
@@ -751,8 +747,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Selects and updates the version of the protocol being used by selecting a
// version from |available_versions| which is also supported. Returns true if
// such a version exists, false otherwise.
- bool SelectMutualVersion(
- const QuicTransportVersionVector& available_versions);
+ bool SelectMutualVersion(const ParsedQuicVersionVector& available_versions);
// Returns the current per-packet options for the connection.
PerPacketOptions* per_packet_options() { return per_packet_options_; }
@@ -783,9 +778,12 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Decides whether to send probing retransmissions, and does so if required.
void MaybeSendProbingRetransmissions();
+ // Notify various components(SendPacketManager, Session etc.) that this
+ // connection has been migrated.
+ void OnConnectionMigration(PeerAddressChangeType addr_change_type);
+
private:
friend class test::QuicConnectionPeer;
- friend class test::PacketSavingConnection;
typedef std::list<SerializedPacket> QueuedPacketList;
@@ -1113,7 +1111,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// If non-empty this contains the set of versions received in a
// version negotiation packet.
- QuicTransportVersionVector server_supported_versions_;
+ ParsedQuicVersionVector server_supported_versions_;
// The size of the packet we are targeting while doing path MTU discovery.
QuicByteCount mtu_discovery_target_;
diff --git a/chromium/net/quic/core/quic_connection_test.cc b/chromium/net/quic/core/quic_connection_test.cc
index 254eabe53b9..adf70273d05 100644
--- a/chromium/net/quic/core/quic_connection_test.cc
+++ b/chromium/net/quic/core/quic_connection_test.cc
@@ -117,6 +117,7 @@ class TaggingEncrypter : public QuicEncrypter {
size_t GetKeySize() const override { return 0; }
size_t GetNoncePrefixSize() const override { return 0; }
+ size_t GetIVSize() const override { return 0; }
size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
return ciphertext_size - kTagSize;
@@ -180,6 +181,8 @@ class TaggingDecrypter : public QuicDecrypter {
return true;
}
+ size_t GetKeySize() const override { return 0; }
+ size_t GetIVSize() const override { return 0; }
QuicStringPiece GetKey() const override { return QuicStringPiece(); }
QuicStringPiece GetNoncePrefix() const override { return QuicStringPiece(); }
// Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
@@ -277,9 +280,9 @@ class TestAlarmFactory : public QuicAlarmFactory {
class TestPacketWriter : public QuicPacketWriter {
public:
- TestPacketWriter(QuicTransportVersion version, MockClock* clock)
+ TestPacketWriter(ParsedQuicVersion version, MockClock* clock)
: version_(version),
- framer_(SupportedTransportVersions(version_), Perspective::IS_SERVER),
+ framer_(SupportedVersions(version_), Perspective::IS_SERVER),
last_packet_size_(0),
write_blocked_(false),
write_should_fail_(false),
@@ -445,9 +448,8 @@ class TestPacketWriter : public QuicPacketWriter {
void Reset() { framer_.Reset(); }
- void SetSupportedTransportVersions(
- const QuicTransportVersionVector& versions) {
- framer_.SetSupportedTransportVersions(versions);
+ void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+ framer_.SetSupportedVersions(versions);
}
void set_max_packet_size(QuicByteCount max_packet_size) {
@@ -455,7 +457,7 @@ class TestPacketWriter : public QuicPacketWriter {
}
private:
- QuicTransportVersion version_;
+ ParsedQuicVersion version_;
SimpleQuicFramer framer_;
size_t last_packet_size_;
QuicPacketHeader last_packet_header_;
@@ -486,7 +488,7 @@ class TestConnection : public QuicConnection {
TestAlarmFactory* alarm_factory,
TestPacketWriter* writer,
Perspective perspective,
- QuicTransportVersion version)
+ ParsedQuicVersion version)
: QuicConnection(connection_id,
address,
helper,
@@ -494,7 +496,7 @@ class TestConnection : public QuicConnection {
writer,
/* owns_writer= */ false,
perspective,
- SupportedTransportVersions(version)) {
+ SupportedVersions(version)) {
writer->set_perspective(perspective);
SetEncrypter(ENCRYPTION_FORWARD_SECURE, new NullEncrypter(perspective));
SetDataProducer(&producer_);
@@ -578,15 +580,13 @@ class TestConnection : public QuicConnection {
return SendStreamDataWithString(kCryptoStreamId, "chlo", 0, NO_FIN);
}
- void set_version(QuicTransportVersion version) {
+ void set_version(ParsedQuicVersion version) {
QuicConnectionPeer::GetFramer(this)->set_version(version);
}
- void SetSupportedTransportVersions(
- const QuicTransportVersionVector& versions) {
- QuicConnectionPeer::GetFramer(this)->SetSupportedTransportVersions(
- versions);
- writer()->SetSupportedTransportVersions(versions);
+ void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+ QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
+ writer()->SetSupportedVersions(versions);
}
void set_perspective(Perspective perspective) {
@@ -674,9 +674,9 @@ class TestConnection : public QuicConnection {
enum class AckResponse { kDefer, kImmediate };
-// Run tests with combinations of {QuicTransportVersion, AckResponse}.
+// Run tests with combinations of {ParsedQuicVersion, AckResponse}.
struct TestParams {
- TestParams(QuicTransportVersion version,
+ TestParams(ParsedQuicVersion version,
AckResponse ack_response,
bool no_stop_waiting)
: version(version),
@@ -684,14 +684,14 @@ struct TestParams {
no_stop_waiting(no_stop_waiting) {}
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ client_version: " << QuicVersionToString(p.version)
+ os << "{ client_version: " << ParsedQuicVersionToString(p.version)
<< " ack_response: "
<< (p.ack_response == AckResponse::kDefer ? "defer" : "immediate")
<< " no_stop_waiting: " << p.no_stop_waiting << " }";
return os;
}
- QuicTransportVersion version;
+ ParsedQuicVersion version;
AckResponse ack_response;
bool no_stop_waiting;
};
@@ -699,8 +699,7 @@ struct TestParams {
// Constructs various test permutations.
std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
- QuicTransportVersionVector all_supported_versions =
- AllSupportedTransportVersions();
+ ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
for (size_t i = 0; i < all_supported_versions.size(); ++i) {
for (AckResponse ack_response :
{AckResponse::kDefer, AckResponse::kImmediate}) {
@@ -717,27 +716,27 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
protected:
QuicConnectionTest()
: connection_id_(42),
- framer_(SupportedTransportVersions(transport_version()),
+ framer_(SupportedVersions(version()),
QuicTime::Zero(),
Perspective::IS_CLIENT),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
alarm_factory_(new TestAlarmFactory()),
- peer_framer_(SupportedTransportVersions(transport_version()),
+ peer_framer_(SupportedVersions(version()),
QuicTime::Zero(),
Perspective::IS_SERVER),
peer_creator_(connection_id_,
&peer_framer_,
/*delegate=*/nullptr),
- writer_(new TestPacketWriter(transport_version(), &clock_)),
+ writer_(new TestPacketWriter(version(), &clock_)),
connection_(connection_id_,
kPeerAddress,
helper_.get(),
alarm_factory_.get(),
writer_.get(),
Perspective::IS_CLIENT,
- transport_version()),
+ version()),
creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
generator_(QuicConnectionPeer::GetPacketGenerator(&connection_)),
manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
@@ -782,7 +781,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
.Times(AnyNumber());
}
- QuicTransportVersion transport_version() { return GetParam().version; }
+ ParsedQuicVersion version() { return GetParam().version; }
QuicAckFrame* outgoing_ack() {
QuicFrame ack_frame = QuicConnectionPeer::GetUpdatedAckFrame(&connection_);
@@ -862,7 +861,8 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
const size_t encrypted_length = peer_framer_.EncryptInPlace(
ENCRYPTION_NONE, header.packet_number,
- GetStartOfEncryptedData(peer_framer_.transport_version(), header),
+ GetStartOfEncryptedData(peer_framer_.version().transport_version,
+ header),
length, kMaxPacketSize, encrypted_buffer);
DCHECK_GT(encrypted_length, 0u);
@@ -1056,7 +1056,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
ConnectionCloseSource::FROM_SELF));
// Call ProcessDataPacket rather than ProcessPacket, as we should not get a
// packet call to the visitor.
- if (FLAGS_quic_restart_flag_quic_enable_accept_random_ipn) {
+ if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
ProcessDataPacket(kMaxRandomInitialPacketNumber + 6000);
} else {
ProcessDataPacket(6000);
@@ -1170,7 +1170,7 @@ TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
QuicIpAddress host;
host.FromString("1.1.1.1");
QuicSocketAddress self_address(host, 123);
- if (FLAGS_quic_reloadable_flag_quic_allow_address_change_for_udp_proxy) {
+ if (GetQuicReloadableFlag(quic_allow_address_change_for_udp_proxy)) {
EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
}
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_ERROR_MIGRATING_ADDRESS, _, _));
@@ -1306,7 +1306,7 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtServer) {
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(1);
} else {
@@ -1326,7 +1326,7 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtServer) {
ConstructReceivedPacket(*probing_packet, clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_EQ(kPeerAddress, connection_.peer_address());
} else {
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
@@ -1355,7 +1355,7 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(1);
} else {
@@ -1373,7 +1373,7 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*probing_packet, clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_EQ(kPeerAddress, connection_.peer_address());
} else {
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
@@ -1381,7 +1381,7 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
// Process another non-probing packet with the new peer address on server
// side will start peer migration.
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
} else {
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
@@ -1440,7 +1440,7 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtClient) {
// Process a padded PING packet with a different self address on client side
// is effectively receiving a connectivity probing.
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(1);
}
@@ -1491,7 +1491,7 @@ TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
QuicConnectionId connection_id = 42;
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
alarm_factory_.get(), writer_.get(),
- Perspective::IS_SERVER, transport_version());
+ Perspective::IS_SERVER, version());
EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
EXPECT_EQ(1000u, connection.max_packet_length());
}
@@ -1517,7 +1517,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSize) {
ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize);
EXPECT_EQ(kMaxPacketSize, encrypted_length);
- framer_.set_version(transport_version());
+ framer_.set_version(version());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
@@ -1550,7 +1550,7 @@ TEST_P(QuicConnectionTest, IncreaseServerMaxPacketSizeWhileWriterLimited) {
ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize);
EXPECT_EQ(kMaxPacketSize, encrypted_length);
- framer_.set_version(transport_version());
+ framer_.set_version(version());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
@@ -1578,7 +1578,7 @@ TEST_P(QuicConnectionTest, LimitMaxPacketSizeByWriterForNewConnection) {
writer_->set_max_packet_size(lower_max_packet_size);
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
alarm_factory_.get(), writer_.get(),
- Perspective::IS_CLIENT, transport_version());
+ Perspective::IS_CLIENT, version());
EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
}
@@ -1670,7 +1670,7 @@ TEST_P(QuicConnectionTest, RejectPacketTooFarOut) {
// Call ProcessDataPacket rather than ProcessPacket, as we should not get a
// packet call to the visitor.
- if (FLAGS_quic_restart_flag_quic_enable_accept_random_ipn) {
+ if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
ProcessDataPacket(kMaxRandomInitialPacketNumber + 6000);
} else {
ProcessDataPacket(6000);
@@ -1793,7 +1793,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
}
TEST_P(QuicConnectionTest, 20AcksCausesAckSend) {
- if (connection_.transport_version() > QUIC_VERSION_38) {
+ if (connection_.version().transport_version > QUIC_VERSION_38) {
return;
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -1815,7 +1815,7 @@ TEST_P(QuicConnectionTest, 20AcksCausesAckSend) {
}
TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
- if (connection_.transport_version() <= QUIC_VERSION_38) {
+ if (connection_.version().transport_version <= QUIC_VERSION_38) {
return;
}
@@ -2085,7 +2085,10 @@ TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
}
TEST_P(QuicConnectionTest, FramePacking) {
- // Send an ack and two stream frames in 1 packet by queueing them.
+ // Send two stream frames in 1 packet by queueing them.
+ // If quic_strict_ack_handling is false, the packet
+ // also bundles an empty ack frame and a stop_waiting frame.
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
{
QuicConnection::ScopedPacketFlusher flusher(&connection_,
QuicConnection::SEND_ACK);
@@ -2099,21 +2102,34 @@ TEST_P(QuicConnectionTest, FramePacking) {
// Parse the last packet and ensure it's an ack and two stream frames from
// two different streams.
if (GetParam().no_stop_waiting) {
- EXPECT_EQ(3u, writer_->frame_count());
+ EXPECT_EQ(GetQuicReloadableFlag(quic_strict_ack_handling) ? 2u : 3u,
+ writer_->frame_count());
EXPECT_TRUE(writer_->stop_waiting_frames().empty());
} else {
- EXPECT_EQ(4u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ EXPECT_EQ(GetQuicReloadableFlag(quic_strict_ack_handling) ? 2u : 4u,
+ writer_->frame_count());
+
+ if (GetQuicReloadableFlag(quic_strict_ack_handling)) {
+ EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+ } else {
+ EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+ }
+ }
+
+ if (GetQuicReloadableFlag(quic_strict_ack_handling)) {
+ EXPECT_TRUE(writer_->ack_frames().empty());
+ } else {
+ EXPECT_FALSE(writer_->ack_frames().empty());
}
- EXPECT_FALSE(writer_->ack_frames().empty());
ASSERT_EQ(2u, writer_->stream_frames().size());
EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
EXPECT_EQ(kClientDataStreamId2, writer_->stream_frames()[1]->stream_id);
}
TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
- // Send an ack and two stream frames (one non-crypto, then one crypto) in 2
- // packets by queueing them.
+ // Send two stream frames (one non-crypto, then one crypto) in 2 packets by
+ // queueing them.
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
{
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
QuicConnection::ScopedPacketFlusher flusher(&connection_,
@@ -2132,8 +2148,8 @@ TEST_P(QuicConnectionTest, FramePackingNonCryptoThenCrypto) {
}
TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
- // Send an ack and two stream frames (one crypto, then one non-crypto) in 2
- // packets by queueing them.
+ // Send two stream frames (one crypto, then one non-crypto) in 2 packets by
+ // queueing them.
{
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
QuicConnection::ScopedPacketFlusher flusher(&connection_,
@@ -3419,11 +3435,11 @@ TEST_P(QuicConnectionTest, MtuDiscoveryFailed) {
mtu_discovery_packets.end());
ack.packets.AddRange(1, min_packet);
ack.packets.AddRange(max_packet + 1, creator_->packet_number() + 1);
- ack.deprecated_largest_observed = creator_->packet_number();
+ ack.largest_acked = creator_->packet_number();
} else {
ack.packets.AddRange(1, creator_->packet_number() + 1);
- ack.deprecated_largest_observed = creator_->packet_number();
+ ack.largest_acked = creator_->packet_number();
}
ProcessAckPacket(&ack);
@@ -3757,7 +3773,7 @@ TEST_P(QuicConnectionTest, NewTimeoutAfterSendSilentClose) {
}
TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
- FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp = true;
+ SetQuicReloadableFlag(quic_explicit_close_after_tlp, true);
// Same test as above, but complete a handshake which enables silent close,
// but sending TLPs causes the connection close to be sent.
EXPECT_TRUE(connection_.connected());
@@ -3812,7 +3828,7 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
}
TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
- FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp = true;
+ SetQuicReloadableFlag(quic_explicit_close_after_tlp, true);
// Same test as above, but complete a handshake which enables silent close,
// but having open streams causes the connection close to be sent.
EXPECT_TRUE(connection_.connected());
@@ -4000,7 +4016,7 @@ TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
}
TEST_P(QuicConnectionTest, TimeoutAfter3ClientRTOs) {
- FLAGS_quic_reloadable_flag_quic_enable_3rtos = true;
+ SetQuicReloadableFlag(quic_enable_3rtos, true);
connection_.SetMaxTailLossProbes(2);
EXPECT_TRUE(connection_.connected());
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
@@ -4065,7 +4081,7 @@ TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
// All packets carry version info till version is negotiated.
size_t payload_length;
size_t length = GetPacketLengthForOneStream(
- connection_.transport_version(), kIncludeVersion,
+ connection_.version().transport_version, kIncludeVersion,
!kIncludeDiversificationNonce, PACKET_8BYTE_CONNECTION_ID,
PACKET_1BYTE_PACKET_NUMBER, &payload_length);
connection_.SetMaxPacketLength(length);
@@ -4088,7 +4104,7 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPackets) {
// stream frames with non-zero offets will fit within the packet length.
size_t length =
2 + GetPacketLengthForOneStream(
- connection_.transport_version(), kIncludeVersion,
+ connection_.version().transport_version, kIncludeVersion,
!kIncludeDiversificationNonce, PACKET_8BYTE_CONNECTION_ID,
PACKET_1BYTE_PACKET_NUMBER, &payload_length);
connection_.SetMaxPacketLength(length);
@@ -4927,9 +4943,10 @@ TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
}
TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) {
- connection_.SetSupportedTransportVersions(AllSupportedTransportVersions());
+ connection_.SetSupportedVersions(AllSupportedVersions());
set_perspective(Perspective::IS_SERVER);
- peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
+ peer_framer_.set_version_for_tests(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
QuicPacketHeader header;
header.connection_id = connection_id_;
@@ -4943,28 +4960,29 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) {
size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
buffer, kMaxPacketSize);
- framer_.set_version(transport_version());
+ framer_.set_version(version());
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
EXPECT_TRUE(writer_->version_negotiation_packet() != nullptr);
- size_t num_versions = arraysize(kSupportedTransportVersions);
- ASSERT_EQ(num_versions,
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ ASSERT_EQ(supported_versions.size(),
writer_->version_negotiation_packet()->versions.size());
- // We expect all versions in kSupportedTransportVersions to be
+ // We expect all versions in supported_versions to be
// included in the packet.
- for (size_t i = 0; i < num_versions; ++i) {
- EXPECT_EQ(kSupportedTransportVersions[i],
+ for (size_t i = 0; i < supported_versions.size(); ++i) {
+ EXPECT_EQ(supported_versions[i],
writer_->version_negotiation_packet()->versions[i]);
}
}
TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) {
- connection_.SetSupportedTransportVersions(AllSupportedTransportVersions());
+ connection_.SetSupportedVersions(AllSupportedVersions());
set_perspective(Perspective::IS_SERVER);
- peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
+ peer_framer_.set_version_for_tests(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
QuicPacketHeader header;
header.connection_id = connection_id_;
@@ -4978,7 +4996,7 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) {
size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
buffer, kMaxPacketSize);
- framer_.set_version(transport_version());
+ framer_.set_version(version());
BlockOnNextWrite();
connection_.ProcessUdpPacket(
kSelfAddress, kPeerAddress,
@@ -4990,23 +5008,24 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) {
connection_.OnCanWrite();
EXPECT_TRUE(writer_->version_negotiation_packet() != nullptr);
- size_t num_versions = arraysize(kSupportedTransportVersions);
- ASSERT_EQ(num_versions,
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ ASSERT_EQ(supported_versions.size(),
writer_->version_negotiation_packet()->versions.size());
- // We expect all versions in kSupportedTransportVersions to be
+ // We expect all versions in supported_versions to be
// included in the packet.
- for (size_t i = 0; i < num_versions; ++i) {
- EXPECT_EQ(kSupportedTransportVersions[i],
+ for (size_t i = 0; i < supported_versions.size(); ++i) {
+ EXPECT_EQ(supported_versions[i],
writer_->version_negotiation_packet()->versions[i]);
}
}
TEST_P(QuicConnectionTest,
ServerSendsVersionNegotiationPacketSocketBlockedDataBuffered) {
- connection_.SetSupportedTransportVersions(AllSupportedTransportVersions());
+ connection_.SetSupportedVersions(AllSupportedVersions());
set_perspective(Perspective::IS_SERVER);
- peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
+ peer_framer_.set_version_for_tests(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
QuicPacketHeader header;
header.connection_id = connection_id_;
@@ -5020,7 +5039,7 @@ TEST_P(QuicConnectionTest,
size_t encryped_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
buffer, kMaxPacketSize);
- framer_.set_version(transport_version());
+ framer_.set_version(version());
set_perspective(Perspective::IS_SERVER);
BlockOnNextWrite();
writer_->set_is_write_blocked_data_buffered(true);
@@ -5034,12 +5053,13 @@ TEST_P(QuicConnectionTest,
TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
// Start out with some unsupported version.
QuicConnectionPeer::GetFramer(&connection_)
- ->set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
+ ->set_version_for_tests(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
// Send a version negotiation packet.
std::unique_ptr<QuicEncryptedPacket> encrypted(
- peer_framer_.BuildVersionNegotiationPacket(
- connection_id_, AllSupportedTransportVersions()));
+ peer_framer_.BuildVersionNegotiationPacket(connection_id_,
+ AllSupportedVersions()));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
@@ -5074,7 +5094,7 @@ TEST_P(QuicConnectionTest, BadVersionNegotiation) {
ConnectionCloseSource::FROM_SELF));
std::unique_ptr<QuicEncryptedPacket> encrypted(
framer_.BuildVersionNegotiationPacket(connection_id_,
- AllSupportedTransportVersions()));
+ AllSupportedVersions()));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received);
@@ -5156,32 +5176,29 @@ TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
}
TEST_P(QuicConnectionTest, SelectMutualVersion) {
- connection_.SetSupportedTransportVersions(AllSupportedTransportVersions());
+ connection_.SetSupportedVersions(AllSupportedVersions());
// Set the connection to speak the lowest quic version.
connection_.set_version(QuicVersionMin());
- EXPECT_EQ(QuicVersionMin(), connection_.transport_version());
+ EXPECT_EQ(QuicVersionMin(), connection_.version());
// Pass in available versions which includes a higher mutually supported
// version. The higher mutually supported version should be selected.
- QuicTransportVersionVector supported_versions;
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
- supported_versions.push_back(kSupportedTransportVersions[i]);
- }
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
EXPECT_TRUE(connection_.SelectMutualVersion(supported_versions));
- EXPECT_EQ(QuicVersionMax(), connection_.transport_version());
+ EXPECT_EQ(QuicVersionMax(), connection_.version());
// Expect that the lowest version is selected.
// Ensure the lowest supported version is less than the max, unless they're
// the same.
- EXPECT_LE(QuicVersionMin(), QuicVersionMax());
- QuicTransportVersionVector lowest_version_vector;
+ ParsedQuicVersionVector lowest_version_vector;
lowest_version_vector.push_back(QuicVersionMin());
EXPECT_TRUE(connection_.SelectMutualVersion(lowest_version_vector));
- EXPECT_EQ(QuicVersionMin(), connection_.transport_version());
+ EXPECT_EQ(QuicVersionMin(), connection_.version());
// Shouldn't be able to find a mutually supported version.
- QuicTransportVersionVector unsupported_version;
- unsupported_version.push_back(QUIC_VERSION_UNSUPPORTED);
+ ParsedQuicVersionVector unsupported_version;
+ unsupported_version.push_back(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
EXPECT_FALSE(connection_.SelectMutualVersion(unsupported_version));
}
@@ -5229,10 +5246,10 @@ TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
TEST_P(QuicConnectionTest, Pacing) {
TestConnection server(connection_id_, kSelfAddress, helper_.get(),
alarm_factory_.get(), writer_.get(),
- Perspective::IS_SERVER, transport_version());
+ Perspective::IS_SERVER, version());
TestConnection client(connection_id_, kPeerAddress, helper_.get(),
alarm_factory_.get(), writer_.get(),
- Perspective::IS_CLIENT, transport_version());
+ Perspective::IS_CLIENT, version());
EXPECT_FALSE(QuicSentPacketManagerPeer::UsingPacing(
static_cast<const QuicSentPacketManager*>(
&client.sent_packet_manager())));
diff --git a/chromium/net/quic/core/quic_constants.h b/chromium/net/quic/core/quic_constants.h
index bb643554f3e..49c3ead62df 100644
--- a/chromium/net/quic/core/quic_constants.h
+++ b/chromium/net/quic/core/quic_constants.h
@@ -113,6 +113,14 @@ const int64_t kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes.
// The default timeout for a connection until the crypto handshake succeeds.
const int64_t kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs.
+// The default maximum time QUIC session could be on non-default network before
+// migrate back to default network.
+const int64_t kMaxTimeOnNonDefaultNetworkSecs = 128;
+
+// The default maximum number of migrations to non default network on path
+// degrading per network.
+const int64_t kMaxMigrationsToNonDefaultNetworkOnPathDegrading = 5;
+
// Default limit on the number of undecryptable packets the connection buffers
// before the CHLO/SHLO arrive.
const size_t kDefaultMaxUndecryptablePackets = 10;
@@ -195,6 +203,9 @@ const QuicPacketNumber kMaxRandomInitialPacketNumber = 0x7fffffff;
// Used to represent an invalid or no control frame id.
const QuicControlFrameId kInvalidControlFrameId = 0;
+// The max length a stream can have.
+const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
+
} // namespace net
#endif // NET_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/chromium/net/quic/core/quic_control_frame_manager.cc b/chromium/net/quic/core/quic_control_frame_manager.cc
index 3e659983096..24f459ace35 100644
--- a/chromium/net/quic/core/quic_control_frame_manager.cc
+++ b/chromium/net/quic/core/quic_control_frame_manager.cc
@@ -28,31 +28,8 @@ void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
}
if (id == least_unacked_ + control_frames_.size()) {
// This is a newly sent control frame. Save a copy of this frame.
- switch (frame.type) {
- case RST_STREAM_FRAME:
- control_frames_.emplace_back(
- QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame)));
- return;
- case GOAWAY_FRAME:
- control_frames_.emplace_back(
- QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame)));
- return;
- case WINDOW_UPDATE_FRAME:
- control_frames_.emplace_back(
- QuicFrame(new QuicWindowUpdateFrame(*frame.window_update_frame)));
- return;
- case BLOCKED_FRAME:
- control_frames_.emplace_back(
- QuicFrame(new QuicBlockedFrame(*frame.blocked_frame)));
- return;
- case PING_FRAME:
- control_frames_.emplace_back(
- QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id)));
- return;
- default:
- DCHECK(false);
- return;
- }
+ control_frames_.emplace_back(CopyRetransmittableControlFrame(frame));
+ return;
}
if (QuicContainsKey(pending_retransmissions_, id)) {
// This is retransmitted control frame.
diff --git a/chromium/net/quic/core/quic_crypto_client_handshaker.cc b/chromium/net/quic/core/quic_crypto_client_handshaker.cc
index 418f9bd3fc6..5c59cc844bc 100644
--- a/chromium/net/quic/core/quic_crypto_client_handshaker.cc
+++ b/chromium/net/quic/core/quic_crypto_client_handshaker.cc
@@ -6,8 +6,8 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "net/quic/core/crypto/crypto_utils.h"
#include "net/quic/core/quic_session.h"
@@ -318,7 +318,8 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
crypto_config_->FillInchoateClientHello(
- server_id_, session()->connection()->supported_versions().front(),
+ server_id_,
+ session()->connection()->supported_versions().front().transport_version,
cached, session()->connection()->random_generator(),
/* demand_x509_proof= */ true, crypto_negotiated_params_, &out);
// Pad the inchoate client hello to fill up a packet.
@@ -350,7 +351,7 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
// If the server nonce is empty, copy over the server nonce from a previous
// SREJ, if there is one.
- if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support &&
+ if (GetQuicReloadableFlag(enable_quic_stateless_reject_support) &&
crypto_negotiated_params_->server_nonce.empty() &&
cached->has_server_nonce()) {
crypto_negotiated_params_->server_nonce = cached->GetNextServerNonce();
@@ -360,8 +361,8 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
string error_details;
QuicErrorCode error = crypto_config_->FillClientHello(
server_id_, session()->connection()->connection_id(),
- session()->connection()->supported_versions().front(), cached,
- session()->connection()->clock()->WallNow(),
+ session()->connection()->supported_versions().front().transport_version,
+ cached, session()->connection()->clock()->WallNow(),
session()->connection()->random_generator(), channel_id_key_.get(),
crypto_negotiated_params_, &out, &error_details);
if (error != QUIC_NO_ERROR) {
@@ -426,16 +427,16 @@ void QuicCryptoClientHandshaker::DoReceiveREJ(
}
DVLOG(1) << "Reasons for rejection: " << packed_error;
if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.TooMany",
- packed_error);
+ base::UmaHistogramSparse("Net.QuicClientHelloRejectReasons.TooMany",
+ packed_error);
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure",
- packed_error);
+ base::UmaHistogramSparse("Net.QuicClientHelloRejectReasons.Secure",
+ packed_error);
}
// Receipt of a REJ message means that the server received the CHLO
// so we can cancel and retransmissions.
- session()->connection()->NeuterUnencryptedPackets();
+ session()->NeuterUnencryptedData();
stateless_reject_received_ = in->tag() == kSREJ;
string error_details;
@@ -619,8 +620,9 @@ void QuicCryptoClientHandshaker::DoReceiveSHLO(
QuicErrorCode error = crypto_config_->ProcessServerHello(
*in, session()->connection()->connection_id(),
session()->connection()->transport_version(),
- session()->connection()->server_supported_versions(), cached,
- crypto_negotiated_params_, &error_details);
+ ParsedVersionsToTransportVersions(
+ session()->connection()->server_supported_versions()),
+ cached, crypto_negotiated_params_, &error_details);
if (error != QUIC_NO_ERROR) {
stream_->CloseConnectionWithDetails(
diff --git a/chromium/net/quic/core/quic_crypto_client_stream.cc b/chromium/net/quic/core/quic_crypto_client_stream.cc
index 1599716cac8..a81670125f0 100644
--- a/chromium/net/quic/core/quic_crypto_client_stream.cc
+++ b/chromium/net/quic/core/quic_crypto_client_stream.cc
@@ -15,8 +15,10 @@
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_session.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_str_cat.h"
using std::string;
@@ -36,8 +38,21 @@ QuicCryptoClientStream::QuicCryptoClientStream(
ProofHandler* proof_handler)
: QuicCryptoClientStreamBase(session) {
DCHECK_EQ(Perspective::IS_CLIENT, session->connection()->perspective());
- handshaker_.reset(new QuicCryptoClientHandshaker(
- server_id, this, session, verify_context, crypto_config, proof_handler));
+ switch (session->connection()->version().handshake_protocol) {
+ case PROTOCOL_QUIC_CRYPTO:
+ handshaker_ = QuicMakeUnique<QuicCryptoClientHandshaker>(
+ server_id, this, session, verify_context, crypto_config,
+ proof_handler);
+ break;
+ case PROTOCOL_TLS1_3:
+ handshaker_ = QuicMakeUnique<TlsClientHandshaker>(
+ this, session, server_id, crypto_config->proof_verifier(),
+ crypto_config->ssl_ctx(), verify_context);
+ break;
+ case PROTOCOL_UNSUPPORTED:
+ QUIC_BUG << "Attempting to create QuicCryptoClientStream for unknown "
+ "handshake protocol";
+ }
}
QuicCryptoClientStream::~QuicCryptoClientStream() {}
diff --git a/chromium/net/quic/core/quic_crypto_client_stream_test.cc b/chromium/net/quic/core/quic_crypto_client_stream_test.cc
index ab338189342..499520608ae 100644
--- a/chromium/net/quic/core/quic_crypto_client_stream_test.cc
+++ b/chromium/net/quic/core/quic_crypto_client_stream_test.cc
@@ -12,6 +12,9 @@
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_server_id.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -34,14 +37,17 @@ const uint16_t kServerPort = 443;
class QuicCryptoClientStreamTest : public QuicTest {
public:
QuicCryptoClientStreamTest()
- : server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
+ : supported_versions_(AllSupportedVersions()),
+ server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()) {
CreateConnection();
}
void CreateConnection() {
- connection_ = new PacketSavingConnection(&client_helper_, &alarm_factory_,
- Perspective::IS_CLIENT);
+ connection_ =
+ new PacketSavingConnection(&client_helper_, &alarm_factory_,
+ Perspective::IS_CLIENT, supported_versions_);
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -50,7 +56,9 @@ class QuicCryptoClientStreamTest : public QuicTest {
}
void CompleteCryptoHandshake() {
- EXPECT_CALL(*session_, OnProofValid(testing::_));
+ if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
+ EXPECT_CALL(*session_, OnProofValid(testing::_));
+ }
EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
.Times(testing::AnyNumber());
stream()->CryptoConnect();
@@ -68,6 +76,7 @@ class QuicCryptoClientStreamTest : public QuicTest {
MockQuicConnectionHelper client_helper_;
MockAlarmFactory alarm_factory_;
PacketSavingConnection* connection_;
+ ParsedQuicVersionVector supported_versions_;
std::unique_ptr<TestQuicSpdyClientSession> session_;
QuicServerId server_id_;
CryptoHandshakeMessage message_;
@@ -86,6 +95,21 @@ TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
EXPECT_TRUE(stream()->handshake_confirmed());
}
+TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) {
+ FLAGS_quic_supports_tls_handshake = true;
+ supported_versions_.clear();
+ for (QuicTransportVersion transport_version :
+ AllSupportedTransportVersions()) {
+ supported_versions_.push_back(
+ ParsedQuicVersion(PROTOCOL_TLS1_3, transport_version));
+ }
+ CreateConnection();
+ CompleteCryptoHandshake();
+ EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
+ EXPECT_TRUE(stream()->encryption_established());
+ EXPECT_TRUE(stream()->handshake_confirmed());
+}
+
TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
CompleteCryptoHandshake();
@@ -222,7 +246,7 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
const string& cached_scfg = state->server_config();
test::CompareCharArraysWithHexError(
"scfg", cached_scfg.data(), cached_scfg.length(),
- reinterpret_cast<char*>(scfg), arraysize(scfg));
+ reinterpret_cast<char*>(scfg), QUIC_ARRAYSIZE(scfg));
QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
@@ -236,7 +260,8 @@ TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
// Build a server config update message with certificates
QuicCryptoServerConfig crypto_config(
QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
crypto_test_utils::FakeServerOptions options;
crypto_test_utils::SetupCryptoServerConfigForTest(
connection_->clock(), QuicRandom::GetInstance(), &crypto_config, options);
@@ -355,10 +380,12 @@ TEST_F(QuicCryptoClientStreamTest, NoTokenBindingInPrivacyMode) {
class QuicCryptoClientStreamStatelessTest : public QuicTest {
public:
QuicCryptoClientStreamStatelessTest()
- : client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
server_crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
server_compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) {
@@ -366,7 +393,7 @@ class QuicCryptoClientStreamStatelessTest : public QuicTest {
CreateClientSessionForTest(server_id_,
/* supports_stateless_rejects= */ true,
QuicTime::Delta::FromSeconds(100000),
- AllSupportedTransportVersions(), &helper_,
+ AllSupportedVersions(), &helper_,
&alarm_factory_, &client_crypto_config_,
&client_connection_, &client_session);
CHECK(client_session);
@@ -392,7 +419,7 @@ class QuicCryptoClientStreamStatelessTest : public QuicTest {
void InitializeFakeStatelessRejectServer() {
TestQuicSpdyServerSession* server_session = nullptr;
CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
- AllSupportedTransportVersions(), &helper_,
+ AllSupportedVersions(), &helper_,
&alarm_factory_, &server_crypto_config_,
&server_compressed_certs_cache_,
&server_connection_, &server_session);
@@ -402,7 +429,7 @@ class QuicCryptoClientStreamStatelessTest : public QuicTest {
crypto_test_utils::SetupCryptoServerConfigForTest(
server_connection_->clock(), server_connection_->random_generator(),
&server_crypto_config_, options);
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
}
MockQuicConnectionHelper helper_;
@@ -422,7 +449,7 @@ class QuicCryptoClientStreamStatelessTest : public QuicTest {
};
TEST_F(QuicCryptoClientStreamStatelessTest, StatelessReject) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
QuicCryptoClientConfig::CachedState* client_state =
client_crypto_config_.LookupOrCreate(server_id_);
diff --git a/chromium/net/quic/core/quic_crypto_handshaker.cc b/chromium/net/quic/core/quic_crypto_handshaker.cc
index 39a9a4e9c9b..7455afd6d71 100644
--- a/chromium/net/quic/core/quic_crypto_handshaker.cc
+++ b/chromium/net/quic/core/quic_crypto_handshaker.cc
@@ -25,7 +25,7 @@ void QuicCryptoHandshaker::SendHandshakeMessage(
const CryptoHandshakeMessage& message) {
QUIC_DVLOG(1) << ENDPOINT << "Sending "
<< message.DebugString(session()->perspective());
- session()->connection()->NeuterUnencryptedPackets();
+ session()->NeuterUnencryptedData();
session()->OnCryptoHandshakeMessageSent(message);
const QuicData& data = message.GetSerialized(session()->perspective());
stream_->WriteOrBufferData(QuicStringPiece(data.data(), data.length()), false,
diff --git a/chromium/net/quic/core/quic_crypto_server_handshaker.cc b/chromium/net/quic/core/quic_crypto_server_handshaker.cc
index b89934621fb..99164153b7e 100644
--- a/chromium/net/quic/core/quic_crypto_server_handshaker.cc
+++ b/chromium/net/quic/core/quic_crypto_server_handshaker.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
@@ -375,7 +376,7 @@ bool QuicCryptoServerHandshaker::GetBase64SHA256ClientChannelID(
SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
digest);
- QuicTextUtils::Base64Encode(digest, arraysize(digest), output);
+ QuicTextUtils::Base64Encode(digest, QUIC_ARRAYSIZE(digest), output);
return true;
}
@@ -435,10 +436,10 @@ void QuicCryptoServerHandshaker::ProcessClientHello(
crypto_config_->ProcessClientHello(
result, /*reject_only=*/false, connection->connection_id(),
connection->self_address(), GetClientAddress(), transport_version(),
- connection->supported_versions(), use_stateless_rejects_in_crypto_config,
- server_designated_connection_id, connection->clock(),
- connection->random_generator(), compressed_certs_cache_,
- crypto_negotiated_params_, signed_config_,
+ ParsedVersionsToTransportVersions(connection->supported_versions()),
+ use_stateless_rejects_in_crypto_config, server_designated_connection_id,
+ connection->clock(), connection->random_generator(),
+ compressed_certs_cache_, crypto_negotiated_params_, signed_config_,
QuicCryptoStream::CryptoMessageFramingOverhead(transport_version()),
chlo_packet_size_, std::move(done_cb));
}
diff --git a/chromium/net/quic/core/quic_crypto_server_handshaker.h b/chromium/net/quic/core/quic_crypto_server_handshaker.h
index 5b5d0f838ac..dbdd94c09cf 100644
--- a/chromium/net/quic/core/quic_crypto_server_handshaker.h
+++ b/chromium/net/quic/core/quic_crypto_server_handshaker.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_CORE_QUIC_CRYPTO_SERVER_HANDSHAKER_H_
#define NET_QUIC_CORE_QUIC_CRYPTO_SERVER_HANDSHAKER_H_
+#include "net/quic/core/proto/cached_network_parameters.pb.h"
+#include "net/quic/core/proto/source_address_token.pb.h"
#include "net/quic/core/quic_crypto_handshaker.h"
#include "net/quic/core/quic_crypto_server_stream.h"
#include "net/quic/core/quic_session.h"
diff --git a/chromium/net/quic/core/quic_crypto_server_stream.cc b/chromium/net/quic/core/quic_crypto_server_stream.cc
index d9d2c83cb33..65b4300212d 100644
--- a/chromium/net/quic/core/quic_crypto_server_stream.cc
+++ b/chromium/net/quic/core/quic_crypto_server_stream.cc
@@ -15,8 +15,10 @@
#include "net/quic/core/quic_crypto_server_handshaker.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_session.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string_piece.h"
using std::string;
@@ -52,9 +54,21 @@ QuicCryptoServerStream::QuicCryptoServerStream(
Helper* helper)
: QuicCryptoServerStreamBase(session) {
DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
- handshaker_.reset(new QuicCryptoServerHandshaker(
- crypto_config, this, compressed_certs_cache,
- use_stateless_rejects_if_peer_supported, session, helper));
+ switch (session->connection()->version().handshake_protocol) {
+ case PROTOCOL_QUIC_CRYPTO:
+ handshaker_ = QuicMakeUnique<QuicCryptoServerHandshaker>(
+ crypto_config, this, compressed_certs_cache,
+ use_stateless_rejects_if_peer_supported, session, helper);
+ break;
+ case PROTOCOL_TLS1_3:
+ handshaker_ = QuicMakeUnique<TlsServerHandshaker>(
+ this, session, crypto_config->ssl_ctx(),
+ crypto_config->proof_source());
+ break;
+ case PROTOCOL_UNSUPPORTED:
+ QUIC_BUG << "Attempting to create QuicCryptoServerStream for unknown "
+ "handshake protocol";
+ }
}
QuicCryptoServerStream::~QuicCryptoServerStream() {}
diff --git a/chromium/net/quic/core/quic_crypto_server_stream.h b/chromium/net/quic/core/quic_crypto_server_stream.h
index 625f2fed0b2..8df4fc536dd 100644
--- a/chromium/net/quic/core/quic_crypto_server_stream.h
+++ b/chromium/net/quic/core/quic_crypto_server_stream.h
@@ -13,7 +13,6 @@
#include "net/quic/core/crypto/crypto_handshake.h"
#include "net/quic/core/crypto/quic_compressed_certs_cache.h"
#include "net/quic/core/crypto/quic_crypto_server_config.h"
-#include "net/quic/core/proto/source_address_token.pb.h"
#include "net/quic/core/quic_config.h"
#include "net/quic/core/quic_crypto_handshaker.h"
#include "net/quic/core/quic_crypto_stream.h"
diff --git a/chromium/net/quic/core/quic_crypto_server_stream_test.cc b/chromium/net/quic/core/quic_crypto_server_stream_test.cc
index f49b5f6a9fc..69cbea3183d 100644
--- a/chromium/net/quic/core/quic_crypto_server_stream_test.cc
+++ b/chromium/net/quic/core/quic_crypto_server_stream_test.cc
@@ -20,6 +20,8 @@
#include "net/quic/core/quic_crypto_client_stream.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_session.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
@@ -66,12 +68,14 @@ class QuicCryptoServerStreamTest : public QuicTestWithParam<bool> {
explicit QuicCryptoServerStreamTest(std::unique_ptr<ProofSource> proof_source)
: server_crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- std::move(proof_source)),
+ std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()),
server_compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
- client_crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = false;
+ client_crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()) {
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, false);
}
void Initialize() { InitializeServer(); }
@@ -180,8 +184,7 @@ class QuicCryptoServerStreamTest : public QuicTestWithParam<bool> {
crypto_test_utils::FakeClientOptions client_options_;
// Which QUIC versions the client and server support.
- QuicTransportVersionVector supported_versions_ =
- AllSupportedTransportVersions();
+ ParsedQuicVersionVector supported_versions_ = AllSupportedVersions();
};
INSTANTIATE_TEST_CASE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
@@ -209,6 +212,22 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
EXPECT_TRUE(server_stream()->handshake_confirmed());
}
+TEST_P(QuicCryptoServerStreamTest, ConnectedAfterTlsHandshake) {
+ FLAGS_quic_supports_tls_handshake = true;
+ client_options_.only_tls_versions = true;
+ supported_versions_.clear();
+ for (QuicTransportVersion transport_version :
+ AllSupportedTransportVersions()) {
+ supported_versions_.push_back(
+ ParsedQuicVersion(PROTOCOL_TLS1_3, transport_version));
+ }
+ Initialize();
+ CompleteCryptoHandshake();
+ EXPECT_EQ(PROTOCOL_TLS1_3, server_stream()->handshake_protocol());
+ EXPECT_TRUE(server_stream()->encryption_established());
+ EXPECT_TRUE(server_stream()->handshake_confirmed());
+}
+
TEST_P(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ false);
@@ -231,7 +250,7 @@ TEST_P(QuicCryptoServerStreamTest, ForwardSecureAfterCHLO) {
}
TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ true);
@@ -265,7 +284,7 @@ TEST_P(QuicCryptoServerStreamTest, StatelessRejectAfterCHLO) {
}
TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ true);
@@ -312,7 +331,7 @@ TEST_P(QuicCryptoServerStreamTest, ConnectedAfterStatelessHandshake) {
}
TEST_P(QuicCryptoServerStreamTest, NoStatelessRejectIfNoClientSupport) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
Initialize();
// The server is configured to use stateless rejects, but the client does not
@@ -435,7 +454,7 @@ TEST_P(QuicCryptoServerStreamTest, SendSCUPAfterHandshakeComplete) {
// crypto_test_utils::MovePackets stops processing parsing following packets.
// Actually, crypto stream test should use QuicSession instead of
// QuicSpdySession (b/32366134).
- FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = false;
+ SetQuicReloadableFlag(quic_send_max_header_list_size, false);
Initialize();
InitializeFakeClient(/* supports_stateless_rejects= */ false);
diff --git a/chromium/net/quic/core/quic_crypto_stream.cc b/chromium/net/quic/core/quic_crypto_stream.cc
index a60e30fc84b..9bd4a47ac06 100644
--- a/chromium/net/quic/core/quic_crypto_stream.cc
+++ b/chromium/net/quic/core/quic_crypto_stream.cc
@@ -97,4 +97,65 @@ void QuicCryptoStream::WriteCryptoData(const QuicStringPiece& data) {
WriteOrBufferData(data, /* fin */ false, /* ack_listener */ nullptr);
}
+void QuicCryptoStream::NeuterUnencryptedStreamData() {
+ for (const auto& interval : bytes_consumed_[ENCRYPTION_NONE]) {
+ QuicByteCount newly_acked_length = 0;
+ send_buffer().OnStreamDataAcked(
+ interval.min(), interval.max() - interval.min(), &newly_acked_length);
+ }
+}
+
+void QuicCryptoStream::OnStreamDataConsumed(size_t bytes_consumed) {
+ if (bytes_consumed > 0) {
+ bytes_consumed_[session()->connection()->encryption_level()].Add(
+ stream_bytes_written(), stream_bytes_written() + bytes_consumed);
+ }
+ QuicStream::OnStreamDataConsumed(bytes_consumed);
+}
+
+void QuicCryptoStream::WritePendingRetransmission() {
+ while (HasPendingRetransmission()) {
+ StreamPendingRetransmission pending =
+ send_buffer().NextPendingRetransmission();
+ QuicIntervalSet<QuicStreamOffset> retransmission(
+ pending.offset, pending.offset + pending.length);
+ EncryptionLevel retransmission_encryption_level = ENCRYPTION_NONE;
+ // Determine the encryption level to write the retransmission
+ // at. The retransmission should be written at the same encryption level
+ // as the original transmission.
+ for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
+ if (retransmission.Intersects(bytes_consumed_[i])) {
+ retransmission_encryption_level = static_cast<EncryptionLevel>(i);
+ retransmission.Intersection(bytes_consumed_[i]);
+ break;
+ }
+ }
+ pending.offset = retransmission.begin()->min();
+ pending.length =
+ retransmission.begin()->max() - retransmission.begin()->min();
+ EncryptionLevel current_encryption_level =
+ session()->connection()->encryption_level();
+ // Set appropriate encryption level.
+ session()->connection()->SetDefaultEncryptionLevel(
+ retransmission_encryption_level);
+ QuicConsumedData consumed = session()->WritevData(
+ this, id(), pending.length, pending.offset, NO_FIN);
+ QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
+ << " tries to retransmit stream data [" << pending.offset
+ << ", " << pending.offset + pending.length
+ << ") with encryption level: "
+ << retransmission_encryption_level
+ << ", consumed: " << consumed;
+ OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
+ consumed.fin_consumed);
+ // Restore encryption level.
+ session()->connection()->SetDefaultEncryptionLevel(
+ current_encryption_level);
+ if (consumed.bytes_consumed < pending.length) {
+ // The connection is write blocked.
+ break;
+ }
+ }
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_crypto_stream.h b/chromium/net/quic/core/quic_crypto_stream.h
index ef6856360ac..695e1e57897 100644
--- a/chromium/net/quic/core/quic_crypto_stream.h
+++ b/chromium/net/quic/core/quic_crypto_stream.h
@@ -79,7 +79,22 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
// Provides the message parser to use when data is received on this stream.
virtual CryptoMessageParser* crypto_message_parser() = 0;
+ // Called to cancel retransmission of unencrypted crypto stream data.
+ void NeuterUnencryptedStreamData();
+
+ // Override to record the encryption level of consumed data.
+ void OnStreamDataConsumed(size_t bytes_consumed) override;
+
+ // Override to retransmit lost crypto data with the appropriate encryption
+ // level.
+ void WritePendingRetransmission() override;
+
private:
+ // Consumed data according to encryption levels.
+ // TODO(fayang): This is not needed once switching from QUIC crypto to
+ // TLS 1.3, which never encrypts crypto data.
+ QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
+
DISALLOW_COPY_AND_ASSIGN(QuicCryptoStream);
};
diff --git a/chromium/net/quic/core/quic_crypto_stream_test.cc b/chromium/net/quic/core/quic_crypto_stream_test.cc
index bf29b6c64f3..59726408615 100644
--- a/chromium/net/quic/core/quic_crypto_stream_test.cc
+++ b/chromium/net/quic/core/quic_crypto_stream_test.cc
@@ -20,6 +20,10 @@
using std::string;
+using testing::_;
+using testing::InSequence;
+using testing::Invoke;
+
namespace net {
namespace test {
namespace {
@@ -125,6 +129,79 @@ TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
QuicStreamPeer::StreamContributesToConnectionFlowControl(&stream_));
}
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
+ if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ return;
+ }
+ InSequence s;
+ // Send [0, 1350) in ENCRYPTION_NONE.
+ EXPECT_EQ(ENCRYPTION_NONE, connection_->encryption_level());
+ string data(1350, 'a');
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 0, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_.WriteOrBufferData(data, false, nullptr);
+ // Send [1350, 2700) in ENCRYPTION_INITIAL.
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 1350, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_.WriteOrBufferData(data, false, nullptr);
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+
+ // Lost [0, 1000).
+ stream_.OnStreamFrameLost(0, 1000, false);
+ EXPECT_TRUE(stream_.HasPendingRetransmission());
+ // Lost [1200, 2000).
+ stream_.OnStreamFrameLost(1200, 800, false);
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1000, 0, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
+ // they are in different encryption levels.
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 150, 1200, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 650, 1350, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_.OnCanWrite();
+ EXPECT_FALSE(stream_.HasPendingRetransmission());
+ // Verify connection's encryption level has restored.
+ EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
+}
+
+TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
+ if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ return;
+ }
+ // Send [0, 1350) in ENCRYPTION_NONE.
+ EXPECT_EQ(ENCRYPTION_NONE, connection_->encryption_level());
+ string data(1350, 'a');
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 0, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_.WriteOrBufferData(data, false, nullptr);
+ // Send [1350, 2700) in ENCRYPTION_INITIAL.
+ connection_->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+ EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 1350, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_.WriteOrBufferData(data, false, nullptr);
+
+ // Lost [0, 1350).
+ stream_.OnStreamFrameLost(0, 1350, false);
+ EXPECT_TRUE(stream_.HasPendingRetransmission());
+ // Neuters [0, 1350).
+ stream_.NeuterUnencryptedStreamData();
+ EXPECT_FALSE(stream_.HasPendingRetransmission());
+ // Lost [0, 1350) again.
+ stream_.OnStreamFrameLost(0, 1350, false);
+ EXPECT_FALSE(stream_.HasPendingRetransmission());
+
+ // Lost [1350, 2000).
+ stream_.OnStreamFrameLost(1350, 650, false);
+ EXPECT_TRUE(stream_.HasPendingRetransmission());
+ stream_.NeuterUnencryptedStreamData();
+ EXPECT_TRUE(stream_.HasPendingRetransmission());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/quic_data_writer_test.cc b/chromium/net/quic/core/quic_data_writer_test.cc
index 2217ed1cbc6..bc59ba4004f 100644
--- a/chromium/net/quic/core/quic_data_writer_test.cc
+++ b/chromium/net/quic/core/quic_data_writer_test.cc
@@ -8,6 +8,7 @@
#include "net/quic/core/quic_data_reader.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -558,22 +559,22 @@ TEST_P(QuicDataWriterTest, WriteIntegers) {
TEST_P(QuicDataWriterTest, WriteBytes) {
char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
- char buf[arraysize(bytes)];
- QuicDataWriter writer(arraysize(buf), buf, GetParam().endianness);
- EXPECT_TRUE(writer.WriteBytes(bytes, arraysize(bytes)));
- for (unsigned int i = 0; i < arraysize(bytes); ++i) {
+ char buf[QUIC_ARRAYSIZE(bytes)];
+ QuicDataWriter writer(QUIC_ARRAYSIZE(buf), buf, GetParam().endianness);
+ EXPECT_TRUE(writer.WriteBytes(bytes, QUIC_ARRAYSIZE(bytes)));
+ for (unsigned int i = 0; i < QUIC_ARRAYSIZE(bytes); ++i) {
EXPECT_EQ(bytes[i], buf[i]);
}
}
TEST_P(QuicDataWriterTest, WriteUInt8AtOffset) {
char bytes[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
- char buf[arraysize(bytes)];
- for (unsigned int i = 0; i < arraysize(bytes); ++i) {
- QuicDataWriter writer(arraysize(buf), buf, GetParam().endianness);
- EXPECT_TRUE(writer.WriteBytes(bytes, arraysize(bytes)));
+ char buf[QUIC_ARRAYSIZE(bytes)];
+ for (unsigned int i = 0; i < QUIC_ARRAYSIZE(bytes); ++i) {
+ QuicDataWriter writer(QUIC_ARRAYSIZE(buf), buf, GetParam().endianness);
+ EXPECT_TRUE(writer.WriteBytes(bytes, QUIC_ARRAYSIZE(bytes)));
EXPECT_TRUE(writer.WriteUInt8AtOffset('I', i));
- for (unsigned int j = 0; j < arraysize(bytes); ++j) {
+ for (unsigned int j = 0; j < QUIC_ARRAYSIZE(bytes); ++j) {
if (j == i) {
EXPECT_EQ('I', buf[j]);
} else {
diff --git a/chromium/net/quic/core/quic_error_codes.cc b/chromium/net/quic/core/quic_error_codes.cc
index 2f734e524b0..3bdd84ca971 100644
--- a/chromium/net/quic/core/quic_error_codes.cc
+++ b/chromium/net/quic/core/quic_error_codes.cc
@@ -128,9 +128,10 @@ const char* QuicErrorCodeToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_CRYPTO_CHLO_TOO_LARGE);
RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST);
RETURN_STRING_LITERAL(QUIC_MULTIPATH_PATH_NOT_ACTIVE);
- RETURN_STRING_LITERAL(QUIC_TOO_MANY_FRAME_GAPS);
+ RETURN_STRING_LITERAL(QUIC_TOO_MANY_STREAM_DATA_INTERVALS);
RETURN_STRING_LITERAL(QUIC_STREAM_SEQUENCER_INVALID_STATE);
RETURN_STRING_LITERAL(QUIC_TOO_MANY_SESSIONS_ON_SERVER);
+ RETURN_STRING_LITERAL(QUIC_STREAM_LENGTH_OVERFLOW);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
// if we add errors and don't put them here.
diff --git a/chromium/net/quic/core/quic_error_codes.h b/chromium/net/quic/core/quic_error_codes.h
index 2a6f335bb45..f5d94ee2e5c 100644
--- a/chromium/net/quic/core/quic_error_codes.h
+++ b/chromium/net/quic/core/quic_error_codes.h
@@ -263,8 +263,8 @@ enum QuicErrorCode {
QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
// Stream frames arrived too discontiguously so that stream sequencer buffer
- // maintains too many gaps.
- QUIC_TOO_MANY_FRAME_GAPS = 93,
+ // maintains too many intervals.
+ QUIC_TOO_MANY_STREAM_DATA_INTERVALS = 93,
// Sequencer buffer get into weird state where continuing read/write will lead
// to crash.
@@ -273,8 +273,11 @@ enum QuicErrorCode {
// Connection closed because of server hits max number of sessions allowed.
QUIC_TOO_MANY_SESSIONS_ON_SERVER = 96,
+ // Receive a RST_STREAM with offset larger than kMaxStreamLength.
+ QUIC_STREAM_LENGTH_OVERFLOW = 98,
+
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 98,
+ QUIC_LAST_ERROR = 99,
};
// QuicErrorCodes is encoded as a single octet on-the-wire.
static_assert(static_cast<int>(QUIC_LAST_ERROR) <=
diff --git a/chromium/net/quic/core/quic_flags_list.h b/chromium/net/quic/core/quic_flags_list.h
index bcd204f9e70..c5f8d924722 100644
--- a/chromium/net/quic/core/quic_flags_list.h
+++ b/chromium/net/quic/core/quic_flags_list.h
@@ -67,13 +67,6 @@ QUIC_FLAG(double, FLAGS_quic_bbr_cwnd_gain, 2.0f)
// Add the equivalent number of bytes as 3 TCP TSO segments to QUIC's BBR CWND.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd, false)
-// If true, enable version 38 which supports new PADDING frame and respects NSTP
-// connection option.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_38, true)
-
-// If true, enable QUIC v39.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_39, true)
-
// Simplify QUIC\'s adaptive time loss detection to measure the necessary
// reordering window for every spurious retransmit.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_adaptive_time_loss, false)
@@ -92,10 +85,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
// option.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_rate_recovery, false)
-// Adds a QuicPacketNumberQueue that is based on a deque and does not support
-// costly AddRange arguments.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_frames_deque3, true)
-
// If true, enable QUIC v42.
QUIC_FLAG(bool, FLAGS_quic_enable_version_42, false)
@@ -110,10 +99,6 @@ QUIC_FLAG(uint32_t, FLAGS_quic_send_buffer_max_data_slice_size, 4096u)
// protocol.
QUIC_FLAG(bool, FLAGS_quic_supports_tls_handshake, false)
-// If true, QUIC v40 is enabled which includes changes to RST_STREAM, ACK
-// and STREAM frames match IETF format.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_41, true)
-
// If true, QUIC can take ownership of data provided in a reference counted
// memory to avoid data copy.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_mem_slices, false)
@@ -121,64 +106,17 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_mem_slices, false)
// Allow QUIC to accept initial packet numbers that are random, not 1.
QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_enable_accept_random_ipn, false)
-// Report the more analogous TLS 1.3 cipher suites rather than TLS 1.2 ECDHE_RSA
-// ciphers in QuicDecrypters.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_tls13_cipher_suites, true)
-
-// If true, read and write QUIC version labels in network byte order.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label,
- true)
-
-// If true, send stateless reset token in SHLO. This token is used in IETF
-// public reset packet.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_send_reset_token_in_shlo, true)
-
-// Default enable all cubic fixes in QUIC Cubic by default.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_cubic_fixes, true)
-
// If true, enable QUIC v43.
QUIC_FLAG(bool, FLAGS_quic_enable_version_43, false)
// If true, allows one address change when UDP proxying.
QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_allow_address_change_for_udp_proxy,
- false)
-
-// If true, allow a new BBR connection option to use a slower STARTUP once loss
-// occurs
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_slower_startup, true)
-
-// Deprecate QuicAckFrame.largest_observed since it is redundant.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_deprecate_largest_observed,
true)
-// Fully drain the queue in QUIC BBR at least once per cycle(8 rounds) when
-// activated by the BBR3 connection option.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_fully_drain_queue, true)
-
-// When true, allows connection options to be sent to completely disable packet
-// conservation in QUIC BBR STARTUP or make it more aggressive.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_bbr_conservation_in_startup,
- false)
-
-// Allows increasing the length of time ack aggregation is windowed for to 20
-// and 40 RTTs.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_window,
- false)
-
-// If true, OnStreamFrameDiscarded is not called on stream cancellation, and
-// canceled stream is immediately closed.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded,
- false)
-
// Explicitly send a connection close if the TLP count is greater than 0 when
// idle timeout occurs.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_explicit_close_after_tlp, true)
// Enables 3 new connection options to make PROBE_RTT more aggressive
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt, false)
@@ -190,10 +128,6 @@ QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing,
true)
-// If true, truncates QUIC error strings to 256 characters before writing them
-// to the wire.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_truncate_long_details, true)
-
// If true, allow stream data and control frames to be acked multiple times.
QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2,
@@ -203,7 +137,34 @@ QUIC_FLAG(bool,
// guaranteed to be 2048.
QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_fix_sequencer_buffer_block_count2,
- false)
+ true)
// If true, use deframer from net/quic/http instead of net/http2.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_hq_deframer, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_hq_deframer, true)
+
+// If true, then 1) at sender, avoid sending empty acks, 2) at receiver, close
+// connection when a ack frame\'s first block length is 0, unless the ack is
+// completely empty.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_strict_ack_handling, false)
+
+// If true, fixes for the two bugs described in crbug.com/723604 will be
+// enabled.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_2rtt_drop_client_cached_certs,
+ false)
+
+// If true, limit quic stream length to be below 2^62.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_stream_too_long, false)
+
+// When true, enables the 1TLP connection option to configure QUIC to send one
+// TLP instead of 2.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_one_tlp, false)
+
+// If true, stream sequencer buffer allows receiving overlapping stream data.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_allow_receiving_overlapping_data,
+ false)
+
+// If true, QuicStreamSendBuffer keeps track of the slice which next write
+// should get data from if writing new data.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_write_index, false)
diff --git a/chromium/net/quic/core/quic_framer.cc b/chromium/net/quic/core/quic_framer.cc
index ef3607dffb8..624f1f691ec 100644
--- a/chromium/net/quic/core/quic_framer.cc
+++ b/chromium/net/quic/core/quic_framer.cc
@@ -28,6 +28,7 @@
#include "net/quic/platform/api/quic_map_util.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_str_cat.h"
+#include "net/quic/platform/api/quic_text_utils.h"
using std::string;
@@ -157,7 +158,7 @@ QuicPacketNumberLength ReadAckPacketNumberLength(QuicTransportVersion version,
} // namespace
-QuicFramer::QuicFramer(const QuicTransportVersionVector& supported_versions,
+QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
QuicTime creation_time,
Perspective perspective)
: visitor_(nullptr),
@@ -165,6 +166,7 @@ QuicFramer::QuicFramer(const QuicTransportVersionVector& supported_versions,
largest_packet_number_(0),
last_serialized_connection_id_(0),
last_version_label_(0),
+ version_(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
supported_versions_(supported_versions),
decrypter_level_(ENCRYPTION_NONE),
alternative_decrypter_level_(ENCRYPTION_NONE),
@@ -175,7 +177,7 @@ QuicFramer::QuicFramer(const QuicTransportVersionVector& supported_versions,
last_timestamp_(QuicTime::Delta::Zero()),
data_producer_(nullptr) {
DCHECK(!supported_versions.empty());
- transport_version_ = supported_versions_[0];
+ version_ = supported_versions_[0];
decrypter_ = QuicMakeUnique<NullDecrypter>(perspective);
encrypter_[ENCRYPTION_NONE] = QuicMakeUnique<NullEncrypter>(perspective);
}
@@ -285,9 +287,20 @@ size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) {
number_versions * kQuicVersionSize;
}
-bool QuicFramer::IsSupportedVersion(const QuicTransportVersion version) const {
- for (size_t i = 0; i < supported_versions_.size(); ++i) {
- if (version == supported_versions_[i]) {
+// TODO(nharper): Change this method to take a ParsedQuicVersion.
+bool QuicFramer::IsSupportedTransportVersion(
+ const QuicTransportVersion version) const {
+ for (ParsedQuicVersion supported_version : supported_versions_) {
+ if (version == supported_version.transport_version) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QuicFramer::IsSupportedVersion(const ParsedQuicVersion version) const {
+ for (ParsedQuicVersion supported_version : supported_versions_) {
+ if (version == supported_version) {
return true;
}
}
@@ -337,8 +350,8 @@ size_t QuicFramer::GetSerializedFrameLength(
}
bool can_truncate =
frame.type == ACK_FRAME &&
- free_bytes >=
- GetMinAckFrameSize(transport_version_, PACKET_6BYTE_PACKET_NUMBER);
+ free_bytes >= GetMinAckFrameSize(version_.transport_version,
+ PACKET_6BYTE_PACKET_NUMBER);
if (can_truncate) {
// Truncate the frame so the packet will not exceed kMaxPacketSize.
// Note that we may not use every byte of the writer in this case.
@@ -531,7 +544,7 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
// static
std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
QuicConnectionId connection_id,
- const QuicTransportVersionVector& versions) {
+ const ParsedQuicVersionVector& versions) {
DCHECK(!versions.empty());
size_t len = GetVersionNegotiationPacketSize(versions.size());
std::unique_ptr<char[]> buffer(new char[len]);
@@ -551,20 +564,12 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
return nullptr;
}
- for (QuicTransportVersion version : versions) {
- if (FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 3, 10);
- // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier
- // are removed.
- if (!writer.WriteTag(QuicEndian::HostToNet32(
- QuicVersionToQuicVersionLabel(version)))) {
- return nullptr;
- }
- } else {
- if (!writer.WriteTag(QuicVersionToQuicVersionLabel(version))) {
- return nullptr;
- }
+ for (ParsedQuicVersion version : versions) {
+ // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier
+ // are removed.
+ if (!writer.WriteTag(
+ QuicEndian::HostToNet32(CreateQuicVersionLabel(version)))) {
+ return nullptr;
}
}
@@ -591,7 +596,7 @@ bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
}
if (perspective_ == Perspective::IS_SERVER && header.version_flag &&
- header.version != transport_version_) {
+ header.version != version_) {
if (!visitor_->OnProtocolVersionMismatch(header.version)) {
return true;
}
@@ -634,14 +639,10 @@ bool QuicFramer::ProcessVersionNegotiationPacket(
set_detailed_error("Unable to read supported version in negotiation.");
return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
}
- if (FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 4, 10);
- // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier
- // are removed.
- version_label = QuicEndian::NetToHost32(version_label);
- }
- packet.versions.push_back(QuicVersionLabelToQuicVersion(version_label));
+ // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier
+ // are removed.
+ version_label = QuicEndian::NetToHost32(version_label);
+ packet.versions.push_back(ParseQuicVersionLabel(version_label));
} while (!reader->IsDoneReading());
visitor_->OnVersionNegotiationPacket(packet);
@@ -775,25 +776,15 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
if (header.version_flag) {
DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
- QuicVersionLabel version_label =
- QuicVersionToQuicVersionLabel(transport_version_);
- if (FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 5, 10);
- // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier
- // are removed.
- if (!writer->WriteTag(QuicEndian::NetToHost32(version_label))) {
- return false;
- }
- } else {
- if (!writer->WriteTag(version_label)) {
- return false;
- }
+ QuicVersionLabel version_label = CreateQuicVersionLabel(version_);
+ // TODO(rch): Use WriteUInt32() once QUIC_VERSION_38 and earlier
+ // are removed.
+ if (!writer->WriteTag(QuicEndian::NetToHost32(version_label))) {
+ return false;
}
- QUIC_DVLOG(1) << ENDPOINT << "version = " << transport_version_
- << ", label = '" << QuicVersionLabelToString(version_label)
- << "'";
+ QUIC_DVLOG(1) << ENDPOINT << "label = '"
+ << QuicVersionLabelToString(version_label) << "'";
}
if (header.nonce != nullptr &&
@@ -903,21 +894,16 @@ bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
set_detailed_error("Unable to read protocol version.");
return false;
}
- if (FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_use_net_byte_order_version_label, 6, 10);
- // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier
- // are removed.
- version_label = QuicEndian::NetToHost32(version_label);
- }
+ // TODO(rch): Use ReadUInt32() once QUIC_VERSION_38 and earlier
+ // are removed.
+ version_label = QuicEndian::NetToHost32(version_label);
// If the version from the new packet is the same as the version of this
// framer, then the public flags should be set to something we understand.
// If not, this raises an error.
last_version_label_ = version_label;
- QuicTransportVersion version = QuicVersionLabelToQuicVersion(version_label);
- if (version == transport_version_ &&
- public_flags > PACKET_PUBLIC_FLAGS_MAX) {
+ ParsedQuicVersion version = ParseQuicVersionLabel(version_label);
+ if (version == version_ && public_flags > PACKET_PUBLIC_FLAGS_MAX) {
set_detailed_error("Illegal public flags value.");
return false;
}
@@ -1067,9 +1053,9 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
if (frame_type & kQuicFrameTypeSpecialMask) {
// Stream Frame
- if ((transport_version_ < QUIC_VERSION_41 &&
+ if ((version_.transport_version < QUIC_VERSION_41 &&
(frame_type & kQuicFrameTypeStreamMask_Pre40)) ||
- (transport_version_ >= QUIC_VERSION_41 &&
+ (version_.transport_version >= QUIC_VERSION_41 &&
((frame_type & kQuicFrameTypeStreamMask) ==
kQuicFrameTypeStreamMask))) {
QuicStreamFrame frame;
@@ -1086,9 +1072,9 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
}
// Ack Frame
- if ((transport_version_ < QUIC_VERSION_41 &&
+ if ((version_.transport_version < QUIC_VERSION_41 &&
(frame_type & kQuicFrameTypeAckMask_Pre40)) ||
- (transport_version_ >= QUIC_VERSION_41 &&
+ (version_.transport_version >= QUIC_VERSION_41 &&
((frame_type & kQuicFrameTypeSpecialMask) ==
kQuicFrameTypeAckMask))) {
QuicAckFrame frame;
@@ -1266,7 +1252,7 @@ bool QuicFramer::ProcessStreamFrame(QuicDataReader* reader,
uint8_t stream_id_length = 0;
uint8_t offset_length = 4;
bool has_data_length = true;
- if (transport_version_ < QUIC_VERSION_41) {
+ if (version_.transport_version < QUIC_VERSION_41) {
stream_flags &= ~kQuicFrameTypeStreamMask_Pre40;
// Read from right to left: StreamID, Offset, Data Length, Fin.
@@ -1340,12 +1326,12 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
uint8_t frame_type,
QuicAckFrame* ack_frame) {
bool has_ack_blocks =
- ExtractBit(frame_type, transport_version_ < QUIC_VERSION_41
+ ExtractBit(frame_type, version_.transport_version < QUIC_VERSION_41
? kQuicHasMultipleAckBlocksOffset_Pre40
: kQuicHasMultipleAckBlocksOffset);
uint8_t num_ack_blocks = 0;
uint8_t num_received_packets = 0;
- if (transport_version_ > QUIC_VERSION_39) {
+ if (version_.transport_version > QUIC_VERSION_39) {
if (has_ack_blocks && !reader->ReadUInt8(&num_ack_blocks)) {
set_detailed_error("Unable to read num of ack blocks.");
return false;
@@ -1359,11 +1345,11 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
// Determine the two lengths from the frame type: largest acked length,
// ack block length.
const QuicPacketNumberLength ack_block_length = ReadAckPacketNumberLength(
- transport_version_,
+ version_.transport_version,
ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
kActBlockLengthOffset));
const QuicPacketNumberLength largest_acked_length = ReadAckPacketNumberLength(
- transport_version_,
+ version_.transport_version,
ExtractBits(frame_type, kQuicSequenceNumberLengthNumBits,
kLargestAckedOffset));
@@ -1387,7 +1373,7 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
}
if (has_ack_blocks) {
- if (transport_version_ <= QUIC_VERSION_39 &&
+ if (version_.transport_version <= QUIC_VERSION_39 &&
!reader->ReadUInt8(&num_ack_blocks)) {
set_detailed_error("Unable to read num of ack blocks.");
return false;
@@ -1400,16 +1386,31 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
return false;
}
+ if (GetQuicReloadableFlag(quic_strict_ack_handling) &&
+ first_block_length == 0) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_strict_ack_handling);
+ // For non-empty ACKs, the first block length must be non-zero.
+ if (largest_acked != 0 || num_ack_blocks != 0) {
+ set_detailed_error(
+ QuicStrCat("First block length is zero but ACK is "
+ "not empty. largest acked is ",
+ largest_acked, ", num ack blocks is ",
+ QuicTextUtils::Uint64ToString(num_ack_blocks), ".")
+ .c_str());
+ return false;
+ }
+ }
+
if (first_block_length > largest_acked + 1) {
set_detailed_error(QuicStrCat("Underflow with first ack block length ",
first_block_length, " largest acked is ",
- largest_acked + 1, ".")
+ largest_acked, ".")
.c_str());
return false;
}
QuicPacketNumber first_received = largest_acked + 1 - first_block_length;
- ack_frame->deprecated_largest_observed = largest_acked;
+ ack_frame->largest_acked = largest_acked;
ack_frame->packets.AddRange(first_received, largest_acked + 1);
if (num_ack_blocks > 0) {
@@ -1440,7 +1441,7 @@ bool QuicFramer::ProcessAckFrame(QuicDataReader* reader,
}
}
- if (transport_version_ <= QUIC_VERSION_39 &&
+ if (version_.transport_version <= QUIC_VERSION_39 &&
!reader->ReadUInt8(&num_received_packets)) {
set_detailed_error("Unable to read num received packets.");
return false;
@@ -1528,7 +1529,7 @@ bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
return false;
}
- if (transport_version_ <= QUIC_VERSION_39) {
+ if (version_.transport_version <= QUIC_VERSION_39) {
if (!reader->ReadUInt64(&frame->byte_offset)) {
set_detailed_error("Unable to read rst stream sent byte offset.");
return false;
@@ -1548,7 +1549,7 @@ bool QuicFramer::ProcessRstStreamFrame(QuicDataReader* reader,
frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
- if (transport_version_ > QUIC_VERSION_39) {
+ if (version_.transport_version > QUIC_VERSION_39) {
if (!reader->ReadUInt64(&frame->byte_offset)) {
set_detailed_error("Unable to read rst stream sent byte offset.");
return false;
@@ -1641,7 +1642,7 @@ bool QuicFramer::ProcessBlockedFrame(QuicDataReader* reader,
void QuicFramer::ProcessPaddingFrame(QuicDataReader* reader,
QuicPaddingFrame* frame) {
- if (transport_version_ <= QUIC_VERSION_37) {
+ if (version_.transport_version <= QUIC_VERSION_37) {
frame->num_padding_bytes = reader->BytesRemaining() + 1;
reader->ReadRemainingPayload();
return;
@@ -1709,7 +1710,7 @@ size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
char* buffer) {
size_t output_length = 0;
if (!encrypter_[level]->EncryptPacket(
- transport_version_, packet_number,
+ version_.transport_version, packet_number,
QuicStringPiece(buffer, ad_len), // Associated data
QuicStringPiece(buffer + ad_len, total_len - ad_len), // Plaintext
buffer + ad_len, // Destination buffer
@@ -1728,7 +1729,8 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level,
size_t buffer_len) {
DCHECK(encrypter_[level] != nullptr);
- QuicStringPiece associated_data = packet.AssociatedData(transport_version_);
+ QuicStringPiece associated_data =
+ packet.AssociatedData(version_.transport_version);
// Copy in the header, because the encrypter only populates the encrypted
// plaintext content.
const size_t ad_len = associated_data.length();
@@ -1736,9 +1738,9 @@ size_t QuicFramer::EncryptPayload(EncryptionLevel level,
// Encrypt the plaintext into the buffer.
size_t output_length = 0;
if (!encrypter_[level]->EncryptPacket(
- transport_version_, packet_number, associated_data,
- packet.Plaintext(transport_version_), buffer + ad_len, &output_length,
- buffer_len - ad_len)) {
+ version_.transport_version, packet_number, associated_data,
+ packet.Plaintext(version_.transport_version), buffer + ad_len,
+ &output_length, buffer_len - ad_len)) {
RaiseError(QUIC_ENCRYPTION_FAILURE);
return 0;
}
@@ -1772,13 +1774,13 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
QuicStringPiece encrypted = encrypted_reader->ReadRemainingPayload();
DCHECK(decrypter_ != nullptr);
QuicStringPiece associated_data = GetAssociatedDataFromEncryptedPacket(
- transport_version_, packet, header.connection_id_length,
+ version_.transport_version, packet, header.connection_id_length,
header.version_flag, header.nonce != nullptr,
header.packet_number_length);
bool success = decrypter_->DecryptPacket(
- transport_version_, header.packet_number, associated_data, encrypted,
- decrypted_buffer, decrypted_length, buffer_length);
+ version_.transport_version, header.packet_number, associated_data,
+ encrypted, decrypted_buffer, decrypted_length, buffer_length);
if (success) {
visitor_->OnDecryptedPacket(decrypter_level_);
} else if (alternative_decrypter_ != nullptr) {
@@ -1800,8 +1802,8 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
if (try_alternative_decryption) {
success = alternative_decrypter_->DecryptPacket(
- transport_version_, header.packet_number, associated_data, encrypted,
- decrypted_buffer, decrypted_length, buffer_length);
+ version_.transport_version, header.packet_number, associated_data,
+ encrypted, decrypted_buffer, decrypted_length, buffer_length);
}
if (success) {
visitor_->OnDecryptedPacket(alternative_decrypter_level_);
@@ -1845,11 +1847,12 @@ size_t QuicFramer::GetAckFrameSize(
AckFrameInfo ack_info = GetAckFrameInfo(ack);
QuicPacketNumberLength largest_acked_length =
- GetMinPacketNumberLength(transport_version_, LargestAcked(ack));
- QuicPacketNumberLength ack_block_length =
- GetMinPacketNumberLength(transport_version_, ack_info.max_block_length);
+ GetMinPacketNumberLength(version_.transport_version, LargestAcked(ack));
+ QuicPacketNumberLength ack_block_length = GetMinPacketNumberLength(
+ version_.transport_version, ack_info.max_block_length);
- ack_size = GetMinAckFrameSize(transport_version_, largest_acked_length);
+ ack_size =
+ GetMinAckFrameSize(version_.transport_version, largest_acked_length);
// First ack block length.
ack_size += ack_block_length;
if (ack_info.num_ack_blocks != 0) {
@@ -1871,14 +1874,15 @@ size_t QuicFramer::ComputeFrameLength(
switch (frame.type) {
case STREAM_FRAME:
return GetMinStreamFrameSize(
- transport_version_, frame.stream_frame->stream_id,
+ version_.transport_version, frame.stream_frame->stream_id,
frame.stream_frame->offset, last_frame_in_packet) +
frame.stream_frame->data_length;
case ACK_FRAME: {
return GetAckFrameSize(*frame.ack_frame, packet_number_length);
}
case STOP_WAITING_FRAME:
- return GetStopWaitingFrameSize(transport_version_, packet_number_length);
+ return GetStopWaitingFrameSize(version_.transport_version,
+ packet_number_length);
case MTU_DISCOVERY_FRAME:
// MTU discovery frames are serialized as ping frames.
case PING_FRAME:
@@ -1919,7 +1923,7 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
if (frame.stream_frame == nullptr) {
QUIC_BUG << "Failed to append STREAM frame with no stream_frame.";
}
- if (transport_version_ < QUIC_VERSION_41) {
+ if (version_.transport_version < QUIC_VERSION_41) {
// Fin bit.
type_byte |= frame.stream_frame->fin ? kQuicStreamFinMask_Pre40 : 0;
@@ -1930,8 +1934,8 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
// Offset 3 bits.
type_byte <<= kQuicStreamShift_Pre40;
- const size_t offset_len =
- GetStreamOffsetSize(transport_version_, frame.stream_frame->offset);
+ const size_t offset_len = GetStreamOffsetSize(
+ version_.transport_version, frame.stream_frame->offset);
if (offset_len > 0) {
type_byte |= offset_len - 1;
}
@@ -1950,7 +1954,7 @@ bool QuicFramer::AppendTypeByte(const QuicFrame& frame,
// Offset 2 bits.
uint8_t offset_len_encode = 3;
- switch (GetStreamOffsetSize(transport_version_,
+ switch (GetStreamOffsetSize(version_.transport_version,
frame.stream_frame->offset)) {
case 0:
offset_len_encode = 0;
@@ -2042,8 +2046,9 @@ bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
QUIC_BUG << "Writing stream id size failed.";
return false;
}
- if (!AppendStreamOffset(GetStreamOffsetSize(transport_version_, frame.offset),
- frame.offset, writer)) {
+ if (!AppendStreamOffset(
+ GetStreamOffsetSize(version_.transport_version, frame.offset),
+ frame.offset, writer)) {
QUIC_BUG << "Writing offset size failed.";
return false;
}
@@ -2075,9 +2080,9 @@ bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
return true;
}
-void QuicFramer::set_version(const QuicTransportVersion version) {
- DCHECK(IsSupportedVersion(version)) << QuicVersionToString(version);
- transport_version_ = version;
+void QuicFramer::set_version(const ParsedQuicVersion version) {
+ DCHECK(IsSupportedVersion(version)) << ParsedQuicVersionToString(version);
+ version_ = version;
}
bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
@@ -2085,13 +2090,13 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
const AckFrameInfo new_ack_info = GetAckFrameInfo(frame);
QuicPacketNumber largest_acked = LargestAcked(frame);
QuicPacketNumberLength largest_acked_length =
- GetMinPacketNumberLength(transport_version_, largest_acked);
+ GetMinPacketNumberLength(version_.transport_version, largest_acked);
QuicPacketNumberLength ack_block_length = GetMinPacketNumberLength(
- transport_version_, new_ack_info.max_block_length);
+ version_.transport_version, new_ack_info.max_block_length);
// Calculate available bytes for timestamps and ack blocks.
int32_t available_timestamp_and_ack_block_bytes =
writer->capacity() - writer->length() - ack_block_length -
- GetMinAckFrameSize(transport_version_, largest_acked_length) -
+ GetMinAckFrameSize(version_.transport_version, largest_acked_length) -
(new_ack_info.num_ack_blocks != 0 ? kNumberOfAckBlocksSize : 0);
DCHECK_LE(0, available_timestamp_and_ack_block_bytes);
@@ -2100,7 +2105,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
// Whether there are multiple ack blocks.
uint8_t type_byte = 0;
SetBit(&type_byte, new_ack_info.num_ack_blocks != 0,
- transport_version_ < QUIC_VERSION_41
+ version_.transport_version < QUIC_VERSION_41
? kQuicHasMultipleAckBlocksOffset_Pre40
: kQuicHasMultipleAckBlocksOffset);
@@ -2110,7 +2115,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
SetBits(&type_byte, GetPacketNumberFlags(ack_block_length),
kQuicSequenceNumberLengthNumBits, kActBlockLengthOffset);
- if (transport_version_ < QUIC_VERSION_41) {
+ if (version_.transport_version < QUIC_VERSION_41) {
type_byte |= kQuicFrameTypeAckMask_Pre40;
} else {
type_byte |= kQuicFrameTypeAckMask;
@@ -2131,7 +2136,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
num_ack_blocks = std::numeric_limits<uint8_t>::max();
}
- if (transport_version_ > QUIC_VERSION_39) {
+ if (version_.transport_version > QUIC_VERSION_39) {
if (num_ack_blocks > 0 && !writer->WriteBytes(&num_ack_blocks, 1)) {
return false;
}
@@ -2160,7 +2165,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
return false;
}
- if (transport_version_ <= QUIC_VERSION_39) {
+ if (version_.transport_version <= QUIC_VERSION_39) {
if (num_ack_blocks > 0) {
if (!writer->WriteBytes(&num_ack_blocks, 1)) {
return false;
@@ -2260,7 +2265,7 @@ bool QuicFramer::AppendTimestampsToAckFrame(const QuicAckFrame& frame,
}
uint8_t num_received_packets = frame.received_packet_times.size();
- if (transport_version_ <= QUIC_VERSION_39) {
+ if (version_.transport_version <= QUIC_VERSION_39) {
if (!writer->WriteBytes(&num_received_packets, 1)) {
return false;
}
@@ -2333,7 +2338,7 @@ bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
<< " is too small for least_unacked_delta: " << least_unacked_delta
<< " packet_number:" << header.packet_number
<< " least_unacked:" << frame.least_unacked
- << " version:" << transport_version_;
+ << " version:" << version_.transport_version;
return false;
}
if (!AppendPacketNumber(header.packet_number_length, least_unacked_delta,
@@ -2351,7 +2356,7 @@ bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
return false;
}
- if (transport_version_ <= QUIC_VERSION_39) {
+ if (version_.transport_version <= QUIC_VERSION_39) {
if (!writer->WriteUInt64(frame.byte_offset)) {
return false;
}
@@ -2362,7 +2367,7 @@ bool QuicFramer::AppendRstStreamFrame(const QuicRstStreamFrame& frame,
return false;
}
- if (transport_version_ > QUIC_VERSION_39) {
+ if (version_.transport_version > QUIC_VERSION_39) {
if (!writer->WriteUInt64(frame.byte_offset)) {
return false;
}
@@ -2423,7 +2428,7 @@ bool QuicFramer::AppendBlockedFrame(const QuicBlockedFrame& frame,
bool QuicFramer::AppendPaddingFrame(const QuicPaddingFrame& frame,
QuicDataWriter* writer) {
- if (transport_version_ <= QUIC_VERSION_37) {
+ if (version_.transport_version <= QUIC_VERSION_37) {
writer->WritePadding();
return true;
}
@@ -2449,8 +2454,8 @@ bool QuicFramer::RaiseError(QuicErrorCode error) {
}
Endianness QuicFramer::endianness() const {
- return transport_version_ > QUIC_VERSION_38 ? NETWORK_BYTE_ORDER
- : HOST_BYTE_ORDER;
+ return version_.transport_version > QUIC_VERSION_38 ? NETWORK_BYTE_ORDER
+ : HOST_BYTE_ORDER;
}
bool QuicFramer::StartsWithChlo(QuicStreamId id,
@@ -2472,11 +2477,9 @@ bool QuicFramer::StartsWithChlo(QuicStreamId id,
}
QuicStringPiece QuicFramer::TruncateErrorString(QuicStringPiece error) {
- if (error.length() <= kMaxErrorStringLength ||
- !FLAGS_quic_reloadable_flag_quic_truncate_long_details) {
+ if (error.length() <= kMaxErrorStringLength) {
return error;
}
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_truncate_long_details);
return QuicStringPiece(error.data(), kMaxErrorStringLength);
}
diff --git a/chromium/net/quic/core/quic_framer.h b/chromium/net/quic/core/quic_framer.h
index f1d4603595f..abea88ffef2 100644
--- a/chromium/net/quic/core/quic_framer.h
+++ b/chromium/net/quic/core/quic_framer.h
@@ -72,7 +72,7 @@ class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
// version of the |framer_| to |received_version| or false to stop processing
// this packet.
virtual bool OnProtocolVersionMismatch(
- QuicTransportVersion received_version) = 0;
+ ParsedQuicVersion received_version) = 0;
// Called when a new packet has been received, before it
// has been validated or processed.
@@ -150,14 +150,17 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// QuicDecrypter for level ENCRYPTION_NONE. |supported_versions| specifies the
// list of supported QUIC versions. |quic_version_| is set to the maximum
// version in |supported_versions|.
- QuicFramer(const QuicTransportVersionVector& supported_versions,
+ QuicFramer(const ParsedQuicVersionVector& supported_versions,
QuicTime creation_time,
Perspective perspective);
virtual ~QuicFramer();
+ // Returns true if |version| is a supported transport version.
+ bool IsSupportedTransportVersion(const QuicTransportVersion version) const;
+
// Returns true if |version| is a supported protocol version.
- bool IsSupportedVersion(const QuicTransportVersion version) const;
+ bool IsSupportedVersion(const ParsedQuicVersion version) const;
// Set callbacks to be called from the framer. A visitor must be set, or
// else the framer will likely crash. It is acceptable for the visitor
@@ -165,18 +168,22 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// will be used.
void set_visitor(QuicFramerVisitorInterface* visitor) { visitor_ = visitor; }
- const QuicTransportVersionVector& supported_versions() const {
+ const ParsedQuicVersionVector& supported_versions() const {
return supported_versions_;
}
- QuicTransportVersion transport_version() const { return transport_version_; }
+ QuicTransportVersion transport_version() const {
+ return version_.transport_version;
+ }
+
+ ParsedQuicVersion version() const { return version_; }
- void set_version(const QuicTransportVersion version);
+ void set_version(const ParsedQuicVersion version);
// Does not DCHECK for supported version. Used by tests to set unsupported
// version to trigger version negotiation.
- void set_version_for_tests(const QuicTransportVersion version) {
- transport_version_ = version;
+ void set_version_for_tests(const ParsedQuicVersion version) {
+ version_ = version;
}
QuicErrorCode error() const { return error_; }
@@ -261,10 +268,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// Returns a new version negotiation packet.
static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
QuicConnectionId connection_id,
- const QuicTransportVersionVector& versions);
+ const ParsedQuicVersionVector& versions);
// If header.version_flag is set, the version in the
- // packet will be set -- but it will be set from transport_version_ not
+ // packet will be set -- but it will be set from version_ not
// header.versions.
bool AppendPacketHeader(const QuicPacketHeader& header,
QuicDataWriter* writer);
@@ -328,10 +335,9 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
QuicTransportVersion version,
QuicPacketNumber packet_number);
- void SetSupportedTransportVersions(
- const QuicTransportVersionVector& versions) {
+ void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
supported_versions_ = versions;
- transport_version_ = versions[0];
+ version_ = versions[0];
}
// Returns true if data with |offset| of stream |id| starts with 'CHLO'.
@@ -513,12 +519,12 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// The last QUIC version label received.
QuicVersionLabel last_version_label_;
// Version of the protocol being used.
- QuicTransportVersion transport_version_;
+ ParsedQuicVersion version_;
// This vector contains QUIC 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).
- QuicTransportVersionVector supported_versions_;
+ ParsedQuicVersionVector supported_versions_;
// Primary decrypter used to decrypt packets during parsing.
std::unique_ptr<QuicDecrypter> decrypter_;
// Alternative decrypter that can also be used to decrypt packets.
diff --git a/chromium/net/quic/core/quic_framer_test.cc b/chromium/net/quic/core/quic_framer_test.cc
index 95bd03b40ae..055af34165b 100644
--- a/chromium/net/quic/core/quic_framer_test.cc
+++ b/chromium/net/quic/core/quic_framer_test.cc
@@ -17,6 +17,7 @@
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
@@ -71,6 +72,7 @@ class TestEncrypter : public QuicEncrypter {
}
size_t GetKeySize() const override { return 0; }
size_t GetNoncePrefixSize() const override { return 0; }
+ size_t GetIVSize() const override { return 0; }
size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
return ciphertext_size;
}
@@ -114,6 +116,8 @@ class TestDecrypter : public QuicDecrypter {
*output_length = ciphertext.length();
return true;
}
+ size_t GetKeySize() const override { return 0; }
+ size_t GetIVSize() const override { return 0; }
QuicStringPiece GetKey() const override { return QuicStringPiece(); }
QuicStringPiece GetNoncePrefix() const override { return QuicStringPiece(); }
// Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
@@ -154,7 +158,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
}
- bool OnProtocolVersionMismatch(QuicTransportVersion version) override {
+ bool OnProtocolVersionMismatch(ParsedQuicVersion version) override {
QUIC_DLOG(INFO) << "QuicFramer Version Mismatch, version: " << version;
++version_mismatch_;
return true;
@@ -271,16 +275,14 @@ struct PacketFragment {
using PacketFragments = std::vector<struct PacketFragment>;
-class QuicFramerTest : public QuicTestWithParam<QuicTransportVersion> {
+class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
public:
QuicFramerTest()
: encrypter_(new test::TestEncrypter()),
decrypter_(new test::TestDecrypter()),
+ version_(GetParam()),
start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
- framer_(AllSupportedTransportVersions(),
- start_,
- Perspective::IS_SERVER) {
- version_ = GetParam();
+ framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER) {
framer_.set_version(version_);
framer_.SetDecrypter(ENCRYPTION_NONE, decrypter_);
framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
@@ -290,17 +292,17 @@ class QuicFramerTest : public QuicTestWithParam<QuicTransportVersion> {
// Helper function to get unsigned char representation of digit in the
// units place of the current QUIC version number.
unsigned char GetQuicVersionDigitOnes() {
- return static_cast<unsigned char>('0' + version_ % 10);
+ return CreateQuicVersionLabel(version_) & 0xff;
}
// Helper function to get unsigned char representation of digit in the
// tens place of the current QUIC version number.
unsigned char GetQuicVersionDigitTens() {
- return static_cast<unsigned char>('0' + (version_ / 10) % 10);
+ return (CreateQuicVersionLabel(version_) >> 8) & 0xff;
}
bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
- EXPECT_EQ(version_, encrypter_->version_);
+ EXPECT_EQ(version_.transport_version, encrypter_->version_);
if (packet_number != encrypter_->packet_number_) {
QUIC_LOG(ERROR) << "Encrypted incorrect packet number. expected "
<< packet_number
@@ -327,7 +329,7 @@ class QuicFramerTest : public QuicTestWithParam<QuicTransportVersion> {
bool CheckDecryption(const QuicEncryptedPacket& encrypted,
bool includes_version,
bool includes_diversification_nonce) {
- EXPECT_EQ(version_, decrypter_->version_);
+ EXPECT_EQ(version_.transport_version, decrypter_->version_);
if (visitor_.header_->packet_number != decrypter_->packet_number_) {
QUIC_LOG(ERROR) << "Decrypted incorrect packet number. expected "
<< visitor_.header_->packet_number
@@ -448,7 +450,7 @@ class QuicFramerTest : public QuicTestWithParam<QuicTransportVersion> {
test::TestEncrypter* encrypter_;
test::TestDecrypter* decrypter_;
- QuicTransportVersion version_;
+ ParsedQuicVersion version_;
QuicTime start_;
QuicFramer framer_;
test::TestQuicVisitor visitor_;
@@ -457,7 +459,7 @@ class QuicFramerTest : public QuicTestWithParam<QuicTransportVersion> {
// Run all framer tests with all supported versions of QUIC.
INSTANTIATE_TEST_CASE_P(QuicFramerTests,
QuicFramerTest,
- ::testing::ValuesIn(kSupportedTransportVersions));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
// A few quick manual sanity checks.
@@ -587,7 +589,7 @@ TEST_P(QuicFramerTest, LargePacket) {
memset(packet + header_size, 0, kMaxPacketSize - header_size);
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_QUIC_BUG(framer_.ProcessPacket(encrypted), "Packet too large:1");
ASSERT_TRUE(visitor_.header_.get());
@@ -953,7 +955,7 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
QuicEncryptedPacket encrypted(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false);
+ QUIC_ARRAYSIZE(packet), false);
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
ASSERT_TRUE(visitor_.header_->nonce != nullptr);
@@ -1002,7 +1004,7 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
QuicEncryptedPacket encrypted(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false);
+ QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
@@ -1046,7 +1048,7 @@ TEST_P(QuicFramerTest, PaddingFrame) {
return;
}
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
@@ -1164,7 +1166,7 @@ TEST_P(QuicFramerTest, NewPaddingFrame) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
ASSERT_TRUE(visitor_.header_.get());
@@ -1387,7 +1389,7 @@ TEST_P(QuicFramerTest, MissingDiversificationNonce) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_DECRYPTION_FAILURE, framer_.error());
}
@@ -1960,7 +1962,7 @@ TEST_P(QuicFramerTest, RejectPacket) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -1984,7 +1986,7 @@ TEST_P(QuicFramerTest, RejectPublicHeader) {
};
// clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -2126,7 +2128,7 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
{"Unable to read first ack block length.",
{0x88, 0x88}},
// num timestamps.
- {"Underflow with first ack block length 34952 largest acked is 4661.",
+ {"Underflow with first ack block length 34952 largest acked is 4660.",
{0x00}}
};
@@ -2154,7 +2156,7 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
{"Unable to read first ack block length.",
{0x88, 0x88}},
// num timestamps.
- {"Underflow with first ack block length 34952 largest acked is 4661.",
+ {"Underflow with first ack block length 34952 largest acked is 4660.",
{0x00}}
};
@@ -2196,6 +2198,155 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
}
+TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
+ SetQuicReloadableFlag(quic_strict_ack_handling,
+ true);
+
+ // clang-format off
+ PacketFragments packet = {
+ // public flags (8 byte connection_id)
+ {"",
+ { 0x3C }},
+ // connection_id
+ {"",
+ { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+ // packet number
+ {"",
+ { 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12 }},
+
+ // frame type (ack frame)
+ // (more than one ack block, 2 byte largest observed, 2 byte block length)
+ {"",
+ { 0x65 }},
+ // largest acked
+ {"Unable to read largest acked.",
+ { 0x34, 0x12 }},
+ // Zero delta time.
+ {"Unable to read ack delay time.",
+ { 0x00, 0x00 }},
+ // num ack blocks ranges.
+ {"Unable to read num of ack blocks.",
+ { 0x01 }},
+ // first ack block length.
+ {"Unable to read first ack block length.",
+ { 0x00, 0x00 }},
+ // gap to next block.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x01 }},
+ // ack block length.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0xaf, 0x0e }},
+ // Number of timestamps.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x00 }},
+ };
+
+ PacketFragments packet39 = {
+ // public flags (8 byte connection_id)
+ {"",
+ { 0x3C }},
+ // connection_id
+ {"",
+ { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+ // packet number
+ {"",
+ { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+
+ // frame type (ack frame)
+ // (more than one ack block, 2 byte largest observed, 2 byte block length)
+ {"",
+ { 0x65 }},
+ // largest acked
+ {"Unable to read largest acked.",
+ { 0x12, 0x34 }},
+ // Zero delta time.
+ {"Unable to read ack delay time.",
+ { 0x00, 0x00 }},
+ // num ack blocks ranges.
+ {"Unable to read num of ack blocks.",
+ { 0x01 }},
+ // first ack block length.
+ {"Unable to read first ack block length.",
+ { 0x00, 0x00 }},
+ // gap to next block.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x01 }},
+ // ack block length.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x0e, 0xaf }},
+ // Number of timestamps.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x00 }},
+ };
+
+ PacketFragments packet41 = {
+ // public flags (8 byte connection_id)
+ {"",
+ { 0x3C }},
+ // connection_id
+ {"",
+ { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
+ // packet number
+ {"",
+ { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+
+ // frame type (ack frame)
+ // (more than one ack block, 2 byte largest observed, 2 byte block length)
+ {"",
+ { 0xB5 }},
+ // num ack blocks ranges.
+ {"Unable to read num of ack blocks.",
+ { 0x01 }},
+ // Number of timestamps.
+ { "Unable to read num received packets.",
+ { 0x00 }},
+ // largest acked
+ {"Unable to read largest acked.",
+ { 0x12, 0x34 }},
+ // Zero delta time.
+ {"Unable to read ack delay time.",
+ { 0x00, 0x00 }},
+ // first ack block length.
+ {"Unable to read first ack block length.",
+ { 0x00, 0x00 }},
+ // gap to next block.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x01 }},
+ // ack block length.
+ { "First block length is zero but ACK is not empty. "
+ "largest acked is 4660, num ack blocks is 1.",
+ { 0x0e, 0xaf }},
+ };
+
+ // clang-format on
+ PacketFragments& fragments =
+ framer_.transport_version() > QUIC_VERSION_39
+ ? packet41
+ : (framer_.transport_version() > QUIC_VERSION_38 ? packet39 : packet);
+
+ std::unique_ptr<QuicEncryptedPacket> encrypted(
+ AssemblePacketFromFragments(fragments));
+
+ EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
+ EXPECT_EQ(QUIC_INVALID_ACK_DATA, framer_.error());
+
+ ASSERT_TRUE(visitor_.header_.get());
+ EXPECT_TRUE(CheckDecryption(*encrypted, !kIncludeVersion,
+ !kIncludeDiversificationNonce));
+
+ EXPECT_EQ(0u, visitor_.stream_frames_.size());
+ ASSERT_EQ(0u, visitor_.ack_frames_.size());
+
+ CheckFramingBoundaries(fragments, QUIC_INVALID_ACK_DATA);
+}
+
TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
// clang-format off
PacketFragments packet = {
@@ -2633,7 +2784,7 @@ TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
QuicEncryptedPacket encrypted(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false);
+ QUIC_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_INVALID_STOP_WAITING_DATA, framer_.error());
EXPECT_EQ("Invalid unacked delta.", framer_.detailed_error());
@@ -3051,7 +3202,7 @@ TEST_P(QuicFramerTest, PingFrame) {
QuicEncryptedPacket encrypted(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false);
+ QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -3192,7 +3343,7 @@ TEST_P(QuicFramerTest, PublicResetPacketWithTrailingJunk) {
};
// clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
ASSERT_EQ(QUIC_INVALID_PUBLIC_RST_PACKET, framer_.error());
EXPECT_EQ("Unable to read reset message.", framer_.detailed_error());
@@ -3377,7 +3528,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
@@ -3491,11 +3642,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
@@ -3550,7 +3701,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
@@ -3605,7 +3756,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
@@ -3643,7 +3794,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacket) {
@@ -3737,7 +3888,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
}
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
@@ -3825,7 +3976,7 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
}
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
@@ -3842,11 +3993,11 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
QuicConnectionId connection_id = kConnectionId;
std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildVersionNegotiationPacket(
- connection_id, SupportedTransportVersions(GetParam())));
+ framer_.BuildVersionNegotiationPacket(connection_id,
+ SupportedVersions(GetParam())));
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
@@ -3937,7 +4088,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
ASSERT_TRUE(data != nullptr);
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
@@ -3948,7 +4099,6 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
header.packet_number = kPacketNumber;
QuicAckFrame ack_frame = InitAckFrame(kPacketNumber);
- FLAGS_quic_reloadable_flag_quic_frames_deque3 = true;
ack_frame.ack_delay_time = QuicTime::Delta::Zero();
QuicFrames frames = {QuicFrame(&ack_frame)};
@@ -4018,13 +4168,13 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
};
// clang-format on
unsigned char* p = packet;
- size_t packet_size = arraysize(packet);
+ size_t packet_size = QUIC_ARRAYSIZE(packet);
if (framer_.transport_version() > QUIC_VERSION_39) {
p = packet41;
- packet_size = arraysize(packet41);
+ packet_size = QUIC_ARRAYSIZE(packet41);
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
- packet_size = arraysize(packet39);
+ packet_size = QUIC_ARRAYSIZE(packet39);
}
std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -4180,7 +4330,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
@@ -4192,7 +4342,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
// Use kSmallLargestObservedto make this test finished in a short time.
QuicAckFrame ack_frame;
- ack_frame.deprecated_largest_observed = kSmallLargestObserved;
+ ack_frame.largest_acked = kSmallLargestObserved;
ack_frame.ack_delay_time = QuicTime::Delta::Zero();
// 300 ack blocks.
for (size_t i = 2; i < 2 * 300; i += 2) {
@@ -4494,7 +4644,7 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
@@ -4548,7 +4698,7 @@ TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
@@ -4636,11 +4786,11 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(p),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildCloseFramePacket) {
@@ -4709,11 +4859,10 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
- FLAGS_quic_reloadable_flag_quic_truncate_long_details = true;
QuicPacketHeader header;
header.connection_id = kConnectionId;
header.reset_flag = false;
@@ -4829,10 +4978,10 @@ TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
// clang-format on
unsigned char* p = packet;
- size_t packet_size = arraysize(packet);
+ size_t packet_size = QUIC_ARRAYSIZE(packet);
if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
- packet_size = arraysize(packet39);
+ packet_size = QUIC_ARRAYSIZE(packet39);
}
std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -4913,11 +5062,10 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
- FLAGS_quic_reloadable_flag_quic_truncate_long_details = true;
QuicPacketHeader header;
header.connection_id = kConnectionId;
header.reset_flag = false;
@@ -5038,10 +5186,10 @@ TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
// clang-format on
unsigned char* p = packet;
- size_t packet_size = arraysize(packet);
+ size_t packet_size = QUIC_ARRAYSIZE(packet);
if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
- packet_size = arraysize(packet39);
+ packet_size = QUIC_ARRAYSIZE(packet39);
}
std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -5109,7 +5257,7 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildBlockedPacket) {
@@ -5163,7 +5311,7 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildPingPacket) {
@@ -5210,7 +5358,7 @@ TEST_P(QuicFramerTest, BuildPingPacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
// Test that the connectivity probing packet is serialized correctly as a
@@ -5257,10 +5405,10 @@ TEST_P(QuicFramerTest, BuildConnectivityProbingPacket) {
// clang-format on
unsigned char* p = packet;
- size_t packet_size = arraysize(packet);
+ size_t packet_size = QUIC_ARRAYSIZE(packet);
if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
- packet_size = arraysize(packet39);
+ packet_size = QUIC_ARRAYSIZE(packet39);
}
std::unique_ptr<char[]> buffer(new char[kMaxPacketSize]);
@@ -5277,7 +5425,7 @@ TEST_P(QuicFramerTest, BuildConnectivityProbingPacket) {
"constructed packet", data.data(), data.length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
// Test that the MTU discovery packet is serialized correctly as a PING packet.
@@ -5325,7 +5473,7 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
"constructed packet", data->data(), data->length(),
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildPublicResetPacket) {
@@ -5358,7 +5506,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacket) {
ASSERT_TRUE(data != nullptr);
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
@@ -5403,7 +5551,7 @@ TEST_P(QuicFramerTest, BuildPublicResetPacketWithClientAddress) {
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
- arraysize(packet));
+ QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, EncryptPacket) {
@@ -5445,8 +5593,9 @@ TEST_P(QuicFramerTest, EncryptPacket) {
std::unique_ptr<QuicPacket> raw(new QuicPacket(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER));
+ QUIC_ARRAYSIZE(packet), false, PACKET_8BYTE_CONNECTION_ID,
+ !kIncludeVersion, !kIncludeDiversificationNonce,
+ PACKET_6BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
@@ -5498,8 +5647,9 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
std::unique_ptr<QuicPacket> raw(new QuicPacket(
AsChars(framer_.transport_version() <= QUIC_VERSION_38 ? packet
: packet39),
- arraysize(packet), false, PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER));
+ QUIC_ARRAYSIZE(packet), false, PACKET_8BYTE_CONNECTION_ID,
+ kIncludeVersion, !kIncludeDiversificationNonce,
+ PACKET_6BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
@@ -5743,7 +5893,7 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicEncryptedPacket encrypted(AsChars(p), arraysize(packet), false);
+ QuicEncryptedPacket encrypted(AsChars(p), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
}
@@ -5767,8 +5917,8 @@ TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
new NullDecrypter(framer_.perspective()));
framer_.SetEncrypter(ENCRYPTION_NONE,
new NullEncrypter(framer_.perspective()));
- QuicTransportVersionVector versions;
- versions.push_back(framer_.transport_version());
+ ParsedQuicVersionVector versions;
+ versions.push_back(framer_.version());
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
42, false, false, kTestQuicStreamId, kTestString,
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions));
@@ -5803,8 +5953,8 @@ TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
new NullDecrypter(framer_.perspective()));
framer_.SetEncrypter(ENCRYPTION_NONE,
new NullEncrypter(framer_.perspective()));
- QuicTransportVersionVector versions;
- versions.push_back(framer_.transport_version());
+ ParsedQuicVersionVector versions;
+ versions.push_back(framer_.version());
std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
42, false, false, kTestQuicStreamId, kTestString,
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions,
@@ -5838,7 +5988,7 @@ extern "C" {
// target function to be fuzzed by Dr. Fuzz
void QuicFramerFuzzFunc(unsigned char* data, size_t size) {
- QuicFramer framer(AllSupportedTransportVersions(), QuicTime::Zero(),
+ QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
Perspective::IS_SERVER);
const char* const packet_bytes = reinterpret_cast<const char*>(data);
@@ -5945,7 +6095,7 @@ TEST_P(QuicFramerTest, FramerFuzzTest) {
} else if (framer_.transport_version() > QUIC_VERSION_38) {
p = packet39;
}
- QuicFramerFuzzFunc(p, arraysize(packet));
+ QuicFramerFuzzFunc(p, QUIC_ARRAYSIZE(packet));
}
TEST_P(QuicFramerTest, StartsWithChlo) {
diff --git a/chromium/net/quic/core/quic_headers_stream.cc b/chromium/net/quic/core/quic_headers_stream.cc
index 68e2b5a6fd4..5f7276d4b8e 100644
--- a/chromium/net/quic/core/quic_headers_stream.cc
+++ b/chromium/net/quic/core/quic_headers_stream.cc
@@ -5,6 +5,7 @@
#include "net/quic/core/quic_headers_stream.h"
#include "net/quic/core/quic_spdy_session.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
@@ -38,7 +39,7 @@ void QuicHeadersStream::OnDataAvailable() {
QuicTime timestamp(QuicTime::Zero());
while (true) {
iov.iov_base = buffer;
- iov.iov_len = arraysize(buffer);
+ iov.iov_len = QUIC_ARRAYSIZE(buffer);
if (!sequencer()->GetReadableRegion(&iov, &timestamp)) {
// No more data to read.
break;
@@ -111,7 +112,8 @@ void QuicHeadersStream::OnStreamFrameAcked(QuicStreamOffset offset,
}
void QuicHeadersStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length) {
+ QuicByteCount data_length,
+ bool /*fin_retransmitted*/) {
for (CompressedHeaderInfo& header : unacked_headers_) {
if (offset < header.headers_stream_offset) {
// This header frame offset belongs to headers with smaller offset, stop
diff --git a/chromium/net/quic/core/quic_headers_stream.h b/chromium/net/quic/core/quic_headers_stream.h
index 9d6df38a51b..4892b0e85dc 100644
--- a/chromium/net/quic/core/quic_headers_stream.h
+++ b/chromium/net/quic/core/quic_headers_stream.h
@@ -44,7 +44,8 @@ class QUIC_EXPORT_PRIVATE QuicHeadersStream : public QuicStream {
QuicTime::Delta ack_delay_time) override;
void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length) override;
+ QuicByteCount data_length,
+ bool fin_retransmitted) override;
private:
friend class test::QuicHeadersStreamPeer;
diff --git a/chromium/net/quic/core/quic_headers_stream_test.cc b/chromium/net/quic/core/quic_headers_stream_test.cc
index 616c8368d9b..cc5ca02babe 100644
--- a/chromium/net/quic/core/quic_headers_stream_test.cc
+++ b/chromium/net/quic/core/quic_headers_stream_test.cc
@@ -133,28 +133,36 @@ class ForceHolAckListener : public QuicAckListenerInterface {
DISALLOW_COPY_AND_ASSIGN(ForceHolAckListener);
};
-typedef testing::tuple<QuicTransportVersion, Perspective> TestParamsTuple;
-
struct TestParams {
- explicit TestParams(TestParamsTuple params)
- : version(testing::get<0>(params)), perspective(testing::get<1>(params)) {
- QUIC_LOG(INFO) << "TestParams: version: " << QuicVersionToString(version)
+ TestParams(const ParsedQuicVersion& version, Perspective perspective)
+ : version(version), perspective(perspective) {
+ QUIC_LOG(INFO) << "TestParams: version: "
+ << ParsedQuicVersionToString(version)
<< ", perspective: " << perspective;
}
- QuicTransportVersion version;
+ TestParams(const TestParams& other)
+ : version(other.version), perspective(other.perspective) {}
+
+ ParsedQuicVersion version;
Perspective perspective;
};
-class QuicHeadersStreamTest : public QuicTestWithParam<TestParamsTuple> {
+std::vector<TestParams> GetTestParams() {
+ std::vector<TestParams> params;
+ ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
+ for (size_t i = 0; i < all_supported_versions.size(); ++i) {
+ for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
+ params.emplace_back(all_supported_versions[i], p);
+ }
+ }
+ return params;
+}
+
+class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
public:
- // Constructing the test_params_ object will set the necessary flags before
- // the MockQuicConnection is constructed, which we need because the latter
- // will construct a SpdyFramer that will use those flags to decide whether
- // to construct a decoder adapter.
QuicHeadersStreamTest()
- : test_params_(GetParam()),
- connection_(new StrictMock<MockQuicConnection>(&helper_,
+ : connection_(new StrictMock<MockQuicConnection>(&helper_,
&alarm_factory_,
perspective(),
GetVersion())),
@@ -250,8 +258,9 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParamsTuple> {
EXPECT_CALL(session_,
WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN))
.WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
- QuicSpdySessionPeer::WriteHeadersImpl(
- &session_, stream_id, headers_.Clone(), fin, priority, nullptr);
+ QuicSpdySessionPeer::WriteHeadersImpl(&session_, stream_id,
+ headers_.Clone(), fin, priority, 0,
+ false, nullptr);
// Parse the outgoing data and check that it matches was was written.
if (is_request) {
@@ -288,15 +297,15 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParamsTuple> {
headers_handler_.reset();
}
- Perspective perspective() const { return test_params_.perspective; }
+ Perspective perspective() const { return GetParam().perspective; }
QuicTransportVersion transport_version() const {
- return test_params_.version;
+ return GetParam().version.transport_version;
}
- QuicTransportVersionVector GetVersion() {
- QuicTransportVersionVector versions;
- versions.push_back(transport_version());
+ ParsedQuicVersionVector GetVersion() {
+ ParsedQuicVersionVector versions;
+ versions.push_back(GetParam().version);
return versions;
}
@@ -311,7 +320,6 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParamsTuple> {
static const bool kFrameComplete = true;
static const bool kHasPriority = true;
- const TestParams test_params_;
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
StrictMock<MockQuicConnection>* connection_;
@@ -335,12 +343,9 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParamsTuple> {
};
// Run all tests with each version, perspective (client or server)..
-INSTANTIATE_TEST_CASE_P(
- Tests,
- QuicHeadersStreamTest,
- ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
- ::testing::Values(Perspective::IS_CLIENT,
- Perspective::IS_SERVER)));
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicHeadersStreamTest,
+ ::testing::ValuesIn(GetTestParams()));
TEST_P(QuicHeadersStreamTest, StreamId) {
EXPECT_EQ(3u, headers_stream_->id());
@@ -460,7 +465,7 @@ TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
}
TEST_P(QuicHeadersStreamTest, ProcessPushPromiseDisabledSetting) {
- FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = true;
+ SetQuicReloadableFlag(quic_respect_http2_settings_frame, true);
session_.OnConfigNegotiated();
SpdySettingsIR data;
// Respect supported settings frames SETTINGS_ENABLE_PUSH.
@@ -629,7 +634,7 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
}
TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
- FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = false;
+ SetQuicReloadableFlag(quic_respect_http2_settings_frame, false);
SpdySettingsIR data;
data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 0);
SpdySerializedFrame frame(framer_->SerializeFrame(data));
@@ -643,8 +648,8 @@ TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
}
TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
- FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = true;
- FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = true;
+ SetQuicReloadableFlag(quic_respect_http2_settings_frame, true);
+ SetQuicReloadableFlag(quic_send_max_header_list_size, true);
const uint32_t kTestHeaderTableSize = 1000;
SpdySettingsIR data;
// Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE,
@@ -660,8 +665,8 @@ TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
}
TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
- FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame = true;
- FLAGS_quic_reloadable_flag_quic_send_max_header_list_size = true;
+ SetQuicReloadableFlag(quic_respect_http2_settings_frame, true);
+ SetQuicReloadableFlag(quic_send_max_header_list_size, true);
SpdySettingsIR data;
// Does not support SETTINGS_MAX_CONCURRENT_STREAMS,
// SETTINGS_INITIAL_WINDOW_SIZE, SETTINGS_ENABLE_PUSH and
@@ -835,8 +840,8 @@ TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) {
TEST_P(QuicHeadersStreamTest, AckSentData) {
EXPECT_CALL(session_,
WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
- if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
+ if (!GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
EXPECT_CALL(*connection_, CloseConnection(QUIC_INTERNAL_ERROR, _, _));
}
InSequence s;
@@ -862,8 +867,8 @@ TEST_P(QuicHeadersStreamTest, AckSentData) {
// Packet 2 gets retransmitted.
EXPECT_CALL(*ack_listener3, OnPacketRetransmitted(7)).Times(1);
EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(7)).Times(1);
- headers_stream_->OnStreamFrameRetransmitted(21, 7);
- headers_stream_->OnStreamFrameRetransmitted(28, 7);
+ headers_stream_->OnStreamFrameRetransmitted(21, 7, false);
+ headers_stream_->OnStreamFrameRetransmitted(28, 7, false);
// Packets are acked in order: 2, 3, 1.
EXPECT_CALL(*ack_listener3, OnPacketAcked(7, _));
@@ -880,7 +885,7 @@ TEST_P(QuicHeadersStreamTest, AckSentData) {
headers_stream_->OnStreamFrameAcked(7, 7, false, QuicTime::Delta::Zero());
// Unsent data is acked.
EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- if (FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ if (GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
headers_stream_->OnStreamFrameAcked(14, 10, false, QuicTime::Delta::Zero());
} else {
EXPECT_QUIC_BUG(headers_stream_->OnStreamFrameAcked(
@@ -893,7 +898,7 @@ TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
// In this test, a stream frame can contain multiple headers.
EXPECT_CALL(session_,
WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
InSequence s;
QuicReferenceCountedPointer<MockAckListener> ack_listener1(
new MockAckListener());
@@ -912,7 +917,7 @@ TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
// Frame 1 is retransmitted.
EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(14));
EXPECT_CALL(*ack_listener2, OnPacketRetransmitted(3));
- headers_stream_->OnStreamFrameRetransmitted(0, 17);
+ headers_stream_->OnStreamFrameRetransmitted(0, 17, false);
// Frames are acked in order: 2, 3, 1.
EXPECT_CALL(*ack_listener2, OnPacketAcked(4, _));
@@ -930,12 +935,12 @@ TEST_P(QuicHeadersStreamTest, FrameContainsMultipleHeaders) {
}
TEST_P(QuicHeadersStreamTest, HeadersGetAckedMultipleTimes) {
- if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ if (!GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
return;
}
EXPECT_CALL(session_,
WritevData(headers_stream_, kHeadersStreamId, _, _, NO_FIN))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
InSequence s;
QuicReferenceCountedPointer<MockAckListener> ack_listener1(
new MockAckListener());
diff --git a/chromium/net/quic/core/quic_packet_creator.cc b/chromium/net/quic/core/quic_packet_creator.cc
index a9056cf03c4..bc52f7dd25f 100644
--- a/chromium/net/quic/core/quic_packet_creator.cc
+++ b/chromium/net/quic/core/quic_packet_creator.cc
@@ -12,6 +12,7 @@
#include "net/quic/core/quic_data_writer.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_aligned.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
@@ -302,7 +303,7 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame(
QuicPacketHeader header;
FillPacketHeader(&header);
QUIC_CACHELINE_ALIGNED char encrypted_buffer[kMaxPacketSize];
- QuicDataWriter writer(arraysize(encrypted_buffer), encrypted_buffer,
+ QuicDataWriter writer(QUIC_ARRAYSIZE(encrypted_buffer), encrypted_buffer,
framer_->endianness());
if (!framer_->AppendPacketHeader(header, &writer)) {
QUIC_BUG << "AppendPacketHeader failed";
@@ -343,7 +344,7 @@ void QuicPacketCreator::CreateAndSerializeStreamFrame(
size_t encrypted_length = framer_->EncryptInPlace(
packet_.encryption_level, packet_.packet_number,
GetStartOfEncryptedData(framer_->transport_version(), header),
- writer.length(), arraysize(encrypted_buffer), encrypted_buffer);
+ writer.length(), QUIC_ARRAYSIZE(encrypted_buffer), encrypted_buffer);
if (encrypted_length == 0) {
QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
return;
@@ -462,7 +463,7 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
std::unique_ptr<QuicEncryptedPacket>
QuicPacketCreator::SerializeVersionNegotiationPacket(
- const QuicTransportVersionVector& supported_versions) {
+ const ParsedQuicVersionVector& supported_versions) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
std::unique_ptr<QuicEncryptedPacket> encrypted =
QuicFramer::BuildVersionNegotiationPacket(connection_id_,
@@ -480,7 +481,7 @@ QuicPacketCreator::SerializeConnectivityProbingPacket() {
std::unique_ptr<char[]> buffer(new char[kMaxPacketSize]);
size_t length = framer_->BuildConnectivityProbingPacket(header, buffer.get(),
- max_packet_length_);
+ max_plaintext_size_);
DCHECK(length);
const size_t encrypted_length = framer_->EncryptInPlace(
diff --git a/chromium/net/quic/core/quic_packet_creator.h b/chromium/net/quic/core/quic_packet_creator.h
index 8888e749906..c73cbd8efab 100644
--- a/chromium/net/quic/core/quic_packet_creator.h
+++ b/chromium/net/quic/core/quic_packet_creator.h
@@ -154,7 +154,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Creates a version negotiation packet which supports |supported_versions|.
std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
// Creates a connectivity probing packet.
std::unique_ptr<QuicEncryptedPacket> SerializeConnectivityProbingPacket();
diff --git a/chromium/net/quic/core/quic_packet_creator_test.cc b/chromium/net/quic/core/quic_packet_creator_test.cc
index 543d088da70..e8a6d6afa7b 100644
--- a/chromium/net/quic/core/quic_packet_creator_test.cc
+++ b/chromium/net/quic/core/quic_packet_creator_test.cc
@@ -39,27 +39,26 @@ namespace {
const QuicStreamId kGetNthClientInitiatedStreamId1 = kHeadersStreamId + 2;
-// Run tests with combinations of {QuicTransportVersion,
+// Run tests with combinations of {ParsedQuicVersion,
// ToggleVersionSerialization}.
struct TestParams {
- TestParams(QuicTransportVersion version, bool version_serialization)
+ TestParams(ParsedQuicVersion version, bool version_serialization)
: version(version), version_serialization(version_serialization) {}
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
- os << "{ version: " << QuicVersionToString(p.version)
+ os << "{ version: " << ParsedQuicVersionToString(p.version)
<< " include version: " << p.version_serialization << " }";
return os;
}
- QuicTransportVersion version;
+ ParsedQuicVersion version;
bool version_serialization;
};
// Constructs various test permutations.
std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
- QuicTransportVersionVector all_supported_versions =
- AllSupportedTransportVersions();
+ ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
for (size_t i = 0; i < all_supported_versions.size(); ++i) {
params.push_back(TestParams(all_supported_versions[i], true));
params.push_back(TestParams(all_supported_versions[i], false));
@@ -127,18 +126,15 @@ class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
protected:
QuicPacketCreatorTest()
- : server_framer_(SupportedTransportVersions(GetParam().version),
+ : server_framer_(SupportedVersions(GetParam().version),
QuicTime::Zero(),
Perspective::IS_SERVER),
- client_framer_(SupportedTransportVersions(GetParam().version),
+ client_framer_(SupportedVersions(GetParam().version),
QuicTime::Zero(),
Perspective::IS_CLIENT),
connection_id_(2),
data_("foo"),
- creator_(connection_id_,
- &client_framer_,
- &delegate_,
- &producer_),
+ creator_(connection_id_, &client_framer_, &delegate_, &producer_),
serialized_packet_(creator_.NoPacket()) {
creator_.SetEncrypter(ENCRYPTION_INITIAL,
new NullEncrypter(Perspective::IS_CLIENT));
@@ -663,7 +659,7 @@ TEST_P(QuicPacketCreatorTest, NonCryptoStreamFramePacketNonPadding) {
TEST_P(QuicPacketCreatorTest, SerializeVersionNegotiationPacket) {
QuicFramerPeer::SetPerspective(&client_framer_, Perspective::IS_SERVER);
- QuicTransportVersionVector versions;
+ ParsedQuicVersionVector versions;
versions.push_back(test::QuicVersionMax());
std::unique_ptr<QuicEncryptedPacket> encrypted(
creator_.SerializeVersionNegotiationPacket(versions));
@@ -724,7 +720,7 @@ TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthLeastAwaiting) {
QuicPacketCreatorPeer::SetPacketNumber(&creator_,
UINT64_C(64) * 256 * 256 * 256 * 256);
creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
- if (GetParam().version <= QUIC_VERSION_39) {
+ if (GetParam().version.transport_version <= QUIC_VERSION_39) {
EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
} else {
@@ -752,7 +748,7 @@ TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
creator_.UpdatePacketNumberLength(
1, UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
- if (GetParam().version <= QUIC_VERSION_39) {
+ if (GetParam().version.transport_version <= QUIC_VERSION_39) {
EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
} else {
diff --git a/chromium/net/quic/core/quic_packet_generator.cc b/chromium/net/quic/core/quic_packet_generator.cc
index e74edcf71ef..2274d32f111 100644
--- a/chromium/net/quic/core/quic_packet_generator.cc
+++ b/chromium/net/quic/core/quic_packet_generator.cc
@@ -309,7 +309,7 @@ void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
std::unique_ptr<QuicEncryptedPacket>
QuicPacketGenerator::SerializeVersionNegotiationPacket(
- const QuicTransportVersionVector& supported_versions) {
+ const ParsedQuicVersionVector& supported_versions) {
return packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
}
diff --git a/chromium/net/quic/core/quic_packet_generator.h b/chromium/net/quic/core/quic_packet_generator.h
index 74a3d9c70be..d3f1473a95a 100644
--- a/chromium/net/quic/core/quic_packet_generator.h
+++ b/chromium/net/quic/core/quic_packet_generator.h
@@ -137,7 +137,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
// Creates a version negotiation packet which supports |supported_versions|.
std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
// Creates a connectivity probing packet.
std::unique_ptr<QuicEncryptedPacket> SerializeConnectivityProbingPacket();
diff --git a/chromium/net/quic/core/quic_packet_generator_test.cc b/chromium/net/quic/core/quic_packet_generator_test.cc
index 8cc2be7b10c..e24df72a8d3 100644
--- a/chromium/net/quic/core/quic_packet_generator_test.cc
+++ b/chromium/net/quic/core/quic_packet_generator_test.cc
@@ -149,14 +149,10 @@ class TestPacketGenerator : public QuicPacketGenerator {
class QuicPacketGeneratorTest : public QuicTest {
public:
QuicPacketGeneratorTest()
- : framer_(AllSupportedTransportVersions(),
+ : framer_(AllSupportedVersions(),
QuicTime::Zero(),
Perspective::IS_CLIENT),
- generator_(42,
- &framer_,
- &random_generator_,
- &delegate_,
- &producer_),
+ generator_(42, &framer_, &random_generator_, &delegate_, &producer_),
creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)) {
creator_->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
new NullEncrypter(Perspective::IS_CLIENT));
@@ -1074,14 +1070,7 @@ TEST_F(QuicPacketGeneratorTest, ConnectionCloseFrameLargerThanPacketSize) {
char buf[2000] = {};
QuicStringPiece error_details(buf, 2000);
frame->error_details = error_details.as_string();
- if (FLAGS_quic_reloadable_flag_quic_truncate_long_details) {
- generator_.AddControlFrame(QuicFrame(frame));
- } else {
- EXPECT_CALL(delegate_, OnUnrecoverableError(
- QUIC_FAILED_TO_SERIALIZE_PACKET,
- "Single frame cannot fit into a packet", _));
- EXPECT_QUIC_BUG(generator_.AddControlFrame(QuicFrame(frame)), "");
- }
+ generator_.AddControlFrame(QuicFrame(frame));
EXPECT_TRUE(generator_.HasQueuedFrames());
EXPECT_TRUE(generator_.HasRetransmittableFrames());
}
diff --git a/chromium/net/quic/core/quic_packets.cc b/chromium/net/quic/core/quic_packets.cc
index 2dbbedea60c..35013e0fadc 100644
--- a/chromium/net/quic/core/quic_packets.cc
+++ b/chromium/net/quic/core/quic_packets.cc
@@ -54,7 +54,8 @@ QuicPacketHeader::QuicPacketHeader()
reset_flag(false),
version_flag(false),
packet_number_length(PACKET_6BYTE_PACKET_NUMBER),
- version(QUIC_VERSION_UNSUPPORTED),
+ version(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED)),
nonce(nullptr),
packet_number(0) {}
@@ -87,7 +88,7 @@ std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
<< ", reset_flag: " << header.reset_flag
<< ", version_flag: " << header.version_flag;
if (header.version_flag) {
- os << ", version: " << QuicVersionToString(header.version);
+ os << ", version: " << ParsedQuicVersionToString(header.version);
}
if (header.nonce != nullptr) {
os << ", diversification_nonce: "
diff --git a/chromium/net/quic/core/quic_packets.h b/chromium/net/quic/core/quic_packets.h
index df73ad88fa2..3ee5a6bd470 100644
--- a/chromium/net/quic/core/quic_packets.h
+++ b/chromium/net/quic/core/quic_packets.h
@@ -72,7 +72,7 @@ struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
bool reset_flag;
bool version_flag;
QuicPacketNumberLength packet_number_length;
- QuicTransportVersion version;
+ ParsedQuicVersion version;
// nonce contains an optional, 32-byte nonce value. If not included in the
// packet, |nonce| will be empty.
DiversificationNonce* nonce;
@@ -95,7 +95,7 @@ struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
~QuicVersionNegotiationPacket();
QuicConnectionId connection_id;
- QuicTransportVersionVector versions;
+ ParsedQuicVersionVector versions;
};
class QUIC_EXPORT_PRIVATE QuicData {
diff --git a/chromium/net/quic/core/quic_received_packet_manager.cc b/chromium/net/quic/core/quic_received_packet_manager.cc
index b2a6cc1e653..2f01d30f944 100644
--- a/chromium/net/quic/core/quic_received_packet_manager.cc
+++ b/chromium/net/quic/core/quic_received_packet_manager.cc
@@ -55,7 +55,7 @@ void QuicReceivedPacketManager::RecordPacketReceived(
std::max(stats_->max_time_reordering_us, reordering_time_us);
}
if (packet_number > LargestAcked(ack_frame_)) {
- ack_frame_.deprecated_largest_observed = packet_number;
+ ack_frame_.largest_acked = packet_number;
time_largest_observed_ = receipt_time;
}
ack_frame_.packets.Add(packet_number);
diff --git a/chromium/net/quic/core/quic_sent_packet_manager.cc b/chromium/net/quic/core/quic_sent_packet_manager.cc
index db69f08b48a..26411993fdd 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager.cc
+++ b/chromium/net/quic/core/quic_sent_packet_manager.cc
@@ -111,11 +111,11 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (config.HasClientRequestedIndependentOption(kRENO, perspective_)) {
SetSendAlgorithm(kRenoBytes);
} else if (config.HasClientRequestedIndependentOption(kBYTE, perspective_) ||
- (FLAGS_quic_reloadable_flag_quic_default_to_bbr &&
+ (GetQuicReloadableFlag(quic_default_to_bbr) &&
config.HasClientRequestedIndependentOption(kQBIC,
perspective_))) {
SetSendAlgorithm(kCubicBytes);
- } else if (FLAGS_quic_reloadable_flag_quic_enable_pcc &&
+ } else if (GetQuicReloadableFlag(quic_enable_pcc) &&
config.HasClientRequestedIndependentOption(kTPCC, perspective_)) {
SetSendAlgorithm(kPCC);
}
@@ -131,6 +131,11 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(kNTLP, perspective_)) {
max_tail_loss_probes_ = 0;
}
+ if (GetQuicReloadableFlag(quic_one_tlp) &&
+ config.HasClientSentConnectionOption(k1TLP, perspective_)) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_one_tlp, 1, 2);
+ max_tail_loss_probes_ = 1;
+ }
if (config.HasClientSentConnectionOption(kTLPR, perspective_)) {
enable_half_rtt_tail_loss_probe_ = true;
}
@@ -450,7 +455,7 @@ void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
pending_retransmissions_.erase(newest_transmission);
if (newest_transmission == packet_number) {
- unacked_packets_.NotifyStreamFramesAcked(*info, ack_delay_time);
+ unacked_packets_.NotifyFramesAcked(*info, ack_delay_time);
} else {
RecordSpuriousRetransmissions(*info, packet_number);
// Remove the most recent packet from flight if it's a crypto handshake
@@ -461,8 +466,8 @@ void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
// only handle nullptr encrypted packets in a special way.
const QuicTransmissionInfo& newest_transmission_info =
unacked_packets_.GetTransmissionInfo(newest_transmission);
- unacked_packets_.NotifyStreamFramesAcked(newest_transmission_info,
- ack_delay_time);
+ unacked_packets_.NotifyFramesAcked(newest_transmission_info,
+ ack_delay_time);
if (HasCryptoHandshake(newest_transmission_info)) {
unacked_packets_.RemoveFromInFlight(newest_transmission);
}
@@ -949,9 +954,9 @@ const SendAlgorithmInterface* QuicSentPacketManager::GetSendAlgorithm() const {
return send_algorithm_.get();
}
-void QuicSentPacketManager::SetStreamNotifier(
- StreamNotifierInterface* stream_notifier) {
- unacked_packets_.SetStreamNotifier(stream_notifier);
+void QuicSentPacketManager::SetSessionNotifier(
+ SessionNotifierInterface* session_notifier) {
+ unacked_packets_.SetSessionNotifier(session_notifier);
}
} // namespace net
diff --git a/chromium/net/quic/core/quic_sent_packet_manager.h b/chromium/net/quic/core/quic_sent_packet_manager.h
index 673982370da..b0c974ce8ec 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager.h
+++ b/chromium/net/quic/core/quic_sent_packet_manager.h
@@ -229,7 +229,7 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
const SendAlgorithmInterface* GetSendAlgorithm() const;
- void SetStreamNotifier(StreamNotifierInterface* stream_notifier);
+ void SetSessionNotifier(SessionNotifierInterface* session_notifier);
QuicPacketNumber largest_packet_peer_knows_is_acked() const {
return largest_packet_peer_knows_is_acked_;
diff --git a/chromium/net/quic/core/quic_sent_packet_manager_test.cc b/chromium/net/quic/core/quic_sent_packet_manager_test.cc
index 25e7a78fc47..8b7071714f7 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager_test.cc
+++ b/chromium/net/quic/core/quic_sent_packet_manager_test.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "net/quic/core/quic_pending_retransmission.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string_piece.h"
@@ -255,9 +256,10 @@ TEST_F(QuicSentPacketManagerTest, IsUnacked) {
SendDataPacket(1);
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
}
TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
@@ -266,9 +268,10 @@ TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {2};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
}
TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
@@ -283,7 +286,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
// Packet 1 is unacked, pending, but not retransmittable.
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
VerifyRetransmittablePackets(nullptr, 0);
}
@@ -320,7 +323,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
EXPECT_FALSE(manager_.HasPendingRetransmissions());
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
}
@@ -338,7 +341,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
// 2 remains unacked, but no packets have retransmittable data.
QuicPacketNumber unacked[] = {2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
VerifyRetransmittablePackets(nullptr, 0);
@@ -406,7 +409,7 @@ TEST_F(QuicSentPacketManagerTest,
// Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
QuicPacketNumber unacked[] = {2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
VerifyRetransmittablePackets(nullptr, 0);
@@ -435,7 +438,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
// 2 and 3 remain unacked, but no packets have retransmittable data.
QuicPacketNumber unacked[] = {2, 3};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
VerifyRetransmittablePackets(nullptr, 0);
@@ -443,11 +446,11 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
SendDataPacket(4);
ack_frame = InitAckFrame({{1, 2}, {3, 5}});
QuicPacketNumber acked[] = {3, 4};
- ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
QuicPacketNumber unacked2[] = {2};
- VerifyUnackedPackets(unacked2, arraysize(unacked2));
+ VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
SendDataPacket(5);
@@ -628,7 +631,8 @@ TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
ack_frame = InitAckFrame({{3, 6}});
QuicPacketNumber acked[] = {4, 5};
QuicPacketNumber lost[] = {1, 2};
- ExpectAcksAndLosses(true, acked, arraysize(acked), lost, arraysize(lost));
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), lost,
+ QUIC_ARRAYSIZE(lost));
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -732,7 +736,7 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
// Now ack the two crypto packets and the speculatively encrypted request,
// and ensure the first four crypto packets get abandoned, but not lost.
QuicPacketNumber acked[] = {3, 4, 5, 8, 9};
- ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
QuicAckFrame ack_frame = InitAckFrame({{3, 6}, {8, 10}});
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
@@ -780,7 +784,7 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutVersionNegotiation) {
// Least unacked isn't raised until an ack is received, so ack the
// crypto packets.
QuicPacketNumber acked[] = {8, 9};
- ExpectAcksAndLosses(true, acked, arraysize(acked), nullptr, 0);
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
QuicAckFrame ack_frame = InitAckFrame({{8, 10}});
manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_EQ(10u, manager_.GetLeastUnacked());
@@ -807,7 +811,7 @@ TEST_F(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
QuicPacketNumber unacked[] = {3};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
}
TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
@@ -841,7 +845,7 @@ TEST_F(QuicSentPacketManagerTest,
// version negotiation.
manager_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
EXPECT_TRUE(manager_.HasPendingRetransmissions());
EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
@@ -868,7 +872,7 @@ TEST_F(QuicSentPacketManagerTest,
manager_.NeuterUnencryptedPackets();
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
QuicPacketNumber unacked[] = {1, 2, 3};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
EXPECT_FALSE(manager_.HasPendingRetransmissions());
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
@@ -1467,6 +1471,33 @@ TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
}
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
+ SetQuicReloadableFlag(quic_one_tlp, true);
+ QuicConfig config;
+ QuicTagVector options;
+
+ options.push_back(k1TLP);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ manager_.SetFromConfig(config);
+ EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
+ SetQuicReloadableFlag(quic_one_tlp, true);
+ QuicConfig client_config;
+ QuicTagVector options;
+
+ options.push_back(k1TLP);
+ QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+ client_config.SetConnectionOptionsToSend(options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ manager_.SetFromConfig(client_config);
+ EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
TEST_F(QuicSentPacketManagerTest, NegotiateTLPRttFromOptionsAtServer) {
QuicConfig config;
QuicTagVector options;
diff --git a/chromium/net/quic/core/quic_server_id.h b/chromium/net/quic/core/quic_server_id.h
index 880afd2be9d..d7cb609b2f2 100644
--- a/chromium/net/quic/core/quic_server_id.h
+++ b/chromium/net/quic/core/quic_server_id.h
@@ -5,8 +5,7 @@
#ifndef NET_QUIC_CORE_QUIC_SERVER_ID_H_
#define NET_QUIC_CORE_QUIC_SERVER_ID_H_
-#include <stdint.h>
-
+#include <cstdint>
#include <string>
#include "net/base/host_port_pair.h"
diff --git a/chromium/net/quic/core/quic_server_id_test.cc b/chromium/net/quic/core/quic_server_id_test.cc
index abf05a3edd4..be8eeb1e79b 100644
--- a/chromium/net/quic/core/quic_server_id_test.cc
+++ b/chromium/net/quic/core/quic_server_id_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/core/quic_server_id.h"
+#include "net/quic/platform/api/quic_estimate_memory_usage.h"
#include "net/quic/platform/api/quic_test.h"
using std::string;
@@ -26,6 +27,16 @@ TEST_F(QuicServerIdTest, ToString) {
EXPECT_EQ("https://google.com:10/private", private_server_id_str);
}
+TEST_F(QuicServerIdTest, HostPortPair) {
+ HostPortPair google_host_port_pair("google.com", 10);
+
+ QuicServerId google_server_id(google_host_port_pair, PRIVACY_MODE_DISABLED);
+ EXPECT_TRUE(google_host_port_pair.Equals(google_server_id.host_port_pair()));
+
+ QuicServerId private_server_id(google_host_port_pair, PRIVACY_MODE_ENABLED);
+ EXPECT_TRUE(google_host_port_pair.Equals(private_server_id.host_port_pair()));
+}
+
TEST_F(QuicServerIdTest, LessThan) {
QuicServerId a_10_https(HostPortPair("a.com", 10), PRIVACY_MODE_DISABLED);
QuicServerId a_11_https(HostPortPair("a.com", 11), PRIVACY_MODE_DISABLED);
@@ -142,6 +153,13 @@ TEST_F(QuicServerIdTest, Equals) {
EXPECT_FALSE(new_a_10_https_no_private == a_10_https_private);
}
+TEST_F(QuicServerIdTest, EstimateMemoryUsage) {
+ HostPortPair host_port_pair("this is a rather very quite long hostname", 10);
+ QuicServerId server_id(host_port_pair, PRIVACY_MODE_ENABLED);
+ EXPECT_EQ(QuicEstimateMemoryUsage(host_port_pair),
+ QuicEstimateMemoryUsage(server_id));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/quic/core/quic_server_session_base_test.cc b/chromium/net/quic/core/quic_server_session_base_test.cc
index 3eefabe3bb6..e91fa773588 100644
--- a/chromium/net/quic/core/quic_server_session_base_test.cc
+++ b/chromium/net/quic/core/quic_server_session_base_test.cc
@@ -14,6 +14,7 @@
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/quic_crypto_server_stream.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_socket_address.h"
@@ -106,7 +107,7 @@ class TestServerSession : public QuicServerSessionBase {
QuicCompressedCertsCache* compressed_certs_cache) override {
return new QuicCryptoServerStream(
crypto_config, compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support, this,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
stream_helper());
}
@@ -116,8 +117,7 @@ class TestServerSession : public QuicServerSessionBase {
const size_t kMaxStreamsForTest = 10;
-class QuicServerSessionBaseTest
- : public QuicTestWithParam<QuicTransportVersion> {
+class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
protected:
QuicServerSessionBaseTest()
: QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
@@ -125,7 +125,8 @@ class QuicServerSessionBaseTest
explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
: crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- std::move(proof_source)),
+ std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()),
compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
@@ -139,7 +140,7 @@ class QuicServerSessionBaseTest
connection_ = new StrictMock<MockQuicConnection>(
&helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(GetParam()));
session_.reset(new TestServerSession(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &response_cache_));
@@ -191,7 +192,7 @@ MATCHER_P(EqualsProto, network_params, "") {
INSTANTIATE_TEST_CASE_P(Tests,
QuicServerSessionBaseTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
// Open a stream, then reset it.
// Send two bytes of payload to open it.
@@ -366,7 +367,7 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
: QuicCryptoServerStream(
crypto_config,
compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support),
session,
helper) {}
~MockQuicCryptoServerStream() override {}
@@ -570,21 +571,21 @@ class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
INSTANTIATE_TEST_CASE_P(StreamMemberLifetimeTests,
StreamMemberLifetimeTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
// Trigger an operation which causes an async invocation of
// ProofSource::GetProof. Delay the completion of the operation until after the
// stream has been destroyed, and verify that there are no memory bugs.
TEST_P(StreamMemberLifetimeTest, Basic) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
const QuicClock* clock = helper_.GetClock();
- QuicTransportVersion version = AllSupportedTransportVersions().front();
+ ParsedQuicVersion version = AllSupportedVersions().front();
CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
- clock, version, &crypto_config_);
+ clock, version.transport_version, &crypto_config_);
chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
- std::vector<QuicTransportVersion> packet_version_list = {version};
+ std::vector<ParsedQuicVersion> packet_version_list = {version};
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
1, true, false, 1,
string(chlo.GetSerialized(Perspective::IS_CLIENT)
diff --git a/chromium/net/quic/core/quic_session.cc b/chromium/net/quic/core/quic_session.cc
index 9d2e6ace311..b53709c0393 100644
--- a/chromium/net/quic/core/quic_session.cc
+++ b/chromium/net/quic/core/quic_session.cc
@@ -54,9 +54,9 @@ QuicSession::QuicSession(QuicConnection* connection,
perspective() == Perspective::IS_SERVER,
nullptr),
currently_writing_stream_id_(0),
- can_use_slices_(FLAGS_quic_reloadable_flag_quic_use_mem_slices),
+ can_use_slices_(GetQuicReloadableFlag(quic_use_mem_slices)),
allow_multiple_acks_for_data_(
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
if (allow_multiple_acks_for_data_) {
QUIC_FLAG_COUNT(quic_reloadable_flag_quic_allow_multiple_acks_for_data2);
}
@@ -64,7 +64,7 @@ QuicSession::QuicSession(QuicConnection* connection,
void QuicSession::Initialize() {
connection_->set_visitor(this);
- connection_->SetStreamNotifier(this);
+ connection_->SetSessionNotifier(this);
connection_->SetDataProducer(this);
connection_->SetFromConfig(config_);
@@ -265,6 +265,11 @@ bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
}
void QuicSession::OnCanWrite() {
+ if (!RetransmitLostStreamData()) {
+ // Cannot finish retransmitting lost data, connection is write blocked.
+ return;
+ }
+
// We limit the number of writes to the number of pending streams. If more
// streams become pending, WillingAndAbleToWrite will be true, which will
// cause the connection to request resumption before yielding to other
@@ -319,17 +324,21 @@ void QuicSession::OnCanWrite() {
}
bool QuicSession::WillingAndAbleToWrite() const {
- // If the crypto or headers streams are blocked, we want to schedule a write -
- // they don't get blocked by connection level flow control. Otherwise only
- // schedule a write if we are not flow control blocked at the connection
- // level.
- return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
+ // Schedule a write when:
+ // 1) any stream has pending retransmissions, or
+ // 2) If the crypto or headers streams are blocked, or
+ // 3) connection is not flow control blocked and there are write blocked
+ // streams.
+ return !streams_with_pending_retransmission_.empty() ||
+ write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
(!flow_controller_.IsBlocked() &&
write_blocked_streams_.HasWriteBlockedDataStreams());
}
bool QuicSession::HasPendingHandshake() const {
- return write_blocked_streams_.crypto_stream_blocked();
+ return QuicContainsKey(streams_with_pending_retransmission_,
+ kCryptoStreamId) ||
+ write_blocked_streams_.crypto_stream_blocked();
}
bool QuicSession::HasOpenDynamicStreams() const {
@@ -368,7 +377,10 @@ QuicConsumedData QuicSession::WritevData(QuicStream* stream,
}
QuicConsumedData data =
connection_->SendStreamData(id, write_length, offset, state);
- write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
+ if (offset >= stream->stream_bytes_written()) {
+ // This is new stream data.
+ write_blocked_streams_.UpdateBytesForStream(id, data.bytes_consumed);
+ }
return data;
}
@@ -430,6 +442,8 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) {
zombie_streams_[stream->id()] = std::move(it->second);
} else {
closed_streams_.push_back(std::move(it->second));
+ // Do not retransmit data of a closed stream.
+ streams_with_pending_retransmission_.erase(stream_id);
}
// If we haven't received a FIN or RST for this stream, we need to keep track
@@ -526,10 +540,7 @@ void QuicSession::OnConfigNegotiated() {
}
}
- if (FLAGS_quic_reloadable_flag_quic_send_reset_token_in_shlo) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_send_reset_token_in_shlo);
- config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
- }
+ config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
}
// A small number of additional incoming streams beyond the limit should be
@@ -763,6 +774,14 @@ bool QuicSession::ShouldYield(QuicStreamId stream_id) {
return write_blocked_streams()->ShouldYield(stream_id);
}
+void QuicSession::NeuterUnencryptedStreamData() {
+ QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+ crypto_stream->NeuterUnencryptedStreamData();
+ if (!crypto_stream->HasPendingRetransmission()) {
+ streams_with_pending_retransmission_.erase(kCryptoStreamId);
+ }
+}
+
QuicStream* QuicSession::GetOrCreateDynamicStream(
const QuicStreamId stream_id) {
DCHECK(!QuicContainsKey(static_stream_map_, stream_id))
@@ -941,6 +960,8 @@ void QuicSession::OnStreamDoneWaitingForAcks(QuicStreamId id) {
closed_streams_.push_back(std::move(it->second));
zombie_streams_.erase(it);
+ // Do not retransmit data of a closed stream.
+ streams_with_pending_retransmission_.erase(id);
}
QuicStream* QuicSession::GetStream(QuicStreamId id) const {
@@ -959,13 +980,20 @@ QuicStream* QuicSession::GetStream(QuicStreamId id) const {
return nullptr;
}
-void QuicSession::OnStreamFrameAcked(const QuicStreamFrame& frame,
- QuicTime::Delta ack_delay_time) {
- QuicStream* stream = GetStream(frame.stream_id);
+void QuicSession::OnFrameAcked(const QuicFrame& frame,
+ QuicTime::Delta ack_delay_time) {
+ if (frame.type != STREAM_FRAME) {
+ return;
+ }
+ QuicStream* stream = GetStream(frame.stream_frame->stream_id);
// Stream can already be reset when sent frame gets acked.
if (stream != nullptr) {
- stream->OnStreamFrameAcked(frame.offset, frame.data_length, frame.fin,
- ack_delay_time);
+ stream->OnStreamFrameAcked(frame.stream_frame->offset,
+ frame.stream_frame->data_length,
+ frame.stream_frame->fin, ack_delay_time);
+ if (!stream->HasPendingRetransmission()) {
+ streams_with_pending_retransmission_.erase(stream->id());
+ }
}
}
@@ -979,20 +1007,27 @@ void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return;
}
- stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length);
+ stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
+ frame.fin);
}
-void QuicSession::OnStreamFrameDiscarded(const QuicStreamFrame& frame) {
- QuicStream* stream = GetStream(frame.stream_id);
+void QuicSession::OnFrameLost(const QuicFrame& frame) {
+ if (frame.type != STREAM_FRAME) {
+ return;
+ }
+ QuicStream* stream = GetStream(frame.stream_frame->stream_id);
if (stream == nullptr) {
- QUIC_BUG << "Stream: " << frame.stream_id << " is closed when " << frame
- << " is discarded.";
- connection()->CloseConnection(
- QUIC_INTERNAL_ERROR, "Attempt to discard frame of a closed stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
return;
}
- stream->OnStreamFrameDiscarded(frame.offset, frame.data_length, frame.fin);
+ stream->OnStreamFrameLost(frame.stream_frame->offset,
+ frame.stream_frame->data_length,
+ frame.stream_frame->fin);
+ if (stream->HasPendingRetransmission() &&
+ !QuicContainsKey(streams_with_pending_retransmission_,
+ frame.stream_frame->stream_id)) {
+ streams_with_pending_retransmission_.insert(
+ std::make_pair(frame.stream_frame->stream_id, true));
+ }
}
bool QuicSession::WriteStreamData(QuicStreamId id,
@@ -1013,4 +1048,48 @@ uint128 QuicSession::GetStatelessResetToken() const {
return kStatelessResetToken;
}
+bool QuicSession::RetransmitLostStreamData() {
+ QuicConnection::ScopedPacketFlusher retransmission_flusher(
+ connection_, QuicConnection::SEND_ACK_IF_QUEUED);
+ while (!streams_with_pending_retransmission_.empty()) {
+ if (!connection_->CanWriteStreamData()) {
+ break;
+ }
+ if (QuicContainsKey(streams_with_pending_retransmission_,
+ kCryptoStreamId)) {
+ // Retransmit crypto data first.
+ QuicStream* crypto_stream = GetStream(kCryptoStreamId);
+ crypto_stream->OnCanWrite();
+ if (crypto_stream->HasPendingRetransmission()) {
+ // Connection is write blocked.
+ break;
+ } else {
+ streams_with_pending_retransmission_.erase(kCryptoStreamId);
+ }
+ continue;
+ }
+ // Retransmit lost data on headers and data streams.
+ QuicStream* stream =
+ GetStream(streams_with_pending_retransmission_.begin()->first);
+ if (stream != nullptr) {
+ stream->OnCanWrite();
+ if (stream->HasPendingRetransmission()) {
+ // Connection is write blocked.
+ break;
+ } else {
+ streams_with_pending_retransmission_.pop_front();
+ }
+ } else {
+ QUIC_BUG << "Try to retransmit data of a closed stream";
+ streams_with_pending_retransmission_.pop_front();
+ }
+ }
+
+ return streams_with_pending_retransmission_.empty();
+}
+
+void QuicSession::NeuterUnencryptedData() {
+ connection_->NeuterUnencryptedPackets();
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_session.h b/chromium/net/quic/core/quic_session.h
index 6387eadba0a..35981f07e42 100644
--- a/chromium/net/quic/core/quic_session.h
+++ b/chromium/net/quic/core/quic_session.h
@@ -23,7 +23,7 @@
#include "net/quic/core/quic_stream.h"
#include "net/quic/core/quic_stream_frame_data_producer.h"
#include "net/quic/core/quic_write_blocked_list.h"
-#include "net/quic/core/stream_notifier_interface.h"
+#include "net/quic/core/session_notifier_interface.h"
#include "net/quic/platform/api/quic_containers.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_socket_address.h"
@@ -39,7 +39,7 @@ class QuicSessionPeer;
} // namespace test
class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
- public StreamNotifierInterface,
+ public SessionNotifierInterface,
public QuicStreamFrameDataProducer {
public:
// An interface from the session to the entity owning the session.
@@ -122,11 +122,11 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
QuicByteCount data_length,
QuicDataWriter* writer) override;
- // StreamNotifierInterface methods:
- void OnStreamFrameAcked(const QuicStreamFrame& frame,
- QuicTime::Delta ack_delay_time) override;
+ // SessionNotifierInterface methods:
+ void OnFrameAcked(const QuicFrame& frame,
+ QuicTime::Delta ack_delay_time) override;
void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override;
- void OnStreamFrameDiscarded(const QuicStreamFrame& frame) override;
+ void OnFrameLost(const QuicFrame& frame) override;
// Called on every incoming packet. Passes |packet| through to |connection_|.
virtual void ProcessUdpPacket(const QuicSocketAddress& self_address,
@@ -233,6 +233,9 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// a stream is reset because of an error).
void OnStreamDoneWaitingForAcks(QuicStreamId id);
+ // Called to cancel retransmission of unencypted crypto stream data.
+ void NeuterUnencryptedData();
+
// Returns true if the session has data to be sent, either queued in the
// connection, or in a write-blocked stream.
bool HasDataToWrite() const;
@@ -275,6 +278,9 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// Returns true if this stream should yield writes to another blocked stream.
bool ShouldYield(QuicStreamId stream_id);
+ // Called to cancel retransmission of unencrypted stream data.
+ void NeuterUnencryptedStreamData();
+
bool can_use_slices() const { return can_use_slices_; }
bool allow_multiple_acks_for_data() const {
@@ -424,6 +430,10 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// closed.
QuicStream* GetStream(QuicStreamId id) const;
+ // Let streams retransmit lost data, returns true if all lost data is
+ // retransmitted. Returns false otherwise.
+ bool RetransmitLostStreamData();
+
// Keep track of highest received byte offset of locally closed streams, while
// waiting for a definitive final highest offset from the peer.
std::map<QuicStreamId, QuicStreamOffset>
@@ -499,6 +509,11 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// Latched value of quic_reloadable_flag_quic_allow_multiple_acks_for_data2.
const bool allow_multiple_acks_for_data_;
+ // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
+ // is not used here.
+ // List of streams with pending retransmissions.
+ QuicLinkedHashMap<QuicStreamId, bool> streams_with_pending_retransmission_;
+
DISALLOW_COPY_AND_ASSIGN(QuicSession);
};
diff --git a/chromium/net/quic/core/quic_session_test.cc b/chromium/net/quic/core/quic_session_test.cc
index d401957bf60..734e2a82711 100644
--- a/chromium/net/quic/core/quic_session_test.cc
+++ b/chromium/net/quic/core/quic_session_test.cc
@@ -92,6 +92,8 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
MOCK_METHOD0(OnCanWrite, void());
+ MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
+
private:
using QuicCryptoStream::session;
@@ -118,6 +120,8 @@ class TestStream : public QuicSpdyStream {
void OnDataAvailable() override {}
MOCK_METHOD0(OnCanWrite, void());
+
+ MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
};
// Poor man's functor for use as callback in a mock.
@@ -241,14 +245,14 @@ class TestSession : public QuicSpdySession {
bool writev_consumes_all_data_;
};
-class QuicSessionTestBase : public QuicTestWithParam<QuicTransportVersion> {
+class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
protected:
explicit QuicSessionTestBase(Perspective perspective)
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_,
- &alarm_factory_,
- perspective,
- SupportedTransportVersions(GetParam()))),
+ : connection_(
+ new StrictMock<MockQuicConnection>(&helper_,
+ &alarm_factory_,
+ perspective,
+ SupportedVersions(GetParam()))),
session_(connection_) {
session_.config()->SetInitialStreamFlowControlWindowToSend(
kInitialStreamFlowControlWindowForTest);
@@ -329,7 +333,7 @@ class QuicSessionTestServer : public QuicSessionTestBase {
INSTANTIATE_TEST_CASE_P(Tests,
QuicSessionTestServer,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSessionTestServer, PeerAddress) {
EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
@@ -562,7 +566,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
CryptoHandshakeMessage msg;
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) {
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
}
@@ -827,7 +831,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, ServerReplyToConnecitivityProbe) {
- if (!FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (!GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
return;
}
QuicSocketAddress old_peer_address =
@@ -837,7 +841,7 @@ TEST_P(QuicSessionTestServer, ServerReplyToConnecitivityProbe) {
QuicSocketAddress new_peer_address =
QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
@@ -850,7 +854,7 @@ TEST_P(QuicSessionTestServer, ServerReplyToConnecitivityProbe) {
}
session_.OnConnectivityProbeReceived(session_.self_address(),
new_peer_address);
- if (FLAGS_quic_reloadable_flag_quic_server_reply_to_connectivity_probing) {
+ if (GetQuicReloadableFlag(quic_server_reply_to_connectivity_probing)) {
EXPECT_EQ(old_peer_address, session_.peer_address());
} else {
EXPECT_EQ(new_peer_address, session_.peer_address());
@@ -1340,7 +1344,7 @@ class QuicSessionTestClient : public QuicSessionTestBase {
INSTANTIATE_TEST_CASE_P(Tests,
QuicSessionTestClient,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSessionTestClient, AvailableStreamsClient) {
ASSERT_TRUE(session_.GetOrCreateDynamicStream(6) != nullptr);
@@ -1423,6 +1427,104 @@ TEST_P(QuicSessionTestServer, ZombieStreams) {
EXPECT_EQ(2u, session_.closed_streams()->front()->id());
}
+TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
+ InSequence s;
+
+ // Drive congestion control manually.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+
+ QuicStreamFrame frame1(kCryptoStreamId, false, 0, 1300);
+ QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+ QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+ // Lost data on cryption stream, streams 2 and 4.
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+ session_.OnFrameLost(QuicFrame(&frame3));
+ session_.OnFrameLost(QuicFrame(&frame1));
+ session_.OnFrameLost(QuicFrame(&frame2));
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // Mark streams 2 and 4 write blocked.
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ // Lost data is retransmitted before new data, and retransmissions for crypto
+ // stream go first.
+ // Do not check congestion window when crypto stream has lost data.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+ EXPECT_CALL(*crypto_stream, OnCanWrite());
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+ .WillOnce(Return(false));
+ // Check congestion window for non crypto streams.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, OnCanWrite());
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+ // Connection is blocked.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // Unblock connection.
+ // Stream 2 retransmits lost data.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ // Stream 2 sends new data.
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, OnCanWrite());
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+ InSequence s;
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+ QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+ QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+ EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+ session_.OnFrameLost(QuicFrame(&frame3));
+ session_.OnFrameLost(QuicFrame(&frame2));
+ session_.OnFrameLost(QuicFrame(&frame1));
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+ // Reset stream 4 locally.
+ EXPECT_CALL(*connection_, SendRstStream(stream4->id(), _, _));
+ stream4->Reset(QUIC_STREAM_CANCELLED);
+
+ // Verify stream 4 is removed from streams with lost data list.
+ EXPECT_CALL(*stream6, OnCanWrite());
+ EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream6, OnCanWrite());
+ session_.OnCanWrite();
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/quic_socket_address_coder_test.cc b/chromium/net/quic/core/quic_socket_address_coder_test.cc
index ce2032fb93b..c538a443d91 100644
--- a/chromium/net/quic/core/quic_socket_address_coder_test.cc
+++ b/chromium/net/quic/core/quic_socket_address_coder_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/core/quic_socket_address_coder.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
using std::string;
@@ -110,7 +111,7 @@ TEST_F(QuicSocketAddressCoderTest, EncodeAndDecode) {
{"::1", 65534},
};
- for (size_t i = 0; i < arraysize(test_case); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(test_case); i++) {
QuicIpAddress ip;
ASSERT_TRUE(ip.FromString(test_case[i].ip_literal));
QuicSocketAddressCoder encoder(QuicSocketAddress(ip, test_case[i].port));
diff --git a/chromium/net/quic/core/quic_spdy_session.cc b/chromium/net/quic/core/quic_spdy_session.cc
index 6679b105561..47bf470407c 100644
--- a/chromium/net/quic/core/quic_spdy_session.cc
+++ b/chromium/net/quic/core/quic_spdy_session.cc
@@ -121,7 +121,7 @@ class QuicSpdySession::SpdyFramerVisitor
}
void OnSetting(SpdySettingsIds id, uint32_t value) override {
- if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) {
+ if (!GetQuicReloadableFlag(quic_respect_http2_settings_frame)) {
CloseConnection("SPDY SETTINGS frame received.",
QUIC_INVALID_HEADERS_STREAM_DATA);
return;
@@ -150,7 +150,7 @@ class QuicSpdySession::SpdyFramerVisitor
// TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when
// clients are actually sending it.
case SETTINGS_MAX_HEADER_LIST_SIZE:
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) {
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
break;
}
default:
@@ -161,14 +161,14 @@ class QuicSpdySession::SpdyFramerVisitor
}
void OnSettingsAck() override {
- if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) {
+ if (!GetQuicReloadableFlag(quic_respect_http2_settings_frame)) {
CloseConnection("SPDY SETTINGS frame received.",
QUIC_INVALID_HEADERS_STREAM_DATA);
}
}
void OnSettingsEnd() override {
- if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) {
+ if (!GetQuicReloadableFlag(quic_respect_http2_settings_frame)) {
CloseConnection("SPDY SETTINGS frame received.",
QUIC_INVALID_HEADERS_STREAM_DATA);
}
@@ -296,10 +296,11 @@ QuicSpdySession::QuicSpdySession(QuicConnection* connection,
supports_push_promise_(perspective() == Perspective::IS_CLIENT),
cur_max_timestamp_(QuicTime::Zero()),
prev_max_timestamp_(QuicTime::Zero()),
- use_hq_deframer_(FLAGS_quic_reloadable_flag_quic_enable_hq_deframer),
+ use_hq_deframer_(GetQuicReloadableFlag(quic_enable_hq_deframer)),
spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
spdy_framer_visitor_(new SpdyFramerVisitor(this)) {
if (use_hq_deframer_) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_enable_hq_deframer);
hq_deframer_.set_visitor(spdy_framer_visitor_.get());
hq_deframer_.set_debug_visitor(spdy_framer_visitor_.get());
} else {
@@ -399,10 +400,21 @@ size_t QuicSpdySession::WriteHeaders(
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- ack_notifier_delegate) {
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
+ return WriteHeadersImpl(id, std::move(headers), fin, priority, 0, false,
+ std::move(ack_listener));
+}
+
+size_t QuicSpdySession::WriteHeaders(
+ QuicStreamId id,
+ SpdyHeaderBlock headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicStreamId parent_stream_id,
+ bool exclusive,
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
return WriteHeadersImpl(id, std::move(headers), fin, priority,
- std::move(ack_notifier_delegate));
+ parent_stream_id, exclusive, std::move(ack_listener));
}
size_t QuicSpdySession::WriteHeadersImpl(
@@ -410,18 +422,32 @@ size_t QuicSpdySession::WriteHeadersImpl(
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
- QuicReferenceCountedPointer<QuicAckListenerInterface>
- ack_notifier_delegate) {
+ QuicStreamId parent_stream_id,
+ bool exclusive,
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
SpdyHeadersIR headers_frame(id, std::move(headers));
headers_frame.set_fin(fin);
if (perspective() == Perspective::IS_CLIENT) {
headers_frame.set_has_priority(true);
headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority));
+ headers_frame.set_parent_stream_id(parent_stream_id);
+ headers_frame.set_exclusive(exclusive);
}
SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
headers_stream_->WriteOrBufferData(
QuicStringPiece(frame.data(), frame.size()), false,
- std::move(ack_notifier_delegate));
+ std::move(ack_listener));
+ return frame.size();
+}
+
+size_t QuicSpdySession::WritePriority(QuicStreamId id,
+ QuicStreamId parent_stream_id,
+ int weight,
+ bool exclusive) {
+ SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
+ SpdySerializedFrame frame(spdy_framer_.SerializeFrame(priority_frame));
+ headers_stream_->WriteOrBufferData(
+ QuicStringPiece(frame.data(), frame.size()), false, nullptr);
return frame.size();
}
@@ -480,7 +506,7 @@ QuicSpdyStream* QuicSpdySession::GetSpdyDataStream(
void QuicSpdySession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
QuicSession::OnCryptoHandshakeEvent(event);
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size &&
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size) &&
event == HANDSHAKE_CONFIRMED && config()->SupportMaxHeaderListSize()) {
SendMaxHeaderListSize(max_inbound_header_list_size_);
}
diff --git a/chromium/net/quic/core/quic_spdy_session.h b/chromium/net/quic/core/quic_spdy_session.h
index a2a4c3ce345..f8a2d5c73bf 100644
--- a/chromium/net/quic/core/quic_spdy_session.h
+++ b/chromium/net/quic/core/quic_spdy_session.h
@@ -92,6 +92,23 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
SpdyPriority priority,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+ // |parent_stream_id| and |exclusive| are HTTP2 stream dependency info.
+ virtual size_t WriteHeaders(
+ QuicStreamId id,
+ SpdyHeaderBlock headers,
+ bool fin,
+ SpdyPriority priority,
+ QuicStreamId parent_stream_id,
+ bool exclusive,
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+ // Writes a PRIORITY frame the to peer. Returns the size in bytes of the
+ // resulting PRIORITY frame.
+ size_t WritePriority(QuicStreamId id,
+ QuicStreamId parent_stream_id,
+ int weight,
+ bool exclusive);
+
// Write |headers| for |promised_stream_id| on |original_stream_id| in a
// PUSH_PROMISE frame to peer.
// Return the size, in bytes, of the resulting PUSH_PROMISE frame.
@@ -109,13 +126,13 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
virtual void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta);
// Called by the stream on creation to set priority in the write blocked list.
- void RegisterStreamPriority(QuicStreamId id, SpdyPriority priority);
+ virtual void RegisterStreamPriority(QuicStreamId id, SpdyPriority priority);
// Called by the stream on deletion to clear priority crom the write blocked
// list.
- void UnregisterStreamPriority(QuicStreamId id);
+ virtual void UnregisterStreamPriority(QuicStreamId id);
// Called by the stream on SetPriority to update priority on the write blocked
// list.
- void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);
+ virtual void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);
void OnConfigNegotiated() override;
@@ -226,6 +243,8 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
+ QuicStreamId parent_stream_id,
+ bool exclusive,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
std::unique_ptr<QuicHeadersStream> headers_stream_;
diff --git a/chromium/net/quic/core/quic_spdy_stream_test.cc b/chromium/net/quic/core/quic_spdy_stream_test.cc
index 04543f69b6d..3e2c4cb765e 100644
--- a/chromium/net/quic/core/quic_spdy_stream_test.cc
+++ b/chromium/net/quic/core/quic_spdy_stream_test.cc
@@ -11,6 +11,7 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/quic_write_blocked_list.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_map_util.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string_piece.h"
@@ -50,7 +51,7 @@ class TestStream : public QuicSpdyStream {
char buffer[2048];
struct iovec vec;
vec.iov_base = buffer;
- vec.iov_len = arraysize(buffer);
+ vec.iov_len = QUIC_ARRAYSIZE(buffer);
size_t bytes_read = Readv(&vec, 1);
data_ += string(buffer, bytes_read);
}
@@ -66,7 +67,7 @@ class TestStream : public QuicSpdyStream {
string data_;
};
-class QuicSpdyStreamTest : public QuicTestWithParam<QuicTransportVersion> {
+class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
public:
QuicSpdyStreamTest() {
headers_[":host"] = "www.google.com";
@@ -101,7 +102,7 @@ class QuicSpdyStreamTest : public QuicTestWithParam<QuicTransportVersion> {
void Initialize(bool stream_should_process_data) {
connection_ = new testing::StrictMock<MockQuicConnection>(
&helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(GetParam()));
session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_));
stream_ = new TestStream(GetNthClientInitiatedId(0), session_.get(),
stream_should_process_data);
@@ -136,7 +137,7 @@ class QuicSpdyStreamTest : public QuicTestWithParam<QuicTransportVersion> {
INSTANTIATE_TEST_CASE_P(Tests,
QuicSpdyStreamTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
Initialize(kShouldProcessData);
@@ -318,10 +319,10 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
stream_->ConsumeHeaderList();
char buffer[2048];
- ASSERT_LT(body.length(), arraysize(buffer));
+ ASSERT_LT(body.length(), QUIC_ARRAYSIZE(buffer));
struct iovec vec;
vec.iov_base = buffer;
- vec.iov_len = arraysize(buffer);
+ vec.iov_len = QUIC_ARRAYSIZE(buffer);
size_t bytes_read = stream_->Readv(&vec, 1);
EXPECT_EQ(body.length(), bytes_read);
@@ -362,7 +363,7 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
char buffer[1];
struct iovec vec;
vec.iov_base = buffer;
- vec.iov_len = arraysize(buffer);
+ vec.iov_len = QUIC_ARRAYSIZE(buffer);
for (size_t i = 0; i < body.length(); ++i) {
size_t bytes_read = stream_->Readv(&vec, 1);
@@ -385,9 +386,9 @@ TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
char buffer2[1];
struct iovec vec[2];
vec[0].iov_base = buffer1;
- vec[0].iov_len = arraysize(buffer1);
+ vec[0].iov_len = QUIC_ARRAYSIZE(buffer1);
vec[1].iov_base = buffer2;
- vec[1].iov_len = arraysize(buffer2);
+ vec[1].iov_len = QUIC_ARRAYSIZE(buffer2);
for (size_t i = 0; i < body.length(); i += 2) {
size_t bytes_read = stream_->Readv(vec, 2);
@@ -844,7 +845,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Write the initial headers, without a FIN.
EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _));
@@ -864,7 +865,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Write the initial headers.
EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _));
@@ -892,7 +893,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Write the initial headers.
EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _));
@@ -916,7 +917,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Write the initial headers.
EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _));
@@ -948,7 +949,7 @@ TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Write the initial headers, with a FIN.
EXPECT_CALL(*session_, WriteHeadersMock(_, _, _, _, _));
@@ -965,7 +966,7 @@ TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
testing::InSequence s;
QuicReferenceCountedPointer<MockAckListener> ack_listener1(
new MockAckListener());
@@ -991,20 +992,20 @@ TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
session_->OnStreamFrameRetransmitted(frame1);
EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
- session_->OnStreamFrameAcked(frame1, QuicTime::Delta::Zero());
+ session_->OnFrameAcked(QuicFrame(&frame1), QuicTime::Delta::Zero());
EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
- session_->OnStreamFrameAcked(frame2, QuicTime::Delta::Zero());
+ session_->OnFrameAcked(QuicFrame(&frame2), QuicTime::Delta::Zero());
EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
- session_->OnStreamFrameAcked(frame3, QuicTime::Delta::Zero());
+ session_->OnFrameAcked(QuicFrame(&frame3), QuicTime::Delta::Zero());
EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
- session_->OnStreamFrameAcked(frame4, QuicTime::Delta::Zero());
+ session_->OnFrameAcked(QuicFrame(&frame4), QuicTime::Delta::Zero());
}
TEST_P(QuicSpdyStreamTest, StreamBecomesZombieWithWriteThatCloses) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
QuicStreamPeer::CloseReadSide(stream_);
// This write causes stream to be closed.
stream_->WriteOrBufferData("Test1", true, nullptr);
diff --git a/chromium/net/quic/core/quic_stream.cc b/chromium/net/quic/core/quic_stream.cc
index 00806bed866..53fae6107c5 100644
--- a/chromium/net/quic/core/quic_stream.cc
+++ b/chromium/net/quic/core/quic_stream.cc
@@ -10,6 +10,7 @@
#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_str_cat.h"
using std::string;
@@ -52,6 +53,7 @@ QuicStream::QuicStream(QuicStreamId id, QuicSession* session)
fin_buffered_(false),
fin_sent_(false),
fin_outstanding_(false),
+ fin_lost_(false),
fin_received_(false),
rst_sent_(false),
rst_received_(false),
@@ -71,9 +73,8 @@ QuicStream::QuicStream(QuicStreamId id, QuicSession* session)
send_buffer_(
session->connection()->helper()->GetStreamSendBufferAllocator(),
session->allow_multiple_acks_for_data()),
- buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
- remove_on_stream_frame_discarded_(
- FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded) {
+ buffered_data_threshold_(
+ GetQuicFlag(FLAGS_quic_buffered_data_threshold)) {
SetFromConfig();
}
@@ -94,6 +95,20 @@ void QuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
DCHECK(!(read_side_closed_ && write_side_closed_));
+ bool is_stream_too_long =
+ (frame.offset > kMaxStreamLength) ||
+ (kMaxStreamLength - frame.offset < frame.data_length);
+ if (GetQuicReloadableFlag(quic_stream_too_long) && is_stream_too_long) {
+ // Close connection if stream becomes too long.
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_stream_too_long, 4, 5);
+ QUIC_PEER_BUG
+ << "Receive stream frame reaches max stream length. frame offset "
+ << frame.offset << " length " << frame.data_length;
+ CloseConnectionWithDetails(
+ QUIC_STREAM_LENGTH_OVERFLOW,
+ "Peer sends more data than allowed on this stream.");
+ return;
+ }
if (frame.fin) {
fin_received_ = true;
if (fin_sent_) {
@@ -141,6 +156,14 @@ int QuicStream::num_duplicate_frames_received() const {
void QuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
rst_received_ = true;
+ if (GetQuicReloadableFlag(quic_stream_too_long) &&
+ frame.byte_offset > kMaxStreamLength) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_stream_too_long, 5, 5);
+ // Peer are not suppose to write bytes more than maxium allowed.
+ CloseConnectionWithDetails(QUIC_STREAM_LENGTH_OVERFLOW,
+ "Reset frame stream offset overflow.");
+ return;
+ }
MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
if (flow_controller_.FlowControlViolation() ||
connection_flow_controller_->FlowControlViolation()) {
@@ -221,6 +244,15 @@ void QuicStream::WriteOrBufferData(
if (data.length() > 0) {
struct iovec iov(MakeIovec(data));
QuicStreamOffset offset = send_buffer_.stream_offset();
+ if (GetQuicReloadableFlag(quic_stream_too_long) &&
+ kMaxStreamLength - offset < data.length()) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_stream_too_long, 1, 5);
+ QUIC_BUG << "Write too many data via stream " << id_;
+ CloseConnectionWithDetails(
+ QUIC_STREAM_LENGTH_OVERFLOW,
+ QuicStrCat("Write too many data via stream ", id_));
+ return;
+ }
send_buffer_.SaveStreamData(&iov, 1, 0, data.length());
OnDataBuffered(offset, data.length(), ack_listener);
}
@@ -231,9 +263,17 @@ void QuicStream::WriteOrBufferData(
}
void QuicStream::OnCanWrite() {
+ if (HasPendingRetransmission()) {
+ // Exit early to allow other streams to write pending retransmissions if
+ // any.
+ WritePendingRetransmission();
+ return;
+ }
+
if (write_side_closed_) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Stream " << id()
- << "attempting to write when the write side is closed";
+ QUIC_DLOG(ERROR)
+ << ENDPOINT << "Stream " << id()
+ << " attempting to write new data when the write side is closed";
return;
}
if (HasBufferedData() || (fin_buffered_ && !fin_sent_)) {
@@ -285,6 +325,16 @@ QuicConsumedData QuicStream::WritevData(const struct iovec* iov,
return consumed_data;
}
+ if (GetQuicReloadableFlag(quic_stream_too_long) &&
+ kMaxStreamLength - send_buffer_.stream_offset() < write_length) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_stream_too_long, 2, 5);
+ QUIC_BUG << "Write too many data via stream " << id_;
+ CloseConnectionWithDetails(
+ QUIC_STREAM_LENGTH_OVERFLOW,
+ QuicStrCat("Write too many data via stream ", id_));
+ return consumed_data;
+ }
+
bool had_buffered_data = HasBufferedData();
if (CanWriteNewData()) {
// Save all data if buffered data size is below low water mark.
@@ -334,6 +384,16 @@ QuicConsumedData QuicStream::WriteMemSlices(QuicMemSliceSpan span, bool fin) {
QuicStreamOffset offset = send_buffer_.stream_offset();
consumed_data.bytes_consumed =
span.SaveMemSlicesInSendBuffer(&send_buffer_);
+ if (GetQuicReloadableFlag(quic_stream_too_long) &&
+ (offset > send_buffer_.stream_offset() ||
+ kMaxStreamLength < send_buffer_.stream_offset())) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_stream_too_long, 3, 5);
+ QUIC_BUG << "Write too many data via stream " << id_;
+ CloseConnectionWithDetails(
+ QUIC_STREAM_LENGTH_OVERFLOW,
+ QuicStrCat("Write too many data via stream ", id_));
+ return consumed_data;
+ }
OnDataBuffered(offset, consumed_data.bytes_consumed, nullptr);
}
}
@@ -347,6 +407,17 @@ QuicConsumedData QuicStream::WriteMemSlices(QuicMemSliceSpan span, bool fin) {
return consumed_data;
}
+bool QuicStream::HasPendingRetransmission() const {
+ return send_buffer_.HasPendingRetransmission() || fin_lost_;
+}
+
+bool QuicStream::IsStreamFrameOutstanding(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin) const {
+ return send_buffer_.IsStreamDataOutstanding(offset, data_length) ||
+ (fin && fin_outstanding_);
+}
+
QuicConsumedData QuicStream::WritevDataInner(size_t write_length,
QuicStreamOffset offset,
bool fin) {
@@ -394,6 +465,10 @@ QuicTransportVersion QuicStream::transport_version() const {
return session_->connection()->transport_version();
}
+HandshakeProtocol QuicStream::handshake_protocol() const {
+ return session_->connection()->version().handshake_protocol;
+}
+
void QuicStream::StopReading() {
QUIC_DLOG(INFO) << ENDPOINT << "Stop reading from stream " << id();
sequencer_.StopReading();
@@ -511,6 +586,7 @@ void QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
(fin_acked && fin_outstanding_);
if (fin_acked) {
fin_outstanding_ = false;
+ fin_lost_ = false;
}
if (!IsWaitingForAcks()) {
session_->OnStreamDoneWaitingForAcks(id_);
@@ -520,48 +596,31 @@ void QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
}
}
-void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset /*offset*/,
- QuicByteCount data_length) {
+void QuicStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin_retransmitted) {
+ send_buffer_.OnStreamDataRetransmitted(offset, data_length);
+ if (fin_retransmitted) {
+ fin_lost_ = false;
+ }
if (ack_listener_ != nullptr) {
ack_listener_->OnPacketRetransmitted(data_length);
}
}
-void QuicStream::OnStreamFrameDiscarded(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_discarded) {
- if (remove_on_stream_frame_discarded_) {
- // TODO(fayang): Remove OnStreamFrameDiscarded from StreamNotifierInterface
- // when deprecating
- // quic_reloadable_flag_quic_remove_on_stream_frame_discarded.
- QUIC_FLAG_COUNT_N(
- quic_reloadable_flag_quic_remove_on_stream_frame_discarded, 1, 2);
- return;
- }
-
- QuicByteCount newly_acked_length = 0;
- if (!send_buffer_.OnStreamDataAcked(offset, data_length,
- &newly_acked_length)) {
- CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
- "Trying to discard unsent data.");
- return;
- }
- if (!fin_sent_ && fin_discarded) {
- CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
- "Trying to discard unsent fin.");
- return;
+void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin_lost) {
+ if (data_length > 0) {
+ send_buffer_.OnStreamDataLost(offset, data_length);
}
- if (fin_discarded) {
- fin_outstanding_ = false;
- }
- if (!IsWaitingForAcks()) {
- session_->OnStreamDoneWaitingForAcks(id_);
+ if (fin_lost && fin_outstanding_) {
+ fin_lost_ = true;
}
}
bool QuicStream::IsWaitingForAcks() const {
- return (!remove_on_stream_frame_discarded_ || !rst_sent_ ||
- stream_error_ == QUIC_STREAM_NO_ERROR) &&
+ return (!rst_sent_ || stream_error_ == QUIC_STREAM_NO_ERROR) &&
(send_buffer_.stream_bytes_outstanding() || fin_outstanding_);
}
@@ -569,6 +628,8 @@ bool QuicStream::WriteStreamData(QuicStreamOffset offset,
QuicByteCount data_length,
QuicDataWriter* writer) {
DCHECK_LT(0u, data_length);
+ QUIC_DVLOG(2) << ENDPOINT << "Write stream " << id_ << " data from offset "
+ << offset << " length " << data_length;
return send_buffer_.WriteStreamData(offset, data_length, writer);
}
@@ -614,7 +675,7 @@ void QuicStream::WriteBufferedData() {
QuicConsumedData consumed_data =
WritevDataInner(write_length, stream_bytes_written(), fin);
- send_buffer_.OnStreamDataConsumed(consumed_data.bytes_consumed);
+ OnStreamDataConsumed(consumed_data.bytes_consumed);
AddBytesSent(consumed_data.bytes_consumed);
QUIC_DVLOG(1) << ENDPOINT << "stream " << id_ << " sends "
@@ -668,4 +729,47 @@ const QuicIntervalSet<QuicStreamOffset>& QuicStream::bytes_acked() const {
return send_buffer_.bytes_acked();
}
+void QuicStream::OnStreamDataConsumed(size_t bytes_consumed) {
+ send_buffer_.OnStreamDataConsumed(bytes_consumed);
+}
+
+void QuicStream::WritePendingRetransmission() {
+ while (HasPendingRetransmission()) {
+ QuicConsumedData consumed(0, false);
+ if (!send_buffer_.HasPendingRetransmission()) {
+ QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+ << " retransmits fin only frame.";
+ consumed =
+ session()->WritevData(this, id_, 0, stream_bytes_written(), FIN);
+ fin_lost_ = !consumed.fin_consumed;
+ if (fin_lost_) {
+ // Connection is write blocked.
+ return;
+ }
+ } else {
+ StreamPendingRetransmission pending =
+ send_buffer_.NextPendingRetransmission();
+ // Determine whether the lost fin can be bundled with the data.
+ const bool can_bundle_fin =
+ fin_lost_ &&
+ (pending.offset + pending.length == stream_bytes_written());
+ consumed =
+ session()->WritevData(this, id_, pending.length, pending.offset,
+ can_bundle_fin ? FIN : NO_FIN);
+ QUIC_DVLOG(1) << ENDPOINT << "stream " << id_
+ << " tries to retransmit stream data [" << pending.offset
+ << ", " << pending.offset + pending.length
+ << ") and fin: " << can_bundle_fin
+ << ", consumed: " << consumed;
+ OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
+ consumed.fin_consumed);
+ if (consumed.bytes_consumed < pending.length ||
+ (can_bundle_fin && !consumed.fin_consumed)) {
+ // Connection is write blocked.
+ return;
+ }
+ }
+ }
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream.h b/chromium/net/quic/core/quic_stream.h
index 31670e6ec28..52bd18f7330 100644
--- a/chromium/net/quic/core/quic_stream.h
+++ b/chromium/net/quic/core/quic_stream.h
@@ -29,7 +29,7 @@
#include "net/quic/core/quic_stream_send_buffer.h"
#include "net/quic/core/quic_stream_sequencer.h"
#include "net/quic/core/quic_types.h"
-#include "net/quic/core/stream_notifier_interface.h"
+#include "net/quic/core/session_notifier_interface.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_mem_slice_span.h"
#include "net/quic/platform/api/quic_reference_counted.h"
@@ -168,6 +168,10 @@ class QUIC_EXPORT_PRIVATE QuicStream {
// Returns the version of QUIC being used for this stream.
QuicTransportVersion transport_version() const;
+ // Returns the crypto handshake protocol that was used on this stream's
+ // connection.
+ HandshakeProtocol handshake_protocol() const;
+
bool fin_received() const { return fin_received_; }
// Sets the sequencer to consume all incoming data itself and not call
@@ -205,21 +209,33 @@ class QUIC_EXPORT_PRIVATE QuicStream {
bool fin_acked,
QuicTime::Delta ack_delay_time);
- // Called when data [offset, offset + data_length) gets retransmitted.
+ // Called when data [offset, offset + data_length) was retransmitted.
+ // |fin_retransmitted| indicates whether fin was retransmitted.
virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
- QuicByteCount data_length);
+ QuicByteCount data_length,
+ bool fin_retransmitted);
- // Called when data [offset, offset + data_length) gets discarded because
- // stream is cancelled. |fin_discarded| indicates whether the fin is
- // discarded.
- void OnStreamFrameDiscarded(QuicStreamOffset offset,
- QuicByteCount data_length,
- bool fin_discarded);
+ // Called when data [offset, offset + data_length) is considered as lost.
+ // |fin_lost| inidacates whether the fin is considered as lost.
+ void OnStreamFrameLost(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin_lost);
// Same as WritevData except data is provided in reference counted memory so
// that data copy is avoided.
QuicConsumedData WriteMemSlices(QuicMemSliceSpan span, bool fin);
+ // Returns true if any stream data is lost (including fin) and needs to be
+ // retransmitted.
+ virtual bool HasPendingRetransmission() const;
+
+ // Returns true if any portion of data [offset, offset + data_length) is
+ // outstanding or fin is outstanding (if |fin| is true). Returns false
+ // otherwise.
+ bool IsStreamFrameOutstanding(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ bool fin) const;
+
protected:
// Sends as many bytes in the first |count| buffers of |iov| to the connection
// as the connection will consume. If FIN is consumed, the write side is
@@ -262,6 +278,12 @@ class QUIC_EXPORT_PRIVATE QuicStream {
// Called when upper layer can write new data.
virtual void OnCanWriteNewData() {}
+ // Called when |bytes_consumed| bytes has been consumed.
+ virtual void OnStreamDataConsumed(size_t bytes_consumed);
+
+ // Writes pending retransmissions if any.
+ virtual void WritePendingRetransmission();
+
bool fin_buffered() const { return fin_buffered_; }
const QuicSession* session() const { return session_; }
@@ -281,6 +303,10 @@ class QUIC_EXPORT_PRIVATE QuicStream {
const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
+ const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
+
+ QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
+
private:
friend class test::QuicStreamPeer;
friend class QuicStreamUtils;
@@ -326,6 +352,8 @@ class QUIC_EXPORT_PRIVATE QuicStream {
bool fin_sent_;
// True if a FIN is waiting to be acked.
bool fin_outstanding_;
+ // True if a FIN is lost.
+ bool fin_lost_;
// True if this stream has received (and the sequencer has accepted) a
// StreamFrame with the FIN set.
@@ -372,10 +400,6 @@ class QUIC_EXPORT_PRIVATE QuicStream {
// Latched value of FLAGS_quic_buffered_data_threshold.
const QuicByteCount buffered_data_threshold_;
- // Latched value of
- // FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded.
- const bool remove_on_stream_frame_discarded_;
-
DISALLOW_COPY_AND_ASSIGN(QuicStream);
};
diff --git a/chromium/net/quic/core/quic_stream_send_buffer.cc b/chromium/net/quic/core/quic_stream_send_buffer.cc
index 5b1fbaaea83..7671245c376 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer.cc
+++ b/chromium/net/quic/core/quic_stream_send_buffer.cc
@@ -26,13 +26,21 @@ BufferedSlice& BufferedSlice::operator=(BufferedSlice&& other) = default;
BufferedSlice::~BufferedSlice() {}
+bool StreamPendingRetransmission::operator==(
+ const StreamPendingRetransmission& other) const {
+ return offset == other.offset && length == other.length;
+}
+
QuicStreamSendBuffer::QuicStreamSendBuffer(QuicBufferAllocator* allocator,
bool allow_multiple_acks_for_data)
: stream_offset_(0),
allocator_(allocator),
stream_bytes_written_(0),
stream_bytes_outstanding_(0),
- allow_multiple_acks_for_data_(allow_multiple_acks_for_data) {}
+ allow_multiple_acks_for_data_(allow_multiple_acks_for_data),
+ write_index_(-1),
+ use_write_index_(allow_multiple_acks_for_data_ &&
+ GetQuicReloadableFlag(quic_use_write_index)) {}
QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
@@ -56,12 +64,17 @@ void QuicStreamSendBuffer::SaveStreamData(const struct iovec* iov,
}
void QuicStreamSendBuffer::SaveMemSlice(QuicMemSlice slice) {
+ QUIC_DVLOG(2) << "Save slice offset " << stream_offset_ << " length "
+ << slice.length();
if (slice.empty()) {
QUIC_BUG << "Try to save empty MemSlice to send buffer.";
return;
}
size_t length = slice.length();
buffered_slices_.emplace_back(std::move(slice), stream_offset_);
+ if (write_index_ == -1) {
+ write_index_ = buffered_slices_.size() - 1;
+ }
stream_offset_ += length;
}
@@ -73,8 +86,11 @@ void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
QuicByteCount data_length,
QuicDataWriter* writer) {
+ if (use_write_index_) {
+ return WriteStreamDataWithIndex(offset, data_length, writer);
+ }
for (const BufferedSlice& slice : buffered_slices_) {
- if (offset < slice.offset) {
+ if (data_length == 0 || offset < slice.offset) {
break;
}
if (offset >= slice.offset + slice.slice.length()) {
@@ -93,6 +109,66 @@ bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
return data_length == 0;
}
+bool QuicStreamSendBuffer::WriteStreamDataWithIndex(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ QuicDataWriter* writer) {
+ bool write_index_hit = false;
+ QuicDeque<BufferedSlice>::iterator slice_it =
+ write_index_ == -1
+ ? buffered_slices_.begin()
+ // Assume with write_index, write mostly starts from indexed slice.
+ : buffered_slices_.begin() + write_index_;
+ if (write_index_ != -1) {
+ if (offset >= slice_it->offset + slice_it->slice.length()) {
+ QUIC_BUG << "Tried to write data out of sequence.";
+ return false;
+ }
+ // Determine if write actually happens at indexed slice.
+ if (offset >= slice_it->offset) {
+ write_index_hit = true;
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_write_index, 1, 2);
+ } else {
+ // Write index missed, move iterator to the beginning.
+ slice_it = buffered_slices_.begin();
+ }
+ }
+
+ for (; slice_it != buffered_slices_.end(); ++slice_it) {
+ if (data_length == 0 || offset < slice_it->offset) {
+ break;
+ }
+ if (offset >= slice_it->offset + slice_it->slice.length()) {
+ continue;
+ }
+ QuicByteCount slice_offset = offset - slice_it->offset;
+ QuicByteCount available_bytes_in_slice =
+ slice_it->slice.length() - slice_offset;
+ QuicByteCount copy_length = std::min(data_length, available_bytes_in_slice);
+ if (!writer->WriteBytes(slice_it->slice.data() + slice_offset,
+ copy_length)) {
+ QUIC_BUG << "Writer fails to write.";
+ return false;
+ }
+ offset += copy_length;
+ data_length -= copy_length;
+
+ if (write_index_hit && copy_length == available_bytes_in_slice) {
+ // Finished writing all data in current slice, advance write index for
+ // next write.
+ ++write_index_;
+ }
+ }
+
+ if (write_index_hit &&
+ static_cast<size_t>(write_index_) == buffered_slices_.size()) {
+ // Already write to the end off buffer.
+ DVLOG(2) << "Finish writing out all buffered data.";
+ write_index_ = -1;
+ }
+
+ return data_length == 0;
+}
+
bool QuicStreamSendBuffer::OnStreamDataAcked(
QuicStreamOffset offset,
QuicByteCount data_length,
@@ -114,12 +190,27 @@ bool QuicStreamSendBuffer::OnStreamDataAcked(
stream_bytes_outstanding_ -= *newly_acked_length;
if (allow_multiple_acks_for_data_) {
bytes_acked_.Add(offset, offset + data_length);
+ pending_retransmissions_.Difference(offset, offset + data_length);
while (!buffered_slices_.empty() &&
bytes_acked_.Contains(buffered_slices_.front().offset,
buffered_slices_.front().offset +
buffered_slices_.front().slice.length())) {
// Remove data which stops waiting for acks. Please note, data can be
// acked out of order, but send buffer is cleaned up in order.
+ if (use_write_index_) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_write_index, 2, 2);
+ QUIC_BUG_IF(write_index_ == 0)
+ << "Fail to advance current_write_slice_. It points to the slice "
+ "whose data has all be written and ACK'ed or ignored. "
+ "current_write_slice_ offset "
+ << buffered_slices_[write_index_].offset << " length "
+ << buffered_slices_[write_index_].slice.length();
+ if (write_index_ > 0) {
+ // If write index is pointing to any slice, reduce the index as the
+ // slices are all shifted to the left by one.
+ --write_index_;
+ }
+ }
buffered_slices_.pop_front();
}
return true;
@@ -150,6 +241,52 @@ bool QuicStreamSendBuffer::OnStreamDataAcked(
return true;
}
+void QuicStreamSendBuffer::OnStreamDataLost(QuicStreamOffset offset,
+ QuicByteCount data_length) {
+ if (data_length == 0) {
+ return;
+ }
+ QuicIntervalSet<QuicStreamOffset> bytes_lost(offset, offset + data_length);
+ bytes_lost.Difference(bytes_acked_);
+ if (bytes_lost.Empty()) {
+ return;
+ }
+ for (const auto& lost : bytes_lost) {
+ pending_retransmissions_.Add(lost.min(), lost.max());
+ }
+}
+
+void QuicStreamSendBuffer::OnStreamDataRetransmitted(
+ QuicStreamOffset offset,
+ QuicByteCount data_length) {
+ if (data_length == 0) {
+ return;
+ }
+ pending_retransmissions_.Difference(offset, offset + data_length);
+}
+
+bool QuicStreamSendBuffer::HasPendingRetransmission() const {
+ return !pending_retransmissions_.Empty();
+}
+
+StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
+ const {
+ if (HasPendingRetransmission()) {
+ const auto pending = pending_retransmissions_.begin();
+ return {pending->min(), pending->max() - pending->min()};
+ }
+ QUIC_BUG << "NextPendingRetransmission is called unexpected with no "
+ "pending retransmissions.";
+ return {0, 0};
+}
+
+bool QuicStreamSendBuffer::IsStreamDataOutstanding(
+ QuicStreamOffset offset,
+ QuicByteCount data_length) const {
+ return data_length > 0 &&
+ !bytes_acked_.Contains(offset, offset + data_length);
+}
+
size_t QuicStreamSendBuffer::size() const {
return buffered_slices_.size();
}
diff --git a/chromium/net/quic/core/quic_stream_send_buffer.h b/chromium/net/quic/core/quic_stream_send_buffer.h
index 79eafccc2dd..c9a7b4aa523 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer.h
+++ b/chromium/net/quic/core/quic_stream_send_buffer.h
@@ -42,6 +42,19 @@ struct BufferedSlice {
QuicByteCount outstanding_data_length;
};
+struct StreamPendingRetransmission {
+ StreamPendingRetransmission(QuicStreamOffset offset, QuicByteCount length)
+ : offset(offset), length(length) {}
+
+ // Starting offset of this pending retransmission.
+ QuicStreamOffset offset;
+ // Length of this pending retransmission.
+ QuicByteCount length;
+
+ QUIC_EXPORT_PRIVATE bool operator==(
+ const StreamPendingRetransmission& other) const;
+};
+
// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
// are added to the tail of the list. Data slices are removed from the head of
// the list when they get fully acked. Stream data can be retrieved and acked
@@ -78,6 +91,24 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
QuicByteCount data_length,
QuicByteCount* newly_acked_length);
+ // Called when data [offset, offset + data_length) is considered as lost.
+ void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
+
+ // Called when data [offset, offset + length) was retransmitted.
+ void OnStreamDataRetransmitted(QuicStreamOffset offset,
+ QuicByteCount data_length);
+
+ // Returns true if there is pending retransmissions.
+ bool HasPendingRetransmission() const;
+
+ // Returns next pending retransmissions.
+ StreamPendingRetransmission NextPendingRetransmission() const;
+
+ // Returns true if data [offset, offset + data_length) is outstanding and
+ // waiting to be acked. Returns false otherwise.
+ bool IsStreamDataOutstanding(QuicStreamOffset offset,
+ QuicByteCount data_length) const;
+
// Number of data slices in send buffer.
size_t size() const;
@@ -97,6 +128,15 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
friend class test::QuicStreamSendBufferPeer;
friend class test::QuicStreamPeer;
+ // Another version of WriteStreamData() to be able to start writing from
+ // write_index_ points to instead of searching through the slices to find the
+ // place to write.
+ // TODO(danzh): inline this method into WriteStreamData() after
+ // quic_reloadable_flag_quic_use_write_index is deprecated.
+ bool WriteStreamDataWithIndex(QuicStreamOffset offset,
+ QuicByteCount data_length,
+ QuicDataWriter* writer);
+
QuicDeque<BufferedSlice> buffered_slices_;
// Offset of next inserted byte.
@@ -115,6 +155,17 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
// Latch value for quic_reloadable_flag_quic_allow_multiple_acks_for_data2.
const bool allow_multiple_acks_for_data_;
+
+ // Data considered as lost and needs to be retransmitted.
+ QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
+
+ // Index of slice which contains data waiting to be written for the first
+ // time. -1 if send buffer is empty or all data has been written.
+ int32_t write_index_;
+
+ // True if quic_reloadable_flag_quic_stream_send_buffer_write_index and
+ // allow_multiple_acks_for_data_ are both true.
+ const bool use_write_index_;
};
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream_send_buffer_test.cc b/chromium/net/quic/core/quic_stream_send_buffer_test.cc
index d2770244731..f4e092f2714 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer_test.cc
+++ b/chromium/net/quic/core/quic_stream_send_buffer_test.cc
@@ -9,6 +9,7 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_test.h"
+#include "net/quic/test_tools/quic_stream_send_buffer_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
using std::string;
@@ -28,7 +29,7 @@ class QuicStreamSendBufferTest : public QuicTest {
QuicStreamSendBufferTest()
: send_buffer_(
&allocator_,
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
EXPECT_EQ(0u, send_buffer_.size());
EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
@@ -41,7 +42,11 @@ class QuicStreamSendBufferTest : public QuicTest {
QuicMemSlice slice1(&allocator_, 1024);
memset(const_cast<char*>(slice1.data()), 'c', 1024);
QuicMemSlice slice2(&allocator_, 768);
- memset(const_cast<char*>(slice2.data()), 'c', 768);
+ memset(const_cast<char*>(slice2.data()), 'd', 768);
+
+ // Index starts from not pointing to any slice.
+ EXPECT_EQ(nullptr,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_));
// Save all data.
SetQuicFlag(&FLAGS_quic_send_buffer_max_data_slice_size, 1024);
@@ -50,12 +55,22 @@ class QuicStreamSendBufferTest : public QuicTest {
EXPECT_TRUE(slice1.empty());
send_buffer_.SaveMemSlice(std::move(slice2));
EXPECT_TRUE(slice2.empty());
+
+ EXPECT_EQ(4u, send_buffer_.size());
+ // At this point, the whole buffer looks like:
+ // | a * 1536 |b * 256| c * 1280 | d * 768 |
+ // | slice1 | slice2 | slice3 | slice4 |
+ }
+
+ void WriteAllData() {
// Write all data.
- send_buffer_.OnStreamDataConsumed(3840);
+ char buf[4000];
+ QuicDataWriter writer(4000, buf, HOST_BYTE_ORDER);
+ send_buffer_.WriteStreamData(0, 3840u, &writer);
+
+ send_buffer_.OnStreamDataConsumed(3840u);
EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
-
- EXPECT_EQ(4u, send_buffer_.size());
}
SimpleBufferAllocator allocator_;
@@ -68,7 +83,7 @@ TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
string copy1(1024, 'a');
string copy2 = string(512, 'a') + string(256, 'b') + string(256, 'c');
string copy3(1024, 'c');
- string copy4(768, 'c');
+ string copy4(768, 'd');
ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
EXPECT_EQ(copy1, QuicStringPiece(buf, 1024));
@@ -76,7 +91,7 @@ TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
EXPECT_EQ(copy2, QuicStringPiece(buf + 1024, 1024));
ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
EXPECT_EQ(copy3, QuicStringPiece(buf + 2048, 1024));
- ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 768, &writer));
+ ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
EXPECT_EQ(copy4, QuicStringPiece(buf + 3072, 768));
// Test data piece across boundries.
@@ -85,15 +100,28 @@ TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
EXPECT_EQ(copy5, QuicStringPiece(buf, 1024));
ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
- EXPECT_EQ(copy3, QuicStringPiece(buf + 1024, 1024));
+ string copy6 = string(572, 'c') + string(452, 'd');
+ EXPECT_EQ(copy6, QuicStringPiece(buf + 1024, 1024));
// Invalid data copy.
QuicDataWriter writer3(4000, buf, HOST_BYTE_ORDER);
EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
- EXPECT_FALSE(send_buffer_.WriteStreamData(0, 4000, &writer3));
+ if (GetQuicReloadableFlag(quic_use_write_index) &&
+ GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
+ EXPECT_DFATAL(send_buffer_.WriteStreamData(0, 4000, &writer3),
+ "Writer fails to write.");
+ } else {
+ EXPECT_FALSE(send_buffer_.WriteStreamData(0, 4000, &writer3));
+ }
+
+ send_buffer_.OnStreamDataConsumed(3840);
+ EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
+ EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
}
TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
+ WriteAllData();
+
QuicByteCount newly_acked_length;
EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
EXPECT_EQ(1024u, newly_acked_length);
@@ -114,6 +142,8 @@ TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
}
TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
+ WriteAllData();
+
QuicByteCount newly_acked_length;
EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
EXPECT_EQ(576u, newly_acked_length);
@@ -138,9 +168,10 @@ TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
}
TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
- if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ if (!GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
return;
}
+ WriteAllData();
QuicByteCount newly_acked_length;
EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
EXPECT_EQ(1500u, newly_acked_length);
@@ -162,6 +193,89 @@ TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
}
+TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
+ if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ return;
+ }
+ WriteAllData();
+ EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
+ EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+ // Lost data [0, 1200).
+ send_buffer_.OnStreamDataLost(0, 1200);
+ // Lost data [1500, 2000).
+ send_buffer_.OnStreamDataLost(1500, 500);
+ EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+
+ EXPECT_EQ(StreamPendingRetransmission(0, 1200),
+ send_buffer_.NextPendingRetransmission());
+ // Retransmit data [0, 500).
+ send_buffer_.OnStreamDataRetransmitted(0, 500);
+ EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
+ EXPECT_EQ(StreamPendingRetransmission(500, 700),
+ send_buffer_.NextPendingRetransmission());
+ // Ack data [500, 1200).
+ QuicByteCount newly_acked_length = 0;
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
+ EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
+ EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+ EXPECT_EQ(StreamPendingRetransmission(1500, 500),
+ send_buffer_.NextPendingRetransmission());
+ // Retransmit data [1500, 2000).
+ send_buffer_.OnStreamDataRetransmitted(1500, 500);
+ EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
+
+ // Lost [200, 800).
+ send_buffer_.OnStreamDataLost(200, 600);
+ EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
+ // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
+ EXPECT_EQ(StreamPendingRetransmission(200, 300),
+ send_buffer_.NextPendingRetransmission());
+
+ // Verify 0 length data is not outstanding.
+ EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
+ // Verify partially acked data is outstanding.
+ EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
+}
+
+TEST_F(QuicStreamSendBufferTest, CurrentWriteIndex) {
+ if (!GetQuicReloadableFlag(quic_use_write_index) ||
+ !GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {
+ return;
+ }
+ char buf[4000];
+ QuicDataWriter writer(4000, buf, HOST_BYTE_ORDER);
+ // With data buffered, index points to the 1st slice of data.
+ EXPECT_EQ(0u,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_)->offset);
+ ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
+ // Wrote all data on 1st slice, index points to next slice.
+ EXPECT_EQ(1024u,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_)->offset);
+ ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
+ // Last write didn't finish a whole slice. Index remains.
+ EXPECT_EQ(1024u,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_)->offset);
+ send_buffer_.OnStreamDataConsumed(1024);
+
+ // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
+ QuicByteCount newly_acked_length;
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
+ EXPECT_EQ(1024u,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_)->offset);
+
+ ASSERT_TRUE(
+ send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));
+ // After writing all buffered data, index become invalid again.
+ EXPECT_EQ(nullptr,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_));
+ QuicMemSlice slice(&allocator_, 60);
+ memset(const_cast<char*>(slice.data()), 'e', 60);
+ send_buffer_.SaveMemSlice(std::move(slice));
+ // With new data, index points to the new data.
+ EXPECT_EQ(3840u,
+ QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer_)->offset);
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream_sequencer.cc b/chromium/net/quic/core/quic_stream_sequencer.cc
index d272910c300..b235e53588d 100644
--- a/chromium/net/quic/core/quic_stream_sequencer.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer.cc
@@ -47,6 +47,7 @@ void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
return;
}
}
+ const size_t previous_readable_bytes = buffered_frames_.ReadableBytes();
size_t bytes_written;
string error_details;
QuicErrorCode result = buffered_frames_.OnStreamData(
@@ -73,7 +74,12 @@ void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
return;
}
- if (byte_offset == buffered_frames_.BytesConsumed()) {
+ bool can_continue_read = byte_offset == buffered_frames_.BytesConsumed();
+ if (buffered_frames_.allow_overlapping_data()) {
+ can_continue_read =
+ previous_readable_bytes == 0 && buffered_frames_.ReadableBytes() > 0;
+ }
+ if (can_continue_read) {
if (ignore_read_data_) {
FlushBufferedFrames();
} else {
diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
index 01d75d556ac..04984afbf8c 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
@@ -18,7 +18,7 @@ namespace net {
namespace {
size_t CalculateBlockCount(size_t max_capacity_bytes) {
- if (FLAGS_quic_reloadable_flag_quic_fix_sequencer_buffer_block_count2) {
+ if (GetQuicReloadableFlag(quic_fix_sequencer_buffer_block_count2)) {
QUIC_FLAG_COUNT(
quic_reloadable_flag_quic_fix_sequencer_buffer_block_count2);
return (max_capacity_bytes + QuicStreamSequencerBuffer::kBlockSizeBytes -
@@ -32,6 +32,8 @@ size_t CalculateBlockCount(size_t max_capacity_bytes) {
// Upper limit of how many gaps allowed in buffer, which ensures a reasonable
// number of iterations needed to find the right gap to fill when a frame
// arrives.
+// TODO(fayang): Rename kMaxNumGapsAllowed to kMaxNumDataIntervalsAllowed when
+// deprecating quic_reloadable_flag_quic_allow_receiving_overlapping_data.
const size_t kMaxNumGapsAllowed = 2 * kMaxPacketGap;
} // namespace
@@ -52,7 +54,12 @@ QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
blocks_count_(CalculateBlockCount(max_capacity_bytes)),
total_bytes_read_(0),
blocks_(nullptr),
- destruction_indicator_(123456) {
+ destruction_indicator_(123456),
+ allow_overlapping_data_(
+ GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) {
+ if (allow_overlapping_data_) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_allow_receiving_overlapping_data);
+ }
CHECK_GT(blocks_count_, 1u)
<< "blocks_count_ = " << blocks_count_
<< ", max_buffer_capacity_bytes_ = " << max_buffer_capacity_bytes_;
@@ -73,11 +80,18 @@ void QuicStreamSequencerBuffer::Clear() {
}
}
num_bytes_buffered_ = 0;
- // Reset gaps_ so that buffer is in a state as if all data before
- // total_bytes_read_ has been consumed, and those after total_bytes_read_
- // has never arrived.
- gaps_ = std::list<Gap>(
- 1, Gap(total_bytes_read_, std::numeric_limits<QuicStreamOffset>::max()));
+ if (allow_overlapping_data_) {
+ bytes_received_.Clear();
+ bytes_received_.Add(0, total_bytes_read_);
+ } else {
+ // Reset gaps_ so that buffer is in a state as if all data before
+ // total_bytes_read_ has been consumed, and those after total_bytes_read_
+ // has never arrived.
+ gaps_ = std::list<Gap>(
+ 1,
+ Gap(total_bytes_read_, std::numeric_limits<QuicStreamOffset>::max()));
+ }
+
frame_arrival_time_map_.clear();
}
@@ -106,6 +120,45 @@ QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
*error_details = "Received empty stream frame without FIN.";
return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
}
+ if (allow_overlapping_data_) {
+ // Write beyond the current range this buffer is covering.
+ if (starting_offset + size >
+ total_bytes_read_ + max_buffer_capacity_bytes_ ||
+ starting_offset + size < starting_offset) {
+ *error_details = "Received data beyond available range.";
+ return QUIC_INTERNAL_ERROR;
+ }
+
+ QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
+ starting_offset + size);
+ newly_received.Difference(bytes_received_);
+ if (newly_received.Empty()) {
+ return QUIC_NO_ERROR;
+ }
+ bytes_received_.Add(starting_offset, starting_offset + size);
+ if (bytes_received_.Size() >= kMaxNumGapsAllowed) {
+ // This frame is going to create more intervals than allowed. Stop
+ // processing.
+ *error_details = "Too many data intervals received for this stream.";
+ return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+ }
+ for (const auto& interval : newly_received) {
+ const QuicStreamOffset copy_offset = interval.min();
+ const QuicByteCount copy_length = interval.max() - interval.min();
+ size_t bytes_copy = 0;
+ if (!CopyStreamData(
+ copy_offset,
+ data.substr(copy_offset - starting_offset, copy_length),
+ &bytes_copy, error_details)) {
+ return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+ }
+ *bytes_buffered += bytes_copy;
+ frame_arrival_time_map_.insert(
+ std::make_pair(copy_offset, FrameInfo(copy_length, timestamp)));
+ }
+ num_bytes_buffered_ += *bytes_buffered;
+ return QUIC_NO_ERROR;
+ }
// Find the first gap not ending before |offset|. This gap maybe the gap to
// fill if the arriving frame doesn't overlaps with previous ones.
@@ -165,7 +218,7 @@ QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
// This frame is going to create one more gap which exceeds max number of
// gaps allowed. Stop processing.
*error_details = "Too many gaps created for this stream.";
- return QUIC_TOO_MANY_FRAME_GAPS;
+ return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
}
if (!CopyStreamData(offset, data, bytes_buffered, error_details)) {
@@ -366,7 +419,7 @@ int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
}
size_t start_block_idx = NextBlockToRead();
- QuicStreamOffset readable_offset_end = gaps_.front().begin_offset - 1;
+ QuicStreamOffset readable_offset_end = FirstMissingByte() - 1;
DCHECK_GE(readable_offset_end + 1, total_bytes_read_);
size_t end_block_offset = GetInBlockOffset(readable_offset_end);
size_t end_block_idx = GetBlockIndex(readable_offset_end);
@@ -483,7 +536,7 @@ bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_used) {
size_t QuicStreamSequencerBuffer::FlushBufferedFrames() {
size_t prev_total_bytes_read = total_bytes_read_;
- total_bytes_read_ = gaps_.back().begin_offset;
+ total_bytes_read_ = NextExpectedByte();
Clear();
return total_bytes_read_ - prev_total_bytes_read;
}
@@ -494,7 +547,7 @@ void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
}
size_t QuicStreamSequencerBuffer::ReadableBytes() const {
- return gaps_.front().begin_offset - total_bytes_read_;
+ return FirstMissingByte() - total_bytes_read_;
}
bool QuicStreamSequencerBuffer::HasBytesToRead() const {
@@ -537,27 +590,46 @@ bool QuicStreamSequencerBuffer::RetireBlockIfEmpty(size_t block_index) {
// Check where the logical end of this buffer is.
// Not empty if the end of circular buffer has been wrapped to this block.
- if (GetBlockIndex(gaps_.back().begin_offset - 1) == block_index) {
+ if (GetBlockIndex(NextExpectedByte() - 1) == block_index) {
return true;
}
// Read index remains in this block, which means a gap has been reached.
if (NextBlockToRead() == block_index) {
- Gap first_gap = gaps_.front();
- DCHECK(first_gap.begin_offset == total_bytes_read_);
- // Check where the next piece data is.
- // Not empty if next piece of data is still in this chunk.
- bool gap_ends_in_this_block =
- (GetBlockIndex(first_gap.end_offset) == block_index);
- if (gap_ends_in_this_block) {
- return true;
+ if (allow_overlapping_data_) {
+ if (bytes_received_.Size() > 1) {
+ auto it = bytes_received_.begin();
+ ++it;
+ if (GetBlockIndex(it->min()) == block_index) {
+ // Do not retire the block if next data interval is in this block.
+ return true;
+ }
+ } else {
+ QUIC_BUG << "Read stopped at where it shouldn't.";
+ return false;
+ }
+ } else {
+ Gap first_gap = gaps_.front();
+ DCHECK(first_gap.begin_offset == total_bytes_read_);
+ // Check where the next piece data is.
+ // Not empty if next piece of data is still in this chunk.
+ bool gap_ends_in_this_block =
+ (GetBlockIndex(first_gap.end_offset) == block_index);
+ if (gap_ends_in_this_block) {
+ return true;
+ }
}
}
return RetireBlock(block_index);
}
bool QuicStreamSequencerBuffer::Empty() const {
- return gaps_.size() == 1 && gaps_.front().begin_offset == total_bytes_read_;
+ if (!allow_overlapping_data_) {
+ return gaps_.size() == 1 && gaps_.front().begin_offset == total_bytes_read_;
+ }
+ return bytes_received_.Empty() ||
+ (bytes_received_.Size() == 1 && total_bytes_read_ > 0 &&
+ bytes_received_.begin()->max() == total_bytes_read_);
}
size_t QuicStreamSequencerBuffer::GetBlockCapacity(size_t block_index) const {
@@ -596,6 +668,9 @@ void QuicStreamSequencerBuffer::UpdateFrameArrivalMap(QuicStreamOffset offset) {
}
string QuicStreamSequencerBuffer::GapsDebugString() {
+ if (allow_overlapping_data_) {
+ return bytes_received_.ToString();
+ }
string current_gaps_string;
for (const Gap& gap : gaps_) {
QuicStreamOffset current_gap_begin = gap.begin_offset;
@@ -619,4 +694,25 @@ string QuicStreamSequencerBuffer::ReceivedFramesDebugString() {
return current_frames_string;
}
+QuicStreamOffset QuicStreamSequencerBuffer::FirstMissingByte() const {
+ if (allow_overlapping_data_) {
+ if (bytes_received_.Empty() || bytes_received_.begin()->min() > 0) {
+ // Offset 0 is not received yet.
+ return 0;
+ }
+ return bytes_received_.begin()->max();
+ }
+ return gaps_.front().begin_offset;
+}
+
+QuicStreamOffset QuicStreamSequencerBuffer::NextExpectedByte() const {
+ if (allow_overlapping_data_) {
+ if (bytes_received_.Empty()) {
+ return 0;
+ }
+ return bytes_received_.rbegin()->max();
+ }
+ return gaps_.back().begin_offset;
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer.h b/chromium/net/quic/core/quic_stream_sequencer_buffer.h
index 439965d5311..9a65dd6b247 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_buffer.h
+++ b/chromium/net/quic/core/quic_stream_sequencer_buffer.h
@@ -7,8 +7,8 @@
// QuicStreamSequencerBuffer is a circular stream buffer with random write and
// in-sequence read. It consists of a vector of pointers pointing
-// to memory blocks created as needed and a list of Gaps to indicate
-// the missing data between the data already written into the buffer.
+// to memory blocks created as needed and an interval set recording received
+// data.
// - Data are written in with offset indicating where it should be in the
// stream, and the buffer grown as needed (up to the maximum buffer capacity),
// without expensive copying (extra blocks are allocated).
@@ -167,6 +167,11 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
// Count how many bytes are in buffer at this moment.
size_t BytesBuffered() const;
+ // Returns number of bytes available to be read out.
+ size_t ReadableBytes() const;
+
+ bool allow_overlapping_data() const { return allow_overlapping_data_; }
+
private:
friend class test::QuicStreamSequencerBufferPeer;
@@ -184,7 +189,7 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
bool RetireBlock(size_t index);
// Should only be called after the indexed block is read till the end of the
- // block or a gap has been reached.
+ // block or missing data has been reached.
// If the block at |block_index| contains no buffered data, the block
// should be retired.
// Return false on success, or false otherwise.
@@ -192,6 +197,8 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
// Called within OnStreamData() to update the gap OnStreamData() writes into
// (remove, split or change begin/end offset).
+ // TODO(fayang): Remove this when deprecating
+ // quic_reloadable_flag_quic_allow_receiving_overlapping_data.
void UpdateGapList(std::list<Gap>::iterator gap_with_new_data_written,
QuicStreamOffset start_offset,
size_t bytes_written);
@@ -214,8 +221,11 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
// Get the index of the logical 1st block to start next read.
size_t NextBlockToRead() const;
- // Returns number of bytes available to be read out.
- size_t ReadableBytes() const;
+ // Returns offset of first missing byte.
+ QuicStreamOffset FirstMissingByte() const;
+
+ // Returns offset of highest received byte + 1.
+ QuicStreamOffset NextExpectedByte() const;
// Called after Readv() and MarkConsumed() to keep frame_arrival_time_map_
// up to date.
@@ -239,6 +249,8 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
QuicStreamOffset total_bytes_read_;
// Contains Gaps which represents currently missing data.
+ // TODO(fayang): Remove list of gaps when deprecating
+ // quic_reloadable_flag_quic_allow_receiving_overlapping_data.
std::list<Gap> gaps_;
// An ordered, variable-length list of blocks, with the length limited
@@ -250,6 +262,8 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
size_t num_bytes_buffered_;
// Stores all the buffered frames' start offset, length and arrival time.
+ // TODO(fayang): Remove this when deprecating
+ // quic_reloadable_flag_quic_allow_receiving_overlapping_data.
std::map<QuicStreamOffset, FrameInfo> frame_arrival_time_map_;
// For debugging use after free, assigned to 123456 in constructor and 654321
@@ -257,6 +271,13 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencerBuffer {
// or memory corruption.
int32_t destruction_indicator_;
+ // Currently received data.
+ QuicIntervalSet<QuicStreamOffset> bytes_received_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_allow_receiving_overlapping_data.
+ const bool allow_overlapping_data_;
+
DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBuffer);
};
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc b/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc
index 168debd538d..9ca1e8264c7 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer_buffer_test.cc
@@ -84,7 +84,7 @@ class QuicStreamSequencerBufferTest : public testing::Test {
};
TEST_F(QuicStreamSequencerBufferTest, InitializeWithMaxRecvWindowSize) {
- if (!FLAGS_quic_reloadable_flag_quic_fix_sequencer_buffer_block_count2) {
+ if (!GetQuicReloadableFlag(quic_fix_sequencer_buffer_block_count2)) {
return;
}
ResetMaxCapacityBytes(16 * 1024 * 1024); // 16MB
@@ -132,9 +132,16 @@ TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
ASSERT_EQ('a', block_ptr->buffer[helper_->GetInBlockOffset(800) + i]);
}
EXPECT_EQ(2, helper_->GapSize());
- std::list<Gap> gaps = helper_->GetGaps();
- EXPECT_EQ(800u, gaps.front().end_offset);
- EXPECT_EQ(1824u, gaps.back().begin_offset);
+ EXPECT_EQ(0u, helper_->ReadableBytes());
+ if (helper_->allow_overlapping_data()) {
+ EXPECT_EQ(1u, helper_->bytes_received().Size());
+ EXPECT_EQ(800u, helper_->bytes_received().begin()->min());
+ EXPECT_EQ(1824u, helper_->bytes_received().begin()->max());
+ } else {
+ std::list<Gap> gaps = helper_->GetGaps();
+ EXPECT_EQ(800u, gaps.front().end_offset);
+ EXPECT_EQ(1824u, gaps.back().begin_offset);
+ }
auto* frame_map = helper_->frame_arrival_time_map();
EXPECT_EQ(1u, frame_map->size());
EXPECT_EQ(800u, frame_map->begin()->first);
@@ -167,14 +174,25 @@ TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithOverlap) {
EXPECT_EQ(QUIC_NO_ERROR,
buffer_->OnStreamData(800, source, t1, &written, &error_details_));
// Try to write to [0, 1024) and [1024, 2048).
- // But no byte will be written since overlap.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
QuicTime t2 = clock_.ApproximateNow();
+ auto* frame_map = helper_->frame_arrival_time_map();
+ if (helper_->allow_overlapping_data()) {
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(0, source, t2, &written, &error_details_));
+ EXPECT_EQ(QUIC_NO_ERROR, buffer_->OnStreamData(1024, source, t2, &written,
+ &error_details_));
+ EXPECT_EQ(3u, frame_map->size());
+ EXPECT_EQ(t1, (*frame_map)[800].timestamp);
+ EXPECT_EQ(t2, (*frame_map)[0].timestamp);
+ EXPECT_EQ(t2, (*frame_map)[1824].timestamp);
+ return;
+ }
+ // But no byte will be written since overlap.
EXPECT_EQ(QUIC_OVERLAPPING_STREAM_DATA,
buffer_->OnStreamData(0, source, t2, &written, &error_details_));
EXPECT_EQ(QUIC_OVERLAPPING_STREAM_DATA,
buffer_->OnStreamData(1024, source, t2, &written, &error_details_));
- auto* frame_map = helper_->frame_arrival_time_map();
EXPECT_EQ(1u, frame_map->size());
EXPECT_EQ(t1, (*frame_map)[800].timestamp);
}
@@ -187,6 +205,31 @@ TEST_F(QuicStreamSequencerBufferTest,
buffer_->OnStreamData(800, source, clock_.ApproximateNow(), &written,
&error_details_);
source = string(800, 'b');
+ string one_byte = "c";
+ auto* frame_map = helper_->frame_arrival_time_map();
+ if (helper_->allow_overlapping_data()) {
+ // Write [1, 801).
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(1, source, clock_.ApproximateNow(),
+ &written, &error_details_));
+ // Write [0, 800).
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(0, source, clock_.ApproximateNow(),
+ &written, &error_details_));
+ // Write [1823, 1824).
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(1823, one_byte, clock_.ApproximateNow(),
+ &written, &error_details_));
+ EXPECT_EQ(0u, written);
+ // write one byte to [1824, 1825)
+ EXPECT_EQ(QUIC_NO_ERROR,
+ buffer_->OnStreamData(1824, one_byte, clock_.ApproximateNow(),
+ &written, &error_details_));
+ EXPECT_EQ(4u, frame_map->size());
+ EXPECT_TRUE(helper_->CheckBufferInvariants());
+ return;
+ }
+
// Try to write to [1, 801), but should fail due to overlapping
EXPECT_EQ(QUIC_OVERLAPPING_STREAM_DATA,
buffer_->OnStreamData(1, source, clock_.ApproximateNow(), &written,
@@ -196,7 +239,6 @@ TEST_F(QuicStreamSequencerBufferTest,
buffer_->OnStreamData(0, source, clock_.ApproximateNow(), &written,
&error_details_));
// Try to write one byte to [1823, 1824), but should count as duplicate
- string one_byte = "c";
EXPECT_EQ(QUIC_NO_ERROR,
buffer_->OnStreamData(1823, one_byte, clock_.ApproximateNow(),
&written, &error_details_));
@@ -205,7 +247,6 @@ TEST_F(QuicStreamSequencerBufferTest,
EXPECT_EQ(QUIC_NO_ERROR,
buffer_->OnStreamData(1824, one_byte, clock_.ApproximateNow(),
&written, &error_details_));
- auto* frame_map = helper_->frame_arrival_time_map();
EXPECT_EQ(3u, frame_map->size());
EXPECT_TRUE(helper_->CheckBufferInvariants());
}
@@ -232,8 +273,13 @@ TEST_F(QuicStreamSequencerBufferTest, OnStreamDataInLongStreamWithOverlap) {
// Assume a stream has already buffered almost 4GB.
uint64_t total_bytes_read = pow(2, 32) - 1;
helper_->set_total_bytes_read(total_bytes_read);
- helper_->set_gaps(std::list<Gap>(
- 1, Gap(total_bytes_read, std::numeric_limits<QuicStreamOffset>::max())));
+ if (helper_->allow_overlapping_data()) {
+ helper_->AddBytesReceived(0, total_bytes_read);
+ } else {
+ helper_->set_gaps(std::list<Gap>(
+ 1,
+ Gap(total_bytes_read, std::numeric_limits<QuicStreamOffset>::max())));
+ }
// Three new out of order frames arrive.
const size_t kBytesToWrite = 100;
@@ -817,8 +863,13 @@ TEST_F(QuicStreamSequencerBufferTest, TooManyGaps) {
QuicStreamOffset last_straw = 2 * kMaxNumGapsAllowed - 1;
if (begin == last_straw) {
- EXPECT_EQ(QUIC_TOO_MANY_FRAME_GAPS, rs);
- EXPECT_EQ("Too many gaps created for this stream.", error_details_);
+ EXPECT_EQ(QUIC_TOO_MANY_STREAM_DATA_INTERVALS, rs);
+ if (GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) {
+ EXPECT_EQ("Too many data intervals received for this stream.",
+ error_details_);
+ } else {
+ EXPECT_EQ("Too many gaps created for this stream.", error_details_);
+ }
break;
}
}
diff --git a/chromium/net/quic/core/quic_stream_sequencer_test.cc b/chromium/net/quic/core/quic_stream_sequencer_test.cc
index 8ca75ff1656..c14e77d65ad 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_test.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer_test.cc
@@ -12,6 +12,7 @@
#include "net/quic/core/quic_stream.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_string_piece.h"
#include "net/quic/platform/api/quic_test.h"
@@ -60,7 +61,7 @@ class QuicStreamSequencerTest : public QuicTest {
public:
void ConsumeData(size_t num_bytes) {
char buffer[1024];
- ASSERT_GT(arraysize(buffer), num_bytes);
+ ASSERT_GT(QUIC_ARRAYSIZE(buffer), num_bytes);
struct iovec iov;
iov.iov_base = buffer;
iov.iov_len = num_bytes;
@@ -90,7 +91,7 @@ class QuicStreamSequencerTest : public QuicTest {
bool VerifyReadableRegions(const std::vector<string>& expected) {
iovec iovecs[5];
size_t num_iovecs =
- sequencer_->GetReadableRegions(iovecs, arraysize(iovecs));
+ sequencer_->GetReadableRegions(iovecs, QUIC_ARRAYSIZE(iovecs));
return VerifyReadableRegion(expected) &&
VerifyIovecs(iovecs, num_iovecs, expected);
}
@@ -384,7 +385,7 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest {
typedef std::vector<Frame> FrameList;
void CreateFrames() {
- int payload_size = arraysize(kPayload) - 1;
+ int payload_size = QUIC_ARRAYSIZE(kPayload) - 1;
int remaining_payload = payload_size;
while (remaining_payload != 0) {
int size = std::min(OneToN(6), remaining_payload);
@@ -406,10 +407,10 @@ class QuicSequencerRandomTest : public QuicStreamSequencerTest {
void ReadAvailableData() {
// Read all available data
- char output[arraysize(kPayload) + 1];
+ char output[QUIC_ARRAYSIZE(kPayload) + 1];
iovec iov;
iov.iov_base = output;
- iov.iov_len = arraysize(output);
+ iov.iov_len = QUIC_ARRAYSIZE(output);
int bytes_read = sequencer_->Readv(&iov, 1);
EXPECT_NE(0, bytes_read);
output_.append(output, bytes_read);
@@ -439,7 +440,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
list_.erase(list_.begin() + index);
}
- ASSERT_EQ(arraysize(kPayload) - 1, output_.size());
+ ASSERT_EQ(QUIC_ARRAYSIZE(kPayload) - 1, output_.size());
EXPECT_EQ(kPayload, output_);
}
@@ -453,7 +454,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber());
- while (output_.size() != arraysize(kPayload) - 1) {
+ while (output_.size() != QUIC_ARRAYSIZE(kPayload) - 1) {
if (!list_.empty() && OneToN(2) == 1) { // Send data
int index = OneToN(list_.size()) - 1;
OnFrame(list_[index].first, list_[index].second.data());
@@ -470,7 +471,7 @@ TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) {
ASSERT_EQ(0, iovs_peeked);
ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov, &timestamp));
}
- int total_bytes_to_peek = arraysize(buffer);
+ int total_bytes_to_peek = QUIC_ARRAYSIZE(buffer);
for (int i = 0; i < iovs_peeked; ++i) {
int bytes_to_peek =
std::min<int>(peek_iov[i].iov_len, total_bytes_to_peek);
@@ -564,7 +565,7 @@ TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
sequencer_->MarkConsumed(6);
}
-TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
+TEST_F(QuicStreamSequencerTest, OverlappingFramesReceived) {
// The peer should never send us non-identical stream frames which contain
// overlapping byte ranges - if they do, we close the connection.
QuicStreamId id =
@@ -574,10 +575,59 @@ TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
sequencer_->OnStreamFrame(frame1);
QuicStreamFrame frame2(id, false, 2, QuicStringPiece("hello"));
- EXPECT_CALL(stream_,
- CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _))
- .Times(1);
+ if (GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) {
+ EXPECT_CALL(stream_,
+ CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _))
+ .Times(0);
+ } else {
+ EXPECT_CALL(stream_,
+ CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _))
+ .Times(1);
+ }
+ sequencer_->OnStreamFrame(frame2);
+}
+
+TEST_F(QuicStreamSequencerTest, DataAvailableOnOverlappingFrames) {
+ if (!GetQuicReloadableFlag(quic_allow_receiving_overlapping_data)) {
+ return;
+ }
+ QuicStreamId id =
+ QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, 0);
+ const string data(1000, '.');
+
+ // Received [0, 1000).
+ QuicStreamFrame frame1(id, false, 0, data);
+ EXPECT_CALL(stream_, OnDataAvailable());
+ sequencer_->OnStreamFrame(frame1);
+ // Consume [0, 500).
+ QuicStreamSequencerTest::ConsumeData(500);
+ EXPECT_EQ(500u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(500u, sequencer_->NumBytesBuffered());
+
+ // Received [500, 1500).
+ QuicStreamFrame frame2(id, false, 500, data);
+ // Do not call OnDataAvailable as there are readable bytes left in the buffer.
+ EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
sequencer_->OnStreamFrame(frame2);
+ // Consume [1000, 1500).
+ QuicStreamSequencerTest::ConsumeData(1000);
+ EXPECT_EQ(1500u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+ // Received [1498, 1503).
+ QuicStreamFrame frame3(id, false, 1498, QuicStringPiece("hello"));
+ EXPECT_CALL(stream_, OnDataAvailable());
+ sequencer_->OnStreamFrame(frame3);
+ QuicStreamSequencerTest::ConsumeData(3);
+ EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
+
+ // Received [1000, 1005).
+ QuicStreamFrame frame4(id, false, 1000, QuicStringPiece("hello"));
+ EXPECT_CALL(stream_, OnDataAvailable()).Times(0);
+ sequencer_->OnStreamFrame(frame4);
+ EXPECT_EQ(1503u, sequencer_->NumBytesConsumed());
+ EXPECT_EQ(0u, sequencer_->NumBytesBuffered());
}
TEST_F(QuicStreamSequencerTest, InOrderTimestamps) {
diff --git a/chromium/net/quic/core/quic_stream_test.cc b/chromium/net/quic/core/quic_stream_test.cc
index 9fc0291473d..ef3667af3b0 100644
--- a/chromium/net/quic/core/quic_stream_test.cc
+++ b/chromium/net/quic/core/quic_stream_test.cc
@@ -10,6 +10,7 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/quic_write_blocked_list.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
@@ -20,18 +21,20 @@
#include "net/quic/test_tools/quic_flow_controller_peer.h"
#include "net/quic/test_tools/quic_session_peer.h"
#include "net/quic/test_tools/quic_stream_peer.h"
+#include "net/quic/test_tools/quic_stream_sequencer_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/test/gtest_util.h"
#include "testing/gmock_mutant.h"
using std::string;
+using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::InSequence;
using testing::Invoke;
+using testing::InvokeWithoutArgs;
using testing::Return;
using testing::StrictMock;
-using testing::_;
namespace net {
namespace test {
@@ -70,7 +73,7 @@ class QuicStreamTest : public QuicTestWithParam<bool> {
QuicStreamTest()
: initial_flow_control_window_bytes_(kMaxPacketSize),
zero_(QuicTime::Delta::Zero()),
- supported_versions_(AllSupportedTransportVersions()) {
+ supported_versions_(AllSupportedVersions()) {
headers_[":host"] = "www.google.com";
headers_[":path"] = "/index.hml";
headers_[":scheme"] = "https";
@@ -153,7 +156,7 @@ class QuicStreamTest : public QuicTestWithParam<bool> {
QuicWriteBlockedList* write_blocked_list_;
uint32_t initial_flow_control_window_bytes_;
QuicTime::Delta zero_;
- QuicTransportVersionVector supported_versions_;
+ ParsedQuicVersionVector supported_versions_;
const QuicStreamId kTestStreamId = 5u;
};
@@ -168,7 +171,7 @@ TEST_F(QuicStreamTest, WriteAllData) {
connection_->SetMaxPacketLength(length);
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(kDataLen, true)));
+ .WillOnce(Invoke(&(MockQuicSession::ConsumeData)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
}
@@ -189,7 +192,9 @@ TEST_F(QuicStreamTest, BlockIfOnlySomeDataConsumed) {
// Write some data and no fin. If we consume some but not all of the data,
// we should be write blocked a not all the data was consumed.
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(1, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 1u, 0u, NO_FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 2), false, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
EXPECT_EQ(1u, stream_->BufferedDataBytes());
@@ -203,7 +208,9 @@ TEST_F(QuicStreamTest, BlockIfFinNotConsumedWithData) {
// (This should never actually happen as the fin should be sent out with the
// last data)
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(2, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 2u, 0u, NO_FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 2), true, nullptr);
ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
}
@@ -243,7 +250,9 @@ TEST_F(QuicStreamTest, WriteOrBufferData) {
connection_->SetMaxPacketLength(length);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), kDataLen - 1, 0u, NO_FIN)));
stream_->WriteOrBufferData(kData1, false, nullptr);
EXPECT_EQ(1u, stream_->BufferedDataBytes());
EXPECT_TRUE(HasWriteBlockedStreams());
@@ -254,15 +263,33 @@ TEST_F(QuicStreamTest, WriteOrBufferData) {
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(kDataLen - 1, false)));
+ .WillOnce(InvokeWithoutArgs(testing::CreateFunctor(
+ &(MockQuicSession::ConsumeData), stream_, stream_->id(), kDataLen - 1,
+ kDataLen - 1, NO_FIN)));
stream_->OnCanWrite();
// And finally the end of the bytes_consumed.
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(2, true)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 2u, 2 * kDataLen - 2, FIN)));
stream_->OnCanWrite();
}
+TEST_F(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+ string data("aaaaa");
+ QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+ stream_);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(&(MockQuicSession::ConsumeData)));
+ stream_->WriteOrBufferData(data, false, nullptr);
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ EXPECT_DFATAL(stream_->WriteOrBufferData("a", false, nullptr),
+ "Write too many data via stream");
+}
+
TEST_F(QuicStreamTest, ConnectionCloseAfterStreamClose) {
Initialize(kShouldProcessData);
@@ -287,7 +314,9 @@ TEST_F(QuicStreamTest, RstAlwaysSentIfNoFinSent) {
// Write some data, with no FIN.
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(1, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 1u, 0u, NO_FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 1), false, nullptr);
EXPECT_FALSE(fin_sent());
EXPECT_FALSE(rst_sent());
@@ -310,7 +339,9 @@ TEST_F(QuicStreamTest, RstNotSentIfFinSent) {
// Write some data, with FIN.
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(1, true)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 1u, 0u, FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 1), true, nullptr);
EXPECT_TRUE(fin_sent());
EXPECT_FALSE(rst_sent());
@@ -505,6 +536,49 @@ TEST_F(QuicStreamTest, FinalByteOffsetFromZeroLengthStreamFrame) {
QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()));
}
+TEST_F(QuicStreamTest, OnStreamResetOffsetOverflow) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
+ QUIC_STREAM_CANCELLED, kMaxStreamLength + 1);
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ stream_->OnStreamReset(rst_frame);
+}
+
+TEST_F(QuicStreamTest, OnStreamFrameUpperLimit) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+
+ // Modify receive window offset and sequencer buffer total_bytes_read_ to
+ // avoid flow control violation.
+ QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+ kMaxStreamLength + 5u);
+ QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
+ kMaxStreamLength + 5u);
+ QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
+ QuicStreamPeer::sequencer(stream_), kMaxStreamLength - 10u);
+
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+ .Times(0);
+ QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength - 1,
+ QuicStringPiece("."));
+ stream_->OnStreamFrame(stream_frame);
+ QuicStreamFrame stream_frame2(stream_->id(), true, kMaxStreamLength,
+ QuicStringPiece(""));
+ stream_->OnStreamFrame(stream_frame2);
+}
+
+TEST_F(QuicStreamTest, StreamTooLong) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+ .Times(1);
+ QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength,
+ QuicStringPiece("."));
+ EXPECT_DFATAL(stream_->OnStreamFrame(stream_frame),
+ "Receive stream frame reaches max stream length");
+}
+
TEST_F(QuicStreamTest, SetDrainingIncomingOutgoing) {
// Don't have incoming data consumed.
Initialize(kShouldNotProcessData);
@@ -522,7 +596,9 @@ TEST_F(QuicStreamTest, SetDrainingIncomingOutgoing) {
// Outgoing data with FIN.
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(2, true)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 2u, 0u, FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 2), true, nullptr);
EXPECT_TRUE(stream_->write_side_closed());
@@ -537,7 +613,9 @@ TEST_F(QuicStreamTest, SetDrainingOutgoingIncoming) {
// Outgoing data with FIN.
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
- .WillOnce(Return(QuicConsumedData(2, true)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 2u, 0u, FIN)));
stream_->WriteOrBufferData(QuicStringPiece(kData1, 2), true, nullptr);
EXPECT_TRUE(stream_->write_side_closed());
@@ -564,7 +642,7 @@ TEST_F(QuicStreamTest, EarlyResponseFinHandling) {
Initialize(kShouldProcessData);
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Receive data for the request.
QuicStreamFrame frame1(stream_->id(), false, 0, QuicStringPiece("Start"));
@@ -588,7 +666,7 @@ TEST_F(QuicStreamTest, StreamWaitsForAcks) {
new StrictMock<MockAckListener>);
stream_->set_ack_listener(mock_ack_listener);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Stream is not waiting for acks initially.
EXPECT_FALSE(stream_->IsWaitingForAcks());
EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
@@ -614,7 +692,7 @@ TEST_F(QuicStreamTest, StreamWaitsForAcks) {
// kData2 is retransmitted.
EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
- stream_->OnStreamFrameRetransmitted(9, 9);
+ stream_->OnStreamFrameRetransmitted(9, 9, false);
// kData2 is acked.
EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
@@ -633,7 +711,7 @@ TEST_F(QuicStreamTest, StreamWaitsForAcks) {
TEST_F(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Send data.
stream_->WriteOrBufferData(kData1, false, nullptr);
stream_->WriteOrBufferData(kData1, false, nullptr);
@@ -657,7 +735,7 @@ TEST_F(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
TEST_F(QuicStreamTest, CancelStream) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
EXPECT_FALSE(stream_->IsWaitingForAcks());
EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
@@ -672,12 +750,7 @@ TEST_F(QuicStreamTest, CancelStream) {
EXPECT_CALL(*session_,
SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 9));
stream_->Reset(QUIC_STREAM_CANCELLED);
- stream_->OnStreamFrameDiscarded(0, 9, false);
- if (!FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded) {
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- } else {
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- }
+ EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
// Stream stops waiting for acks as data is not going to be retransmitted.
EXPECT_FALSE(stream_->IsWaitingForAcks());
}
@@ -685,7 +758,7 @@ TEST_F(QuicStreamTest, CancelStream) {
TEST_F(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
EXPECT_FALSE(stream_->IsWaitingForAcks());
EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
@@ -699,12 +772,7 @@ TEST_F(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
EXPECT_CALL(*session_,
SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9));
stream_->OnStreamReset(rst_frame);
- stream_->OnStreamFrameDiscarded(0, 9, false);
- if (!FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded) {
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- } else {
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- }
+ EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
// Stream stops waiting for acks as it does not finish sending and rst is
// sent.
EXPECT_FALSE(stream_->IsWaitingForAcks());
@@ -713,7 +781,7 @@ TEST_F(QuicStreamTest, RstFrameReceivedStreamNotFinishSending) {
TEST_F(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
EXPECT_FALSE(stream_->IsWaitingForAcks());
EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
@@ -733,7 +801,7 @@ TEST_F(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
TEST_F(QuicStreamTest, ConnectionClosed) {
Initialize(kShouldProcessData);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
EXPECT_FALSE(stream_->IsWaitingForAcks());
EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
@@ -744,12 +812,7 @@ TEST_F(QuicStreamTest, ConnectionClosed) {
SendRstStream(stream_->id(), QUIC_RST_ACKNOWLEDGEMENT, 9));
stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR,
ConnectionCloseSource::FROM_SELF);
- stream_->OnStreamFrameDiscarded(0, 9, false);
- if (!FLAGS_quic_reloadable_flag_quic_remove_on_stream_frame_discarded) {
- EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
- } else {
- EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
- }
+ EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
// Stream stops waiting for acks as connection is going to close.
EXPECT_FALSE(stream_->IsWaitingForAcks());
}
@@ -766,7 +829,9 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
// Testing WriteOrBufferData.
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(100, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 100u, 0u, NO_FIN)));
stream_->WriteOrBufferData(data, false, nullptr);
stream_->WriteOrBufferData(data, false, nullptr);
stream_->WriteOrBufferData(data, false, nullptr);
@@ -774,7 +839,9 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(100, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 100, 100u, NO_FIN)));
// Buffered data size > threshold, do not ask upper layer for more data.
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
stream_->OnCanWrite();
@@ -782,11 +849,12 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
EXPECT_FALSE(stream_->CanWriteNewData());
// Send buffered data to make buffered data size < threshold.
+ size_t data_to_write = 3 * data.length() - 200 -
+ GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(
- 3 * data.length() - 200 -
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1,
- false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), data_to_write, 200u, NO_FIN)));
// Buffered data size < threshold, ask upper layer for more data.
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
stream_->OnCanWrite();
@@ -796,7 +864,7 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
// Flush all buffered data.
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Invoke(MockQuicSession::ConsumeAllData));
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
stream_->OnCanWrite();
EXPECT_EQ(0u, stream_->BufferedDataBytes());
@@ -822,9 +890,13 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
EXPECT_FALSE(consumed.fin_consumed);
EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
+ data_to_write =
+ data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(
- data.length() - FLAGS_quic_buffered_data_threshold + 1, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), data_to_write, 0u, NO_FIN)));
+
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
stream_->OnCanWrite();
EXPECT_EQ(GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
@@ -841,6 +913,23 @@ TEST_F(QuicStreamTest, WriteBufferedData) {
EXPECT_FALSE(stream_->CanWriteNewData());
}
+TEST_F(QuicStreamTest, WritevDataReachStreamLimit) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+ string data("aaaaa");
+ QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
+ stream_);
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(&(MockQuicSession::ConsumeData)));
+ struct iovec iov = {const_cast<char*>(data.data()), 5u};
+ QuicConsumedData consumed = stream_->WritevData(&iov, 1u, false);
+ EXPECT_EQ(data.length(), consumed.bytes_consumed);
+ struct iovec iov2 = {const_cast<char*>(data.data()), 1u};
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ EXPECT_DFATAL(stream_->WritevData(&iov2, 1u, false),
+ "Write too many data via stream");
+}
+
TEST_F(QuicStreamTest, WriteMemSlices) {
// Set buffered data low water mark to be 100.
SetQuicFlag(&FLAGS_quic_buffered_data_threshold, 100);
@@ -853,20 +942,22 @@ TEST_F(QuicStreamTest, WriteMemSlices) {
}
char data[1024];
std::vector<std::pair<char*, int>> buffers;
- buffers.push_back(std::make_pair(data, arraysize(data)));
- buffers.push_back(std::make_pair(data, arraysize(data)));
+ buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
+ buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
QuicTestMemSliceVector vector1(buffers);
QuicTestMemSliceVector vector2(buffers);
QuicMemSliceSpan span1 = vector1.span();
QuicMemSliceSpan span2 = vector2.span();
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(100, false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 100u, 0u, NO_FIN)));
// There is no buffered data before, all data should be consumed.
QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
EXPECT_EQ(2048u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(2 * arraysize(data) - 100, stream_->BufferedDataBytes());
+ EXPECT_EQ(2 * QUIC_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes());
EXPECT_FALSE(stream_->fin_buffered());
EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(0);
@@ -874,14 +965,15 @@ TEST_F(QuicStreamTest, WriteMemSlices) {
consumed = stream_->WriteMemSlices(span2, true);
EXPECT_EQ(0u, consumed.bytes_consumed);
EXPECT_FALSE(consumed.fin_consumed);
- EXPECT_EQ(2 * arraysize(data) - 100, stream_->BufferedDataBytes());
+ EXPECT_EQ(2 * QUIC_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes());
EXPECT_FALSE(stream_->fin_buffered());
+ size_t data_to_write = 2 * QUIC_ARRAYSIZE(data) - 100 -
+ GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Return(QuicConsumedData(
- 2 * arraysize(data) - 100 -
- GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1,
- false)));
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), data_to_write, 100u, NO_FIN)));
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
stream_->OnCanWrite();
EXPECT_EQ(GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
@@ -891,28 +983,57 @@ TEST_F(QuicStreamTest, WriteMemSlices) {
consumed = stream_->WriteMemSlices(span2, true);
EXPECT_EQ(2048u, consumed.bytes_consumed);
EXPECT_TRUE(consumed.fin_consumed);
- EXPECT_EQ(
- 2 * arraysize(data) + GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
- stream_->BufferedDataBytes());
+ EXPECT_EQ(2 * QUIC_ARRAYSIZE(data) +
+ GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1,
+ stream_->BufferedDataBytes());
EXPECT_TRUE(stream_->fin_buffered());
// Flush all buffered data.
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillOnce(Invoke(MockQuicSession::ConsumeAllData));
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
stream_->OnCanWrite();
EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
EXPECT_FALSE(stream_->HasBufferedData());
EXPECT_TRUE(stream_->write_side_closed());
}
+TEST_F(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
+ SetQuicReloadableFlag(quic_stream_too_long, true);
+ Initialize(kShouldProcessData);
+ if (!session_->can_use_slices()) {
+ return;
+ }
+ QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
+ char data[5];
+ std::vector<std::pair<char*, int>> buffers;
+ buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
+ QuicTestMemSliceVector vector1(buffers);
+ QuicMemSliceSpan span1 = vector1.span();
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 5u, 0u, NO_FIN)));
+ // There is no buffered data before, all data should be consumed.
+ QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
+ EXPECT_EQ(5u, consumed.bytes_consumed);
+
+ std::vector<std::pair<char*, int>> buffers2;
+ buffers2.push_back(std::make_pair(data, 1u));
+ QuicTestMemSliceVector vector2(buffers);
+ QuicMemSliceSpan span2 = vector2.span();
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ EXPECT_DFATAL(stream_->WriteMemSlices(span2, false),
+ "Write too many data via stream");
+}
+
TEST_F(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2 = true;
+ SetQuicReloadableFlag(quic_allow_multiple_acks_for_data2, true);
Initialize(kShouldProcessData);
QuicReferenceCountedPointer<MockAckListener> mock_ack_listener(
new StrictMock<MockAckListener>);
stream_->set_ack_listener(mock_ack_listener);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
// Send [0, 27) and fin.
stream_->WriteOrBufferData(kData1, false, nullptr);
stream_->WriteOrBufferData(kData1, false, nullptr);
@@ -956,6 +1077,94 @@ TEST_F(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
EXPECT_FALSE(stream_->IsWaitingForAcks());
}
+TEST_F(QuicStreamTest, OnStreamFrameLost) {
+ if (!FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {
+ return;
+ }
+ Initialize(kShouldProcessData);
+
+ // Send [0, 9).
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_->WriteOrBufferData(kData1, false, nullptr);
+ EXPECT_FALSE(stream_->HasBufferedData());
+
+ // Try to send [9, 27), but connection is blocked.
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(0, false)));
+ stream_->WriteOrBufferData(kData2, false, nullptr);
+ stream_->WriteOrBufferData(kData2, false, nullptr);
+ EXPECT_TRUE(stream_->HasBufferedData());
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
+
+ // Lost [0, 9). When stream gets a chance to write, only lost data is
+ // transmitted.
+ stream_->OnStreamFrameLost(0, 9, false);
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_->OnCanWrite();
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
+ EXPECT_TRUE(stream_->HasBufferedData());
+
+ // This OnCanWrite causes [9, 27) to be sent.
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_->OnCanWrite();
+ EXPECT_FALSE(stream_->HasBufferedData());
+
+ // Send a fin only frame.
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
+ stream_->WriteOrBufferData("", true, nullptr);
+
+ // Lost [9, 27) and fin.
+ stream_->OnStreamFrameLost(9, 18, false);
+ stream_->OnStreamFrameLost(27, 0, true);
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
+
+ // Ack [9, 18).
+ stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero());
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
+ // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
+ // be bundled with data.
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 9, 18u, FIN)));
+ stream_->OnCanWrite();
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
+ // Lost [9, 18) again, but it is not considered as lost because kData2
+ // has been acked.
+ stream_->OnStreamFrameLost(9, 9, false);
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
+}
+
+TEST_F(QuicStreamTest, CannotBundleLostFin) {
+ Initialize(kShouldProcessData);
+
+ // Send [0, 18) and fin.
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
+ stream_->WriteOrBufferData(kData1, false, nullptr);
+ stream_->WriteOrBufferData(kData2, true, nullptr);
+
+ // Lost [0, 9) and fin.
+ stream_->OnStreamFrameLost(0, 9, false);
+ stream_->OnStreamFrameLost(18, 0, true);
+
+ // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
+ // frames.
+ InSequence s;
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(InvokeWithoutArgs(
+ testing::CreateFunctor(&(MockQuicSession::ConsumeData), stream_,
+ stream_->id(), 9, 0u, NO_FIN)));
+ EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+ .WillOnce(Return(QuicConsumedData(0, true)));
+ stream_->OnCanWrite();
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/quic_tag.cc b/chromium/net/quic/core/quic_tag.cc
index 2d0f1ecc083..9a44300a8fd 100644
--- a/chromium/net/quic/core/quic_tag.cc
+++ b/chromium/net/quic/core/quic_tag.cc
@@ -6,6 +6,7 @@
#include "base/macros.h"
#include "base/stl_util.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_text_utils.h"
namespace net {
@@ -36,9 +37,10 @@ std::string QuicTagToString(QuicTag tag) {
bool ascii = true;
const QuicTag orig_tag = tag;
- for (size_t i = 0; i < arraysize(chars); i++) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(chars); i++) {
chars[i] = static_cast<char>(tag);
- if ((chars[i] == 0 || chars[i] == '\xff') && i == arraysize(chars) - 1) {
+ if ((chars[i] == 0 || chars[i] == '\xff') &&
+ i == QUIC_ARRAYSIZE(chars) - 1) {
chars[i] = ' ';
}
if (!isprint(static_cast<unsigned char>(chars[i]))) {
diff --git a/chromium/net/quic/core/quic_unacked_packet_map.cc b/chromium/net/quic/core/quic_unacked_packet_map.cc
index 8ff3645f5a3..18be0ba3839 100644
--- a/chromium/net/quic/core/quic_unacked_packet_map.cc
+++ b/chromium/net/quic/core/quic_unacked_packet_map.cc
@@ -17,7 +17,7 @@ QuicUnackedPacketMap::QuicUnackedPacketMap()
least_unacked_(1),
bytes_in_flight_(0),
pending_crypto_packet_count_(0),
- stream_notifier_(nullptr) {}
+ session_notifier_(nullptr) {}
QuicUnackedPacketMap::~QuicUnackedPacketMap() {
for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
@@ -102,10 +102,10 @@ void QuicUnackedPacketMap::TransferRetransmissionInfo(
QuicTransmissionInfo* transmission_info =
&unacked_packets_.at(old_packet_number - least_unacked_);
QuicFrames* frames = &transmission_info->retransmittable_frames;
- if (stream_notifier_ != nullptr) {
+ if (session_notifier_ != nullptr) {
for (const QuicFrame& frame : *frames) {
if (frame.type == STREAM_FRAME) {
- stream_notifier_->OnStreamFrameRetransmitted(*frame.stream_frame);
+ session_notifier_->OnStreamFrameRetransmitted(*frame.stream_frame);
}
}
}
@@ -237,15 +237,6 @@ void QuicUnackedPacketMap::CancelRetransmissionsForStream(
if (frames->empty()) {
continue;
}
- if (stream_notifier_ != nullptr) {
- for (const QuicFrame& frame : *frames) {
- if (frame.type != STREAM_FRAME ||
- frame.stream_frame->stream_id != stream_id) {
- continue;
- }
- stream_notifier_->OnStreamFrameDiscarded(*frame.stream_frame);
- }
- }
RemoveFramesForStream(frames, stream_id);
if (frames->empty()) {
RemoveRetransmittability(packet_number);
@@ -332,22 +323,19 @@ QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
return least_unacked_;
}
-void QuicUnackedPacketMap::SetStreamNotifier(
- StreamNotifierInterface* stream_notifier) {
- stream_notifier_ = stream_notifier;
+void QuicUnackedPacketMap::SetSessionNotifier(
+ SessionNotifierInterface* session_notifier) {
+ session_notifier_ = session_notifier;
}
-void QuicUnackedPacketMap::NotifyStreamFramesAcked(
- const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay) {
- if (stream_notifier_ == nullptr) {
+void QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
+ QuicTime::Delta ack_delay) {
+ if (session_notifier_ == nullptr) {
return;
}
for (const QuicFrame& frame : info.retransmittable_frames) {
- if (frame.type == STREAM_FRAME) {
- stream_notifier_->OnStreamFrameAcked(*frame.stream_frame, ack_delay);
- }
+ session_notifier_->OnFrameAcked(frame, ack_delay);
}
}
diff --git a/chromium/net/quic/core/quic_unacked_packet_map.h b/chromium/net/quic/core/quic_unacked_packet_map.h
index 43bc635f278..6e2eb8a8f1c 100644
--- a/chromium/net/quic/core/quic_unacked_packet_map.h
+++ b/chromium/net/quic/core/quic_unacked_packet_map.h
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_transmission_info.h"
-#include "net/quic/core/stream_notifier_interface.h"
+#include "net/quic/core/session_notifier_interface.h"
#include "net/quic/platform/api/quic_export.h"
namespace net {
@@ -42,9 +42,9 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
// Returns true if the packet |packet_number| is unacked.
bool IsUnacked(QuicPacketNumber packet_number) const;
- // Notifies stream_notifier that stream frames have been acked.
- void NotifyStreamFramesAcked(const QuicTransmissionInfo& info,
- QuicTime::Delta ack_delay);
+ // Notifies session_notifier that frames have been acked.
+ void NotifyFramesAcked(const QuicTransmissionInfo& info,
+ QuicTime::Delta ack_delay);
// Marks |info| as no longer in flight.
void RemoveFromInFlight(QuicTransmissionInfo* info);
@@ -141,7 +141,7 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
// RTT measurement purposes.
void RemoveObsoletePackets();
- void SetStreamNotifier(StreamNotifierInterface* stream_notifier);
+ void SetSessionNotifier(SessionNotifierInterface* session_notifier);
private:
// Called when a packet is retransmitted with a new packet number.
@@ -191,9 +191,8 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
// Number of retransmittable crypto handshake packets.
size_t pending_crypto_packet_count_;
- // Receives notifications of stream frames being retransmitted or
- // acknowledged.
- StreamNotifierInterface* stream_notifier_;
+ // Receives notifications of frames being retransmitted or acknowledged.
+ SessionNotifierInterface* session_notifier_;
DISALLOW_COPY_AND_ASSIGN(QuicUnackedPacketMap);
};
diff --git a/chromium/net/quic/core/quic_unacked_packet_map_test.cc b/chromium/net/quic/core/quic_unacked_packet_map_test.cc
index 69e3315cef7..cf81a97be94 100644
--- a/chromium/net/quic/core/quic_unacked_packet_map_test.cc
+++ b/chromium/net/quic/core/quic_unacked_packet_map_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/core/quic_unacked_packet_map.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -16,20 +17,12 @@ namespace {
// Default packet length.
const uint32_t kDefaultLength = 1000;
-class MockStreamNotifier : public StreamNotifierInterface {
- public:
- MOCK_METHOD2(OnStreamFrameAcked,
- void(const QuicStreamFrame&, QuicTime::Delta));
- MOCK_METHOD1(OnStreamFrameRetransmitted, void(const QuicStreamFrame&));
- MOCK_METHOD1(OnStreamFrameDiscarded, void(const QuicStreamFrame&));
-};
-
class QuicUnackedPacketMapTest : public QuicTest {
protected:
QuicUnackedPacketMapTest()
: unacked_packets_(),
now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {
- unacked_packets_.SetStreamNotifier(&notifier_);
+ unacked_packets_.SetSessionNotifier(&notifier_);
}
~QuicUnackedPacketMapTest() override {}
@@ -115,7 +108,7 @@ class QuicUnackedPacketMapTest : public QuicTest {
}
QuicUnackedPacketMap unacked_packets_;
QuicTime now_;
- MockStreamNotifier notifier_;
+ MockSessionNotifier notifier_;
};
TEST_F(QuicUnackedPacketMapTest, RttOnly) {
@@ -124,7 +117,7 @@ TEST_F(QuicUnackedPacketMapTest, RttOnly) {
unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, false);
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyInFlightPackets(nullptr, 0);
VerifyRetransmittablePackets(nullptr, 0);
@@ -140,18 +133,18 @@ TEST_F(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
- VerifyRetransmittablePackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyRetransmittablePackets(unacked, QUIC_ARRAYSIZE(unacked));
unacked_packets_.RemoveRetransmittability(1);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.IncreaseLargestObserved(1);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.RemoveFromInFlight(1);
@@ -166,15 +159,15 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmission) {
unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
- EXPECT_CALL(notifier_, OnStreamFrameDiscarded(_)).Times(1);
unacked_packets_.CancelRetransmissionsForStream(stream_id);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
}
@@ -184,17 +177,18 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {1};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
// Stop retransmissions on another stream and verify the packet is unchanged.
- EXPECT_CALL(notifier_, OnStreamFrameDiscarded(_)).Times(0);
unacked_packets_.CancelRetransmissionsForStream(stream_id + 2);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
}
TEST_F(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
@@ -205,15 +199,15 @@ TEST_F(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
unacked_packets_.AddSentPacket(&packet2, 1, LOSS_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {2};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
- EXPECT_CALL(notifier_, OnStreamFrameDiscarded(_)).Times(1);
unacked_packets_.CancelRetransmissionsForStream(stream_id);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
}
@@ -226,25 +220,26 @@ TEST_F(QuicUnackedPacketMapTest, RetransmittedPacket) {
unacked_packets_.AddSentPacket(&packet2, 1, LOSS_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {2};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
unacked_packets_.RemoveRetransmittability(1);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.IncreaseLargestObserved(2);
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.RemoveFromInFlight(2);
QuicPacketNumber unacked2[] = {1};
- VerifyUnackedPackets(unacked2, arraysize(unacked2));
- VerifyInFlightPackets(unacked2, arraysize(unacked2));
+ VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
+ VerifyInFlightPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.RemoveFromInFlight(1);
@@ -261,10 +256,11 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {1, 2};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
// Early retransmit 1 as 3 and send new data as 4.
unacked_packets_.IncreaseLargestObserved(2);
@@ -277,11 +273,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.AddSentPacket(&packet4, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked2[] = {1, 3, 4};
- VerifyUnackedPackets(unacked2, arraysize(unacked2));
+ VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
QuicPacketNumber pending2[] = {3, 4};
- VerifyInFlightPackets(pending2, arraysize(pending2));
+ VerifyInFlightPackets(pending2, QUIC_ARRAYSIZE(pending2));
QuicPacketNumber retransmittable2[] = {3, 4};
- VerifyRetransmittablePackets(retransmittable2, arraysize(retransmittable2));
+ VerifyRetransmittablePackets(retransmittable2,
+ QUIC_ARRAYSIZE(retransmittable2));
// Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
unacked_packets_.IncreaseLargestObserved(4);
@@ -293,11 +290,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.AddSentPacket(&packet6, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked3[] = {3, 5, 6};
- VerifyUnackedPackets(unacked3, arraysize(unacked3));
+ VerifyUnackedPackets(unacked3, QUIC_ARRAYSIZE(unacked3));
QuicPacketNumber pending3[] = {3, 5, 6};
- VerifyInFlightPackets(pending3, arraysize(pending3));
+ VerifyInFlightPackets(pending3, QUIC_ARRAYSIZE(pending3));
QuicPacketNumber retransmittable3[] = {5, 6};
- VerifyRetransmittablePackets(retransmittable3, arraysize(retransmittable3));
+ VerifyRetransmittablePackets(retransmittable3,
+ QUIC_ARRAYSIZE(retransmittable3));
// Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
unacked_packets_.IncreaseLargestObserved(6);
@@ -307,17 +305,18 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
unacked_packets_.AddSentPacket(&packet7, 5, LOSS_RETRANSMISSION, now_, true);
QuicPacketNumber unacked4[] = {3, 5, 7};
- VerifyUnackedPackets(unacked4, arraysize(unacked4));
+ VerifyUnackedPackets(unacked4, QUIC_ARRAYSIZE(unacked4));
QuicPacketNumber pending4[] = {3, 5, 7};
- VerifyInFlightPackets(pending4, arraysize(pending4));
+ VerifyInFlightPackets(pending4, QUIC_ARRAYSIZE(pending4));
QuicPacketNumber retransmittable4[] = {7};
- VerifyRetransmittablePackets(retransmittable4, arraysize(retransmittable4));
+ VerifyRetransmittablePackets(retransmittable4,
+ QUIC_ARRAYSIZE(retransmittable4));
// Remove the older two transmissions from in flight.
unacked_packets_.RemoveFromInFlight(3);
unacked_packets_.RemoveFromInFlight(5);
QuicPacketNumber pending5[] = {7};
- VerifyInFlightPackets(pending5, arraysize(pending5));
+ VerifyInFlightPackets(pending5, QUIC_ARRAYSIZE(pending5));
}
TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
@@ -328,10 +327,11 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked[] = {1, 2};
- VerifyUnackedPackets(unacked, arraysize(unacked));
- VerifyInFlightPackets(unacked, arraysize(unacked));
+ VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+ VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
QuicPacketNumber retransmittable[] = {1, 2};
- VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
+ VerifyRetransmittablePackets(retransmittable,
+ QUIC_ARRAYSIZE(retransmittable));
// Early retransmit 1 as 3.
unacked_packets_.IncreaseLargestObserved(2);
@@ -342,11 +342,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.AddSentPacket(&packet3, 1, LOSS_RETRANSMISSION, now_, true);
QuicPacketNumber unacked2[] = {1, 3};
- VerifyUnackedPackets(unacked2, arraysize(unacked2));
+ VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
QuicPacketNumber pending2[] = {3};
- VerifyInFlightPackets(pending2, arraysize(pending2));
+ VerifyInFlightPackets(pending2, QUIC_ARRAYSIZE(pending2));
QuicPacketNumber retransmittable2[] = {3};
- VerifyRetransmittablePackets(retransmittable2, arraysize(retransmittable2));
+ VerifyRetransmittablePackets(retransmittable2,
+ QUIC_ARRAYSIZE(retransmittable2));
// TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
SerializedPacket packet4(CreateNonRetransmittablePacket(4));
@@ -355,11 +356,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.AddSentPacket(&packet5, 0, NOT_RETRANSMISSION, now_, true);
QuicPacketNumber unacked3[] = {1, 3, 4, 5};
- VerifyUnackedPackets(unacked3, arraysize(unacked3));
+ VerifyUnackedPackets(unacked3, QUIC_ARRAYSIZE(unacked3));
QuicPacketNumber pending3[] = {3, 4, 5};
- VerifyInFlightPackets(pending3, arraysize(pending3));
+ VerifyInFlightPackets(pending3, QUIC_ARRAYSIZE(pending3));
QuicPacketNumber retransmittable3[] = {4, 5};
- VerifyRetransmittablePackets(retransmittable3, arraysize(retransmittable3));
+ VerifyRetransmittablePackets(retransmittable3,
+ QUIC_ARRAYSIZE(retransmittable3));
// Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
unacked_packets_.IncreaseLargestObserved(5);
@@ -371,11 +373,12 @@ TEST_F(QuicUnackedPacketMapTest, RetransmitFourTimes) {
unacked_packets_.AddSentPacket(&packet6, 4, LOSS_RETRANSMISSION, now_, true);
QuicPacketNumber unacked4[] = {4, 6};
- VerifyUnackedPackets(unacked4, arraysize(unacked4));
+ VerifyUnackedPackets(unacked4, QUIC_ARRAYSIZE(unacked4));
QuicPacketNumber pending4[] = {6};
- VerifyInFlightPackets(pending4, arraysize(pending4));
+ VerifyInFlightPackets(pending4, QUIC_ARRAYSIZE(pending4));
QuicPacketNumber retransmittable4[] = {6};
- VerifyRetransmittablePackets(retransmittable4, arraysize(retransmittable4));
+ VerifyRetransmittablePackets(retransmittable4,
+ QUIC_ARRAYSIZE(retransmittable4));
}
TEST_F(QuicUnackedPacketMapTest, SendWithGap) {
diff --git a/chromium/net/quic/core/quic_utils.cc b/chromium/net/quic/core/quic_utils.cc
index cce8c16c57f..109f3760a71 100644
--- a/chromium/net/quic/core/quic_utils.cc
+++ b/chromium/net/quic/core/quic_utils.cc
@@ -6,13 +6,12 @@
#include <algorithm>
#include <cstdint>
-#include <vector>
-#include "base/containers/adapters.h"
-#include "base/logging.h"
#include "net/quic/core/quic_constants.h"
+#include "net/quic/platform/api/quic_aligned.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_flags.h"
+#include "net/quic/platform/api/quic_prefetch.h"
using std::string;
@@ -237,16 +236,12 @@ void QuicUtils::CopyToBuffer(const struct iovec* iov,
// generally, the iov_offset is not 0, input iov consists of 2K buffers and
// the output buffer is ~1.4K.
if (copy_len == iov_available && iovnum + 1 < iov_count) {
- // TODO(ckrasic) - this is unused without prefetch()
- // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base);
- // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base);
+ char* next_base = static_cast<char*>(iov[iovnum + 1].iov_base);
// Prefetch 2 cachelines worth of data to get the prefetcher started; leave
// it to the hardware prefetcher after that.
- // TODO(ckrasic) - investigate what to do about prefetch directives.
- // ::base::PrefetchT0(next_base);
+ QuicPrefetchT0(next_base);
if (iov[iovnum + 1].iov_len >= 64) {
- // TODO(ckrasic) - investigate what to do about prefetch directives.
- // ::base::PrefetchT0(next_base + ABSL_CACHELINE_SIZE);
+ QuicPrefetchT0(next_base + QUIC_CACHELINE_SIZE);
}
}
diff --git a/chromium/net/quic/core/quic_version_manager.cc b/chromium/net/quic/core/quic_version_manager.cc
index 610189fdee1..489b7beacfd 100644
--- a/chromium/net/quic/core/quic_version_manager.cc
+++ b/chromium/net/quic/core/quic_version_manager.cc
@@ -10,42 +10,42 @@
namespace net {
QuicVersionManager::QuicVersionManager(
- QuicTransportVersionVector supported_versions)
+ ParsedQuicVersionVector supported_versions)
: enable_version_43_(GetQuicFlag(FLAGS_quic_enable_version_43)),
enable_version_42_(GetQuicFlag(FLAGS_quic_enable_version_42)),
- enable_version_41_(FLAGS_quic_reloadable_flag_quic_enable_version_41),
- enable_version_39_(FLAGS_quic_reloadable_flag_quic_enable_version_39),
- enable_version_38_(FLAGS_quic_reloadable_flag_quic_enable_version_38),
- allowed_supported_versions_(supported_versions),
- filtered_supported_versions_(
- FilterSupportedTransportVersions(supported_versions)) {}
+ allowed_supported_versions_(std::move(supported_versions)) {
+ RefilterSupportedVersions();
+}
QuicVersionManager::~QuicVersionManager() {}
const QuicTransportVersionVector&
QuicVersionManager::GetSupportedTransportVersions() {
- MaybeRefilterSupportedTransportVersions();
+ MaybeRefilterSupportedVersions();
+ return filtered_transport_versions_;
+}
+
+const ParsedQuicVersionVector& QuicVersionManager::GetSupportedVersions() {
+ MaybeRefilterSupportedVersions();
return filtered_supported_versions_;
}
-void QuicVersionManager::MaybeRefilterSupportedTransportVersions() {
+void QuicVersionManager::MaybeRefilterSupportedVersions() {
if (enable_version_43_ != GetQuicFlag(FLAGS_quic_enable_version_43) ||
- enable_version_42_ != GetQuicFlag(FLAGS_quic_enable_version_42) ||
- enable_version_41_ != FLAGS_quic_reloadable_flag_quic_enable_version_41 ||
- enable_version_39_ != FLAGS_quic_reloadable_flag_quic_enable_version_39 ||
- enable_version_38_ != FLAGS_quic_reloadable_flag_quic_enable_version_38) {
+ enable_version_42_ != GetQuicFlag(FLAGS_quic_enable_version_42)) {
enable_version_43_ = GetQuicFlag(FLAGS_quic_enable_version_43);
enable_version_42_ = GetQuicFlag(FLAGS_quic_enable_version_42);
- enable_version_41_ = FLAGS_quic_reloadable_flag_quic_enable_version_41;
- enable_version_39_ = FLAGS_quic_reloadable_flag_quic_enable_version_39;
- enable_version_38_ = FLAGS_quic_reloadable_flag_quic_enable_version_38;
- RefilterSupportedTransportVersions();
+ RefilterSupportedVersions();
}
}
-void QuicVersionManager::RefilterSupportedTransportVersions() {
+void QuicVersionManager::RefilterSupportedVersions() {
filtered_supported_versions_ =
- FilterSupportedTransportVersions(allowed_supported_versions_);
+ FilterSupportedVersions(allowed_supported_versions_);
+ filtered_transport_versions_.clear();
+ for (ParsedQuicVersion version : filtered_supported_versions_) {
+ filtered_transport_versions_.push_back(version.transport_version);
+ }
}
} // namespace net
diff --git a/chromium/net/quic/core/quic_version_manager.h b/chromium/net/quic/core/quic_version_manager.h
index 732180223c4..0982873d447 100644
--- a/chromium/net/quic/core/quic_version_manager.h
+++ b/chromium/net/quic/core/quic_version_manager.h
@@ -13,21 +13,25 @@ namespace net {
// Used to generate filtered supported versions based on flags.
class QUIC_EXPORT_PRIVATE QuicVersionManager {
public:
- explicit QuicVersionManager(QuicTransportVersionVector supported_versions);
+ explicit QuicVersionManager(ParsedQuicVersionVector supported_versions);
virtual ~QuicVersionManager();
// Returns currently supported QUIC versions.
+ // TODO(nharper): Remove this method once it is unused.
const QuicTransportVersionVector& GetSupportedTransportVersions();
+ // Returns currently supported QUIC versions.
+ const ParsedQuicVersionVector& GetSupportedVersions();
+
protected:
// Maybe refilter filtered_supported_versions_ based on flags.
- void MaybeRefilterSupportedTransportVersions();
+ void MaybeRefilterSupportedVersions();
// Refilters filtered_supported_versions_.
- virtual void RefilterSupportedTransportVersions();
+ virtual void RefilterSupportedVersions();
const QuicTransportVersionVector& filtered_supported_versions() const {
- return filtered_supported_versions_;
+ return filtered_transport_versions_;
}
private:
@@ -35,17 +39,15 @@ class QUIC_EXPORT_PRIVATE QuicVersionManager {
bool enable_version_43_;
// FLAGS_quic_enable_version_42
bool enable_version_42_;
- // FLAGS_quic_reloadable_flag_quic_enable_version_41
- bool enable_version_41_;
- // FLAGS_quic_reloadable_flag_quic_enable_version_39
- bool enable_version_39_;
- // FLAGS_quic_reloadable_flag_quic_enable_version_38
- bool enable_version_38_;
// The list of versions that may be supported.
- QuicTransportVersionVector allowed_supported_versions_;
+ ParsedQuicVersionVector allowed_supported_versions_;
// This vector contains QUIC versions which are currently supported based on
// flags.
- QuicTransportVersionVector filtered_supported_versions_;
+ ParsedQuicVersionVector filtered_supported_versions_;
+ // This vector contains the transport versions from
+ // |filtered_supported_versions_|. No guarantees are made that the same
+ // transport version isn't repeated.
+ QuicTransportVersionVector filtered_transport_versions_;
};
} // namespace net
diff --git a/chromium/net/quic/core/quic_version_manager_test.cc b/chromium/net/quic/core/quic_version_manager_test.cc
index 94deeee6509..ab8c101b0e2 100644
--- a/chromium/net/quic/core/quic_version_manager_test.cc
+++ b/chromium/net/quic/core/quic_version_manager_test.cc
@@ -18,37 +18,10 @@ class QuicVersionManagerTest : public QuicTest {};
TEST_F(QuicVersionManagerTest, QuicVersionManager) {
SetQuicFlag(&FLAGS_quic_enable_version_43, false);
SetQuicFlag(&FLAGS_quic_enable_version_42, false);
- FLAGS_quic_reloadable_flag_quic_enable_version_41 = false;
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = false;
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = false;
- QuicVersionManager manager(AllSupportedTransportVersions());
- EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
- manager.GetSupportedTransportVersions());
-
- EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
- manager.GetSupportedTransportVersions());
- ASSERT_EQ(2u, manager.GetSupportedTransportVersions().size());
- EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[0]);
- EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[1]);
+ QuicVersionManager manager(AllSupportedVersions());
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = true;
EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
manager.GetSupportedTransportVersions());
- ASSERT_EQ(3u, manager.GetSupportedTransportVersions().size());
- EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedTransportVersions()[0]);
- EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[1]);
- EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[2]);
-
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = true;
- EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
- manager.GetSupportedTransportVersions());
- ASSERT_EQ(4u, manager.GetSupportedTransportVersions().size());
- EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedTransportVersions()[0]);
- EXPECT_EQ(QUIC_VERSION_38, manager.GetSupportedTransportVersions()[1]);
- EXPECT_EQ(QUIC_VERSION_37, manager.GetSupportedTransportVersions()[2]);
- EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedTransportVersions()[3]);
-
- FLAGS_quic_reloadable_flag_quic_enable_version_41 = true;
ASSERT_EQ(5u, manager.GetSupportedTransportVersions().size());
EXPECT_EQ(QUIC_VERSION_41, manager.GetSupportedTransportVersions()[0]);
EXPECT_EQ(QUIC_VERSION_39, manager.GetSupportedTransportVersions()[1]);
diff --git a/chromium/net/quic/core/quic_versions.cc b/chromium/net/quic/core/quic_versions.cc
index af86dc4d6fd..d9fec40a738 100644
--- a/chromium/net/quic/core/quic_versions.cc
+++ b/chromium/net/quic/core/quic_versions.cc
@@ -21,16 +21,16 @@ namespace {
// Constructs a version label from the 4 bytes such that the on-the-wire
// order will be: d, c, b, a.
QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- return MakeQuicTag(a, b, c, d);
- }
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_net_byte_order_version_label,
- 1, 10);
return MakeQuicTag(d, c, b, a);
}
} // namespace
+std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
+ os << ParsedQuicVersionToString(version);
+ return os;
+}
+
QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
char proto = 0;
switch (parsed_version.handshake_protocol) {
@@ -93,49 +93,62 @@ ParsedQuicVersion ParseQuicVersionLabel(QuicVersionLabel version_label) {
QuicTransportVersionVector AllSupportedTransportVersions() {
QuicTransportVersionVector supported_versions;
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
- supported_versions.push_back(kSupportedTransportVersions[i]);
+ for (QuicTransportVersion version : kSupportedTransportVersions) {
+ supported_versions.push_back(version);
+ }
+ return supported_versions;
+}
+
+ParsedQuicVersionVector AllSupportedVersions() {
+ ParsedQuicVersionVector supported_versions;
+ for (HandshakeProtocol protocol : kSupportedHandshakeProtocols) {
+ if (protocol == PROTOCOL_TLS1_3 && !FLAGS_quic_supports_tls_handshake) {
+ continue;
+ }
+ for (QuicTransportVersion version : kSupportedTransportVersions) {
+ supported_versions.push_back(ParsedQuicVersion(protocol, version));
+ }
}
return supported_versions;
}
+// TODO(nharper): Remove this function when it is no longer in use.
QuicTransportVersionVector CurrentSupportedTransportVersions() {
return FilterSupportedTransportVersions(AllSupportedTransportVersions());
}
+ParsedQuicVersionVector CurrentSupportedVersions() {
+ return FilterSupportedVersions(AllSupportedVersions());
+}
+
+// TODO(nharper): Remove this function when it is no longer in use.
QuicTransportVersionVector FilterSupportedTransportVersions(
QuicTransportVersionVector versions) {
- QuicTransportVersionVector filtered_versions(versions.size());
- filtered_versions.clear(); // Guaranteed by spec not to change capacity.
+ ParsedQuicVersionVector parsed_versions;
for (QuicTransportVersion version : versions) {
- if (version == QUIC_VERSION_43) {
+ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+ }
+ ParsedQuicVersionVector filtered_parsed_versions =
+ FilterSupportedVersions(parsed_versions);
+ QuicTransportVersionVector filtered_versions;
+ for (ParsedQuicVersion version : filtered_parsed_versions) {
+ filtered_versions.push_back(version.transport_version);
+ }
+ return filtered_versions;
+}
+
+ParsedQuicVersionVector FilterSupportedVersions(
+ ParsedQuicVersionVector versions) {
+ ParsedQuicVersionVector filtered_versions;
+ filtered_versions.reserve(versions.size());
+ for (ParsedQuicVersion version : versions) {
+ if (version.transport_version == QUIC_VERSION_43) {
if (GetQuicFlag(FLAGS_quic_enable_version_43) &&
- GetQuicFlag(FLAGS_quic_enable_version_42) &&
- FLAGS_quic_reloadable_flag_quic_enable_version_41 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_39 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_38) {
- filtered_versions.push_back(version);
- }
- } else if (version == QUIC_VERSION_42) {
- if (GetQuicFlag(FLAGS_quic_enable_version_42) &&
- FLAGS_quic_reloadable_flag_quic_enable_version_41 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_39 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_38) {
- filtered_versions.push_back(version);
- }
- } else if (version == QUIC_VERSION_41) {
- if (FLAGS_quic_reloadable_flag_quic_enable_version_41 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_39 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_38) {
+ GetQuicFlag(FLAGS_quic_enable_version_42)) {
filtered_versions.push_back(version);
}
- } else if (version == QUIC_VERSION_39) {
- if (FLAGS_quic_reloadable_flag_quic_enable_version_39 &&
- FLAGS_quic_reloadable_flag_quic_enable_version_38) {
- filtered_versions.push_back(version);
- }
- } else if (version == QUIC_VERSION_38) {
- if (FLAGS_quic_reloadable_flag_quic_enable_version_38) {
+ } else if (version.transport_version == QUIC_VERSION_42) {
+ if (GetQuicFlag(FLAGS_quic_enable_version_42)) {
filtered_versions.push_back(version);
}
} else {
@@ -158,6 +171,30 @@ QuicTransportVersionVector VersionOfIndex(
return version;
}
+ParsedQuicVersionVector ParsedVersionOfIndex(
+ const ParsedQuicVersionVector& versions,
+ int index) {
+ ParsedQuicVersionVector version;
+ int version_count = versions.size();
+ if (index >= 0 && index < version_count) {
+ version.push_back(versions[index]);
+ } else {
+ version.push_back(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED));
+ }
+ return version;
+}
+
+QuicTransportVersionVector ParsedVersionsToTransportVersions(
+ const ParsedQuicVersionVector& versions) {
+ QuicTransportVersionVector transport_versions;
+ transport_versions.resize(versions.size());
+ for (size_t i = 0; i < versions.size(); ++i) {
+ transport_versions[i] = versions[i].transport_version;
+ }
+ return transport_versions;
+}
+
QuicVersionLabel QuicVersionToQuicVersionLabel(
QuicTransportVersion transport_version) {
return CreateQuicVersionLabel(
@@ -165,11 +202,6 @@ QuicVersionLabel QuicVersionToQuicVersionLabel(
}
string QuicVersionLabelToString(QuicVersionLabel version_label) {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- return QuicTagToString(version_label);
- }
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_net_byte_order_version_label,
- 2, 10);
return QuicTagToString(QuicEndian::HostToNet32(version_label));
}
@@ -201,6 +233,10 @@ string QuicVersionToString(QuicTransportVersion transport_version) {
}
}
+string ParsedQuicVersionToString(ParsedQuicVersion version) {
+ return QuicVersionLabelToString(CreateQuicVersionLabel(version));
+}
+
string QuicTransportVersionVectorToString(
const QuicTransportVersionVector& versions) {
string result = "";
@@ -213,4 +249,16 @@ string QuicTransportVersionVectorToString(
return result;
}
+string ParsedQuicVersionVectorToString(
+ const ParsedQuicVersionVector& versions) {
+ string result = "";
+ for (size_t i = 0; i < versions.size(); ++i) {
+ if (i != 0) {
+ result.append(",");
+ }
+ result.append(ParsedQuicVersionToString(versions[i]));
+ }
+ return result;
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_versions.h b/chromium/net/quic/core/quic_versions.h
index 33c2824b6fa..b99596ff688 100644
--- a/chromium/net/quic/core/quic_versions.h
+++ b/chromium/net/quic/core/quic_versions.h
@@ -59,12 +59,34 @@ struct ParsedQuicVersion {
: handshake_protocol(handshake_protocol),
transport_version(transport_version) {}
+ ParsedQuicVersion(const ParsedQuicVersion& other)
+ : handshake_protocol(other.handshake_protocol),
+ transport_version(other.transport_version) {}
+
+ ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
+ if (this != &other) {
+ handshake_protocol = other.handshake_protocol;
+ transport_version = other.transport_version;
+ }
+ return *this;
+ }
+
bool operator==(const ParsedQuicVersion& other) const {
return handshake_protocol == other.handshake_protocol &&
transport_version == other.transport_version;
}
+
+ bool operator!=(const ParsedQuicVersion& other) const {
+ return handshake_protocol != other.handshake_protocol ||
+ transport_version != other.transport_version;
+ }
};
+QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+ const ParsedQuicVersion& version);
+
+using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;
+
// Representation of the on-the-wire QUIC version number. Will be written/read
// to the wire in network-byte-order.
using QuicVersionLabel = uint32_t;
@@ -81,26 +103,57 @@ static const QuicTransportVersion kSupportedTransportVersions[] = {
QUIC_VERSION_43, QUIC_VERSION_42, QUIC_VERSION_41, QUIC_VERSION_39,
QUIC_VERSION_38, QUIC_VERSION_37, QUIC_VERSION_35};
+// This vector contains all crypto handshake protocols that are supported.
+static const HandshakeProtocol kSupportedHandshakeProtocols[] = {
+ PROTOCOL_QUIC_CRYPTO, PROTOCOL_TLS1_3};
+
typedef std::vector<QuicTransportVersion> QuicTransportVersionVector;
// Returns a vector of QUIC versions in kSupportedTransportVersions.
QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();
+// Returns a vector of QUIC versions that is the cartesian product of
+// kSupportedTransportVersions and kSupportedHandshakeProtocols.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();
+
// Returns a vector of QUIC versions from kSupportedTransportVersions which
// exclude any versions which are disabled by flags.
QUIC_EXPORT_PRIVATE QuicTransportVersionVector
CurrentSupportedTransportVersions();
+// Returns a vector of QUIC versions that is the cartesian product of
+// kSupportedTransportVersions and kSupportedHandshakeProtocols, with any
+// versions disabled by flags excluded.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();
+
// Returns a vector of QUIC versions from |versions| which exclude any versions
// which are disabled by flags.
QUIC_EXPORT_PRIVATE QuicTransportVersionVector
FilterSupportedTransportVersions(QuicTransportVersionVector versions);
+// Returns a vector of QUIC versions from |versions| which exclude any versions
+// which are disabled by flags.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+FilterSupportedVersions(ParsedQuicVersionVector versions);
+
// Returns QUIC version of |index| in result of |versions|. Returns
// QUIC_VERSION_UNSUPPORTED if |index| is out of bounds.
QUIC_EXPORT_PRIVATE QuicTransportVersionVector
VersionOfIndex(const QuicTransportVersionVector& versions, int index);
+// Returns QUIC version of |index| in result of |versions|. Returns
+// ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED) if |index|
+// is out of bounds.
+QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
+ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);
+
+// Returns a vector of QuicTransportVersions corresponding to just the transport
+// versions in |versions|. If the input vector contains multiple parsed versions
+// with different handshake protocols (but the same transport version), that
+// transport version will appear in the resulting vector multiple times.
+QUIC_EXPORT_PRIVATE QuicTransportVersionVector
+ParsedVersionsToTransportVersions(const ParsedQuicVersionVector& versions);
+
// QuicVersionLabel is written to and read from the wire, but we prefer to use
// the more readable ParsedQuicVersion at other levels.
// Helper function which translates from a QuicVersionLabel to a
@@ -138,11 +191,21 @@ QuicVersionLabelToHandshakeProtocol(QuicVersionLabel version_label);
QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
QuicTransportVersion transport_version);
+// Helper function which translates from a ParsedQuicVersion to a std::string.
+// Returns std::strings corresponding to the on-the-wire tag.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
+ ParsedQuicVersion version);
+
// Returns comma separated list of string representations of QuicVersion enum
// values in the supplied |versions| vector.
QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
const QuicTransportVersionVector& versions);
+// Returns comma separated list of std::string representations of
+// ParsedQuicVersion values in the supplied |versions| vector.
+QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
+ const ParsedQuicVersionVector& versions);
+
} // namespace net
#endif // NET_QUIC_CORE_QUIC_VERSIONS_H_
diff --git a/chromium/net/quic/core/quic_versions_test.cc b/chromium/net/quic/core/quic_versions_test.cc
index 60fe66e1fd1..1a4a553a53e 100644
--- a/chromium/net/quic/core/quic_versions_test.cc
+++ b/chromium/net/quic/core/quic_versions_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/core/quic_versions.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
@@ -15,9 +16,6 @@ namespace {
class QuicVersionsTest : public QuicTest {
protected:
QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- return MakeQuicTag(a, b, c, d);
- }
return MakeQuicTag(d, c, b, a);
}
};
@@ -36,20 +34,15 @@ TEST_F(QuicVersionsTest, QuicVersionToQuicVersionLabel) {
#endif
// Explicitly test a specific version.
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- EXPECT_EQ(MakeQuicTag('Q', '0', '3', '5'),
- QuicVersionToQuicVersionLabel(QUIC_VERSION_35));
- } else {
EXPECT_EQ(MakeQuicTag('5', '3', '0', 'Q'),
QuicVersionToQuicVersionLabel(QUIC_VERSION_35));
- }
// Loop over all supported versions and make sure that we never hit the
// default case (i.e. all supported versions should be successfully converted
// to valid QuicVersionLabels).
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
- QuicTransportVersion version = kSupportedTransportVersions[i];
- EXPECT_LT(0u, QuicVersionToQuicVersionLabel(version));
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kSupportedTransportVersions); ++i) {
+ QuicTransportVersion version = kSupportedTransportVersions[i];
+ EXPECT_LT(0u, QuicVersionToQuicVersionLabel(version));
}
}
@@ -83,15 +76,10 @@ TEST_F(QuicVersionsTest, QuicVersionLabelToQuicTransportVersion) {
#endif
// Explicitly test specific versions.
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- EXPECT_EQ(QUIC_VERSION_35,
- QuicVersionLabelToQuicVersion(MakeQuicTag('Q', '0', '3', '5')));
- } else {
- EXPECT_EQ(QUIC_VERSION_35,
- QuicVersionLabelToQuicVersion(MakeQuicTag('5', '3', '0', 'Q')));
- }
+ EXPECT_EQ(QUIC_VERSION_35,
+ QuicVersionLabelToQuicVersion(MakeQuicTag('5', '3', '0', 'Q')));
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kSupportedTransportVersions); ++i) {
QuicTransportVersion version = kSupportedTransportVersions[i];
// Get the label from the version (we can loop over QuicVersions easily).
@@ -111,15 +99,9 @@ TEST_F(QuicVersionsTest, QuicVersionLabelToQuicVersionUnsupported) {
#if 0
ScopedMockLog log(kDoNotCaptureLogsYet);
#ifndef NDEBUG
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- EXPECT_CALL(log, Log(base_logging::INFO, _,
- "Unsupported QuicVersionLabel version: FAKE"))
- .Times(1);
- } else {
- EXPECT_CALL(log, Log(base_logging::INFO, _,
- "Unsupported QuicVersionLabel version: EKAF"))
- .Times(1);
- }
+ EXPECT_CALL(log, Log(base_logging::INFO, _,
+ "Unsupported QuicVersionLabel version: EKAF"))
+ .Times(1);
#endif
log.StartCapturingLogs();
#endif
@@ -136,7 +118,7 @@ TEST_F(QuicVersionsTest, QuicVersionLabelToHandshakeProtocol) {
log.StartCapturingLogs();
#endif
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kSupportedTransportVersions); ++i) {
QuicVersionLabel version_label =
QuicVersionToQuicVersionLabel(kSupportedTransportVersions[i]);
EXPECT_EQ(PROTOCOL_QUIC_CRYPTO,
@@ -145,12 +127,7 @@ TEST_F(QuicVersionsTest, QuicVersionLabelToHandshakeProtocol) {
// Test a TLS version:
FLAGS_quic_supports_tls_handshake = true;
- QuicTag tls_tag;
- if (!FLAGS_quic_reloadable_flag_quic_use_net_byte_order_version_label) {
- tls_tag = MakeQuicTag('T', '0', '4', '1');
- } else {
- tls_tag = MakeQuicTag('1', '4', '0', 'T');
- }
+ QuicTag tls_tag = MakeQuicTag('1', '4', '0', 'T');
EXPECT_EQ(PROTOCOL_TLS1_3, QuicVersionLabelToHandshakeProtocol(tls_tag));
FLAGS_quic_supports_tls_handshake = false;
@@ -285,7 +262,7 @@ TEST_F(QuicVersionsTest, QuicVersionToString) {
QuicTransportVersion single_version[] = {QUIC_VERSION_35};
QuicTransportVersionVector versions_vector;
- for (size_t i = 0; i < arraysize(single_version); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(single_version); ++i) {
versions_vector.push_back(single_version[i]);
}
EXPECT_EQ("QUIC_VERSION_35",
@@ -294,57 +271,57 @@ TEST_F(QuicVersionsTest, QuicVersionToString) {
QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
QUIC_VERSION_35};
versions_vector.clear();
- for (size_t i = 0; i < arraysize(multiple_versions); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(multiple_versions); ++i) {
versions_vector.push_back(multiple_versions[i]);
}
EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_35",
QuicTransportVersionVectorToString(versions_vector));
// Make sure that all supported versions are present in QuicVersionToString.
- for (size_t i = 0; i < arraysize(kSupportedTransportVersions); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(kSupportedTransportVersions); ++i) {
QuicTransportVersion version = kSupportedTransportVersions[i];
EXPECT_NE("QUIC_VERSION_UNSUPPORTED", QuicVersionToString(version));
}
}
-TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo38) {
- QuicTransportVersionVector all_versions = {QUIC_VERSION_35, QUIC_VERSION_37,
- QUIC_VERSION_38, QUIC_VERSION_39};
+TEST_F(QuicVersionsTest, ParsedQuicVersionToString) {
+ ParsedQuicVersion unsupported(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
+ ParsedQuicVersion version35(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_35);
+ EXPECT_EQ("Q035", ParsedQuicVersionToString(version35));
+ EXPECT_EQ("0", ParsedQuicVersionToString(unsupported));
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = false;
+ ParsedQuicVersionVector versions_vector = {version35};
+ EXPECT_EQ("Q035", ParsedQuicVersionVectorToString(versions_vector));
- QuicTransportVersionVector filtered_versions =
- FilterSupportedTransportVersions(all_versions);
- ASSERT_EQ(2u, filtered_versions.size());
- EXPECT_EQ(QUIC_VERSION_35, filtered_versions[0]);
- EXPECT_EQ(QUIC_VERSION_37, filtered_versions[1]);
-}
+ versions_vector = {unsupported, version35};
+ EXPECT_EQ("0,Q035", ParsedQuicVersionVectorToString(versions_vector));
-TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo39) {
- QuicTransportVersionVector all_versions = {QUIC_VERSION_35, QUIC_VERSION_37,
- QUIC_VERSION_38, QUIC_VERSION_39};
-
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = true;
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = false;
-
- QuicTransportVersionVector filtered_versions =
- FilterSupportedTransportVersions(all_versions);
- ASSERT_EQ(3u, filtered_versions.size());
- EXPECT_EQ(QUIC_VERSION_35, filtered_versions[0]);
- EXPECT_EQ(QUIC_VERSION_37, filtered_versions[1]);
- EXPECT_EQ(QUIC_VERSION_38, filtered_versions[2]);
+ // Make sure that all supported versions are present in
+ // ParsedQuicVersionToString.
+ FLAGS_quic_supports_tls_handshake = true;
+ for (QuicTransportVersion transport_version : kSupportedTransportVersions) {
+ for (HandshakeProtocol protocol : kSupportedHandshakeProtocols) {
+ EXPECT_NE("0", ParsedQuicVersionToString(
+ ParsedQuicVersion(protocol, transport_version)));
+ }
+ }
}
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsAllVersions) {
QuicTransportVersionVector all_versions = {QUIC_VERSION_35, QUIC_VERSION_37,
QUIC_VERSION_38, QUIC_VERSION_39};
-
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = true;
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = true;
+ ParsedQuicVersionVector parsed_versions;
+ for (QuicTransportVersion version : all_versions) {
+ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+ }
QuicTransportVersionVector filtered_versions =
FilterSupportedTransportVersions(all_versions);
ASSERT_EQ(all_versions, filtered_versions);
+
+ ParsedQuicVersionVector filtered_parsed_versions =
+ FilterSupportedVersions(parsed_versions);
+ ASSERT_EQ(parsed_versions, filtered_parsed_versions);
}
TEST_F(QuicVersionsTest, LookUpVersionByIndex) {
@@ -359,11 +336,36 @@ TEST_F(QuicVersionsTest, LookUpVersionByIndex) {
}
}
}
+
+TEST_F(QuicVersionsTest, LookUpParsedVersionByIndex) {
+ ParsedQuicVersionVector all_versions = AllSupportedVersions();
+ int version_count = all_versions.size();
+ for (int i = -5; i <= version_count + 1; ++i) {
+ if (i >= 0 && i < version_count) {
+ EXPECT_EQ(all_versions[i], ParsedVersionOfIndex(all_versions, i)[0]);
+ } else {
+ EXPECT_EQ(
+ ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
+ ParsedVersionOfIndex(all_versions, i)[0]);
+ }
+ }
+}
+
+TEST_F(QuicVersionsTest, ParsedVersionsToTransportVersions) {
+ ParsedQuicVersionVector all_versions = AllSupportedVersions();
+ QuicTransportVersionVector transport_versions =
+ ParsedVersionsToTransportVersions(all_versions);
+ ASSERT_EQ(all_versions.size(), transport_versions.size());
+ for (size_t i = 0; i < all_versions.size(); ++i) {
+ EXPECT_EQ(transport_versions[i], all_versions[i].transport_version);
+ }
+}
+
// This test may appear to be so simplistic as to be unnecessary,
// yet a typo was made in doing the #defines and it was caught
// only in some test far removed from here... Better safe than sorry.
TEST_F(QuicVersionsTest, CheckVersionNumbersForTypos) {
- static_assert(arraysize(net::kSupportedTransportVersions) == 7u,
+ static_assert(QUIC_ARRAYSIZE(net::kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
EXPECT_EQ(QUIC_VERSION_35, 35);
EXPECT_EQ(QUIC_VERSION_37, 37);
diff --git a/chromium/net/quic/core/session_notifier_interface.h b/chromium/net/quic/core/session_notifier_interface.h
new file mode 100644
index 00000000000..9a1e4e37d3f
--- /dev/null
+++ b/chromium/net/quic/core/session_notifier_interface.h
@@ -0,0 +1,32 @@
+// 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 NET_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
+#define NET_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
+
+#include "net/quic/core/frames/quic_frame.h"
+#include "net/quic/core/quic_time.h"
+
+namespace net {
+
+// Pure virtual class to be notified when a packet containing a frame is acked
+// or lost.
+class QUIC_EXPORT_PRIVATE SessionNotifierInterface {
+ public:
+ virtual ~SessionNotifierInterface() {}
+
+ // Called when |frame| is acked.
+ virtual void OnFrameAcked(const QuicFrame& frame,
+ QuicTime::Delta ack_delay_time) = 0;
+
+ // Called when |frame| is retransmitted.
+ virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
+
+ // Called when |frame| is considered as lost.
+ virtual void OnFrameLost(const QuicFrame& frame) = 0;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CORE_SESSION_NOTIFIER_INTERFACE_H_
diff --git a/chromium/net/quic/core/stream_notifier_interface.h b/chromium/net/quic/core/stream_notifier_interface.h
deleted file mode 100644
index 1237e5c52f1..00000000000
--- a/chromium/net/quic/core/stream_notifier_interface.h
+++ /dev/null
@@ -1,33 +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 NET_QUIC_CORE_STREAM_NOTIFIER_INTERFACE_H_
-#define NET_QUIC_CORE_STREAM_NOTIFIER_INTERFACE_H_
-
-#include "net/quic/core/frames/quic_stream_frame.h"
-#include "net/quic/core/quic_time.h"
-
-namespace net {
-
-// Pure virtual class to be notified when a packet containing a stream frame is
-// acked or lost.
-class QUIC_EXPORT_PRIVATE StreamNotifierInterface {
- public:
- virtual ~StreamNotifierInterface() {}
-
- // Called when |frame| is acked.
- virtual void OnStreamFrameAcked(const QuicStreamFrame& frame,
- QuicTime::Delta ack_delay_time) = 0;
-
- // Called when |frame| is retransmitted.
- virtual void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) = 0;
-
- // Called when |frame| is discarded from unacked packet map because stream is
- // reset.
- virtual void OnStreamFrameDiscarded(const QuicStreamFrame& frame) = 0;
-};
-
-} // namespace net
-
-#endif // NET_QUIC_CORE_STREAM_NOTIFIER_INTERFACE_H_
diff --git a/chromium/net/quic/core/tls_client_handshaker.cc b/chromium/net/quic/core/tls_client_handshaker.cc
index c540a25bc69..9f64a86d365 100644
--- a/chromium/net/quic/core/tls_client_handshaker.cc
+++ b/chromium/net/quic/core/tls_client_handshaker.cc
@@ -46,7 +46,8 @@ TlsClientHandshaker::TlsClientHandshaker(QuicCryptoStream* stream,
: TlsHandshaker(stream, session, ssl_ctx),
server_id_(server_id),
proof_verifier_(proof_verifier),
- verify_context_(verify_context) {}
+ verify_context_(verify_context),
+ crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
TlsClientHandshaker::~TlsClientHandshaker() {
if (proof_verify_callback_) {
@@ -54,6 +55,11 @@ TlsClientHandshaker::~TlsClientHandshaker() {
}
}
+// static
+bssl::UniquePtr<SSL_CTX> TlsClientHandshaker::CreateSslCtx() {
+ return TlsHandshaker::CreateSslCtx();
+}
+
bool TlsClientHandshaker::CryptoConnect() {
state_ = STATE_HANDSHAKE_RUNNING;
// Configure certificate verification.
@@ -169,25 +175,41 @@ void TlsClientHandshaker::FinishHandshake() {
QUIC_LOG(INFO) << "Client: handshake finished";
state_ = STATE_HANDSHAKE_COMPLETE;
std::vector<uint8_t> client_secret, server_secret;
- if (!DeriveSecrets(ssl(), &client_secret, &server_secret)) {
+ if (!DeriveSecrets(&client_secret, &server_secret)) {
CloseConnection();
return;
}
- // TODO(nharper): Use |client_secret| and |server_secret| to set the
- // appropriate crypters on the connection, and set |encryption_established_|
- // to true. Whenever encryption keys are set, call
- // session()->connection()->NeuterUnencryptedPackets().
+ QUIC_LOG(INFO) << "Client: setting crypters";
+ QuicEncrypter* initial_encrypter = CreateEncrypter(client_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, initial_encrypter);
+ QuicEncrypter* encrypter = CreateEncrypter(client_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, encrypter);
+
+ QuicDecrypter* initial_decrypter = CreateDecrypter(server_secret);
+ session()->connection()->SetDecrypter(ENCRYPTION_INITIAL, initial_decrypter);
+ QuicDecrypter* decrypter = CreateDecrypter(server_secret);
+ session()->connection()->SetAlternativeDecrypter(ENCRYPTION_FORWARD_SECURE,
+ decrypter, true);
+
+ session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+ session()->NeuterUnencryptedData();
+ encryption_established_ = true;
handshake_confirmed_ = true;
}
// static
+TlsClientHandshaker* TlsClientHandshaker::HandshakerFromSsl(SSL* ssl) {
+ return static_cast<TlsClientHandshaker*>(
+ TlsHandshaker::HandshakerFromSsl(ssl));
+}
+
+// static
enum ssl_verify_result_t TlsClientHandshaker::VerifyCallback(
SSL* ssl,
uint8_t* out_alert) {
- return static_cast<TlsClientHandshaker*>(
- TlsHandshaker::HandshakerFromSsl(ssl))
- ->VerifyCert(out_alert);
+ return HandshakerFromSsl(ssl)->VerifyCert(out_alert);
}
enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) {
diff --git a/chromium/net/quic/core/tls_client_handshaker.h b/chromium/net/quic/core/tls_client_handshaker.h
index 85c362f40d3..39234dd57b2 100644
--- a/chromium/net/quic/core/tls_client_handshaker.h
+++ b/chromium/net/quic/core/tls_client_handshaker.h
@@ -31,6 +31,10 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
~TlsClientHandshaker() override;
+ // Creates and configures an SSL_CTX to be used with a TlsClientHandshaker.
+ // The caller is responsible for ownership of the newly created struct.
+ static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+
// From QuicCryptoClientStream::HandshakerDelegate
bool CryptoConnect() override;
int num_sent_client_hellos() const override;
@@ -85,6 +89,11 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
// Static method to supply to SSL_set_custom_verify.
static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
+ // Takes an SSL* |ssl| and returns a pointer to the TlsClientHandshaker that
+ // it belongs to. This is a specialization of
+ // TlsHandshaker::HandshakerFromSsl.
+ static TlsClientHandshaker* HandshakerFromSsl(SSL* ssl);
+
QuicServerId server_id_;
// Objects used for verifying the server's certificate chain.
diff --git a/chromium/net/quic/core/tls_handshaker.cc b/chromium/net/quic/core/tls_handshaker.cc
index 72380b8ff69..ba15d0cdff5 100644
--- a/chromium/net/quic/core/tls_handshaker.cc
+++ b/chromium/net/quic/core/tls_handshaker.cc
@@ -6,7 +6,9 @@
#include "base/memory/singleton.h"
#include "net/quic/core/quic_crypto_stream.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
namespace net {
@@ -17,29 +19,6 @@ const char kServerLabel[] = "EXPORTER-QUIC server 1-RTT Secret";
} // namespace
-// static
-bool TlsHandshaker::DeriveSecrets(SSL* ssl,
- std::vector<uint8_t>* client_secret_out,
- std::vector<uint8_t>* server_secret_out) {
- const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
- if (cipher == nullptr) {
- return false;
- }
- const EVP_MD* prf = EVP_get_digestbynid(SSL_CIPHER_get_prf_nid(cipher));
- if (prf == nullptr) {
- return false;
- }
- size_t hash_len = EVP_MD_size(prf);
- client_secret_out->resize(hash_len);
- server_secret_out->resize(hash_len);
- return SSL_export_keying_material(ssl, client_secret_out->data(), hash_len,
- kClientLabel, arraysize(kClientLabel),
- nullptr, 0, 0) &&
- SSL_export_keying_material(ssl, server_secret_out->data(), hash_len,
- kServerLabel, arraysize(kServerLabel),
- nullptr, 0, 0);
-}
-
namespace {
class SslIndexSingleton {
@@ -72,6 +51,66 @@ TlsHandshaker* TlsHandshaker::HandshakerFromSsl(const SSL* ssl) {
ssl, SslIndexSingleton::GetInstance()->HandshakerIndex()));
}
+const EVP_MD* TlsHandshaker::Prf() {
+ return EVP_get_digestbynid(
+ SSL_CIPHER_get_prf_nid(SSL_get_current_cipher(ssl())));
+}
+
+bool TlsHandshaker::DeriveSecrets(std::vector<uint8_t>* client_secret_out,
+ std::vector<uint8_t>* server_secret_out) {
+ size_t hash_len = EVP_MD_size(Prf());
+ client_secret_out->resize(hash_len);
+ server_secret_out->resize(hash_len);
+ return (SSL_export_keying_material(
+ ssl(), client_secret_out->data(), hash_len, kClientLabel,
+ QUIC_ARRAYSIZE(kClientLabel) - 1, nullptr, 0, 0) == 1) &&
+ (SSL_export_keying_material(
+ ssl(), server_secret_out->data(), hash_len, kServerLabel,
+ QUIC_ARRAYSIZE(kServerLabel) - 1, nullptr, 0, 0) == 1);
+}
+
+namespace {
+
+template <class QuicCrypter>
+void SetKeyAndIV(const EVP_MD* prf,
+ const std::vector<uint8_t>& pp_secret,
+ QuicCrypter* crypter) {
+ std::vector<uint8_t> key = CryptoUtils::HkdfExpandLabel(
+ prf, pp_secret, "key", crypter->GetKeySize());
+ std::vector<uint8_t> iv =
+ CryptoUtils::HkdfExpandLabel(prf, pp_secret, "iv", crypter->GetIVSize());
+ crypter->SetKey(
+ QuicStringPiece(reinterpret_cast<char*>(key.data()), key.size()));
+ crypter->SetIV(
+ QuicStringPiece(reinterpret_cast<char*>(iv.data()), iv.size()));
+}
+
+} // namespace
+
+QuicEncrypter* TlsHandshaker::CreateEncrypter(
+ const std::vector<uint8_t>& pp_secret) {
+ QuicEncrypter* encrypter = QuicEncrypter::CreateFromCipherSuite(
+ SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
+ SetKeyAndIV(Prf(), pp_secret, encrypter);
+ return encrypter;
+}
+
+QuicDecrypter* TlsHandshaker::CreateDecrypter(
+ const std::vector<uint8_t>& pp_secret) {
+ QuicDecrypter* decrypter = QuicDecrypter::CreateFromCipherSuite(
+ SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
+ SetKeyAndIV(Prf(), pp_secret, decrypter);
+ return decrypter;
+}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsHandshaker::CreateSslCtx() {
+ bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_with_buffers_method()));
+ SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+ SSL_CTX_set_max_proto_version(ssl_ctx.get(), TLS1_3_VERSION);
+ return ssl_ctx;
+}
+
TlsHandshaker::TlsHandshaker(QuicCryptoStream* stream,
QuicSession* session,
SSL_CTX* ssl_ctx)
diff --git a/chromium/net/quic/core/tls_handshaker.h b/chromium/net/quic/core/tls_handshaker.h
index bdef510788d..c542be36aff 100644
--- a/chromium/net/quic/core/tls_handshaker.h
+++ b/chromium/net/quic/core/tls_handshaker.h
@@ -6,6 +6,8 @@
#define NET_QUIC_CORE_TLS_HANDSHAKER_H_
#include "net/quic/core/crypto/crypto_handshake.h"
+#include "net/quic/core/crypto/quic_decrypter.h"
+#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/crypto/quic_tls_adapter.h"
#include "net/quic/platform/api/quic_export.h"
#include "third_party/boringssl/src/include/openssl/base.h"
@@ -29,14 +31,6 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public QuicTlsAdapter::Visitor {
~TlsHandshaker() override;
- // Computes the 1-RTT secrets client_pp_secret_0 and server_pp_secret_0 from
- // which the packet protection keys are derived, as defined in
- // draft-ietf-quic-tls section 5.2.2. Returns true on success and false if
- // |ssl| is not in a state to export secrets.
- static bool DeriveSecrets(SSL* ssl,
- std::vector<uint8_t>* client_secret_out,
- std::vector<uint8_t>* server_secret_out);
-
// From QuicTlsAdapter::Visitor
void OnDataAvailableForBIO() override;
void OnDataReceivedFromBIO(const QuicStringPiece& data) override;
@@ -51,12 +45,29 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public QuicTlsAdapter::Visitor {
protected:
virtual void AdvanceHandshake() = 0;
+ // Creates an SSL_CTX and configures it with the options that are appropriate
+ // for both client and server. The caller is responsible for ownership of the
+ // newly created struct.
+ static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+
// From a given SSL* |ssl|, returns a pointer to the TlsHandshaker that it
// belongs to. This is a helper method for implementing callbacks set on an
// SSL, as it allows the callback function to find the TlsHandshaker instance
// and call an instance method.
static TlsHandshaker* HandshakerFromSsl(const SSL* ssl);
+ // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
+ const EVP_MD* Prf();
+
+ // Computes the 1-RTT secrets client_pp_secret_0 and server_pp_secret_0 from
+ // which the packet protection keys are derived, as defined in
+ // draft-ietf-quic-tls section 5.2.2.
+ bool DeriveSecrets(std::vector<uint8_t>* client_secret_out,
+ std::vector<uint8_t>* server_secret_out);
+
+ QuicEncrypter* CreateEncrypter(const std::vector<uint8_t>& pp_secret);
+ QuicDecrypter* CreateDecrypter(const std::vector<uint8_t>& pp_secret);
+
SSL* ssl() { return ssl_.get(); }
QuicCryptoStream* stream() { return stream_; }
QuicSession* session() { return session_; }
diff --git a/chromium/net/quic/core/tls_handshaker_test.cc b/chromium/net/quic/core/tls_handshaker_test.cc
index d0f90b164d9..08919bd504d 100644
--- a/chromium/net/quic/core/tls_handshaker_test.cc
+++ b/chromium/net/quic/core/tls_handshaker_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/fake_proof_source.h"
@@ -178,17 +179,14 @@ class TestQuicCryptoClientStream : public TestQuicCryptoStream {
explicit TestQuicCryptoClientStream(QuicSession* session)
: TestQuicCryptoStream(session),
proof_verifier_(new FakeProofVerifier),
- ssl_ctx_(SSL_CTX_new(TLS_with_buffers_method())),
+ ssl_ctx_(TlsClientHandshaker::CreateSslCtx()),
handshaker_(new TlsClientHandshaker(
this,
session,
QuicServerId("test.example.com", 443),
proof_verifier_.get(),
ssl_ctx_.get(),
- crypto_test_utils::ProofVerifyContextForTesting())) {
- SSL_CTX_set_min_proto_version(ssl_ctx_.get(), TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(ssl_ctx_.get(), TLS1_3_VERSION);
- }
+ crypto_test_utils::ProofVerifyContextForTesting())) {}
~TestQuicCryptoClientStream() override = default;
@@ -212,16 +210,11 @@ class TestQuicCryptoServerStream : public TestQuicCryptoStream {
FakeProofSource* proof_source)
: TestQuicCryptoStream(session),
proof_source_(proof_source),
- ssl_ctx_(SSL_CTX_new(TLS_with_buffers_method())),
+ ssl_ctx_(TlsServerHandshaker::CreateSslCtx()),
handshaker_(new TlsServerHandshaker(this,
session,
ssl_ctx_.get(),
- proof_source_)) {
- SSL_CTX_set_min_proto_version(ssl_ctx_.get(), TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(ssl_ctx_.get(), TLS1_3_VERSION);
- SSL_CTX_set_tlsext_servername_callback(
- ssl_ctx_.get(), TlsServerHandshaker::SelectCertificateCallback);
- }
+ proof_source_)) {}
~TestQuicCryptoServerStream() override = default;
@@ -286,10 +279,10 @@ TEST_F(TlsHandshakerTest, CryptoHandshake) {
client_stream_.CryptoConnect();
MoveStreamFrames(&client_stream_, server_stream_.get());
- // TODO(nharper): Once encryption keys are set, check that
- // encryption_established() is true on the streams.
EXPECT_TRUE(client_stream_.handshake_confirmed());
+ EXPECT_TRUE(client_stream_.encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
+ EXPECT_TRUE(server_stream_->encryption_established());
}
TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
@@ -309,10 +302,10 @@ TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
MoveStreamFrames(&client_stream_, server_stream_.get());
- // TODO(nharper): Once encryption keys are set, check that
- // encryption_established() is true on the streams.
EXPECT_TRUE(client_stream_.handshake_confirmed());
+ EXPECT_TRUE(client_stream_.encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
+ EXPECT_TRUE(server_stream_->encryption_established());
}
TEST_F(TlsHandshakerTest, CancelPendingProofSource) {
@@ -350,10 +343,10 @@ TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofVerifier) {
MoveStreamFrames(&client_stream_, server_stream_.get());
- // TODO(nharper): Once encryption keys are set, check that
- // encryption_established() is true on the streams.
EXPECT_TRUE(client_stream_.handshake_confirmed());
+ EXPECT_TRUE(client_stream_.encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
+ EXPECT_TRUE(server_stream_->encryption_established());
}
TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsAlert) {
@@ -373,7 +366,7 @@ TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsAlert) {
};
QuicStreamFrame alert(kCryptoStreamId, false,
client_stream_.stream_bytes_read(),
- QuicStringPiece(alert_msg, arraysize(alert_msg)));
+ QuicStringPiece(alert_msg, QUIC_ARRAYSIZE(alert_msg)));
client_stream_.OnStreamFrame(alert);
EXPECT_FALSE(client_stream_.handshake_confirmed());
@@ -394,7 +387,7 @@ TEST_F(TlsHandshakerTest, ServerConnectionClosedOnTlsAlert) {
};
QuicStreamFrame alert(kCryptoStreamId, false,
server_stream_->stream_bytes_read(),
- QuicStringPiece(alert_msg, arraysize(alert_msg)));
+ QuicStringPiece(alert_msg, QUIC_ARRAYSIZE(alert_msg)));
server_stream_->OnStreamFrame(alert);
EXPECT_FALSE(server_stream_->handshake_confirmed());
diff --git a/chromium/net/quic/core/tls_server_handshaker.cc b/chromium/net/quic/core/tls_server_handshaker.cc
index 0e7c491a9d0..31734e0e852 100644
--- a/chromium/net/quic/core/tls_server_handshaker.cc
+++ b/chromium/net/quic/core/tls_server_handshaker.cc
@@ -45,11 +45,21 @@ const SSL_PRIVATE_KEY_METHOD TlsServerHandshaker::kPrivateKeyMethod{
&TlsServerHandshaker::PrivateKeyComplete,
};
+// static
+bssl::UniquePtr<SSL_CTX> TlsServerHandshaker::CreateSslCtx() {
+ bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsHandshaker::CreateSslCtx();
+ SSL_CTX_set_tlsext_servername_callback(
+ ssl_ctx.get(), TlsServerHandshaker::SelectCertificateCallback);
+ return ssl_ctx;
+}
+
TlsServerHandshaker::TlsServerHandshaker(QuicCryptoStream* stream,
QuicSession* session,
SSL_CTX* ssl_ctx,
ProofSource* proof_source)
- : TlsHandshaker(stream, session, ssl_ctx), proof_source_(proof_source) {
+ : TlsHandshaker(stream, session, ssl_ctx),
+ proof_source_(proof_source),
+ crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {
// Set callback to provide SNI.
// SSL_CTX_set_tlsext_servername_callback(ssl_ctx, SelectCertificateCallback);
@@ -171,6 +181,7 @@ void TlsServerHandshaker::AdvanceHandshake() {
if (should_close) {
QUIC_LOG(WARNING) << "SSL_do_handshake failed; SSL_get_error returns "
<< ssl_error << ", state_ = " << state_;
+ ERR_print_errors_fp(stderr);
CloseConnection();
}
}
@@ -188,14 +199,27 @@ void TlsServerHandshaker::FinishHandshake() {
QUIC_LOG(INFO) << "Server: handshake finished";
state_ = STATE_HANDSHAKE_COMPLETE;
std::vector<uint8_t> client_secret, server_secret;
- if (!DeriveSecrets(ssl(), &client_secret, &server_secret)) {
+ if (!DeriveSecrets(&client_secret, &server_secret)) {
CloseConnection();
return;
}
- // TODO(nharper): Use |client_secret| and |server_secret| to set the
- // appropriate crypters on the connection, and set |encryption_established_|
- // to true. Also call session()->connection()->NeuterUnencryptedPackets().
+ QUIC_LOG(INFO) << "Server: setting crypters";
+ QuicEncrypter* initial_encrypter = CreateEncrypter(server_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, initial_encrypter);
+ QuicEncrypter* encrypter = CreateEncrypter(server_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, encrypter);
+
+ QuicDecrypter* initial_decrypter = CreateDecrypter(client_secret);
+ session()->connection()->SetDecrypter(ENCRYPTION_INITIAL, initial_decrypter);
+ QuicDecrypter* decrypter = CreateDecrypter(client_secret);
+ session()->connection()->SetAlternativeDecrypter(ENCRYPTION_FORWARD_SECURE,
+ decrypter, true);
+
+ session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+ session()->NeuterUnencryptedData();
+ encryption_established_ = true;
handshake_confirmed_ = true;
}
diff --git a/chromium/net/quic/core/tls_server_handshaker.h b/chromium/net/quic/core/tls_server_handshaker.h
index f07dcf47e83..382d7bb1ec2 100644
--- a/chromium/net/quic/core/tls_server_handshaker.h
+++ b/chromium/net/quic/core/tls_server_handshaker.h
@@ -6,6 +6,7 @@
#define NET_QUIC_CORE_TLS_SERVER_HANDSHAKER_H_
#include "net/quic/core/crypto/quic_tls_adapter.h"
+#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/core/quic_crypto_server_stream.h"
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/tls_handshaker.h"
@@ -28,6 +29,10 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
~TlsServerHandshaker() override;
+ // Creates and configures an SSL_CTX to be used with a TlsServerHandshaker.
+ // The caller is responsible for ownership of the newly created struct.
+ static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
+
// From QuicCryptoServerStream::HandshakerDelegate
void CancelOutstandingCallbacks() override;
bool GetBase64SHA256ClientChannelID(std::string* output) const override;
diff --git a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
index 4dae7e3f2c5..aea455138ab 100644
--- a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
+++ b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
@@ -130,7 +130,11 @@ const char* QuicHttpDecoderAdapter::StateToString(int state) {
return "UNKNOWN_STATE";
}
-QuicHttpDecoderAdapter::QuicHttpDecoderAdapter() {
+QuicHttpDecoderAdapter::QuicHttpDecoderAdapter()
+ : QuicHttpDecoderAdapter(false) {}
+
+QuicHttpDecoderAdapter::QuicHttpDecoderAdapter(bool h2_on_stream_pad_length)
+ : h2_on_stream_pad_length_(h2_on_stream_pad_length) {
DVLOG(1) << "QuicHttpDecoderAdapter ctor";
ResetInternal();
}
@@ -401,10 +405,13 @@ void QuicHttpDecoderAdapter::OnContinuationEnd() {
void QuicHttpDecoderAdapter::OnPadLength(size_t trailing_length) {
DVLOG(1) << "OnPadLength: " << trailing_length;
opt_pad_length_ = trailing_length;
+ DCHECK_LT(trailing_length, 256u);
if (frame_header_.type == QuicHttpFrameType::DATA) {
- visitor()->OnStreamPadding(stream_id(), 1);
- } else if (frame_header_.type == QuicHttpFrameType::HEADERS) {
- CHECK_LT(trailing_length, 256u);
+ if (h2_on_stream_pad_length_) {
+ visitor()->OnStreamPadLength(stream_id(), trailing_length);
+ } else {
+ visitor()->OnStreamPadding(stream_id(), 1);
+ }
}
}
diff --git a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.h b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.h
index aa96f34a634..42a05166b57 100644
--- a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.h
+++ b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.h
@@ -54,6 +54,7 @@ class SPDY_EXPORT_PRIVATE QuicHttpDecoderAdapter
static const char* StateToString(int state);
QuicHttpDecoderAdapter();
+ explicit QuicHttpDecoderAdapter(bool h2_on_stream_pad_length);
~QuicHttpDecoderAdapter() override;
// Set callbacks to be called from the framer. A visitor must be set, or
@@ -290,6 +291,9 @@ class SPDY_EXPORT_PRIVATE QuicHttpDecoderAdapter
bool handling_extension_payload_ = false;
bool process_single_input_frame_ = false;
+
+ // Flag value latched at construction.
+ const bool h2_on_stream_pad_length_ : 1;
};
} // namespace net
diff --git a/chromium/net/quic/platform/api/quic_aligned.h b/chromium/net/quic/platform/api/quic_aligned.h
index 7e5d9357a67..202c2197fd6 100644
--- a/chromium/net/quic/platform/api/quic_aligned.h
+++ b/chromium/net/quic/platform/api/quic_aligned.h
@@ -10,5 +10,6 @@
#define QUIC_ALIGN_OF QUIC_ALIGN_OF_IMPL
#define QUIC_ALIGNED(X) QUIC_ALIGNED_IMPL(X)
#define QUIC_CACHELINE_ALIGNED QUIC_CACHELINE_ALIGNED_IMPL
+#define QUIC_CACHELINE_SIZE QUIC_CACHELINE_SIZE_IMPL
#endif // NET_QUIC_PLATFORM_API_QUIC_ALIGNED_H_
diff --git a/chromium/net/quic/platform/api/quic_arraysize.h b/chromium/net/quic/platform/api/quic_arraysize.h
new file mode 100644
index 00000000000..effd46fc180
--- /dev/null
+++ b/chromium/net/quic/platform/api/quic_arraysize.h
@@ -0,0 +1,12 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_ARRAYSIZE_H_
+#define NET_QUIC_PLATFORM_API_QUIC_ARRAYSIZE_H_
+
+#include "net/quic/platform/impl/quic_arraysize_impl.h"
+
+#define QUIC_ARRAYSIZE(array) QUIC_ARRAYSIZE_IMPL(array)
+
+#endif // NET_QUIC_PLATFORM_API_QUIC_ARRAYSIZE_H_
diff --git a/chromium/net/quic/platform/api/quic_bug_tracker.h b/chromium/net/quic/platform/api/quic_bug_tracker.h
index 1db197003c3..202d0e955d8 100644
--- a/chromium/net/quic/platform/api/quic_bug_tracker.h
+++ b/chromium/net/quic/platform/api/quic_bug_tracker.h
@@ -8,5 +8,7 @@
#define QUIC_BUG QUIC_BUG_IMPL
#define QUIC_BUG_IF QUIC_BUG_IF_IMPL
+#define QUIC_PEER_BUG QUIC_PEER_BUG_IMPL
+#define QUIC_PEER_BUG_IF QUIC_PEER_BUG_IF_IMPL
#endif // NET_QUIC_PLATFORM_API_QUIC_BUG_TRACKER_H_ \ No newline at end of file
diff --git a/chromium/net/quic/platform/api/quic_flags.h b/chromium/net/quic/platform/api/quic_flags.h
index 1739e37c275..a832ab78797 100644
--- a/chromium/net/quic/platform/api/quic_flags.h
+++ b/chromium/net/quic/platform/api/quic_flags.h
@@ -7,6 +7,11 @@
#include "net/quic/platform/impl/quic_flags_impl.h"
+#define GetQuicReloadableFlag(flag) GetQuicReloadableFlagImpl(flag)
+#define SetQuicReloadableFlag(flag, value) \
+ SetQuicReloadableFlagImpl(flag, value)
+#define GetQuicRestartFlag(flag) GetQuicRestartFlagImpl(flag)
+#define SetQuicRestartFlag(flag, value) SetQuicRestartFlagImpl(flag, value)
#define GetQuicFlag(flag) GetQuicFlagImpl(flag)
#define SetQuicFlag(flag, value) SetQuicFlagImpl(flag, value)
diff --git a/chromium/net/quic/platform/api/quic_hostname_utils.cc b/chromium/net/quic/platform/api/quic_hostname_utils.cc
index 2f5e65dd96c..c7bbf27d1da 100644
--- a/chromium/net/quic/platform/api/quic_hostname_utils.cc
+++ b/chromium/net/quic/platform/api/quic_hostname_utils.cc
@@ -18,10 +18,4 @@ char* QuicHostnameUtils::NormalizeHostname(char* hostname) {
return QuicHostnameUtilsImpl::NormalizeHostname(hostname);
}
-// static
-void QuicHostnameUtils::StringToQuicServerId(const string& str,
- QuicServerId* out) {
- QuicHostnameUtilsImpl::StringToQuicServerId(str, out);
-}
-
} // namespace net
diff --git a/chromium/net/quic/platform/api/quic_hostname_utils.h b/chromium/net/quic/platform/api/quic_hostname_utils.h
index 9c46d68356c..382d93a2540 100644
--- a/chromium/net/quic/platform/api/quic_hostname_utils.h
+++ b/chromium/net/quic/platform/api/quic_hostname_utils.h
@@ -12,8 +12,6 @@
namespace net {
-class QuicServerId;
-
class QUIC_EXPORT_PRIVATE QuicHostnameUtils {
public:
// Returns true if the sni is valid, false otherwise.
@@ -26,10 +24,6 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtils {
// WARNING: mutates |hostname| in place and returns |hostname|.
static char* NormalizeHostname(char* hostname);
- // Creates a QuicServerId from a string formatted in same manner as
- // QuicServerId::ToString().
- static void StringToQuicServerId(const std::string& str, QuicServerId* out);
-
private:
DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtils);
};
diff --git a/chromium/net/quic/platform/api/quic_hostname_utils_test.cc b/chromium/net/quic/platform/api/quic_hostname_utils_test.cc
index 65bbcb17491..9412d5b93e5 100644
--- a/chromium/net/quic/platform/api/quic_hostname_utils_test.cc
+++ b/chromium/net/quic/platform/api/quic_hostname_utils_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/platform/api/quic_hostname_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_test.h"
using std::string;
@@ -53,7 +54,7 @@ TEST_F(QuicHostnameUtilsTest, NormalizeHostname) {
},
};
- for (size_t i = 0; i < arraysize(tests); ++i) {
+ for (size_t i = 0; i < QUIC_ARRAYSIZE(tests); ++i) {
char buf[256];
snprintf(buf, sizeof(buf), "%s", tests[i].input);
EXPECT_EQ(string(tests[i].expected),
diff --git a/chromium/net/quic/platform/api/quic_mem_slice_span_test.cc b/chromium/net/quic/platform/api/quic_mem_slice_span_test.cc
index 0ad1d299abc..6e37f08409e 100644
--- a/chromium/net/quic/platform/api/quic_mem_slice_span_test.cc
+++ b/chromium/net/quic/platform/api/quic_mem_slice_span_test.cc
@@ -29,8 +29,7 @@ class QuicMemSliceSpanImplTest : public QuicTest {
TEST_F(QuicMemSliceSpanImplTest, SaveDataInSendBuffer) {
SimpleBufferAllocator allocator;
QuicStreamSendBuffer send_buffer(
- &allocator,
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2);
+ &allocator, GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2));
QuicTestMemSliceVector vector(buffers_);
EXPECT_EQ(10 * 1024u, vector.span().SaveMemSlicesInSendBuffer(&send_buffer));
@@ -40,8 +39,7 @@ TEST_F(QuicMemSliceSpanImplTest, SaveDataInSendBuffer) {
TEST_F(QuicMemSliceSpanImplTest, SaveEmptyMemSliceInSendBuffer) {
SimpleBufferAllocator allocator;
QuicStreamSendBuffer send_buffer(
- &allocator,
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2);
+ &allocator, GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2));
buffers_.push_back(std::make_pair(nullptr, 0));
QuicTestMemSliceVector vector(buffers_);
EXPECT_EQ(10 * 1024u, vector.span().SaveMemSlicesInSendBuffer(&send_buffer));
diff --git a/chromium/net/quic/platform/api/quic_prefetch.h b/chromium/net/quic/platform/api/quic_prefetch.h
new file mode 100644
index 00000000000..edc73a63d4c
--- /dev/null
+++ b/chromium/net/quic/platform/api/quic_prefetch.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_PREFETCH_H_
+#define NET_QUIC_PLATFORM_API_QUIC_PREFETCH_H_
+
+#include "net/quic/platform/impl/quic_prefetch_impl.h"
+
+namespace net {
+
+// Move data into the cache before it is read, or "prefetch" it.
+//
+// The value of `addr` is the address of the memory to prefetch. If
+// the target and compiler support it, data prefetch instructions are
+// generated. If the prefetch is done some time before the memory is
+// read, it may be in the cache by the time the read occurs.
+//
+// The function names specify the temporal locality heuristic applied,
+// using the names of Intel prefetch instructions:
+//
+// T0 - high degree of temporal locality; data should be left in as
+// many levels of the cache possible
+// T1 - moderate degree of temporal locality
+// T2 - low degree of temporal locality
+// Nta - no temporal locality, data need not be left in the cache
+// after the read
+//
+// Incorrect or gratuitous use of these functions can degrade
+// performance, so use them only when representative benchmarks show
+// an improvement.
+
+inline void QuicPrefetchT0(const void* addr) {
+ return QuicPrefetchT0Impl(addr);
+}
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_API_QUIC_PREFETCH_H_
diff --git a/chromium/net/quic/platform/api/quic_reference_counted.h b/chromium/net/quic/platform/api/quic_reference_counted.h
index 296fe483e1a..16e7936ac1f 100644
--- a/chromium/net/quic/platform/api/quic_reference_counted.h
+++ b/chromium/net/quic/platform/api/quic_reference_counted.h
@@ -114,8 +114,8 @@ class QuicReferenceCountedPointer {
explicit operator bool() const { return static_cast<bool>(impl_); }
// Assignment operator on raw pointer. Drops a reference to current pointee,
- // if any and replaces it with |p|. This garantee the reference count of *p is
- // 1. This should only be used when a new object is created, calling this
+ // if any, and replaces it with |p|. This guarantees the reference count of *p
+ // is 1. This should only be used when a new object is created, calling this
// on a already existent object is undefined behavior.
QuicReferenceCountedPointer<T>& operator=(T* p) {
impl_ = p;
diff --git a/chromium/net/quic/platform/impl/quic_aligned_impl.h b/chromium/net/quic/platform/impl/quic_aligned_impl.h
index 3ca83db3c9b..f38835e4b35 100644
--- a/chromium/net/quic/platform/impl/quic_aligned_impl.h
+++ b/chromium/net/quic/platform/impl/quic_aligned_impl.h
@@ -17,6 +17,7 @@
// TODO(rtenneti): Change the default 64 alignas value (used the default
// value from ABSL_CACHELINE_SIZE).
-#define QUIC_CACHELINE_ALIGNED_IMPL ALIGNAS(64)
+#define QUIC_CACHELINE_SIZE_IMPL (64)
+#define QUIC_CACHELINE_ALIGNED_IMPL ALIGNAS(QUIC_CACHELINE_SIZE)
#endif // NET_QUIC_PLATFORM_IMPL_QUIC_ALIGNED_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_arraysize_impl.h b/chromium/net/quic/platform/impl/quic_arraysize_impl.h
new file mode 100644
index 00000000000..0dd9cb3de3c
--- /dev/null
+++ b/chromium/net/quic/platform/impl/quic_arraysize_impl.h
@@ -0,0 +1,10 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_ARRAYSIZE_IMPL_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_ARRAYSIZE_IMPL_H_
+
+#define QUIC_ARRAYSIZE_IMPL(array) arraysize(array)
+
+#endif // NET_QUIC_PLATFORM_IMPL_QUIC_ARRAYSIZE_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h b/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h
index a0b0efd1acf..d0afd5e4722 100644
--- a/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h
+++ b/chromium/net/quic/platform/impl/quic_bug_tracker_impl.h
@@ -8,5 +8,7 @@
#define QUIC_BUG_IMPL QUIC_LOG(DFATAL)
#define QUIC_BUG_IF_IMPL(condition) QUIC_LOG_IF(DFATAL, condition)
+#define QUIC_PEER_BUG_IMPL QUIC_LOG(DFATAL)
+#define QUIC_PEER_BUG_IF_IMPL(condition) QUIC_LOG_IF(DFATAL, condition)
#endif // NET_QUIC_PLATFORM_IMPL_QUIC_BUG_TRACKER_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_flags_impl.h b/chromium/net/quic/platform/impl/quic_flags_impl.h
index 22885431b25..666cea57419 100644
--- a/chromium/net/quic/platform/impl/quic_flags_impl.h
+++ b/chromium/net/quic/platform/impl/quic_flags_impl.h
@@ -61,5 +61,18 @@ inline void SetQuicFlagImpl(std::string* f, const std::string& v) {
*f = v;
}
+// ------------------------------------------------------------------------
+// // QUIC feature flags implementation.
+// // ------------------------------------------------------------------------
+#define RELOADABLE_FLAG(flag) FLAGS_quic_reloadable_flag_##flag
+#define RESTART_FLAG(flag) FLAGS_quic_restart_flag_##flag
+
+#define GetQuicReloadableFlagImpl(flag) GetQuicFlag(RELOADABLE_FLAG(flag))
+#define SetQuicReloadableFlagImpl(flag, value) \
+ SetQuicFlag(&RELOADABLE_FLAG(flag), value)
+#define GetQuicRestartFlagImpl(flag) GetQuicFlag(RESTART_FLAG(flag))
+#define SetQuicRestartFlagImpl(flag, value) \
+ SetQuicFlag(&RESTART_FLAG(flag), value)
+
} // namespace net
#endif // NET_QUIC_PLATFORM_IMPL_QUIC_FLAGS_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc
index 040a724ce4f..750b3d4674a 100644
--- a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc
+++ b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.cc
@@ -48,17 +48,4 @@ char* QuicHostnameUtilsImpl::NormalizeHostname(char* hostname) {
return hostname;
}
-// static
-void QuicHostnameUtilsImpl::StringToQuicServerId(const string& str,
- QuicServerId* out) {
- GURL url(str);
- if (!url.is_valid()) {
- *out = QuicServerId();
- return;
- }
- *out = QuicServerId(HostPortPair::FromURL(url), url.path_piece() == "/private"
- ? PRIVACY_MODE_ENABLED
- : PRIVACY_MODE_DISABLED);
-}
-
} // namespace net
diff --git a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h
index 57c67473e00..3883a638d2c 100644
--- a/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h
+++ b/chromium/net/quic/platform/impl/quic_hostname_utils_impl.h
@@ -6,7 +6,6 @@
#define NET_QUIC_PLATFORM_IMPL_QUIC_HOSTNAME_UTILS_IMPL_H_
#include "base/macros.h"
-#include "net/quic/core/quic_server_id.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_string_piece.h"
@@ -24,10 +23,6 @@ class QUIC_EXPORT_PRIVATE QuicHostnameUtilsImpl {
// WARNING: mutates |hostname| in place and returns |hostname|.
static char* NormalizeHostname(char* hostname);
- // Creates a QuicServerId from a string formatted in same manner as
- // QuicServerId::ToString().
- static void StringToQuicServerId(const std::string& str, QuicServerId* out);
-
private:
DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtilsImpl);
};
diff --git a/chromium/net/quic/platform/impl/quic_prefetch_impl.h b/chromium/net/quic/platform/impl/quic_prefetch_impl.h
new file mode 100644
index 00000000000..2f5d1eb943b
--- /dev/null
+++ b/chromium/net/quic/platform/impl/quic_prefetch_impl.h
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_PREFETCH_IMPL_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_PREFETCH_IMPL_H_
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+namespace net {
+
+inline void QuicPrefetchT0Impl(const void* addr) {
+#if defined(__GNUC__)
+ __builtin_prefetch(addr, 0, 3);
+#elif defined(_MSC_VER)
+ _mm_prefetch(reinterpret_cast<const char*>(addr), _MM_HINT_T0);
+#endif
+}
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_IMPL_QUIC_PREFETCH_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_text_utils_impl.h b/chromium/net/quic/platform/impl/quic_text_utils_impl.h
index 40871774d28..05fa6122474 100644
--- a/chromium/net/quic/platform/impl/quic_text_utils_impl.h
+++ b/chromium/net/quic/platform/impl/quic_text_utils_impl.h
@@ -70,7 +70,7 @@ class QuicTextUtilsImpl {
// Returns a new std::string representing |in|.
static std::string Uint64ToString(uint64_t in) {
- return base::Uint64ToString(in);
+ return base::NumberToString(in);
}
// This converts |length| bytes of binary to a 2*|length|-character
diff --git a/chromium/net/quic/quartc/quartc_factory.cc b/chromium/net/quic/quartc/quartc_factory.cc
index b45011d6d9e..3e182fa99e1 100644
--- a/chromium/net/quic/quartc/quartc_factory.cc
+++ b/chromium/net/quic/quartc/quartc_factory.cc
@@ -113,13 +113,14 @@ std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession(
std::unique_ptr<QuicConnection> quic_connection =
CreateQuicConnection(quartc_session_config, perspective);
QuicTagVector copt;
+ copt.push_back(kNSTP);
if (quartc_session_config.congestion_control ==
QuartcCongestionControl::kBBR) {
copt.push_back(kTBBR);
- FLAGS_quic_reloadable_flag_quic_bbr_slower_startup = true;
- FLAGS_quic_reloadable_flag_quic_bbr_fully_drain_queue = true;
- FLAGS_quic_reloadable_flag_quic_bbr_less_probe_rtt = true;
+ // Note: These settings have no effect for Exoblaze builds since
+ // SetQuicReloadableFlag() gets stubbed out.
+ SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true);
for (const auto option : quartc_session_config.bbr_options) {
switch (option) {
case (QuartcBbrOptions::kSlowerStartup):
@@ -176,7 +177,7 @@ std::unique_ptr<QuicConnection> QuartcFactory::CreateQuicConnection(
return std::unique_ptr<QuicConnection>(new QuicConnection(
dummy_id, dummy_address, this, /*QuicConnectionHelperInterface*/
this /*QuicAlarmFactory*/, writer.release(), true /*own the writer*/,
- perspective, AllSupportedTransportVersions()));
+ perspective, AllSupportedVersions()));
}
QuicAlarm* QuartcFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
diff --git a/chromium/net/quic/quartc/quartc_packet_writer.cc b/chromium/net/quic/quartc/quartc_packet_writer.cc
index 73ddbe8439f..70ff00a48c5 100644
--- a/chromium/net/quic/quartc/quartc_packet_writer.cc
+++ b/chromium/net/quic/quartc/quartc_packet_writer.cc
@@ -20,6 +20,7 @@ WriteResult QuartcPacketWriter::WritePacket(
DCHECK(packet_transport_);
int bytes_written = packet_transport_->Write(buffer, buf_len);
if (bytes_written <= 0) {
+ writable_ = false;
return WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK);
}
return WriteResult(WRITE_STATUS_OK, bytes_written);
@@ -30,8 +31,7 @@ bool QuartcPacketWriter::IsWriteBlockedDataBuffered() const {
}
bool QuartcPacketWriter::IsWriteBlocked() const {
- DCHECK(packet_transport_);
- return !packet_transport_->CanWrite();
+ return !writable_;
}
QuicByteCount QuartcPacketWriter::GetMaxPacketSize(
@@ -39,6 +39,8 @@ QuicByteCount QuartcPacketWriter::GetMaxPacketSize(
return max_packet_size_;
}
-void QuartcPacketWriter::SetWritable() {}
+void QuartcPacketWriter::SetWritable() {
+ writable_ = true;
+}
} // namespace net
diff --git a/chromium/net/quic/quartc/quartc_packet_writer.h b/chromium/net/quic/quartc/quartc_packet_writer.h
index ab855eb13cf..d50626c6868 100644
--- a/chromium/net/quic/quartc/quartc_packet_writer.h
+++ b/chromium/net/quic/quartc/quartc_packet_writer.h
@@ -32,8 +32,8 @@ class QUIC_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter {
bool IsWriteBlockedDataBuffered() const override;
// Whether the underneath |transport_| is blocked. If this returns true,
- // outgoing QUIC packets are queued by QuicConnection until
- // Transport::Observer::OnCanWrite() is called.
+ // 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
@@ -42,8 +42,7 @@ class QUIC_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter {
QuicByteCount GetMaxPacketSize(
const QuicSocketAddress& peer_address) const override;
- // This method is not used because the network layer in WebRTC will determine
- // the writing states.
+ // Sets the packet writer to a writable (non-blocked) state.
void SetWritable() override;
private:
@@ -51,6 +50,9 @@ class QUIC_EXPORT_PRIVATE QuartcPacketWriter : public QuicPacketWriter {
QuartcSessionInterface::PacketTransport* 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 net
diff --git a/chromium/net/quic/quartc/quartc_session.cc b/chromium/net/quic/quartc/quartc_session.cc
index a4c74d20ff0..68b0e0a301b 100644
--- a/chromium/net/quic/quartc/quartc_session.cc
+++ b/chromium/net/quic/quartc/quartc_session.cc
@@ -4,6 +4,8 @@
#include "net/quic/quartc/quartc_session.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_ptr_util.h"
using std::string;
@@ -128,8 +130,8 @@ QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection,
// Initialization with default crypto configuration.
if (perspective_ == Perspective::IS_CLIENT) {
std::unique_ptr<ProofVerifier> proof_verifier(new InsecureProofVerifier);
- quic_crypto_client_config_.reset(
- new QuicCryptoClientConfig(std::move(proof_verifier)));
+ quic_crypto_client_config_.reset(new QuicCryptoClientConfig(
+ std::move(proof_verifier), TlsClientHandshaker::CreateSslCtx()));
} else {
std::unique_ptr<ProofSource> proof_source(new DummyProofSource);
// Generate a random source address token secret. For long-running servers
@@ -140,7 +142,8 @@ QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection,
kInputKeyingMaterialLength);
quic_crypto_server_config_.reset(new QuicCryptoServerConfig(
string(source_address_token_secret, kInputKeyingMaterialLength),
- helper_->GetRandomGenerator(), std::move(proof_source)));
+ helper_->GetRandomGenerator(), std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()));
// Provide server with serialized config string to prove ownership.
QuicCryptoServerConfig::ConfigOptions options;
// The |message| is used to handle the return value of AddDefaultConfig
@@ -282,6 +285,7 @@ void QuartcSession::SetDelegate(
}
void QuartcSession::OnTransportCanWrite() {
+ connection()->writer()->SetWritable();
if (HasDataToWrite()) {
connection()->OnCanWrite();
}
diff --git a/chromium/net/quic/quartc/quartc_session_interface.h b/chromium/net/quic/quartc/quartc_session_interface.h
index 536079a88c1..59233839d52 100644
--- a/chromium/net/quic/quartc/quartc_session_interface.h
+++ b/chromium/net/quic/quartc/quartc_session_interface.h
@@ -95,11 +95,6 @@ class QUIC_EXPORT_PRIVATE QuartcSessionInterface {
public:
virtual ~PacketTransport() {}
- // Called by the QuartcPacketWriter to check if the underneath transport is
- // writable. True if packets written are expected to be sent. False if
- // packets will be dropped.
- virtual bool CanWrite() = 0;
-
// 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) = 0;
diff --git a/chromium/net/quic/quartc/quartc_session_test.cc b/chromium/net/quic/quartc/quartc_session_test.cc
index 9e82001309c..549c8ec110b 100644
--- a/chromium/net/quic/quartc/quartc_session_test.cc
+++ b/chromium/net/quic/quartc/quartc_session_test.cc
@@ -7,6 +7,8 @@
#include "net/quic/core/crypto/crypto_server_config_protobuf.h"
#include "net/quic/core/quic_simple_buffer_allocator.h"
#include "net/quic/core/quic_types.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/quartc/quartc_factory.h"
#include "net/quic/quartc/quartc_factory_interface.h"
#include "net/quic/quartc/quartc_packet_writer.h"
@@ -300,8 +302,6 @@ class FakeTransport : public QuartcSessionInterface::PacketTransport {
public:
explicit FakeTransport(FakeTransportChannel* channel) : channel_(channel) {}
- bool CanWrite() override { return true; }
-
int Write(const char* buffer, size_t buf_len) override {
DCHECK(channel_);
return channel_->SendPacket(buffer, buf_len);
@@ -422,6 +422,9 @@ class QuartcSessionTest : public ::testing::Test,
new QuartcPacketWriter(client_transport_.get(), kDefaultMaxPacketSize));
server_writer_.reset(
new QuartcPacketWriter(server_transport_.get(), kDefaultMaxPacketSize));
+
+ client_writer_->SetWritable();
+ server_writer_->SetWritable();
}
// The parameters are used to control whether the handshake will success or
@@ -435,14 +438,16 @@ class QuartcSessionTest : public ::testing::Test,
client_channel_->SetObserver(client_peer_.get());
server_channel_->SetObserver(server_peer_.get());
- client_peer_->SetClientCryptoConfig(
- new QuicCryptoClientConfig(std::unique_ptr<ProofVerifier>(
- new FakeProofVerifier(client_handshake_success))));
+ client_peer_->SetClientCryptoConfig(new QuicCryptoClientConfig(
+ std::unique_ptr<ProofVerifier>(
+ new FakeProofVerifier(client_handshake_success)),
+ TlsClientHandshaker::CreateSslCtx()));
QuicCryptoServerConfig* server_config = new QuicCryptoServerConfig(
"TESTING", QuicRandom::GetInstance(),
std::unique_ptr<FakeProofSource>(
- new FakeProofSource(server_handshake_success)));
+ new FakeProofSource(server_handshake_success)),
+ TlsServerHandshaker::CreateSslCtx());
// Provide server with serialized config string to prove ownership.
QuicCryptoServerConfig::ConfigOptions options;
std::unique_ptr<QuicServerConfigProtobuf> primary_config(
@@ -481,7 +486,7 @@ class QuartcSessionTest : public ::testing::Test,
return std::unique_ptr<QuicConnection>(new QuicConnection(
0, QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/,
alarm_factory_.get(), writer, owns_writer, perspective,
- AllSupportedTransportVersions()));
+ AllSupportedVersions()));
}
// Runs all tasks scheduled in the next 200 ms.
diff --git a/chromium/net/quic/quartc/quartc_stream_test.cc b/chromium/net/quic/quartc/quartc_stream_test.cc
index b065f9a1cc7..408f18d6eb6 100644
--- a/chromium/net/quic/quartc/quartc_stream_test.cc
+++ b/chromium/net/quic/quartc/quartc_stream_test.cc
@@ -168,7 +168,7 @@ class QuartcStreamTest : public ::testing::Test,
connection_.reset(new QuicConnection(
0, QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/,
alarm_factory_.get(), new DummyPacketWriter(), owns_writer, perspective,
- AllSupportedTransportVersions()));
+ AllSupportedVersions()));
session_.reset(
new MockQuicSession(connection_.get(), QuicConfig(), &write_buffer_));
diff --git a/chromium/net/quic/test_tools/crypto_test_utils.cc b/chromium/net/quic/test_tools/crypto_test_utils.cc
index 2115559a7bd..7f43881ccee 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils.cc
@@ -20,6 +20,8 @@
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/quic_server_id.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_clock.h"
#include "net/quic/platform/api/quic_logging.h"
@@ -390,9 +392,9 @@ int HandshakeWithFakeServer(QuicConfig* server_quic_config,
new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER,
client_conn->supported_versions());
- QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
- QuicRandom::GetInstance(),
- ProofSourceForTesting());
+ QuicCryptoServerConfig crypto_config(
+ QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+ ProofSourceForTesting(), TlsServerHandshaker::CreateSslCtx());
QuicCompressedCertsCache compressed_certs_cache(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize);
SetupCryptoServerConfigForTest(server_conn->clock(),
@@ -427,12 +429,22 @@ int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
QuicCryptoServerStream* server,
const QuicServerId& server_id,
const FakeClientOptions& options) {
- PacketSavingConnection* client_conn =
- new PacketSavingConnection(helper, alarm_factory, Perspective::IS_CLIENT);
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ if (options.only_tls_versions) {
+ supported_versions.clear();
+ for (QuicTransportVersion transport_version :
+ AllSupportedTransportVersions()) {
+ supported_versions.push_back(
+ ParsedQuicVersion(PROTOCOL_TLS1_3, transport_version));
+ }
+ }
+ PacketSavingConnection* client_conn = new PacketSavingConnection(
+ helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
// Advance the time, because timers do not like uninitialized times.
client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
- QuicCryptoClientConfig crypto_config(ProofVerifierForTesting());
+ QuicCryptoClientConfig crypto_config(ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx());
AsyncTestChannelIDSource* async_channel_id_source = nullptr;
if (options.channel_id_enabled) {
ChannelIDSource* source = ChannelIDSourceForTesting();
@@ -515,7 +527,7 @@ void CommunicateHandshakeMessagesAndRunCallbacks(
QuicCryptoStream* server,
CallbackSource* callback_source) {
size_t client_i = 0, server_i = 0;
- while (!client->handshake_confirmed()) {
+ while (!client->handshake_confirmed() || !server->handshake_confirmed()) {
ASSERT_GT(client_conn->encrypted_packets_.size(), client_i);
QUIC_LOG(INFO) << "Processing "
<< client_conn->encrypted_packets_.size() - client_i
@@ -897,11 +909,37 @@ ChannelIDSource* ChannelIDSourceForTesting() {
return new TestChannelIDSource();
}
+void MovePacketsForTlsHandshake(PacketSavingConnection* source_conn,
+ size_t* inout_packet_index,
+ QuicCryptoStream* dest_stream,
+ PacketSavingConnection* dest_conn,
+ Perspective dest_perspective) {
+ SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
+ size_t index = *inout_packet_index;
+ for (; index < source_conn->encrypted_packets_.size(); index++) {
+ 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.
+ break;
+ }
+
+ for (const auto& stream_frame : framer.stream_frames()) {
+ dest_conn->OnStreamFrame(*stream_frame);
+ }
+ }
+ *inout_packet_index = index;
+}
+
void MovePackets(PacketSavingConnection* source_conn,
size_t* inout_packet_index,
QuicCryptoStream* dest_stream,
PacketSavingConnection* dest_conn,
Perspective dest_perspective) {
+ if (dest_stream->handshake_protocol() == PROTOCOL_TLS1_3) {
+ MovePacketsForTlsHandshake(source_conn, inout_packet_index, dest_stream,
+ dest_conn, dest_perspective);
+ return;
+ }
SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
CryptoFramer crypto_framer;
CryptoFramerVisitor crypto_visitor;
diff --git a/chromium/net/quic/test_tools/crypto_test_utils.h b/chromium/net/quic/test_tools/crypto_test_utils.h
index 38dc33e7a58..b3baa5c5659 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils.h
+++ b/chromium/net/quic/test_tools/crypto_test_utils.h
@@ -112,6 +112,10 @@ struct FakeClientOptions {
// The Token Binding params that the client supports and will negotiate.
QuicTagVector token_binding_params;
+
+ // If only_tls_versions is set, then the client will only use TLS for the
+ // crypto handshake.
+ bool only_tls_versions = false;
};
// returns: the number of client hellos that the client sent.
diff --git a/chromium/net/quic/test_tools/crypto_test_utils_test.cc b/chromium/net/quic/test_tools/crypto_test_utils_test.cc
index b3fcf55ab2c..053c468200e 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils_test.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils_test.cc
@@ -6,6 +6,7 @@
#include "net/quic/core/crypto/crypto_server_config_protobuf.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/platform/api/quic_text_utils.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -115,7 +116,8 @@ TEST(CryptoTestUtilsTest, TestGenerateFullCHLO) {
MockClock clock;
QuicCryptoServerConfig crypto_config(
QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting());
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx());
QuicSocketAddress server_addr;
QuicSocketAddress client_addr(QuicIpAddress::Loopback4(), 1);
QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config(
diff --git a/chromium/net/quic/test_tools/mock_decrypter.cc b/chromium/net/quic/test_tools/mock_decrypter.cc
index f33eec96d2d..f48ff7b1f68 100644
--- a/chromium/net/quic/test_tools/mock_decrypter.cc
+++ b/chromium/net/quic/test_tools/mock_decrypter.cc
@@ -49,6 +49,14 @@ bool MockDecrypter::DecryptPacket(QuicTransportVersion version,
return true;
}
+size_t MockDecrypter::GetKeySize() const {
+ return 0;
+}
+
+size_t MockDecrypter::GetIVSize() const {
+ return 0;
+}
+
QuicStringPiece MockDecrypter::GetKey() const {
return QuicStringPiece();
}
diff --git a/chromium/net/quic/test_tools/mock_decrypter.h b/chromium/net/quic/test_tools/mock_decrypter.h
index 67449a4b472..6f4a43c79f7 100644
--- a/chromium/net/quic/test_tools/mock_decrypter.h
+++ b/chromium/net/quic/test_tools/mock_decrypter.h
@@ -39,6 +39,8 @@ class MockDecrypter : public QuicDecrypter {
char* output,
size_t* output_length,
size_t max_output_length) override;
+ size_t GetKeySize() const override;
+ size_t GetIVSize() const override;
QuicStringPiece GetKey() const override;
QuicStringPiece GetNoncePrefix() const override;
diff --git a/chromium/net/quic/test_tools/mock_encrypter.cc b/chromium/net/quic/test_tools/mock_encrypter.cc
index 7ebcea38d1d..1d2fe633548 100644
--- a/chromium/net/quic/test_tools/mock_encrypter.cc
+++ b/chromium/net/quic/test_tools/mock_encrypter.cc
@@ -46,6 +46,10 @@ size_t MockEncrypter::GetNoncePrefixSize() const {
return 0;
}
+size_t MockEncrypter::GetIVSize() const {
+ return 0;
+}
+
size_t MockEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
return ciphertext_size;
}
diff --git a/chromium/net/quic/test_tools/mock_encrypter.h b/chromium/net/quic/test_tools/mock_encrypter.h
index 59b8097e1ce..0432ea9a2ee 100644
--- a/chromium/net/quic/test_tools/mock_encrypter.h
+++ b/chromium/net/quic/test_tools/mock_encrypter.h
@@ -37,6 +37,7 @@ class MockEncrypter : public QuicEncrypter {
size_t max_output_length) override;
size_t GetKeySize() const override;
size_t GetNoncePrefixSize() const override;
+ size_t GetIVSize() const override;
size_t GetMaxPlaintextSize(size_t ciphertext_size) const override;
size_t GetCiphertextSize(size_t plaintext_size) const override;
QuicStringPiece GetKey() const override;
diff --git a/chromium/net/quic/test_tools/quic_spdy_session_peer.cc b/chromium/net/quic/test_tools/quic_spdy_session_peer.cc
index 06350f8c3ff..acd51f2b72e 100644
--- a/chromium/net/quic/test_tools/quic_spdy_session_peer.cc
+++ b/chromium/net/quic/test_tools/quic_spdy_session_peer.cc
@@ -55,8 +55,11 @@ size_t QuicSpdySessionPeer::WriteHeadersImpl(
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
+ QuicStreamId parent_stream_id,
+ bool exclusive,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
return session->WriteHeadersImpl(id, std::move(headers), fin, priority,
+ parent_stream_id, exclusive,
std::move(ack_listener));
}
diff --git a/chromium/net/quic/test_tools/quic_spdy_session_peer.h b/chromium/net/quic/test_tools/quic_spdy_session_peer.h
index ea844e6e30d..fa1faffea8a 100644
--- a/chromium/net/quic/test_tools/quic_spdy_session_peer.h
+++ b/chromium/net/quic/test_tools/quic_spdy_session_peer.h
@@ -39,6 +39,8 @@ class QuicSpdySessionPeer {
SpdyHeaderBlock headers,
bool fin,
SpdyPriority priority,
+ QuicStreamId parent_stream_id,
+ bool exclusive,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
// Helper functions for stream ids, to allow test logic to abstract
// over the HTTP stream numbering scheme (i.e. whether one or
diff --git a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
index 7e6dbc43aa5..5ca41adbfd2 100644
--- a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
@@ -15,6 +15,14 @@ void QuicStreamSendBufferPeer::SetStreamOffset(
send_buffer->stream_offset_ = stream_offset;
}
+// static
+const BufferedSlice* QuicStreamSendBufferPeer::CurrentWriteSlice(
+ QuicStreamSendBuffer* send_buffer) {
+ if (send_buffer->write_index_ == -1) {
+ return nullptr;
+ }
+ return &send_buffer->buffered_slices_[send_buffer->write_index_];
+}
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
index 2b1ec7720b9..6b8b115e718 100644
--- a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
+++ b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
@@ -15,6 +15,9 @@ class QuicStreamSendBufferPeer {
public:
static void SetStreamOffset(QuicStreamSendBuffer* send_buffer,
QuicStreamOffset stream_offset);
+
+ static const BufferedSlice* CurrentWriteSlice(
+ QuicStreamSendBuffer* send_buffer);
};
} // namespace test
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
index da5754a68f2..c7aa8e969f4 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
@@ -64,16 +64,16 @@ bool QuicStreamSequencerBufferPeer::CheckInitialState() {
bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() {
QuicStreamOffset data_span =
- buffer_->gaps_.back().begin_offset - buffer_->total_bytes_read_;
+ buffer_->NextExpectedByte() - buffer_->total_bytes_read_;
bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
data_span >= buffer_->num_bytes_buffered_;
if (!capacity_sane) {
QUIC_LOG(ERROR) << "data span is larger than capacity.";
QUIC_LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
- << " last byte: " << buffer_->gaps_.back().begin_offset;
+ << " last byte: " << buffer_->NextExpectedByte();
}
bool total_read_sane =
- buffer_->gaps_.front().begin_offset >= buffer_->total_bytes_read_;
+ buffer_->FirstMissingByte() >= buffer_->total_bytes_read_;
if (!total_read_sane) {
QUIC_LOG(ERROR) << "read across 1st gap.";
}
@@ -106,7 +106,24 @@ BufferBlock* QuicStreamSequencerBufferPeer::GetBlock(size_t index) {
}
int QuicStreamSequencerBufferPeer::GapSize() {
- return buffer_->gaps_.size();
+ if (!buffer_->allow_overlapping_data_) {
+ return buffer_->gaps_.size();
+ }
+ if (buffer_->bytes_received_.Empty()) {
+ return 1;
+ }
+ int gap_size = buffer_->bytes_received_.Size() + 1;
+ if (buffer_->bytes_received_.Empty()) {
+ return gap_size;
+ }
+ if (buffer_->bytes_received_.begin()->min() == 0) {
+ --gap_size;
+ }
+ if (buffer_->bytes_received_.rbegin()->max() ==
+ std::numeric_limits<uint64_t>::max()) {
+ --gap_size;
+ }
+ return gap_size;
}
std::list<Gap> QuicStreamSequencerBufferPeer::GetGaps() {
@@ -135,6 +152,11 @@ void QuicStreamSequencerBufferPeer::set_gaps(const std::list<Gap>& gaps) {
buffer_->gaps_ = gaps;
}
+void QuicStreamSequencerBufferPeer::AddBytesReceived(QuicStreamOffset offset,
+ QuicByteCount length) {
+ buffer_->bytes_received_.Add(offset, offset + length);
+}
+
bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
return buffer_->blocks_ != nullptr;
}
@@ -142,5 +164,15 @@ bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
size_t QuicStreamSequencerBufferPeer::block_count() {
return buffer_->blocks_count_;
}
+
+const QuicIntervalSet<QuicStreamOffset>&
+QuicStreamSequencerBufferPeer::bytes_received() {
+ return buffer_->bytes_received_;
+}
+
+bool QuicStreamSequencerBufferPeer::allow_overlapping_data() {
+ return buffer_->allow_overlapping_data_;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h
index 1255d3a723b..655e78b8cda 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_buffer_peer.h
@@ -34,6 +34,8 @@ class QuicStreamSequencerBufferPeer {
QuicStreamSequencerBuffer::BufferBlock* GetBlock(size_t index);
+ // TODO(fayang): Rename this to IntervalSize when deprecating
+ // quic_reloadable_flag_quic_allow_receiving_overlapping_data.
int GapSize();
std::list<QuicStreamSequencerBuffer::Gap> GetGaps();
@@ -49,10 +51,16 @@ class QuicStreamSequencerBufferPeer {
void set_gaps(const std::list<QuicStreamSequencerBuffer::Gap>& gaps);
+ void AddBytesReceived(QuicStreamOffset offset, QuicByteCount length);
+
bool IsBufferAllocated();
size_t block_count();
+ const QuicIntervalSet<QuicStreamOffset>& bytes_received();
+
+ bool allow_overlapping_data();
+
private:
QuicStreamSequencerBuffer* buffer_;
DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBufferPeer);
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
index 29c8741afa3..beb24e84da8 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.cc
@@ -31,5 +31,12 @@ bool QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(
return buffer_peer.IsBufferAllocated();
}
+// static
+void QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
+ QuicStreamSequencer* sequencer,
+ QuicStreamOffset total_bytes_read) {
+ QuicStreamSequencerBufferPeer buffer_peer(&(sequencer->buffered_frames_));
+ buffer_peer.set_total_bytes_read(total_bytes_read);
+}
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
index 9982e738977..538e903aa96 100644
--- a/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
+++ b/chromium/net/quic/test_tools/quic_stream_sequencer_peer.h
@@ -22,6 +22,9 @@ class QuicStreamSequencerPeer {
static bool IsUnderlyingBufferAllocated(QuicStreamSequencer* sequencer);
+ static void SetFrameBufferTotalBytesRead(QuicStreamSequencer* sequencer,
+ QuicStreamOffset total_bytes_read);
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerPeer);
};
diff --git a/chromium/net/quic/test_tools/quic_test_utils.cc b/chromium/net/quic/test_tools/quic_test_utils.cc
index 5d1b1dc029d..3725ca92234 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.cc
+++ b/chromium/net/quic/test_tools/quic_test_utils.cc
@@ -17,6 +17,7 @@
#include "net/quic/core/quic_framer.h"
#include "net/quic/core/quic_packet_creator.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
@@ -45,7 +46,7 @@ QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks) {
end_of_previous_block = block.limit;
}
- ack.deprecated_largest_observed = ack.packets.Max();
+ ack.largest_acked = ack.packets.Max();
return ack;
}
@@ -57,7 +58,7 @@ QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked) {
QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
QuicPacketNumber least_unacked) {
QuicAckFrame ack;
- ack.deprecated_largest_observed = 2 * num_ack_blocks + least_unacked;
+ ack.largest_acked = 2 * num_ack_blocks + least_unacked;
// Add enough received packets to get num_ack_blocks ack blocks.
for (QuicPacketNumber i = 2; i < 2 * num_ack_blocks + 1; i += 2) {
ack.packets.Add(least_unacked + i);
@@ -100,7 +101,7 @@ string Sha1Hash(QuicStringPiece data) {
char buffer[SHA_DIGEST_LENGTH];
SHA1(reinterpret_cast<const uint8_t*>(data.data()), data.size(),
reinterpret_cast<uint8_t*>(buffer));
- return string(buffer, arraysize(buffer));
+ return string(buffer, QUIC_ARRAYSIZE(buffer));
}
uint64_t SimpleRandom::RandUint64() {
@@ -161,8 +162,7 @@ MockFramerVisitor::MockFramerVisitor() {
MockFramerVisitor::~MockFramerVisitor() {}
-bool NoOpFramerVisitor::OnProtocolVersionMismatch(
- QuicTransportVersion version) {
+bool NoOpFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
return false;
}
@@ -269,7 +269,7 @@ MockQuicConnection::MockQuicConnection(MockQuicConnectionHelper* helper,
helper,
alarm_factory,
perspective,
- AllSupportedTransportVersions()) {}
+ AllSupportedVersions()) {}
MockQuicConnection::MockQuicConnection(QuicSocketAddress address,
MockQuicConnectionHelper* helper,
@@ -280,7 +280,7 @@ MockQuicConnection::MockQuicConnection(QuicSocketAddress address,
helper,
alarm_factory,
perspective,
- AllSupportedTransportVersions()) {}
+ AllSupportedVersions()) {}
MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id,
MockQuicConnectionHelper* helper,
@@ -291,13 +291,13 @@ MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id,
helper,
alarm_factory,
perspective,
- CurrentSupportedTransportVersions()) {}
+ CurrentSupportedVersions()) {}
MockQuicConnection::MockQuicConnection(
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: MockQuicConnection(QuicEndian::NetToHost64(kTestConnectionId),
QuicSocketAddress(TestPeerIPAddress(), kTestPort),
helper,
@@ -311,7 +311,7 @@ MockQuicConnection::MockQuicConnection(
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: QuicConnection(connection_id,
address,
helper,
@@ -331,8 +331,7 @@ void MockQuicConnection::AdvanceTime(QuicTime::Delta delta) {
static_cast<MockQuicConnectionHelper*>(helper())->AdvanceTime(delta);
}
-bool MockQuicConnection::OnProtocolVersionMismatch(
- QuicTransportVersion version) {
+bool MockQuicConnection::OnProtocolVersionMismatch(ParsedQuicVersion version) {
return false;
}
@@ -345,7 +344,7 @@ PacketSavingConnection::PacketSavingConnection(
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: MockQuicConnection(helper,
alarm_factory,
perspective,
@@ -358,9 +357,9 @@ void PacketSavingConnection::SendOrQueuePacket(SerializedPacket* packet) {
CopyBuffer(*packet), packet->encrypted_length, true));
// Transfer ownership of the packet to the SentPacketManager and the
// ack notifier to the AckNotifierManager.
- sent_packet_manager_.OnPacketSent(packet, 0, QuicTime::Zero(),
- NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA);
+ QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
+ packet, 0, QuicTime::Zero(), NOT_RETRANSMISSION,
+ HAS_RETRANSMITTABLE_DATA);
}
MockQuicSession::MockQuicSession(QuicConnection* connection)
@@ -384,11 +383,18 @@ const QuicCryptoStream* MockQuicSession::GetCryptoStream() const {
}
// static
-QuicConsumedData MockQuicSession::ConsumeAllData(QuicStream* /*stream*/,
- QuicStreamId /*id*/,
- size_t write_length,
- QuicStreamOffset /*offset*/,
- StreamSendingState state) {
+QuicConsumedData MockQuicSession::ConsumeData(QuicStream* stream,
+ QuicStreamId /*id*/,
+ size_t write_length,
+ QuicStreamOffset offset,
+ StreamSendingState state) {
+ if (write_length > 0) {
+ auto buf = QuicMakeUnique<char[]>(write_length);
+ QuicDataWriter writer(write_length, buf.get(), HOST_BYTE_ORDER);
+ stream->WriteStreamData(offset, write_length, &writer);
+ } else {
+ DCHECK(state != NO_FIN);
+ }
return QuicConsumedData(write_length, state != NO_FIN);
}
@@ -473,7 +479,7 @@ TestQuicSpdyServerSession::CreateQuicCryptoServerStream(
QuicCompressedCertsCache* compressed_certs_cache) {
return new QuicCryptoServerStream(
crypto_config, compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support, this,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
&helper_);
}
@@ -602,11 +608,19 @@ QuicIpAddress TestPeerIPAddress() {
return QuicIpAddress::Loopback4();
}
-QuicTransportVersion QuicVersionMax() {
+ParsedQuicVersion QuicVersionMax() {
+ return AllSupportedVersions().front();
+}
+
+ParsedQuicVersion QuicVersionMin() {
+ return AllSupportedVersions().back();
+}
+
+QuicTransportVersion QuicTransportVersionMax() {
return AllSupportedTransportVersions().front();
}
-QuicTransportVersion QuicVersionMin() {
+QuicTransportVersion QuicTransportVersionMin() {
return AllSupportedTransportVersions().back();
}
@@ -641,7 +655,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
const string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions) {
+ ParsedQuicVersionVector* versions) {
return ConstructEncryptedPacket(connection_id, version_flag, reset_flag,
packet_number, data, connection_id_length,
packet_number_length, versions,
@@ -655,7 +669,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
const string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions,
+ ParsedQuicVersionVector* versions,
Perspective perspective) {
QuicPacketHeader header;
header.connection_id = connection_id;
@@ -669,7 +683,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
QuicFrames frames;
frames.push_back(frame);
QuicFramer framer(
- versions != nullptr ? *versions : CurrentSupportedTransportVersions(),
+ versions != nullptr ? *versions : CurrentSupportedVersions(),
QuicTime::Zero(), perspective);
std::unique_ptr<QuicPacket> packet(
@@ -699,7 +713,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
const string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions,
+ ParsedQuicVersionVector* versions,
Perspective perspective) {
QuicPacketHeader header;
header.connection_id = connection_id;
@@ -712,9 +726,8 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
QuicFrame frame(&stream_frame);
QuicFrames frames;
frames.push_back(frame);
- QuicFramer framer(
- versions != nullptr ? *versions : AllSupportedTransportVersions(),
- QuicTime::Zero(), perspective);
+ QuicFramer framer(versions != nullptr ? *versions : AllSupportedVersions(),
+ QuicTime::Zero(), perspective);
std::unique_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header, frames));
@@ -817,6 +830,12 @@ QuicTransportVersionVector SupportedTransportVersions(
return versions;
}
+ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version) {
+ ParsedQuicVersionVector versions;
+ versions.push_back(version);
+ return versions;
+}
+
MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {}
MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {}
@@ -833,15 +852,19 @@ MockConnectionCloseDelegate::~MockConnectionCloseDelegate() {}
MockPacketCreatorDelegate::MockPacketCreatorDelegate() {}
MockPacketCreatorDelegate::~MockPacketCreatorDelegate() {}
-void CreateClientSessionForTest(QuicServerId server_id,
- bool supports_stateless_rejects,
- QuicTime::Delta connection_start_time,
- QuicTransportVersionVector supported_versions,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicCryptoClientConfig* crypto_client_config,
- PacketSavingConnection** client_connection,
- TestQuicSpdyClientSession** client_session) {
+MockSessionNotifier::MockSessionNotifier() {}
+MockSessionNotifier::~MockSessionNotifier() {}
+
+void CreateClientSessionForTest(
+ QuicServerId server_id,
+ bool supports_stateless_rejects,
+ QuicTime::Delta connection_start_time,
+ const ParsedQuicVersionVector& supported_versions,
+ MockQuicConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
+ QuicCryptoClientConfig* crypto_client_config,
+ PacketSavingConnection** client_connection,
+ TestQuicSpdyClientSession** client_session) {
CHECK(crypto_client_config);
CHECK(client_connection);
CHECK(client_session);
@@ -862,7 +885,7 @@ void CreateClientSessionForTest(QuicServerId server_id,
void CreateServerSessionForTest(
QuicServerId server_id,
QuicTime::Delta connection_start_time,
- QuicTransportVersionVector supported_versions,
+ ParsedQuicVersionVector supported_versions,
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
QuicCryptoServerConfig* server_crypto_config,
diff --git a/chromium/net/quic/test_tools/quic_test_utils.h b/chromium/net/quic/test_tools/quic_test_utils.h
index c94a32bdd7f..375ad0e10f6 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.h
+++ b/chromium/net/quic/test_tools/quic_test_utils.h
@@ -54,13 +54,21 @@ static const uint32_t kInitialSessionFlowControlWindowForTest =
QuicIpAddress TestPeerIPAddress();
// Upper limit on versions we support.
-QuicTransportVersion QuicVersionMax();
+ParsedQuicVersion QuicVersionMax();
// Lower limit on versions we support.
-QuicTransportVersion QuicVersionMin();
+ParsedQuicVersion QuicVersionMin();
+
+// Upper limit on versions we support.
+// TODO(nharper): Remove this function when it is no longer used.
+QuicTransportVersion QuicTransportVersionMax();
+
+// Lower limit on versions we support.
+// TODO(nharper): Remove this function when it is no longer used.
+QuicTransportVersion QuicTransportVersionMin();
// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedTransportVersions().
+// If versions == nullptr, uses &AllSupportedVersions().
// Note that the packet is encrypted with NullEncrypter, so to decrypt the
// constructed packet, the framer must be set to use NullDecrypter.
QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -71,11 +79,11 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
const std::string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions,
+ ParsedQuicVersionVector* versions,
Perspective perspective);
// Create an encrypted packet for testing.
-// If versions == nullptr, uses &AllSupportedTransportVersions().
+// If versions == nullptr, uses &AllSupportedVersions().
// Note that the packet is encrypted with NullEncrypter, so to decrypt the
// constructed packet, the framer must be set to use NullDecrypter.
QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -86,7 +94,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
const std::string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions);
+ ParsedQuicVersionVector* versions);
// This form assumes |versions| == nullptr.
QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -126,7 +134,7 @@ QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
const std::string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
- QuicTransportVersionVector* versions,
+ ParsedQuicVersionVector* versions,
Perspective perspective);
void CompareCharArraysWithHexError(const std::string& description,
@@ -155,6 +163,8 @@ QuicConfig DefaultQuicConfigStatelessRejects();
QuicTransportVersionVector SupportedTransportVersions(
QuicTransportVersion version);
+ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version);
+
struct QuicAckBlock {
QuicPacketNumber start; // Included
QuicPacketNumber limit; // Excluded
@@ -224,7 +234,7 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
MOCK_METHOD1(OnError, void(QuicFramer* framer));
// The constructor sets this up to return false by default.
- MOCK_METHOD1(OnProtocolVersionMismatch, bool(QuicTransportVersion version));
+ MOCK_METHOD1(OnProtocolVersionMismatch, bool(ParsedQuicVersion version));
MOCK_METHOD0(OnPacket, void());
MOCK_METHOD1(OnPublicResetPacket, void(const QuicPublicResetPacket& header));
MOCK_METHOD1(OnVersionNegotiationPacket,
@@ -262,7 +272,7 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}
void OnVersionNegotiationPacket(
const QuicVersionNegotiationPacket& packet) override {}
- bool OnProtocolVersionMismatch(QuicTransportVersion version) override;
+ bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
void OnDecryptedPacket(EncryptionLevel level) override {}
@@ -383,14 +393,14 @@ class MockQuicConnection : public QuicConnection {
MockQuicConnection(MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
MockQuicConnection(QuicConnectionId connection_id,
QuicSocketAddress address,
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
~MockQuicConnection() override;
@@ -444,7 +454,7 @@ class MockQuicConnection : public QuicConnection {
QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
}
- bool OnProtocolVersionMismatch(QuicTransportVersion version) override;
+ bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
void ReallySendGoAway(QuicErrorCode error,
QuicStreamId last_good_stream_id,
@@ -472,7 +482,7 @@ class PacketSavingConnection : public MockQuicConnection {
PacketSavingConnection(MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
~PacketSavingConnection() override;
@@ -525,11 +535,11 @@ class MockQuicSession : public QuicSession {
// Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
// if set) has been consumed.
- static QuicConsumedData ConsumeAllData(QuicStream* stream,
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state);
+ static QuicConsumedData ConsumeData(QuicStream* stream,
+ QuicStreamId id,
+ size_t write_length,
+ QuicStreamOffset offset,
+ StreamSendingState state);
private:
std::unique_ptr<QuicCryptoStream> crypto_stream_;
@@ -861,7 +871,7 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
MOCK_METHOD1(OnIncorrectConnectionId, void(QuicConnectionId));
- MOCK_METHOD1(OnProtocolVersionMismatch, void(QuicTransportVersion));
+ MOCK_METHOD1(OnProtocolVersionMismatch, void(ParsedQuicVersion));
MOCK_METHOD1(OnPacketHeader, void(const QuicPacketHeader& header));
@@ -926,6 +936,16 @@ class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
DISALLOW_COPY_AND_ASSIGN(MockPacketCreatorDelegate);
};
+class MockSessionNotifier : public SessionNotifierInterface {
+ public:
+ MockSessionNotifier();
+ ~MockSessionNotifier() override;
+
+ MOCK_METHOD2(OnFrameAcked, void(const QuicFrame&, QuicTime::Delta));
+ MOCK_METHOD1(OnStreamFrameRetransmitted, void(const QuicStreamFrame&));
+ MOCK_METHOD1(OnFrameLost, void(const QuicFrame&));
+};
+
// Creates a client session for testing.
//
// server_id: The server id associated with this stream.
@@ -942,15 +962,16 @@ class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
// client_session.
// client_session: Pointer reference for the newly created client
// session. The new object will be owned by the caller.
-void CreateClientSessionForTest(QuicServerId server_id,
- bool supports_stateless_rejects,
- QuicTime::Delta connection_start_time,
- QuicTransportVersionVector supported_versions,
- MockQuicConnectionHelper* helper,
- MockAlarmFactory* alarm_factory,
- QuicCryptoClientConfig* crypto_client_config,
- PacketSavingConnection** client_connection,
- TestQuicSpdyClientSession** client_session);
+void CreateClientSessionForTest(
+ QuicServerId server_id,
+ bool supports_stateless_rejects,
+ QuicTime::Delta connection_start_time,
+ const ParsedQuicVersionVector& supported_versions,
+ MockQuicConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
+ QuicCryptoClientConfig* crypto_client_config,
+ PacketSavingConnection** client_connection,
+ TestQuicSpdyClientSession** client_session);
// Creates a server session for testing.
//
@@ -970,7 +991,7 @@ void CreateClientSessionForTest(QuicServerId server_id,
void CreateServerSessionForTest(
QuicServerId server_id,
QuicTime::Delta connection_start_time,
- QuicTransportVersionVector supported_versions,
+ ParsedQuicVersionVector supported_versions,
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
QuicCryptoServerConfig* crypto_server_config,
diff --git a/chromium/net/quic/test_tools/quic_time_wait_list_manager_peer.cc b/chromium/net/quic/test_tools/quic_time_wait_list_manager_peer.cc
index ba47d8b9e36..c2d4c79c901 100644
--- a/chromium/net/quic/test_tools/quic_time_wait_list_manager_peer.cc
+++ b/chromium/net/quic/test_tools/quic_time_wait_list_manager_peer.cc
@@ -22,7 +22,8 @@ QuicTransportVersion
QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
QuicTimeWaitListManager* manager,
QuicConnectionId connection_id) {
- return manager->GetQuicVersionFromConnectionId(connection_id);
+ return manager->GetQuicVersionFromConnectionId(connection_id)
+ .transport_version;
}
QuicAlarm* QuicTimeWaitListManagerPeer::expiration_alarm(
diff --git a/chromium/net/quic/test_tools/simple_data_producer.cc b/chromium/net/quic/test_tools/simple_data_producer.cc
index 14f2f6c8910..e581357fbab 100644
--- a/chromium/net/quic/test_tools/simple_data_producer.cc
+++ b/chromium/net/quic/test_tools/simple_data_producer.cc
@@ -26,8 +26,7 @@ void SimpleDataProducer::SaveStreamData(QuicStreamId id,
}
if (!QuicContainsKey(send_buffer_map_, id)) {
send_buffer_map_[id] = QuicMakeUnique<QuicStreamSendBuffer>(
- &allocator_,
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2);
+ &allocator_, GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2));
}
send_buffer_map_[id]->SaveStreamData(iov, iov_count, iov_offset, data_length);
}
@@ -39,21 +38,6 @@ bool SimpleDataProducer::WriteStreamData(QuicStreamId id,
return send_buffer_map_[id]->WriteStreamData(offset, data_length, writer);
}
-void SimpleDataProducer::OnStreamFrameAcked(
- const QuicStreamFrame& frame,
- QuicTime::Delta /*ack_delay_time*/) {
- OnStreamFrameDiscarded(frame);
-}
-
-void SimpleDataProducer::OnStreamFrameDiscarded(const QuicStreamFrame& frame) {
- if (!QuicContainsKey(send_buffer_map_, frame.stream_id)) {
- return;
- }
- QuicByteCount newly_acked_length = 0;
- send_buffer_map_[frame.stream_id]->OnStreamDataAcked(
- frame.offset, frame.data_length, &newly_acked_length);
-}
-
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/simple_data_producer.h b/chromium/net/quic/test_tools/simple_data_producer.h
index 22b6d0b5337..4cb678f7b43 100644
--- a/chromium/net/quic/test_tools/simple_data_producer.h
+++ b/chromium/net/quic/test_tools/simple_data_producer.h
@@ -8,7 +8,6 @@
#include "net/quic/core/quic_simple_buffer_allocator.h"
#include "net/quic/core/quic_stream_frame_data_producer.h"
#include "net/quic/core/quic_stream_send_buffer.h"
-#include "net/quic/core/stream_notifier_interface.h"
#include "net/quic/platform/api/quic_containers.h"
namespace net {
@@ -17,8 +16,7 @@ namespace test {
// A simple data producer which copies stream data into a map from stream
// id to send buffer.
-class SimpleDataProducer : public QuicStreamFrameDataProducer,
- public StreamNotifierInterface {
+class SimpleDataProducer : public QuicStreamFrameDataProducer {
public:
SimpleDataProducer();
~SimpleDataProducer() override;
@@ -36,12 +34,6 @@ class SimpleDataProducer : public QuicStreamFrameDataProducer,
QuicByteCount data_length,
QuicDataWriter* writer) override;
- // StreamNotifierInterface methods:
- void OnStreamFrameAcked(const QuicStreamFrame& frame,
- QuicTime::Delta ack_delay_time) override;
- void OnStreamFrameRetransmitted(const QuicStreamFrame& frame) override {}
- void OnStreamFrameDiscarded(const QuicStreamFrame& frame) override;
-
private:
using SendBufferMap =
QuicUnorderedMap<QuicStreamId, std::unique_ptr<QuicStreamSendBuffer>>;
diff --git a/chromium/net/quic/test_tools/simple_quic_framer.cc b/chromium/net/quic/test_tools/simple_quic_framer.cc
index 87775550ecd..2cab678f1e4 100644
--- a/chromium/net/quic/test_tools/simple_quic_framer.cc
+++ b/chromium/net/quic/test_tools/simple_quic_framer.cc
@@ -25,7 +25,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
void OnError(QuicFramer* framer) override { error_ = framer->error(); }
- bool OnProtocolVersionMismatch(QuicTransportVersion version) override {
+ bool OnProtocolVersionMismatch(ParsedQuicVersion version) override {
return false;
}
@@ -159,16 +159,16 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
};
SimpleQuicFramer::SimpleQuicFramer()
- : framer_(AllSupportedTransportVersions(),
+ : framer_(AllSupportedVersions(),
QuicTime::Zero(),
Perspective::IS_SERVER) {}
SimpleQuicFramer::SimpleQuicFramer(
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: framer_(supported_versions, QuicTime::Zero(), Perspective::IS_SERVER) {}
SimpleQuicFramer::SimpleQuicFramer(
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
Perspective perspective)
: framer_(supported_versions, QuicTime::Zero(), perspective) {}
diff --git a/chromium/net/quic/test_tools/simple_quic_framer.h b/chromium/net/quic/test_tools/simple_quic_framer.h
index 5e0ebb0fd48..c9030df799c 100644
--- a/chromium/net/quic/test_tools/simple_quic_framer.h
+++ b/chromium/net/quic/test_tools/simple_quic_framer.h
@@ -24,9 +24,8 @@ class SimpleFramerVisitor;
class SimpleQuicFramer {
public:
SimpleQuicFramer();
- explicit SimpleQuicFramer(
- const QuicTransportVersionVector& supported_versions);
- SimpleQuicFramer(const QuicTransportVersionVector& supported_versions,
+ explicit SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions);
+ SimpleQuicFramer(const ParsedQuicVersionVector& supported_versions,
Perspective perspective);
~SimpleQuicFramer();
@@ -48,9 +47,8 @@ class SimpleQuicFramer {
QuicFramer* framer();
- void SetSupportedTransportVersions(
- const QuicTransportVersionVector& versions) {
- framer_.SetSupportedTransportVersions(versions);
+ void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
+ framer_.SetSupportedVersions(versions);
}
private:
diff --git a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
index 032a8f18ae6..79650e0aad9 100644
--- a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
+++ b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
@@ -73,7 +73,7 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator,
&writer_,
false,
perspective,
- CurrentSupportedTransportVersions()),
+ CurrentSupportedVersions()),
bytes_to_transfer_(0),
bytes_transferred_(0),
write_blocked_count_(0),
diff --git a/chromium/net/reporting/reporting_browsing_data_remover.cc b/chromium/net/reporting/reporting_browsing_data_remover.cc
index 9b391d49371..8f42253c9a8 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover.cc
+++ b/chromium/net/reporting/reporting_browsing_data_remover.cc
@@ -17,7 +17,7 @@ namespace net {
void ReportingBrowsingDataRemover::RemoveBrowsingData(
ReportingCache* cache,
int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter) {
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
bool remove_reports = (data_type_mask & DATA_TYPE_REPORTS) != 0;
bool remove_clients = (data_type_mask & DATA_TYPE_CLIENTS) != 0;
diff --git a/chromium/net/reporting/reporting_browsing_data_remover.h b/chromium/net/reporting/reporting_browsing_data_remover.h
index f93d6348a27..abb34bc9d25 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover.h
+++ b/chromium/net/reporting/reporting_browsing_data_remover.h
@@ -33,7 +33,7 @@ class NET_EXPORT ReportingBrowsingDataRemover {
static void RemoveBrowsingData(
ReportingCache* cache,
int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter);
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter);
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 ceaf9d59d8a..3d8d10d8122 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -29,16 +29,29 @@ class ReportingBrowsingDataRemoverTest : public ReportingTestBase {
if (remove_clients)
data_type_mask |= ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS;
- base::Callback<bool(const GURL&)> origin_filter;
+ base::RepeatingCallback<bool(const GURL&)> origin_filter;
if (!host.empty()) {
origin_filter =
- base::Bind(&ReportingBrowsingDataRemoverTest::HostIs, host);
+ base::BindRepeating(&ReportingBrowsingDataRemoverTest::HostIs, host);
}
ReportingBrowsingDataRemover::RemoveBrowsingData(cache(), data_type_mask,
origin_filter);
}
+ void AddReport(const GURL& url) {
+ cache()->AddReport(url, kGroup_, kType_,
+ std::make_unique<base::DictionaryValue>(),
+ tick_clock()->NowTicks(), 0);
+ }
+
+ void SetClient(const url::Origin& origin, const GURL& endpoint) {
+ cache()->SetClient(
+ origin, endpoint, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+ tick_clock()->NowTicks() + base::TimeDelta::FromDays(7),
+ ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+ }
+
static bool HostIs(std::string host, const GURL& url) {
return url.host() == host;
}
@@ -65,18 +78,11 @@ class ReportingBrowsingDataRemoverTest : public ReportingTestBase {
};
TEST_F(ReportingBrowsingDataRemoverTest, RemoveNothing) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ false,
/* host= */ "");
@@ -85,18 +91,11 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveNothing) {
}
TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReports) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ false,
/* host= */ "");
@@ -105,18 +104,11 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReports) {
}
TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllClients) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ true,
/* host= */ "");
@@ -125,18 +117,11 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllClients) {
}
TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReportsAndClients) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ true,
/* host= */ "");
@@ -145,18 +130,11 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveAllReportsAndClients) {
}
TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeReports) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ true, /* remove_clients= */ false,
/* host= */ kUrl1_.host());
@@ -169,18 +147,11 @@ TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeReports) {
}
TEST_F(ReportingBrowsingDataRemoverTest, RemoveSomeClients) {
- cache()->AddReport(kUrl1_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->AddReport(kUrl2_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
- tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin1_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
- cache()->SetClient(kOrigin2_, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ AddReport(kUrl1_);
+ AddReport(kUrl2_);
+
+ SetClient(kOrigin1_, kEndpoint_);
+ SetClient(kOrigin2_, kEndpoint_);
RemoveBrowsingData(/* remove_reports= */ false, /* remove_clients= */ true,
/* host= */ kUrl1_.host());
diff --git a/chromium/net/reporting/reporting_cache.cc b/chromium/net/reporting/reporting_cache.cc
index dde13eda388..0ed130bc52e 100644
--- a/chromium/net/reporting/reporting_cache.cc
+++ b/chromium/net/reporting/reporting_cache.cc
@@ -167,43 +167,13 @@ class ReportingCacheImpl : public ReportingCache {
context_->NotifyCacheUpdated();
}
- void GetClients(
- std::vector<const ReportingClient*>* clients_out) const override {
- clients_out->clear();
- for (const auto& it : clients_)
- for (const auto& endpoint_and_client : it.second)
- clients_out->push_back(endpoint_and_client.second.get());
- }
-
- void GetClientsForOriginAndGroup(
- const url::Origin& origin,
- const std::string& group,
- std::vector<const ReportingClient*>* clients_out) const override {
- clients_out->clear();
-
- const auto it = clients_.find(origin);
- if (it != clients_.end()) {
- for (const auto& endpoint_and_client : it->second) {
- if (endpoint_and_client.second->group == group)
- clients_out->push_back(endpoint_and_client.second.get());
- }
- }
-
- // If no clients were found, try successive superdomain suffixes until a
- // client with includeSubdomains is found or there are no more domain
- // components left.
- std::string domain = origin.host();
- while (clients_out->empty() && !domain.empty()) {
- GetWildcardClientsForDomainAndGroup(domain, group, clients_out);
- domain = GetSuperdomain(domain);
- }
- }
-
void SetClient(const url::Origin& origin,
const GURL& endpoint,
ReportingClient::Subdomains subdomains,
const std::string& group,
- base::TimeTicks expires) override {
+ base::TimeTicks expires,
+ int priority,
+ int weight) override {
DCHECK(endpoint.SchemeIsCryptographic());
base::TimeTicks last_used = tick_clock()->NowTicks();
@@ -215,9 +185,10 @@ class ReportingCacheImpl : public ReportingCache {
RemoveClient(old_client);
}
- AddClient(std::make_unique<ReportingClient>(origin, endpoint, subdomains,
- group, expires),
- last_used);
+ AddClient(
+ std::make_unique<ReportingClient>(origin, endpoint, subdomains, group,
+ expires, priority, weight),
+ last_used);
if (client_last_used_.size() > context_->policy().max_client_count) {
// There should only ever be one extra client, added above.
@@ -242,6 +213,51 @@ class ReportingCacheImpl : public ReportingCache {
client_last_used_[client] = tick_clock()->NowTicks();
}
+ void GetClients(
+ std::vector<const ReportingClient*>* clients_out) const override {
+ clients_out->clear();
+ for (const auto& it : clients_)
+ for (const auto& endpoint_and_client : it.second)
+ clients_out->push_back(endpoint_and_client.second.get());
+ }
+
+ void GetClientsForOriginAndGroup(
+ const url::Origin& origin,
+ const std::string& group,
+ std::vector<const ReportingClient*>* clients_out) const override {
+ clients_out->clear();
+
+ const auto it = clients_.find(origin);
+ if (it != clients_.end()) {
+ for (const auto& endpoint_and_client : it->second) {
+ if (endpoint_and_client.second->group == group)
+ clients_out->push_back(endpoint_and_client.second.get());
+ }
+ }
+
+ // If no clients were found, try successive superdomain suffixes until a
+ // client with includeSubdomains is found or there are no more domain
+ // components left.
+ std::string domain = origin.host();
+ while (clients_out->empty() && !domain.empty()) {
+ GetWildcardClientsForDomainAndGroup(domain, group, clients_out);
+ domain = GetSuperdomain(domain);
+ }
+ }
+
+ // TODO(juliatuttle): Unittests.
+ void GetEndpointsForOrigin(const url::Origin& origin,
+ std::vector<GURL>* endpoints_out) const override {
+ endpoints_out->clear();
+
+ const auto it = clients_.find(origin);
+ if (it == clients_.end())
+ return;
+
+ for (const auto& endpoint_and_client : it->second)
+ endpoints_out->push_back(endpoint_and_client.first);
+ }
+
void RemoveClients(
const std::vector<const ReportingClient*>& clients_to_remove) override {
for (const ReportingClient* client : clients_to_remove)
@@ -295,36 +311,6 @@ class ReportingCacheImpl : public ReportingCache {
}
private:
- ReportingContext* context_;
-
- // Owns all reports, keyed by const raw pointer for easier lookup.
- std::unordered_map<const ReportingReport*, std::unique_ptr<ReportingReport>>
- reports_;
-
- // Reports that have been marked pending (in use elsewhere and should not be
- // deleted until no longer pending).
- std::unordered_set<const ReportingReport*> pending_reports_;
-
- // Reports that have been marked doomed (would have been deleted, but were
- // pending when the deletion was requested).
- std::unordered_set<const ReportingReport*> doomed_reports_;
-
- // Owns all clients, keyed by origin, then endpoint URL.
- // (These would be unordered_map, but neither url::Origin nor GURL has a hash
- // function implemented.)
- std::map<url::Origin, std::map<GURL, std::unique_ptr<ReportingClient>>>
- clients_;
-
- // References but does not own all clients with includeSubdomains set, keyed
- // by domain name.
- std::unordered_map<std::string, std::unordered_set<const ReportingClient*>>
- wildcard_clients_;
-
- // The time that each client has last been used.
- std::unordered_map<const ReportingClient*, base::TimeTicks> client_last_used_;
-
- base::TickClock* tick_clock() { return context_->tick_clock(); }
-
void RemoveReportInternal(const ReportingReport* report) {
reports_[report]->RecordOutcome(tick_clock()->NowTicks());
size_t erased = reports_.erase(report);
@@ -454,6 +440,36 @@ class ReportingCacheImpl : public ReportingCache {
else
return earliest_used;
}
+
+ base::TickClock* tick_clock() { return context_->tick_clock(); }
+
+ ReportingContext* context_;
+
+ // Owns all reports, keyed by const raw pointer for easier lookup.
+ std::unordered_map<const ReportingReport*, std::unique_ptr<ReportingReport>>
+ reports_;
+
+ // Reports that have been marked pending (in use elsewhere and should not be
+ // deleted until no longer pending).
+ std::unordered_set<const ReportingReport*> pending_reports_;
+
+ // Reports that have been marked doomed (would have been deleted, but were
+ // pending when the deletion was requested).
+ std::unordered_set<const ReportingReport*> doomed_reports_;
+
+ // Owns all clients, keyed by origin, then endpoint URL.
+ // (These would be unordered_map, but neither url::Origin nor GURL has a hash
+ // function implemented.)
+ std::map<url::Origin, std::map<GURL, std::unique_ptr<ReportingClient>>>
+ clients_;
+
+ // References but does not own all clients with includeSubdomains set, keyed
+ // by domain name.
+ std::unordered_map<std::string, std::unordered_set<const ReportingClient*>>
+ wildcard_clients_;
+
+ // The time that each client has last been used.
+ std::unordered_map<const ReportingClient*, base::TimeTicks> client_last_used_;
};
} // namespace
@@ -464,6 +480,6 @@ std::unique_ptr<ReportingCache> ReportingCache::Create(
return std::make_unique<ReportingCacheImpl>(context);
}
-ReportingCache::~ReportingCache() {}
+ReportingCache::~ReportingCache() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_cache.h b/chromium/net/reporting/reporting_cache.h
index 2cd4bb7172c..eca3c5cd0ec 100644
--- a/chromium/net/reporting/reporting_cache.h
+++ b/chromium/net/reporting/reporting_cache.h
@@ -87,14 +87,16 @@ class NET_EXPORT ReportingCache {
// endpoint.
//
// All parameters correspond to the desired values for the fields in
- // |Client|.
+ // ReportingClient.
//
// |endpoint| must use a cryptographic scheme.
virtual void SetClient(const url::Origin& origin,
const GURL& endpoint,
ReportingClient::Subdomains subdomains,
const std::string& group,
- base::TimeTicks expires) = 0;
+ base::TimeTicks expires,
+ int priority,
+ int client) = 0;
virtual void MarkClientUsed(const url::Origin& origin,
const GURL& endpoint) = 0;
@@ -126,6 +128,13 @@ class NET_EXPORT ReportingCache {
const std::string& group,
std::vector<const ReportingClient*>* clients_out) const = 0;
+ // Gets all of the endpoints in the cache configured for a particular origin.
+ // Does not pay attention to wildcard hosts; only returns endpoints configured
+ // by |origin| itself.
+ virtual void GetEndpointsForOrigin(
+ const url::Origin& origin,
+ std::vector<GURL>* endpoints_out) const = 0;
+
// Removes a set of clients.
//
// May invalidate ReportingClient pointers returned by |GetClients| or
diff --git a/chromium/net/reporting/reporting_cache_unittest.cc b/chromium/net/reporting/reporting_cache_unittest.cc
index 9c77e71b4b0..6e447fcf01f 100644
--- a/chromium/net/reporting/reporting_cache_unittest.cc
+++ b/chromium/net/reporting/reporting_cache_unittest.cc
@@ -60,6 +60,18 @@ class ReportingCacheTest : public ReportingTestBase {
return clients.size();
}
+ void SetClient(const url::Origin& origin,
+ const GURL& endpoint,
+ bool subdomains,
+ const std::string& group,
+ base::TimeTicks expires) {
+ cache()->SetClient(origin, endpoint,
+ subdomains ? ReportingClient::Subdomains::INCLUDE
+ : ReportingClient::Subdomains::EXCLUDE,
+ group, expires, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
+ }
+
const GURL kUrl1_ = GURL("https://origin1/path");
const url::Origin kOrigin1_ = url::Origin::Create(GURL("https://origin1/"));
const url::Origin kOrigin2_ = url::Origin::Create(GURL("https://origin2/"));
@@ -195,9 +207,7 @@ TEST_F(ReportingCacheTest, RemoveAllPendingReports) {
}
TEST_F(ReportingCacheTest, Endpoints) {
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
EXPECT_EQ(1, observer()->cache_update_count());
const ReportingClient* client =
@@ -209,8 +219,7 @@ TEST_F(ReportingCacheTest, Endpoints) {
EXPECT_EQ(kGroup1_, client->group);
EXPECT_EQ(kExpires1_, client->expires);
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup2, kExpires2_);
+ SetClient(kOrigin1_, kEndpoint1_, true, kGroup2, kExpires2_);
EXPECT_EQ(2, observer()->cache_update_count());
client = FindClientInCache(cache(), kOrigin1_, kEndpoint1_);
@@ -229,14 +238,9 @@ TEST_F(ReportingCacheTest, Endpoints) {
}
TEST_F(ReportingCacheTest, GetClientsForOriginAndGroup) {
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
- cache()->SetClient(kOrigin1_, kEndpoint2_,
- ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
- cache()->SetClient(kOrigin2_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+ SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+ SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin1_, kGroup1_, &clients);
@@ -248,14 +252,9 @@ TEST_F(ReportingCacheTest, GetClientsForOriginAndGroup) {
}
TEST_F(ReportingCacheTest, RemoveClientForOriginAndEndpoint) {
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
- cache()->SetClient(kOrigin1_, kEndpoint2_,
- ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
- cache()->SetClient(kOrigin2_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+ SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+ SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
EXPECT_EQ(3, observer()->cache_update_count());
cache()->RemoveClientForOriginAndEndpoint(kOrigin1_, kEndpoint1_);
@@ -273,14 +272,9 @@ TEST_F(ReportingCacheTest, RemoveClientForOriginAndEndpoint) {
}
TEST_F(ReportingCacheTest, RemoveClientsForEndpoint) {
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
- cache()->SetClient(kOrigin1_, kEndpoint2_,
- ReportingClient::Subdomains::EXCLUDE, kGroup2, kExpires1_);
- cache()->SetClient(kOrigin2_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+ SetClient(kOrigin1_, kEndpoint2_, false, kGroup2, kExpires1_);
+ SetClient(kOrigin2_, kEndpoint1_, false, kGroup1_, kExpires1_);
EXPECT_EQ(3, observer()->cache_update_count());
cache()->RemoveClientsForEndpoint(kEndpoint1_);
@@ -298,12 +292,8 @@ TEST_F(ReportingCacheTest, RemoveClientsForEndpoint) {
}
TEST_F(ReportingCacheTest, RemoveAllClients) {
- cache()->SetClient(kOrigin1_, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
- cache()->SetClient(kOrigin2_, kEndpoint2_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, kExpires1_);
+ SetClient(kOrigin2_, kEndpoint2_, false, kGroup1_, kExpires1_);
EXPECT_EQ(2, observer()->cache_update_count());
cache()->RemoveAllClients();
@@ -319,9 +309,7 @@ TEST_F(ReportingCacheTest, ExcludeSubdomainsDifferentPort) {
const url::Origin kDifferentPortOrigin =
url::Origin::Create(GURL("https://example:444/"));
- cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kDifferentPortOrigin, kEndpoint1_, false, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -333,9 +321,7 @@ TEST_F(ReportingCacheTest, ExcludeSubdomainsSuperdomain) {
const url::Origin kSuperOrigin =
url::Origin::Create(GURL("https://example/"));
- cache()->SetClient(kSuperOrigin, kEndpoint1_,
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kSuperOrigin, kEndpoint1_, false, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -347,9 +333,7 @@ TEST_F(ReportingCacheTest, IncludeSubdomainsDifferentPort) {
const url::Origin kDifferentPortOrigin =
url::Origin::Create(GURL("https://example:444/"));
- cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kDifferentPortOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -362,9 +346,7 @@ TEST_F(ReportingCacheTest, IncludeSubdomainsSuperdomain) {
const url::Origin kSuperOrigin =
url::Origin::Create(GURL("https://example/"));
- cache()->SetClient(kSuperOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -377,11 +359,8 @@ TEST_F(ReportingCacheTest, IncludeSubdomainsPreferOriginToDifferentPort) {
const url::Origin kDifferentPortOrigin =
url::Origin::Create(GURL("https://example:444/"));
- cache()->SetClient(kOrigin, kEndpoint1_, ReportingClient::Subdomains::INCLUDE,
- kGroup1_, kExpires1_);
- cache()->SetClient(kDifferentPortOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+ SetClient(kDifferentPortOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -394,11 +373,8 @@ TEST_F(ReportingCacheTest, IncludeSubdomainsPreferOriginToSuperdomain) {
const url::Origin kSuperOrigin =
url::Origin::Create(GURL("https://example/"));
- cache()->SetClient(kOrigin, kEndpoint1_, ReportingClient::Subdomains::INCLUDE,
- kGroup1_, kExpires1_);
- cache()->SetClient(kSuperOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+ SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -414,12 +390,8 @@ TEST_F(ReportingCacheTest, IncludeSubdomainsPreferMoreSpecificSuperdomain) {
const url::Origin kSuperSuperOrigin =
url::Origin::Create(GURL("https://example/"));
- cache()->SetClient(kSuperOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
- cache()->SetClient(kSuperSuperOrigin, kEndpoint1_,
- ReportingClient::Subdomains::INCLUDE, kGroup1_,
- kExpires1_);
+ SetClient(kSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
+ SetClient(kSuperSuperOrigin, kEndpoint1_, true, kGroup1_, kExpires1_);
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin, kGroup1_, &clients);
@@ -502,9 +474,7 @@ TEST_F(ReportingCacheTest, EvictLRUClient) {
ASSERT_GT(std::numeric_limits<size_t>::max(), max_client_count);
for (size_t i = 0; i < max_client_count; ++i) {
- cache()->SetClient(kOrigin1_, MakeEndpoint(i),
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- tomorrow());
+ SetClient(kOrigin1_, MakeEndpoint(i), false, kGroup1_, tomorrow());
}
EXPECT_EQ(max_client_count, client_count());
@@ -515,9 +485,8 @@ TEST_F(ReportingCacheTest, EvictLRUClient) {
}
// Add one more client, forcing the cache to evict the LRU.
- cache()->SetClient(kOrigin1_, MakeEndpoint(max_client_count),
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- tomorrow());
+ SetClient(kOrigin1_, MakeEndpoint(max_client_count), false, kGroup1_,
+ tomorrow());
EXPECT_EQ(max_client_count, client_count());
EXPECT_FALSE(FindClientInCache(cache(), kOrigin1_,
MakeEndpoint(max_client_count - 1)));
@@ -532,15 +501,13 @@ TEST_F(ReportingCacheTest, EvictExpiredClient) {
for (size_t i = 0; i < max_client_count; ++i) {
base::TimeTicks expires =
(i == max_client_count - 1) ? yesterday() : tomorrow();
- cache()->SetClient(kOrigin1_, MakeEndpoint(i),
- ReportingClient::Subdomains::EXCLUDE, kGroup1_, expires);
+ SetClient(kOrigin1_, MakeEndpoint(i), false, kGroup1_, expires);
}
EXPECT_EQ(max_client_count, client_count());
// Add one more client, forcing the cache to evict the expired one.
- cache()->SetClient(kOrigin1_, MakeEndpoint(max_client_count),
- ReportingClient::Subdomains::EXCLUDE, kGroup1_,
- tomorrow());
+ SetClient(kOrigin1_, MakeEndpoint(max_client_count), false, kGroup1_,
+ tomorrow());
EXPECT_EQ(max_client_count, client_count());
EXPECT_FALSE(FindClientInCache(cache(), kOrigin1_,
MakeEndpoint(max_client_count - 1)));
diff --git a/chromium/net/reporting/reporting_client.cc b/chromium/net/reporting/reporting_client.cc
index d8c8a0f35b7..5f01048ceda 100644
--- a/chromium/net/reporting/reporting_client.cc
+++ b/chromium/net/reporting/reporting_client.cc
@@ -12,17 +12,27 @@
namespace net {
+const char ReportingClient::kDefaultGroup[] = "default";
+const int ReportingClient::kDefaultPriority = 0;
+const int ReportingClient::kDefaultWeight = 1;
+
ReportingClient::ReportingClient(const url::Origin& origin,
const GURL& endpoint,
Subdomains subdomains,
const std::string& group,
- base::TimeTicks expires)
+ base::TimeTicks expires,
+ int priority,
+ int weight)
: origin(origin),
endpoint(endpoint),
subdomains(subdomains),
group(group),
- expires(expires) {}
+ expires(expires),
+ priority(priority),
+ weight(weight) {
+ DCHECK_LT(0, weight);
+}
-ReportingClient::~ReportingClient() {}
+ReportingClient::~ReportingClient() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_client.h b/chromium/net/reporting/reporting_client.h
index 0aa11bea57d..c2b87f4fd11 100644
--- a/chromium/net/reporting/reporting_client.h
+++ b/chromium/net/reporting/reporting_client.h
@@ -18,13 +18,19 @@ namespace net {
// The configuration by an origin to use an endpoint for report delivery.
struct NET_EXPORT ReportingClient {
public:
+ static const char kDefaultGroup[];
+ static const int kDefaultPriority;
+ static const int kDefaultWeight;
+
enum class Subdomains { EXCLUDE = 0, INCLUDE = 1 };
ReportingClient(const url::Origin& origin,
const GURL& endpoint,
Subdomains subdomains,
const std::string& group,
- base::TimeTicks expires);
+ base::TimeTicks expires,
+ int priority,
+ int weight);
~ReportingClient();
// The origin from which reports will be delivered.
@@ -39,11 +45,20 @@ struct NET_EXPORT ReportingClient {
Subdomains subdomains = Subdomains::EXCLUDE;
// The endpoint group to which this client belongs.
- std::string group = "default";
+ std::string group = kDefaultGroup;
// When this client's max-age has expired.
base::TimeTicks expires;
+ // Priority when multiple endpoints are configured for an origin; endpoints
+ // with numerically lower priorities are used first.
+ int priority = kDefaultPriority;
+
+ // Weight when multiple endpoints are configured for an origin with the same
+ // priority; among those with the same priority, each endpoint has a chance of
+ // being chosen that is proportional to its weight.
+ int weight = kDefaultWeight;
+
private:
DISALLOW_COPY_AND_ASSIGN(ReportingClient);
};
diff --git a/chromium/net/reporting/reporting_context.cc b/chromium/net/reporting/reporting_context.cc
index b46bc865a5d..8f2a280e5b2 100644
--- a/chromium/net/reporting/reporting_context.cc
+++ b/chromium/net/reporting/reporting_context.cc
@@ -6,13 +6,16 @@
#include <utility>
+#include "base/bind.h"
#include "base/observer_list.h"
+#include "base/rand_util.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
+#include "net/base/rand_callback.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_delivery_agent.h"
@@ -20,7 +23,6 @@
#include "net/reporting/reporting_garbage_collector.h"
#include "net/reporting/reporting_network_change_observer.h"
#include "net/reporting/reporting_observer.h"
-#include "net/reporting/reporting_persister.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_uploader.h"
@@ -35,8 +37,9 @@ class ReportingContextImpl : public ReportingContext {
ReportingContextImpl(const ReportingPolicy& policy,
URLRequestContext* request_context)
: ReportingContext(policy,
- std::make_unique<base::DefaultClock>(),
- std::make_unique<base::DefaultTickClock>(),
+ base::DefaultClock::GetInstance(),
+ base::DefaultTickClock::GetInstance(),
+ base::BindRepeating(&base::RandInt),
ReportingUploader::Create(request_context),
ReportingDelegate::Create(request_context)) {}
};
@@ -50,7 +53,7 @@ std::unique_ptr<ReportingContext> ReportingContext::Create(
return std::make_unique<ReportingContextImpl>(policy, request_context);
}
-ReportingContext::~ReportingContext() {}
+ReportingContext::~ReportingContext() = default;
void ReportingContext::AddObserver(ReportingObserver* observer) {
DCHECK(!observers_.HasObserver(observer));
@@ -68,19 +71,19 @@ void ReportingContext::NotifyCacheUpdated() {
}
ReportingContext::ReportingContext(const ReportingPolicy& policy,
- std::unique_ptr<base::Clock> clock,
- std::unique_ptr<base::TickClock> tick_clock,
+ base::Clock* clock,
+ base::TickClock* tick_clock,
+ const RandIntCallback& rand_callback,
std::unique_ptr<ReportingUploader> uploader,
std::unique_ptr<ReportingDelegate> delegate)
: policy_(policy),
- clock_(std::move(clock)),
- tick_clock_(std::move(tick_clock)),
+ clock_(clock),
+ tick_clock_(tick_clock),
uploader_(std::move(uploader)),
delegate_(std::move(delegate)),
cache_(ReportingCache::Create(this)),
- endpoint_manager_(ReportingEndpointManager::Create(this)),
+ endpoint_manager_(ReportingEndpointManager::Create(this, rand_callback)),
delivery_agent_(ReportingDeliveryAgent::Create(this)),
- persister_(ReportingPersister::Create(this)),
garbage_collector_(ReportingGarbageCollector::Create(this)),
network_change_observer_(ReportingNetworkChangeObserver::Create(this)) {}
diff --git a/chromium/net/reporting/reporting_context.h b/chromium/net/reporting/reporting_context.h
index 139ca02dbc5..9b4a6021279 100644
--- a/chromium/net/reporting/reporting_context.h
+++ b/chromium/net/reporting/reporting_context.h
@@ -11,6 +11,7 @@
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "net/base/net_export.h"
+#include "net/base/rand_callback.h"
#include "net/reporting/reporting_policy.h"
namespace base {
@@ -27,7 +28,6 @@ class ReportingEndpointManager;
class ReportingGarbageCollector;
class ReportingNetworkChangeObserver;
class ReportingObserver;
-class ReportingPersister;
class ReportingUploader;
class URLRequestContext;
@@ -43,8 +43,8 @@ class NET_EXPORT ReportingContext {
const ReportingPolicy& policy() { return policy_; }
- base::Clock* clock() { return clock_.get(); }
- base::TickClock* tick_clock() { return tick_clock_.get(); }
+ base::Clock* clock() { return clock_; }
+ base::TickClock* tick_clock() { return tick_clock_; }
ReportingUploader* uploader() { return uploader_.get(); }
ReportingDelegate* delegate() { return delegate_.get(); }
@@ -57,8 +57,6 @@ class NET_EXPORT ReportingContext {
return garbage_collector_.get();
}
- ReportingPersister* persister() { return persister_.get(); }
-
void AddObserver(ReportingObserver* observer);
void RemoveObserver(ReportingObserver* observer);
@@ -66,16 +64,17 @@ class NET_EXPORT ReportingContext {
protected:
ReportingContext(const ReportingPolicy& policy,
- std::unique_ptr<base::Clock> clock,
- std::unique_ptr<base::TickClock> tick_clock,
+ base::Clock* clock,
+ base::TickClock* tick_clock,
+ const RandIntCallback& rand_callback,
std::unique_ptr<ReportingUploader> uploader,
std::unique_ptr<ReportingDelegate> delegate);
private:
ReportingPolicy policy_;
- std::unique_ptr<base::Clock> clock_;
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::Clock* clock_;
+ base::TickClock* tick_clock_;
std::unique_ptr<ReportingUploader> uploader_;
base::ObserverList<ReportingObserver, /* check_empty= */ true> observers_;
@@ -91,9 +90,6 @@ class NET_EXPORT ReportingContext {
// |cache_|, and |endpoint_manager_|.
std::unique_ptr<ReportingDeliveryAgent> delivery_agent_;
- // |persister_| must come after |clock_|, |tick_clock_|, and |cache_|.
- std::unique_ptr<ReportingPersister> persister_;
-
// |garbage_collector_| must come after |tick_clock_| and |cache_|.
std::unique_ptr<ReportingGarbageCollector> garbage_collector_;
diff --git a/chromium/net/reporting/reporting_delegate.cc b/chromium/net/reporting/reporting_delegate.cc
index 4e4e3d12375..42006db4b49 100644
--- a/chromium/net/reporting/reporting_delegate.cc
+++ b/chromium/net/reporting/reporting_delegate.cc
@@ -18,7 +18,7 @@ class ReportingDelegateImpl : public ReportingDelegate {
DCHECK(request_context);
}
- ~ReportingDelegateImpl() override {}
+ ~ReportingDelegateImpl() override = default;
bool CanQueueReport(const url::Origin& origin) const override {
return network_delegate() &&
@@ -58,6 +58,6 @@ std::unique_ptr<ReportingDelegate> ReportingDelegate::Create(
return std::make_unique<ReportingDelegateImpl>(request_context);
}
-ReportingDelegate::~ReportingDelegate() {}
+ReportingDelegate::~ReportingDelegate() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_delivery_agent.cc b/chromium/net/reporting/reporting_delivery_agent.cc
index ad439cb2617..8786e3068c2 100644
--- a/chromium/net/reporting/reporting_delivery_agent.cc
+++ b/chromium/net/reporting/reporting_delivery_agent.cc
@@ -81,7 +81,7 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
const std::vector<const ReportingReport*>& reports)
: endpoint(endpoint), reports(reports) {}
- ~Delivery() {}
+ ~Delivery() = default;
const GURL endpoint;
const std::vector<const ReportingReport*> reports;
@@ -97,8 +97,8 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
void StartTimer() {
timer_->Start(FROM_HERE, policy().delivery_interval,
- base::Bind(&ReportingDeliveryAgentImpl::OnTimerFired,
- base::Unretained(this)));
+ base::BindRepeating(&ReportingDeliveryAgentImpl::OnTimerFired,
+ base::Unretained(this)));
}
void OnTimerFired() {
@@ -160,9 +160,9 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
uploader()->StartUpload(
endpoint, json,
- base::Bind(&ReportingDeliveryAgentImpl::OnUploadComplete,
- weak_factory_.GetWeakPtr(),
- std::make_unique<Delivery>(endpoint, reports)));
+ base::BindOnce(&ReportingDeliveryAgentImpl::OnUploadComplete,
+ weak_factory_.GetWeakPtr(),
+ std::make_unique<Delivery>(endpoint, reports)));
}
}
@@ -219,6 +219,6 @@ std::unique_ptr<ReportingDeliveryAgent> ReportingDeliveryAgent::Create(
return std::make_unique<ReportingDeliveryAgentImpl>(context);
}
-ReportingDeliveryAgent::~ReportingDeliveryAgent() {}
+ReportingDeliveryAgent::~ReportingDeliveryAgent() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_delivery_agent_unittest.cc b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
index 4bc74893bfb..c4e233a9ad2 100644
--- a/chromium/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
@@ -42,6 +42,14 @@ class ReportingDeliveryAgentTest : public ReportingTestBase {
return tick_clock()->NowTicks() + base::TimeDelta::FromDays(1);
}
+ void SetClient(const url::Origin& origin,
+ const GURL& endpoint,
+ const std::string& group) {
+ cache()->SetClient(origin, endpoint, ReportingClient::Subdomains::EXCLUDE,
+ group, tomorrow(), ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
+ }
+
const GURL kUrl_ = GURL("https://origin/path");
const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
const GURL kEndpoint_ = GURL("https://endpoint/");
@@ -55,8 +63,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) {
base::DictionaryValue body;
body.SetString("key", "value");
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(),
tick_clock()->NowTicks(), 0);
@@ -94,8 +101,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) {
}
TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
@@ -124,10 +130,8 @@ TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
static const url::Origin kDifferentOrigin =
url::Origin::Create(GURL("https://origin2/"));
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
- cache()->SetClient(kDifferentOrigin, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
ASSERT_TRUE(FindClientInCache(cache(), kOrigin_, kEndpoint_));
ASSERT_TRUE(FindClientInCache(cache(), kDifferentOrigin, kEndpoint_));
@@ -159,8 +163,7 @@ TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
}
TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
@@ -200,10 +203,8 @@ TEST_F(ReportingDeliveryAgentTest,
static const url::Origin kDifferentOrigin =
url::Origin::Create(kDifferentUrl);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
- cache()->SetClient(kDifferentOrigin, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
@@ -228,10 +229,8 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) {
static const url::Origin kDifferentOrigin =
url::Origin::Create(kDifferentUrl);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
- cache()->SetClient(kDifferentOrigin, kEndpoint_,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
@@ -266,10 +265,8 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) {
TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
static const GURL kDifferentEndpoint("https://endpoint2/");
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
- cache()->SetClient(kOrigin_, kDifferentEndpoint,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ SetClient(kOrigin_, kDifferentEndpoint, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
@@ -304,11 +301,8 @@ TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
static const GURL kDifferentEndpoint("https://endpoint2/");
static const std::string kDifferentGroup("group2");
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
- cache()->SetClient(kOrigin_, kDifferentEndpoint,
- ReportingClient::Subdomains::EXCLUDE, kDifferentGroup,
- tomorrow());
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ SetClient(kOrigin_, kDifferentEndpoint, kDifferentGroup);
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
diff --git a/chromium/net/reporting/reporting_endpoint_manager.cc b/chromium/net/reporting/reporting_endpoint_manager.cc
index f216a86da2f..6a4c6c126a5 100644
--- a/chromium/net/reporting/reporting_endpoint_manager.cc
+++ b/chromium/net/reporting/reporting_endpoint_manager.cc
@@ -15,6 +15,7 @@
#include "base/stl_util.h"
#include "base/time/tick_clock.h"
#include "net/base/backoff_entry.h"
+#include "net/base/rand_callback.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_delegate.h"
@@ -28,9 +29,11 @@ namespace {
class ReportingEndpointManagerImpl : public ReportingEndpointManager {
public:
- ReportingEndpointManagerImpl(ReportingContext* context) : context_(context) {}
+ ReportingEndpointManagerImpl(ReportingContext* context,
+ const RandIntCallback& rand_callback)
+ : context_(context), rand_callback_(rand_callback) {}
- ~ReportingEndpointManagerImpl() override {}
+ ~ReportingEndpointManagerImpl() override = default;
bool FindEndpointForOriginAndGroup(const url::Origin& origin,
const std::string& group,
@@ -38,8 +41,12 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(origin, group, &clients);
- // Filter out expired, pending, and backed-off endpoints.
+ // Highest-priority client(s) that are not expired, pending, failing, or
+ // forbidden for use by the ReportingDelegate.
std::vector<const ReportingClient*> available_clients;
+ // Total weight of clients in available_clients.
+ int total_weight = 0;
+
base::TimeTicks now = tick_clock()->NowTicks();
for (const ReportingClient* client : clients) {
if (client->expires < now)
@@ -52,7 +59,23 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
}
if (!delegate()->CanUseClient(client->origin, client->endpoint))
continue;
+
+ // If this client is lower priority than the ones we've found, skip it.
+ if (!available_clients.empty() &&
+ client->priority > available_clients[0]->priority) {
+ continue;
+ }
+
+ // If this client is higher priority than the ones we've found (or we
+ // haven't found any), forget about those ones and remember this one.
+ if (available_clients.empty() ||
+ client->priority < available_clients[0]->priority) {
+ available_clients.clear();
+ total_weight = 0;
+ }
+
available_clients.push_back(client);
+ total_weight += client->weight;
}
if (available_clients.empty()) {
@@ -60,9 +83,20 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
return false;
}
- int random_index = base::RandInt(0, available_clients.size() - 1);
- *endpoint_url_out = available_clients[random_index]->endpoint;
- return true;
+ int random_index = rand_callback_.Run(0, total_weight - 1);
+ int weight_so_far = 0;
+ for (size_t i = 0; i < available_clients.size(); ++i) {
+ const ReportingClient* client = available_clients[i];
+ weight_so_far += client->weight;
+ if (random_index < weight_so_far) {
+ *endpoint_url_out = client->endpoint;
+ return true;
+ }
+ }
+
+ // TODO(juliatuttle): Can we reach this in some weird overflow case?
+ NOTREACHED();
+ return false;
}
void SetEndpointPending(const GURL& endpoint) override {
@@ -91,6 +125,8 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
ReportingContext* context_;
+ RandIntCallback rand_callback_;
+
std::set<GURL> pending_endpoints_;
// Note: Currently the ReportingBrowsingDataRemover does not clear this data
@@ -105,10 +141,11 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
// static
std::unique_ptr<ReportingEndpointManager> ReportingEndpointManager::Create(
- ReportingContext* context) {
- return std::make_unique<ReportingEndpointManagerImpl>(context);
+ ReportingContext* context,
+ const RandIntCallback& rand_callback) {
+ return std::make_unique<ReportingEndpointManagerImpl>(context, rand_callback);
}
-ReportingEndpointManager::~ReportingEndpointManager() {}
+ReportingEndpointManager::~ReportingEndpointManager() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_endpoint_manager.h b/chromium/net/reporting/reporting_endpoint_manager.h
index 1f35198479a..6df5f38b2c5 100644
--- a/chromium/net/reporting/reporting_endpoint_manager.h
+++ b/chromium/net/reporting/reporting_endpoint_manager.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "net/base/net_export.h"
+#include "net/base/rand_callback.h"
#include "net/reporting/reporting_context.h"
class GURL;
@@ -27,7 +28,8 @@ class NET_EXPORT ReportingEndpointManager {
public:
// |context| must outlive the ReportingEndpointManager.
static std::unique_ptr<ReportingEndpointManager> Create(
- ReportingContext* context);
+ ReportingContext* context,
+ const RandIntCallback& rand_callback);
virtual ~ReportingEndpointManager();
diff --git a/chromium/net/reporting/reporting_endpoint_manager_unittest.cc b/chromium/net/reporting/reporting_endpoint_manager_unittest.cc
index 28915e07f66..de26c007f2a 100644
--- a/chromium/net/reporting/reporting_endpoint_manager_unittest.cc
+++ b/chromium/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -22,6 +22,11 @@ namespace {
class ReportingEndpointManagerTest : public ReportingTestBase {
protected:
+ void SetClient(const GURL& endpoint, int priority, int weight) {
+ cache()->SetClient(kOrigin_, endpoint, ReportingClient::Subdomains::EXCLUDE,
+ kGroup_, tomorrow(), priority, weight);
+ }
+
const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
const GURL kEndpoint_ = GURL("https://endpoint/");
const std::string kGroup_ = "group";
@@ -35,8 +40,8 @@ TEST_F(ReportingEndpointManagerTest, NoEndpoint) {
}
TEST_F(ReportingEndpointManagerTest, Endpoint) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
GURL endpoint_url;
bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
@@ -46,8 +51,11 @@ TEST_F(ReportingEndpointManagerTest, Endpoint) {
}
TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, yesterday());
+ SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
+
+ // Default expiration is "tomorrow", so make sure we're past that.
+ tick_clock()->Advance(base::TimeDelta::FromDays(2));
GURL endpoint_url;
bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
@@ -56,8 +64,8 @@ TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) {
}
TEST_F(ReportingEndpointManagerTest, PendingEndpoint) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
endpoint_manager()->SetEndpointPending(kEndpoint_);
@@ -80,8 +88,8 @@ TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) {
base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(
policy().endpoint_backoff_policy.initial_delay_ms);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_, tomorrow());
+ SetClient(kEndpoint_, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false);
@@ -142,28 +150,28 @@ TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) {
// Make sure that multiple endpoints will all be returned at some point, to
// avoid accidentally or intentionally implementing any priority ordering.
TEST_F(ReportingEndpointManagerTest, RandomEndpoint) {
- static const GURL kEndpoint_1("https://endpoint1/");
- static const GURL kEndpoint_2("https://endpoint2/");
+ static const GURL kEndpoint1("https://endpoint1/");
+ static const GURL kEndpoint2("https://endpoint2/");
static const int kMaxAttempts = 20;
- cache()->SetClient(kOrigin_, kEndpoint_1,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
- cache()->SetClient(kOrigin_, kEndpoint_2,
- ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow());
+ SetClient(kEndpoint1, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
+ SetClient(kEndpoint2, ReportingClient::kDefaultPriority,
+ ReportingClient::kDefaultWeight);
bool endpoint1_seen = false;
bool endpoint2_seen = false;
- for (int i = 0; i < kMaxAttempts; i++) {
+ for (int i = 0; i < kMaxAttempts; ++i) {
GURL endpoint_url;
bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
kOrigin_, kGroup_, &endpoint_url);
ASSERT_TRUE(found_endpoint);
- ASSERT_TRUE(endpoint_url == kEndpoint_1 || endpoint_url == kEndpoint_2);
+ ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2);
- if (endpoint_url == kEndpoint_1)
+ if (endpoint_url == kEndpoint1)
endpoint1_seen = true;
- else if (endpoint_url == kEndpoint_2)
+ else if (endpoint_url == kEndpoint2)
endpoint2_seen = true;
if (endpoint1_seen && endpoint2_seen)
@@ -174,5 +182,68 @@ TEST_F(ReportingEndpointManagerTest, RandomEndpoint) {
EXPECT_TRUE(endpoint2_seen);
}
+TEST_F(ReportingEndpointManagerTest, Priority) {
+ static const GURL kPrimaryEndpoint("https://endpoint1/");
+ static const GURL kBackupEndpoint("https://endpoint2/");
+
+ SetClient(kPrimaryEndpoint, 10, ReportingClient::kDefaultWeight);
+ SetClient(kBackupEndpoint, 20, ReportingClient::kDefaultWeight);
+
+ GURL endpoint_url;
+
+ bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+ kOrigin_, kGroup_, &endpoint_url);
+ ASSERT_TRUE(found_endpoint);
+ EXPECT_EQ(kPrimaryEndpoint, endpoint_url);
+
+ endpoint_manager()->SetEndpointPending(kPrimaryEndpoint);
+
+ found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+ kOrigin_, kGroup_, &endpoint_url);
+ ASSERT_TRUE(found_endpoint);
+ EXPECT_EQ(kBackupEndpoint, endpoint_url);
+
+ endpoint_manager()->ClearEndpointPending(kPrimaryEndpoint);
+
+ found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+ kOrigin_, kGroup_, &endpoint_url);
+ ASSERT_TRUE(found_endpoint);
+ EXPECT_EQ(kPrimaryEndpoint, endpoint_url);
+}
+
+// Note: This test depends on the deterministic mock RandIntCallback set up in
+// TestReportingContext, which returns consecutive integers starting at 0
+// (modulo the requested range, plus the requested minimum).
+TEST_F(ReportingEndpointManagerTest, Weight) {
+ static const GURL kEndpoint1("https://endpoint1/");
+ static const GURL kEndpoint2("https://endpoint2/");
+
+ static const int kEndpoint1Weight = 5;
+ static const int kEndpoint2Weight = 2;
+ static const int kTotalEndpointWeight = kEndpoint1Weight + kEndpoint2Weight;
+
+ SetClient(kEndpoint1, ReportingClient::kDefaultPriority, kEndpoint1Weight);
+ SetClient(kEndpoint2, ReportingClient::kDefaultPriority, kEndpoint2Weight);
+
+ int endpoint1_count = 0;
+ int endpoint2_count = 0;
+
+ for (int i = 0; i < kTotalEndpointWeight; ++i) {
+ GURL endpoint_url;
+ bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup(
+ kOrigin_, kGroup_, &endpoint_url);
+ ASSERT_TRUE(found_endpoint);
+ ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2);
+
+ if (endpoint_url == kEndpoint1)
+ ++endpoint1_count;
+ else if (endpoint_url == kEndpoint2)
+ ++endpoint2_count;
+ }
+
+ EXPECT_EQ(kEndpoint1Weight, endpoint1_count);
+ EXPECT_EQ(kEndpoint2Weight, endpoint2_count);
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/reporting/reporting_garbage_collector.cc b/chromium/net/reporting/reporting_garbage_collector.cc
index 3cefeaa2524..bb66cb0349d 100644
--- a/chromium/net/reporting/reporting_garbage_collector.cc
+++ b/chromium/net/reporting/reporting_garbage_collector.cc
@@ -43,9 +43,10 @@ class ReportingGarbageCollectorImpl : public ReportingGarbageCollector,
if (timer_->IsRunning())
return;
- timer_->Start(FROM_HERE, context_->policy().garbage_collection_interval,
- base::Bind(&ReportingGarbageCollectorImpl::CollectGarbage,
- base::Unretained(this)));
+ timer_->Start(
+ FROM_HERE, context_->policy().garbage_collection_interval,
+ base::BindRepeating(&ReportingGarbageCollectorImpl::CollectGarbage,
+ base::Unretained(this)));
}
private:
@@ -86,6 +87,6 @@ std::unique_ptr<ReportingGarbageCollector> ReportingGarbageCollector::Create(
return std::make_unique<ReportingGarbageCollectorImpl>(context);
}
-ReportingGarbageCollector::~ReportingGarbageCollector() {}
+ReportingGarbageCollector::~ReportingGarbageCollector() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_header_parser.cc b/chromium/net/reporting/reporting_header_parser.cc
index e5db601c748..5512a5b7fe5 100644
--- a/chromium/net/reporting/reporting_header_parser.cc
+++ b/chromium/net/reporting/reporting_header_parser.cc
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "base/values.h"
#include "net/reporting/reporting_cache.h"
+#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_delegate.h"
@@ -49,9 +50,19 @@ enum class HeaderEndpointOutcome {
SET_REJECTED_BY_DELEGATE = 10,
SET = 11,
+ DISCARDED_PRIORITY_NOT_INTEGER = 12,
+ DISCARDED_WEIGHT_NOT_INTEGER = 13,
+ DISCARDED_WEIGHT_NOT_POSITIVE = 14,
+
MAX
};
+bool EndpointParsedSuccessfully(HeaderEndpointOutcome outcome) {
+ return outcome == HeaderEndpointOutcome::REMOVED ||
+ outcome == HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE ||
+ outcome == HeaderEndpointOutcome::SET;
+}
+
void RecordHeaderEndpointOutcome(HeaderEndpointOutcome outcome) {
UMA_HISTOGRAM_ENUMERATION("Reporting.HeaderEndpointOutcome", outcome,
HeaderEndpointOutcome::MAX);
@@ -62,12 +73,24 @@ const char kIncludeSubdomainsKey[] = "includeSubdomains";
const char kGroupKey[] = "group";
const char kGroupDefaultValue[] = "default";
const char kMaxAgeKey[] = "max-age";
-
+const char kPriorityKey[] = "priority";
+const char kWeightKey[] = "weight";
+
+// Processes a single endpoint tuple received in a Report-To header.
+//
+// |origin| is the origin that sent the Report-To header.
+//
+// |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,
ReportingCache* cache,
base::TimeTicks now,
- const GURL& url,
- const base::Value& value) {
+ const url::Origin& origin,
+ const base::Value& value,
+ GURL* endpoint_url_out) {
+ *endpoint_url_out = GURL();
+
const base::DictionaryValue* dict = nullptr;
if (!value.GetAsDictionary(&dict))
return HeaderEndpointOutcome::DISCARDED_NOT_DICTIONARY;
@@ -105,18 +128,29 @@ HeaderEndpointOutcome ProcessEndpoint(ReportingDelegate* delegate,
subdomains = ReportingClient::Subdomains::INCLUDE;
}
+ int priority = ReportingClient::kDefaultPriority;
+ if (dict->HasKey(kPriorityKey) && !dict->GetInteger(kPriorityKey, &priority))
+ return HeaderEndpointOutcome::DISCARDED_PRIORITY_NOT_INTEGER;
+
+ int weight = ReportingClient::kDefaultWeight;
+ if (dict->HasKey(kWeightKey) && !dict->GetInteger(kWeightKey, &weight))
+ return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_INTEGER;
+ if (weight <= 0)
+ return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_POSITIVE;
+
+ *endpoint_url_out = endpoint_url;
+
if (ttl_sec == 0) {
- cache->RemoveClientForOriginAndEndpoint(url::Origin::Create(url),
- endpoint_url);
+ cache->RemoveClientForOriginAndEndpoint(origin, endpoint_url);
return HeaderEndpointOutcome::REMOVED;
}
- url::Origin origin = url::Origin::Create(url);
if (!delegate->CanSetClient(origin, endpoint_url))
return HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE;
cache->SetClient(origin, endpoint_url, subdomains, group,
- now + base::TimeDelta::FromSeconds(ttl_sec));
+ now + base::TimeDelta::FromSeconds(ttl_sec), priority,
+ weight);
return HeaderEndpointOutcome::SET;
}
@@ -150,19 +184,37 @@ void ReportingHeaderParser::ParseHeader(ReportingContext* context,
return;
}
- const base::ListValue* list = nullptr;
- bool is_list = value->GetAsList(&list);
+ const base::ListValue* endpoint_list = nullptr;
+ bool is_list = value->GetAsList(&endpoint_list);
DCHECK(is_list);
ReportingDelegate* delegate = context->delegate();
ReportingCache* cache = context->cache();
+
+ url::Origin origin = url::Origin::Create(url);
+
+ std::vector<GURL> old_endpoints;
+ cache->GetEndpointsForOrigin(origin, &old_endpoints);
+
+ std::set<GURL> new_endpoints;
+
base::TimeTicks now = context->tick_clock()->NowTicks();
- for (size_t i = 0; i < list->GetSize(); i++) {
+ for (size_t i = 0; i < endpoint_list->GetSize(); i++) {
const base::Value* endpoint = nullptr;
- bool got_endpoint = list->Get(i, &endpoint);
+ bool got_endpoint = endpoint_list->Get(i, &endpoint);
DCHECK(got_endpoint);
- RecordHeaderEndpointOutcome(
- ProcessEndpoint(delegate, cache, now, url, *endpoint));
+ GURL endpoint_url;
+ HeaderEndpointOutcome outcome =
+ ProcessEndpoint(delegate, cache, now, origin, *endpoint, &endpoint_url);
+ if (EndpointParsedSuccessfully(outcome))
+ new_endpoints.insert(endpoint_url);
+ RecordHeaderEndpointOutcome(outcome);
+ }
+
+ // Remove any endpoints that weren't specified in the current header(s).
+ for (const GURL& old_endpoint : old_endpoints) {
+ if (new_endpoints.count(old_endpoint) == 0u)
+ cache->RemoveClientForOriginAndEndpoint(origin, old_endpoint);
}
}
diff --git a/chromium/net/reporting/reporting_header_parser_fuzzer.cc b/chromium/net/reporting/reporting_header_parser_fuzzer.cc
index 1c31b9ec17b..470d496a633 100644
--- a/chromium/net/reporting/reporting_header_parser_fuzzer.cc
+++ b/chromium/net/reporting/reporting_header_parser_fuzzer.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/time/default_clock.h"
+#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_client.h"
@@ -24,7 +26,9 @@ namespace net_reporting_header_parser_fuzzer {
void FuzzReportingHeaderParser(const std::string& data,
const net::ReportingPolicy& policy) {
- net::TestReportingContext context(policy);
+ net::TestReportingContext context(base::DefaultClock::GetInstance(),
+ base::DefaultTickClock::GetInstance(),
+ policy);
net::ReportingHeaderParser::ParseHeader(&context, kUrl_, data.c_str());
std::vector<const net::ReportingClient*> clients;
context.cache()->GetClients(&clients);
diff --git a/chromium/net/reporting/reporting_header_parser_unittest.cc b/chromium/net/reporting/reporting_header_parser_unittest.cc
index 7d8710ad936..151675e6d12 100644
--- a/chromium/net/reporting/reporting_header_parser_unittest.cc
+++ b/chromium/net/reporting/reporting_header_parser_unittest.cc
@@ -49,6 +49,16 @@ TEST_F(ReportingHeaderParserTest, Invalid) {
// Note that a non-boolean includeSubdomains field is *not* invalid, per
// the spec.
+ {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"priority\":\"\"}",
+ "non-integer priority"},
+
+ {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":\"\"}",
+ "non-integer weight"},
+ {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":-1}",
+ "negative weight"},
+ {"{\"url\":\"https://endpoint/\",\"max-age\":1,\"weight\":0}",
+ "zero weight"},
+
{"[{\"url\":\"https://a/\",\"max-age\":1},"
"{\"url\":\"https://b/\",\"max-age\":1}]",
"wrapped in list"}};
@@ -78,6 +88,21 @@ TEST_F(ReportingHeaderParserTest, Valid) {
EXPECT_EQ(kEndpoint_, client->endpoint);
EXPECT_EQ(ReportingClient::Subdomains::EXCLUDE, client->subdomains);
EXPECT_EQ(86400, (client->expires - tick_clock()->NowTicks()).InSeconds());
+ EXPECT_EQ(ReportingClient::kDefaultPriority, client->priority);
+ EXPECT_EQ(ReportingClient::kDefaultWeight, client->weight);
+}
+
+TEST_F(ReportingHeaderParserTest, ZeroMaxAge) {
+ cache()->SetClient(
+ kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+ tick_clock()->NowTicks() + base::TimeDelta::FromDays(1),
+ ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+
+ ReportingHeaderParser::ParseHeader(
+ context(), kUrl_,
+ "{\"url\":\"" + kEndpoint_.spec() + "\",\"max-age\":0}");
+
+ EXPECT_EQ(nullptr, FindClientInCache(cache(), kOrigin_, kEndpoint_));
}
TEST_F(ReportingHeaderParserTest, Subdomains) {
@@ -92,16 +117,57 @@ TEST_F(ReportingHeaderParserTest, Subdomains) {
EXPECT_EQ(ReportingClient::Subdomains::INCLUDE, client->subdomains);
}
-TEST_F(ReportingHeaderParserTest, ZeroMaxAge) {
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(1));
+TEST_F(ReportingHeaderParserTest, PriorityPositive) {
+ ReportingHeaderParser::ParseHeader(context(), kUrl_,
+ "{\"url\":\"" + kEndpoint_.spec() +
+ "\",\"max-age\":86400,"
+ "\"priority\":2}");
+
+ const ReportingClient* client =
+ FindClientInCache(cache(), kOrigin_, kEndpoint_);
+ ASSERT_TRUE(client);
+ EXPECT_EQ(2, client->priority);
+}
+
+TEST_F(ReportingHeaderParserTest, PriorityNegative) {
+ ReportingHeaderParser::ParseHeader(context(), kUrl_,
+ "{\"url\":\"" + kEndpoint_.spec() +
+ "\",\"max-age\":86400,"
+ "\"priority\":-2}");
+
+ const ReportingClient* client =
+ FindClientInCache(cache(), kOrigin_, kEndpoint_);
+ ASSERT_TRUE(client);
+ EXPECT_EQ(-2, client->priority);
+}
+
+TEST_F(ReportingHeaderParserTest, Weight) {
+ ReportingHeaderParser::ParseHeader(context(), kUrl_,
+ "{\"url\":\"" + kEndpoint_.spec() +
+ "\",\"max-age\":86400,"
+ "\"weight\":3}");
+
+ const ReportingClient* client =
+ FindClientInCache(cache(), kOrigin_, kEndpoint_);
+ ASSERT_TRUE(client);
+ EXPECT_EQ(3, client->weight);
+}
+
+TEST_F(ReportingHeaderParserTest, RemoveOld) {
+ static const GURL kDifferentEndpoint_ = GURL("https://endpoint2/");
ReportingHeaderParser::ParseHeader(
context(), kUrl_,
- "{\"url\":\"" + kEndpoint_.spec() + "\",\"max-age\":0}");
+ "{\"url\":\"" + kEndpoint_.spec() + "\",\"max-age\":86400}");
- EXPECT_EQ(nullptr, FindClientInCache(cache(), kOrigin_, kEndpoint_));
+ EXPECT_TRUE(FindClientInCache(cache(), kOrigin_, kEndpoint_));
+
+ ReportingHeaderParser::ParseHeader(
+ context(), kUrl_,
+ "{\"url\":\"" + kDifferentEndpoint_.spec() + "\",\"max-age\":86400}");
+
+ EXPECT_FALSE(FindClientInCache(cache(), kOrigin_, kEndpoint_));
+ EXPECT_TRUE(FindClientInCache(cache(), kOrigin_, kDifferentEndpoint_));
}
} // namespace
diff --git a/chromium/net/reporting/reporting_network_change_observer.cc b/chromium/net/reporting/reporting_network_change_observer.cc
index 2141efaafb1..20e33a303eb 100644
--- a/chromium/net/reporting/reporting_network_change_observer.cc
+++ b/chromium/net/reporting/reporting_network_change_observer.cc
@@ -60,6 +60,6 @@ ReportingNetworkChangeObserver::Create(ReportingContext* context) {
return std::make_unique<ReportingNetworkChangeObserverImpl>(context);
}
-ReportingNetworkChangeObserver::~ReportingNetworkChangeObserver() {}
+ReportingNetworkChangeObserver::~ReportingNetworkChangeObserver() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_network_change_observer_unittest.cc b/chromium/net/reporting/reporting_network_change_observer_unittest.cc
index 8350e8dd34d..ce114d1ab3b 100644
--- a/chromium/net/reporting/reporting_network_change_observer_unittest.cc
+++ b/chromium/net/reporting/reporting_network_change_observer_unittest.cc
@@ -32,6 +32,13 @@ class ReportingNetworkChangeObserverTest : public ReportingTestBase {
base::RunLoop().RunUntilIdle();
}
+ void SetClient() {
+ cache()->SetClient(
+ kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, kGroup_,
+ tick_clock()->NowTicks() + base::TimeDelta::FromDays(7),
+ ReportingClient::kDefaultPriority, ReportingClient::kDefaultWeight);
+ }
+
size_t report_count() {
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
@@ -60,9 +67,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearNothing) {
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ SetClient();
ASSERT_EQ(1u, report_count());
ASSERT_EQ(1u, client_count());
@@ -81,9 +86,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReports) {
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ SetClient();
ASSERT_EQ(1u, report_count());
ASSERT_EQ(1u, client_count());
@@ -102,9 +105,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearClients) {
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ SetClient();
ASSERT_EQ(1u, report_count());
ASSERT_EQ(1u, client_count());
@@ -123,9 +124,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReportsAndClients) {
cache()->AddReport(kUrl_, kGroup_, kType_,
std::make_unique<base::DictionaryValue>(),
tick_clock()->NowTicks(), 0);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(7));
+ SetClient();
ASSERT_EQ(1u, report_count());
ASSERT_EQ(1u, client_count());
diff --git a/chromium/net/reporting/reporting_observer.cc b/chromium/net/reporting/reporting_observer.cc
index 5e8d778a61b..a37548c73c8 100644
--- a/chromium/net/reporting/reporting_observer.cc
+++ b/chromium/net/reporting/reporting_observer.cc
@@ -8,8 +8,8 @@ namespace net {
void ReportingObserver::OnCacheUpdated() {}
-ReportingObserver::ReportingObserver() {}
+ReportingObserver::ReportingObserver() = default;
-ReportingObserver::~ReportingObserver() {}
+ReportingObserver::~ReportingObserver() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_persister.cc b/chromium/net/reporting/reporting_persister.cc
deleted file mode 100644
index 198ee76b98b..00000000000
--- a/chromium/net/reporting/reporting_persister.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/reporting/reporting_persister.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/strings/string_number_conversions.h"
-#include "base/time/clock.h"
-#include "base/time/tick_clock.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "base/values.h"
-#include "net/reporting/reporting_cache.h"
-#include "net/reporting/reporting_client.h"
-#include "net/reporting/reporting_context.h"
-#include "net/reporting/reporting_observer.h"
-#include "net/reporting/reporting_policy.h"
-#include "net/reporting/reporting_report.h"
-
-namespace net {
-namespace {
-
-std::unique_ptr<base::Value> SerializeOrigin(const url::Origin& origin) {
- auto serialized = std::make_unique<base::DictionaryValue>();
-
- serialized->SetString("scheme", origin.scheme());
- serialized->SetString("host", origin.host());
- serialized->SetInteger("port", origin.port());
- serialized->SetString("suborigin", origin.suborigin());
-
- return std::move(serialized);
-}
-
-bool DeserializeOrigin(const base::DictionaryValue& serialized,
- url::Origin* origin_out) {
- std::string scheme;
- if (!serialized.GetString("scheme", &scheme))
- return false;
-
- std::string host;
- if (!serialized.GetString("host", &host))
- return false;
-
- int port_int;
- if (!serialized.GetInteger("port", &port_int))
- return false;
- uint16_t port = static_cast<uint16_t>(port_int);
- if (port_int != port)
- return false;
-
- std::string suborigin;
- if (!serialized.GetString("suborigin", &suborigin))
- return false;
-
- *origin_out = url::Origin::CreateFromNormalizedTupleWithSuborigin(
- scheme, host, port, suborigin);
- return true;
-}
-
-class ReportingPersisterImpl : public ReportingPersister {
- public:
- ReportingPersisterImpl(ReportingContext* context) : context_(context) {}
-
- // ReportingPersister implementation:
-
- ~ReportingPersisterImpl() override {}
-
- private:
- std::string SerializeTicks(base::TimeTicks time_ticks) {
- base::Time time = time_ticks - tick_clock()->NowTicks() + clock()->Now();
- return base::Int64ToString(time.ToInternalValue());
- }
-
- bool DeserializeTicks(const std::string& serialized,
- base::TimeTicks* time_ticks_out) {
- int64_t internal;
- if (!base::StringToInt64(serialized, &internal))
- return false;
-
- base::Time time = base::Time::FromInternalValue(internal);
- *time_ticks_out = time - clock()->Now() + tick_clock()->NowTicks();
- return true;
- }
-
- std::unique_ptr<base::Value> SerializeReport(const ReportingReport& report) {
- auto serialized = std::make_unique<base::DictionaryValue>();
-
- serialized->SetString("url", report.url.spec());
- serialized->SetString("group", report.group);
- serialized->SetString("type", report.type);
- serialized->Set("body", report.body->CreateDeepCopy());
- serialized->SetString("queued", SerializeTicks(report.queued));
- serialized->SetInteger("attempts", report.attempts);
-
- return std::move(serialized);
- }
-
- bool DeserializeReport(const base::DictionaryValue& report) {
- std::string url_string;
- if (!report.GetString("url", &url_string))
- return false;
- GURL url(url_string);
- if (!url.is_valid())
- return false;
-
- std::string group;
- if (!report.GetString("group", &group))
- return false;
-
- std::string type;
- if (!report.GetString("type", &type))
- return false;
-
- const base::Value* body_original;
- if (!report.Get("body", &body_original))
- return false;
- std::unique_ptr<base::Value> body = body_original->CreateDeepCopy();
-
- std::string queued_string;
- if (!report.GetString("queued", &queued_string))
- return false;
- base::TimeTicks queued;
- if (!DeserializeTicks(queued_string, &queued))
- return false;
-
- int attempts;
- if (!report.GetInteger("attempts", &attempts))
- return false;
- if (attempts < 0)
- return false;
-
- cache()->AddReport(url, group, type, std::move(body), queued, attempts);
- return true;
- }
-
- std::unique_ptr<base::Value> SerializeReports() {
- std::vector<const ReportingReport*> reports;
- cache()->GetReports(&reports);
-
- auto serialized = std::make_unique<base::ListValue>();
- for (const ReportingReport* report : reports)
- serialized->Append(SerializeReport(*report));
-
- return std::move(serialized);
- }
-
- bool DeserializeReports(const base::ListValue& reports) {
- for (size_t i = 0; i < reports.GetSize(); ++i) {
- const base::DictionaryValue* report;
- if (!reports.GetDictionary(i, &report))
- return false;
- if (!DeserializeReport(*report))
- return false;
- }
-
- return true;
- }
-
- std::unique_ptr<base::Value> SerializeClient(const ReportingClient& client) {
- auto serialized = std::make_unique<base::DictionaryValue>();
-
- serialized->Set("origin", SerializeOrigin(client.origin));
- serialized->SetString("endpoint", client.endpoint.spec());
- serialized->SetBoolean(
- "subdomains",
- client.subdomains == ReportingClient::Subdomains::INCLUDE);
- serialized->SetString("group", client.group);
- serialized->SetString("expires", SerializeTicks(client.expires));
-
- return std::move(serialized);
- }
-
- bool DeserializeClient(const base::DictionaryValue& client) {
- const base::DictionaryValue* origin_value;
- if (!client.GetDictionary("origin", &origin_value))
- return false;
- url::Origin origin;
- if (!DeserializeOrigin(*origin_value, &origin))
- return false;
-
- std::string endpoint_string;
- if (!client.GetString("endpoint", &endpoint_string))
- return false;
- GURL endpoint(endpoint_string);
- if (!endpoint.is_valid())
- return false;
-
- bool subdomains_bool;
- if (!client.GetBoolean("subdomains", &subdomains_bool))
- return false;
- ReportingClient::Subdomains subdomains =
- subdomains_bool ? ReportingClient::Subdomains::INCLUDE
- : ReportingClient::Subdomains::EXCLUDE;
-
- std::string group;
- if (!client.GetString("group", &group))
- return false;
-
- std::string expires_string;
- if (!client.GetString("expires", &expires_string))
- return false;
- base::TimeTicks expires;
- if (!DeserializeTicks(expires_string, &expires))
- return false;
-
- cache()->SetClient(origin, endpoint, subdomains, group, expires);
- return true;
- }
-
- std::unique_ptr<base::Value> SerializeClients() {
- std::vector<const ReportingClient*> clients;
- cache()->GetClients(&clients);
-
- auto serialized = std::make_unique<base::ListValue>();
- for (const ReportingClient* client : clients)
- serialized->Append(SerializeClient(*client));
-
- return std::move(serialized);
- }
-
- bool DeserializeClients(const base::ListValue& clients) {
- for (size_t i = 0; i < clients.GetSize(); ++i) {
- const base::DictionaryValue* client;
- if (!clients.GetDictionary(i, &client))
- return false;
- if (!DeserializeClient(*client))
- return false;
- }
-
- return true;
- }
-
- static const int kSupportedVersion = 1;
-
- std::unique_ptr<base::Value> Serialize() {
- auto serialized = std::make_unique<base::DictionaryValue>();
-
- serialized->SetInteger("reporting_serialized_cache_version",
- kSupportedVersion);
-
- bool persist_reports = policy().persist_reports_across_restarts;
- serialized->SetBoolean("includes_reports", persist_reports);
- if (persist_reports)
- serialized->Set("reports", SerializeReports());
-
- bool persist_clients = policy().persist_clients_across_restarts;
- serialized->SetBoolean("includes_clients", persist_clients);
- if (persist_clients)
- serialized->Set("clients", SerializeClients());
-
- return std::move(serialized);
- }
-
- bool Deserialize(const base::Value& serialized_value) {
- std::vector<const ReportingReport*> reports;
- cache()->GetReports(&reports);
- DCHECK(reports.empty());
-
- std::vector<const ReportingClient*> clients;
- cache()->GetClients(&clients);
- DCHECK(clients.empty());
-
- int version;
-
- const base::DictionaryValue* serialized;
- if (!serialized_value.GetAsDictionary(&serialized))
- return false;
-
- if (!serialized->GetInteger("reporting_serialized_cache_version", &version))
- return false;
- if (version != kSupportedVersion)
- return false;
-
- bool includes_reports;
- bool includes_clients;
- if (!serialized->GetBoolean("includes_reports", &includes_reports) ||
- !serialized->GetBoolean("includes_clients", &includes_clients)) {
- return false;
- }
-
- if (includes_reports) {
- const base::ListValue* reports;
- if (!serialized->GetList("reports", &reports))
- return false;
- if (!DeserializeReports(*reports))
- return false;
- }
-
- if (includes_clients) {
- const base::ListValue* clients;
- if (!serialized->GetList("clients", &clients))
- return false;
- if (!DeserializeClients(*clients))
- return false;
- }
-
- return true;
- }
-
- const ReportingPolicy& policy() { return context_->policy(); }
- base::Clock* clock() { return context_->clock(); }
- base::TickClock* tick_clock() { return context_->tick_clock(); }
- ReportingCache* cache() { return context_->cache(); }
-
- ReportingContext* context_;
-};
-
-} // namespace
-
-// static
-std::unique_ptr<ReportingPersister> ReportingPersister::Create(
- ReportingContext* context) {
- return std::make_unique<ReportingPersisterImpl>(context);
-}
-
-ReportingPersister::~ReportingPersister() {}
-
-} // namespace net
diff --git a/chromium/net/reporting/reporting_persister.h b/chromium/net/reporting/reporting_persister.h
deleted file mode 100644
index 40414f0c9e1..00000000000
--- a/chromium/net/reporting/reporting_persister.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_REPORTING_REPORTING_PERSISTER_H_
-#define NET_REPORTING_REPORTING_PERSISTER_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "net/base/net_export.h"
-
-namespace net {
-
-class ReportingContext;
-
-// Will persist the state of the Reporting system to (reasonably) stable
-// storage using an as-yet-unwritten persistence mechanism within //net.
-class NET_EXPORT ReportingPersister {
- public:
- // Creates a ReportingPersister. |context| must outlive the persister.
- static std::unique_ptr<ReportingPersister> Create(ReportingContext* context);
-
- virtual ~ReportingPersister();
-};
-
-} // namespace net
-
-#endif // NET_REPORTING_REPORTING_PERSISTER_H_
diff --git a/chromium/net/reporting/reporting_persister_unittest.cc b/chromium/net/reporting/reporting_persister_unittest.cc
deleted file mode 100644
index 547c7208382..00000000000
--- a/chromium/net/reporting/reporting_persister_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/reporting/reporting_persister.h"
-
-#include "base/json/json_writer.h"
-#include "base/test/simple_test_clock.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/time/time.h"
-#include "base/timer/mock_timer.h"
-#include "base/values.h"
-#include "net/base/test_completion_callback.h"
-#include "net/reporting/reporting_cache.h"
-#include "net/reporting/reporting_client.h"
-#include "net/reporting/reporting_policy.h"
-#include "net/reporting/reporting_report.h"
-#include "net/reporting/reporting_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace {
-
-class ReportingPersisterTest : public ReportingTestBase {
- protected:
- const GURL kUrl_ = GURL("https://origin/path");
- const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
- const GURL kEndpoint_ = GURL("https://endpoint/");
- const std::string kGroup_ = "group";
- const std::string kType_ = "default";
-};
-
-// Disabled because the Persister has no persistence layer to use yet.
-TEST_F(ReportingPersisterTest, DISABLED_Test) {
- ReportingPolicy policy;
- policy.persist_reports_across_restarts = true;
- policy.persist_clients_across_restarts = true;
- // Make sure reports don't expire on our simulated restart.
- policy.max_report_age = base::TimeDelta::FromDays(30);
- UsePolicy(policy);
-
- static const int kAttempts = 3;
-
- base::DictionaryValue body;
- body.SetString("key", "value");
-
- cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(),
- tick_clock()->NowTicks(), kAttempts);
- cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE,
- kGroup_,
- tick_clock()->NowTicks() + base::TimeDelta::FromDays(1));
-
- // TODO: Actually save data, once it's possible.
-
- SimulateRestart(/* delta= */ base::TimeDelta::FromHours(1),
- /* delta_ticks= */ base::TimeDelta::FromHours(-3));
-
- // TODO: Actually load data, once it's possible.
-
- std::vector<const ReportingReport*> reports;
- cache()->GetReports(&reports);
- ASSERT_EQ(1u, reports.size());
- EXPECT_EQ(kUrl_, reports[0]->url);
- EXPECT_EQ(kGroup_, reports[0]->group);
- EXPECT_EQ(kType_, reports[0]->type);
- EXPECT_EQ(body, *reports[0]->body);
- EXPECT_EQ(tick_clock()->NowTicks() - base::TimeDelta::FromHours(1),
- reports[0]->queued);
- EXPECT_EQ(kAttempts, reports[0]->attempts);
-
- const ReportingClient* client =
- FindClientInCache(cache(), kOrigin_, kEndpoint_);
- ASSERT_TRUE(client);
- EXPECT_EQ(ReportingClient::Subdomains::EXCLUDE, client->subdomains);
- EXPECT_EQ(kGroup_, client->group);
- EXPECT_EQ(tick_clock()->NowTicks() + base::TimeDelta::FromDays(1) -
- base::TimeDelta::FromHours(1),
- client->expires);
-}
-
-// TODO(juliatuttle): Test asynchronous behavior.
-
-} // namespace
-} // namespace net
diff --git a/chromium/net/reporting/reporting_policy.cc b/chromium/net/reporting/reporting_policy.cc
index 62b7f68ce56..007eb89bd9a 100644
--- a/chromium/net/reporting/reporting_policy.cc
+++ b/chromium/net/reporting/reporting_policy.cc
@@ -29,21 +29,8 @@ ReportingPolicy::ReportingPolicy()
endpoint_backoff_policy.always_use_initial_delay = false;
}
-ReportingPolicy::ReportingPolicy(const ReportingPolicy& other)
- : max_report_count(other.max_report_count),
- max_client_count(other.max_client_count),
- delivery_interval(other.delivery_interval),
- endpoint_backoff_policy(other.endpoint_backoff_policy),
- persistence_interval(other.persistence_interval),
- persist_reports_across_restarts(other.persist_reports_across_restarts),
- persist_clients_across_restarts(other.persist_clients_across_restarts),
- garbage_collection_interval(other.garbage_collection_interval),
- max_report_age(other.max_report_age),
- max_report_attempts(other.max_report_attempts),
- clear_reports_on_network_changes(other.clear_reports_on_network_changes),
- clear_clients_on_network_changes(other.clear_clients_on_network_changes) {
-}
+ReportingPolicy::ReportingPolicy(const ReportingPolicy& other) = default;
-ReportingPolicy::~ReportingPolicy() {}
+ReportingPolicy::~ReportingPolicy() = default;
} // namespace net
diff --git a/chromium/net/reporting/reporting_service.cc b/chromium/net/reporting/reporting_service.cc
index e72eb7520cd..59976e23224 100644
--- a/chromium/net/reporting/reporting_service.cc
+++ b/chromium/net/reporting/reporting_service.cc
@@ -16,7 +16,7 @@
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_header_parser.h"
-#include "net/reporting/reporting_persister.h"
+#include "net/reporting/reporting_uploader.h"
#include "url/gurl.h"
namespace net {
@@ -28,12 +28,17 @@ class ReportingServiceImpl : public ReportingService {
ReportingServiceImpl(std::unique_ptr<ReportingContext> context)
: context_(std::move(context)) {}
- ~ReportingServiceImpl() override {}
+ // ReportingService implementation:
+
+ ~ReportingServiceImpl() override = default;
void QueueReport(const GURL& url,
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body) override {
+ DCHECK(context_);
+ DCHECK(context_->delegate());
+
if (!context_->delegate()->CanQueueReport(url::Origin::Create(url)))
return;
@@ -46,13 +51,17 @@ class ReportingServiceImpl : public ReportingService {
ReportingHeaderParser::ParseHeader(context_.get(), url, header_value);
}
- void RemoveBrowsingData(
- int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter) override {
+ void RemoveBrowsingData(int data_type_mask,
+ const base::RepeatingCallback<bool(const GURL&)>&
+ origin_filter) override {
ReportingBrowsingDataRemover::RemoveBrowsingData(
context_->cache(), data_type_mask, origin_filter);
}
+ bool RequestIsUpload(const URLRequest& request) override {
+ return context_->uploader()->RequestIsUpload(request);
+ }
+
private:
std::unique_ptr<ReportingContext> context_;
@@ -61,7 +70,7 @@ class ReportingServiceImpl : public ReportingService {
} // namespace
-ReportingService::~ReportingService() {}
+ReportingService::~ReportingService() = default;
// static
std::unique_ptr<ReportingService> ReportingService::Create(
diff --git a/chromium/net/reporting/reporting_service.h b/chromium/net/reporting/reporting_service.h
index 45f9ac7830f..aa7dc40e369 100644
--- a/chromium/net/reporting/reporting_service.h
+++ b/chromium/net/reporting/reporting_service.h
@@ -22,6 +22,7 @@ namespace net {
class ReportingContext;
struct ReportingPolicy;
+class URLRequest;
class URLRequestContext;
// The external interface to the Reporting system, used by the embedder of //net
@@ -63,7 +64,11 @@ class NET_EXPORT ReportingService {
// ReportingBrowsingDataRemover for more details.
virtual void RemoveBrowsingData(
int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter) = 0;
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0;
+
+ // Checks whether |request| is a Reporting upload, to avoid loops of reporting
+ // about report uploads.
+ virtual bool RequestIsUpload(const URLRequest& request) = 0;
protected:
ReportingService() {}
diff --git a/chromium/net/reporting/reporting_service_unittest.cc b/chromium/net/reporting/reporting_service_unittest.cc
index d8978c81f27..24ebceda354 100644
--- a/chromium/net/reporting/reporting_service_unittest.cc
+++ b/chromium/net/reporting/reporting_service_unittest.cc
@@ -30,7 +30,8 @@ class ReportingServiceTest : public ::testing::Test {
const std::string kType_ = "type";
ReportingServiceTest()
- : context_(new TestReportingContext(ReportingPolicy())),
+ : context_(
+ new TestReportingContext(&clock_, &tick_clock_, ReportingPolicy())),
service_(
ReportingService::CreateForTesting(base::WrapUnique(context_))) {}
@@ -38,6 +39,9 @@ class ReportingServiceTest : public ::testing::Test {
ReportingService* service() { return service_.get(); }
private:
+ base::SimpleTestClock clock_;
+ base::SimpleTestTickClock tick_clock_;
+
TestReportingContext* context_;
std::unique_ptr<ReportingService> service_;
};
diff --git a/chromium/net/reporting/reporting_test_util.cc b/chromium/net/reporting/reporting_test_util.cc
index d5f0a8ce755..17671b21a80 100644
--- a/chromium/net/reporting/reporting_test_util.cc
+++ b/chromium/net/reporting/reporting_test_util.cc
@@ -10,17 +10,18 @@
#include "base/bind.h"
#include "base/json/json_reader.h"
+#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/test/simple_test_clock.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/timer/mock_timer.h"
+#include "net/base/rand_callback.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_delivery_agent.h"
#include "net/reporting/reporting_garbage_collector.h"
-#include "net/reporting/reporting_persister.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_uploader.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,17 +34,16 @@ namespace {
class PendingUploadImpl : public TestReportingUploader::PendingUpload {
public:
- PendingUploadImpl(
- const GURL& url,
- const std::string& json,
- const ReportingUploader::Callback& callback,
- const base::Callback<void(PendingUpload*)>& complete_callback)
+ PendingUploadImpl(const GURL& url,
+ const std::string& json,
+ ReportingUploader::UploadCallback callback,
+ base::OnceCallback<void(PendingUpload*)> complete_callback)
: url_(url),
json_(json),
- callback_(callback),
- complete_callback_(complete_callback) {}
+ callback_(std::move(callback)),
+ complete_callback_(std::move(complete_callback)) {}
- ~PendingUploadImpl() override {}
+ ~PendingUploadImpl() override = default;
// PendingUpload implementationP:
const GURL& url() const override { return url_; }
@@ -53,16 +53,16 @@ class PendingUploadImpl : public TestReportingUploader::PendingUpload {
}
void Complete(ReportingUploader::Outcome outcome) override {
- callback_.Run(outcome);
+ std::move(callback_).Run(outcome);
// Deletes |this|.
- complete_callback_.Run(this);
+ std::move(complete_callback_).Run(this);
}
private:
GURL url_;
std::string json_;
- ReportingUploader::Callback callback_;
- base::Callback<void(PendingUpload*)> complete_callback_;
+ ReportingUploader::UploadCallback callback_;
+ base::OnceCallback<void(PendingUpload*)> complete_callback_;
};
void ErasePendingUpload(
@@ -91,22 +91,28 @@ const ReportingClient* FindClientInCache(const ReportingCache* cache,
return nullptr;
}
-TestReportingUploader::PendingUpload::~PendingUpload() {}
-TestReportingUploader::PendingUpload::PendingUpload() {}
+TestReportingUploader::PendingUpload::~PendingUpload() = default;
+TestReportingUploader::PendingUpload::PendingUpload() = default;
-TestReportingUploader::TestReportingUploader() {}
-TestReportingUploader::~TestReportingUploader() {}
+TestReportingUploader::TestReportingUploader() = default;
+TestReportingUploader::~TestReportingUploader() = default;
void TestReportingUploader::StartUpload(const GURL& url,
const std::string& json,
- const Callback& callback) {
+ UploadCallback callback) {
pending_uploads_.push_back(std::make_unique<PendingUploadImpl>(
- url, json, callback, base::Bind(&ErasePendingUpload, &pending_uploads_)));
+ url, json, std::move(callback),
+ base::BindOnce(&ErasePendingUpload, &pending_uploads_)));
}
-TestReportingDelegate::TestReportingDelegate() {}
+bool TestReportingUploader::RequestIsUpload(const URLRequest& request) {
+ NOTIMPLEMENTED();
+ return true;
+}
+
+TestReportingDelegate::TestReportingDelegate() = default;
-TestReportingDelegate::~TestReportingDelegate() {}
+TestReportingDelegate::~TestReportingDelegate() = default;
bool TestReportingDelegate::CanQueueReport(const url::Origin& origin) const {
return true;
@@ -126,12 +132,18 @@ bool TestReportingDelegate::CanUseClient(const url::Origin& origin,
return true;
}
-TestReportingContext::TestReportingContext(const ReportingPolicy& policy)
- : ReportingContext(policy,
- std::make_unique<base::SimpleTestClock>(),
- std::make_unique<base::SimpleTestTickClock>(),
- std::make_unique<TestReportingUploader>(),
- std::make_unique<TestReportingDelegate>()),
+TestReportingContext::TestReportingContext(base::Clock* clock,
+ base::TickClock* tick_clock,
+ const ReportingPolicy& policy)
+ : ReportingContext(
+ policy,
+ clock,
+ tick_clock,
+ base::BindRepeating(&TestReportingContext::RandIntCallback,
+ base::Unretained(this)),
+ std::make_unique<TestReportingUploader>(),
+ std::make_unique<TestReportingDelegate>()),
+ rand_counter_(0),
delivery_timer_(new base::MockTimer(/* retain_user_task= */ false,
/* is_repeating= */ false)),
garbage_collection_timer_(
@@ -147,6 +159,11 @@ TestReportingContext::~TestReportingContext() {
garbage_collection_timer_ = nullptr;
}
+int TestReportingContext::RandIntCallback(int min, int max) {
+ DCHECK_LE(min, max);
+ return min + (rand_counter_++ % (max - min + 1));
+}
+
ReportingTestBase::ReportingTestBase() {
// For tests, disable jitter.
ReportingPolicy policy;
@@ -155,7 +172,7 @@ ReportingTestBase::ReportingTestBase() {
CreateContext(policy, base::Time::Now(), base::TimeTicks::Now());
}
-ReportingTestBase::~ReportingTestBase() {}
+ReportingTestBase::~ReportingTestBase() = default;
void ReportingTestBase::UsePolicy(const ReportingPolicy& new_policy) {
CreateContext(new_policy, clock()->Now(), tick_clock()->NowTicks());
@@ -170,7 +187,8 @@ void ReportingTestBase::SimulateRestart(base::TimeDelta delta,
void ReportingTestBase::CreateContext(const ReportingPolicy& policy,
base::Time now,
base::TimeTicks now_ticks) {
- context_ = std::make_unique<TestReportingContext>(policy);
+ context_ =
+ std::make_unique<TestReportingContext>(&clock_, &tick_clock_, policy);
clock()->SetNow(now);
tick_clock()->SetNowTicks(now_ticks);
}
diff --git a/chromium/net/reporting/reporting_test_util.h b/chromium/net/reporting/reporting_test_util.h
index 488284ee7e5..f2dff8fb6a1 100644
--- a/chromium/net/reporting/reporting_test_util.h
+++ b/chromium/net/reporting/reporting_test_util.h
@@ -10,6 +10,8 @@
#include <vector>
#include "base/macros.h"
+#include "base/test/simple_test_clock.h"
+#include "base/test/simple_test_tick_clock.h"
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_uploader.h"
@@ -66,9 +68,12 @@ class TestReportingUploader : public ReportingUploader {
}
// ReportingUploader implementation:
+
void StartUpload(const GURL& url,
const std::string& json,
- const Callback& callback) override;
+ UploadCallback callback) override;
+
+ bool RequestIsUpload(const URLRequest& request) override;
private:
std::vector<std::unique_ptr<PendingUpload>> pending_uploads_;
@@ -102,15 +107,11 @@ class TestReportingDelegate : public ReportingDelegate {
// Clock, TickClock, Timer, and ReportingUploader.
class TestReportingContext : public ReportingContext {
public:
- TestReportingContext(const ReportingPolicy& policy);
+ TestReportingContext(base::Clock* clock,
+ base::TickClock* tick_clock,
+ const ReportingPolicy& policy);
~TestReportingContext();
- base::SimpleTestClock* test_clock() {
- return reinterpret_cast<base::SimpleTestClock*>(clock());
- }
- base::SimpleTestTickClock* test_tick_clock() {
- return reinterpret_cast<base::SimpleTestTickClock*>(tick_clock());
- }
base::MockTimer* test_delivery_timer() { return delivery_timer_; }
base::MockTimer* test_garbage_collection_timer() {
return garbage_collection_timer_;
@@ -123,8 +124,12 @@ class TestReportingContext : public ReportingContext {
}
private:
- // Owned by the Persister and GarbageCollector, respectively, but referenced
- // here to preserve type:
+ int RandIntCallback(int min, int max);
+
+ int rand_counter_;
+
+ // Owned by the DeliveryAgent and GarbageCollector, respectively, but
+ // referenced here to preserve type:
base::MockTimer* delivery_timer_;
base::MockTimer* garbage_collection_timer_;
@@ -151,10 +156,8 @@ class ReportingTestBase : public ::testing::Test {
const ReportingPolicy& policy() { return context_->policy(); }
- base::SimpleTestClock* clock() { return context_->test_clock(); }
- base::SimpleTestTickClock* tick_clock() {
- return context_->test_tick_clock();
- }
+ base::SimpleTestClock* clock() { return &clock_; }
+ base::SimpleTestTickClock* tick_clock() { return &tick_clock_; }
base::MockTimer* delivery_timer() { return context_->test_delivery_timer(); }
base::MockTimer* garbage_collection_timer() {
return context_->test_garbage_collection_timer();
@@ -172,8 +175,6 @@ class ReportingTestBase : public ::testing::Test {
return context_->garbage_collector();
}
- ReportingPersister* persister() { return context_->persister(); }
-
base::TimeTicks yesterday();
base::TimeTicks now();
base::TimeTicks tomorrow();
@@ -188,6 +189,8 @@ class ReportingTestBase : public ::testing::Test {
base::Time now,
base::TimeTicks now_ticks);
+ base::SimpleTestClock clock_;
+ base::SimpleTestTickClock tick_clock_;
std::unique_ptr<TestReportingContext> context_;
DISALLOW_COPY_AND_ASSIGN(ReportingTestBase);
diff --git a/chromium/net/reporting/reporting_uploader.cc b/chromium/net/reporting/reporting_uploader.cc
index 72352ba6072..2220858c3b0 100644
--- a/chromium/net/reporting/reporting_uploader.cc
+++ b/chromium/net/reporting/reporting_uploader.cc
@@ -23,6 +23,15 @@ namespace net {
namespace {
+class UploadUserData : public base::SupportsUserData::Data {
+ public:
+ static const void* const kUserDataKey;
+};
+
+// SetUserData needs a unique const void* to serve as the key, so create a const
+// void* and use its own address as the unique pointer.
+const void* const UploadUserData::kUserDataKey = &UploadUserData::kUserDataKey;
+
ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) {
if (response_code >= 200 && response_code <= 299)
return ReportingUploader::Outcome::SUCCESS;
@@ -47,7 +56,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
void StartUpload(const GURL& url,
const std::string& json,
- const Callback& callback) override {
+ UploadCallback callback) override {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("reporting", R"(
semantics {
@@ -85,6 +94,9 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
request->set_upload(
ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
+ request->SetUserData(UploadUserData::kUserDataKey,
+ std::make_unique<UploadUserData>());
+
// This inherently sets mode = "no-cors", but that doesn't matter, because
// the origins that are included in the upload don't actually get to see
// the response.
@@ -95,7 +107,12 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
// Have to grab the unique_ptr* first to ensure request.get() happens
// before std::move(request).
std::unique_ptr<Upload>* upload = &uploads_[request.get()];
- *upload = std::make_unique<Upload>(std::move(request), callback);
+ *upload = std::make_unique<Upload>(std::move(request), std::move(callback));
+ }
+
+ // static
+ bool RequestIsUpload(const net::URLRequest& request) override {
+ return request.GetUserData(UploadUserData::kUserDataKey);
}
// URLRequest::Delegate implementation:
@@ -140,7 +157,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
int response_code = headers ? headers->response_code() : 0;
Outcome outcome = ResponseCodeToOutcome(response_code);
- upload->second.Run(outcome);
+ std::move(upload->second).Run(outcome);
request->Cancel();
}
@@ -152,7 +169,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
}
private:
- using Upload = std::pair<std::unique_ptr<URLRequest>, Callback>;
+ using Upload = std::pair<std::unique_ptr<URLRequest>, UploadCallback>;
const URLRequestContext* context_;
std::map<const URLRequest*, std::unique_ptr<Upload>> uploads_;
@@ -163,7 +180,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
// static
const char ReportingUploader::kUploadContentType[] = "application/report";
-ReportingUploader::~ReportingUploader() {}
+ReportingUploader::~ReportingUploader() = default;
// static
std::unique_ptr<ReportingUploader> ReportingUploader::Create(
diff --git a/chromium/net/reporting/reporting_uploader.h b/chromium/net/reporting/reporting_uploader.h
index dfe50e73624..f6c65c701b5 100644
--- a/chromium/net/reporting/reporting_uploader.h
+++ b/chromium/net/reporting/reporting_uploader.h
@@ -15,6 +15,7 @@ class GURL;
namespace net {
+class URLRequest;
class URLRequestContext;
// Uploads already-serialized reports and converts responses to one of the
@@ -23,7 +24,7 @@ class NET_EXPORT ReportingUploader {
public:
enum class Outcome { SUCCESS, REMOVE_ENDPOINT, FAILURE };
- using Callback = base::Callback<void(Outcome outcome)>;
+ using UploadCallback = base::OnceCallback<void(Outcome outcome)>;
static const char kUploadContentType[];
@@ -33,7 +34,10 @@ class NET_EXPORT ReportingUploader {
// |url|, and calls |callback| when complete (whether successful or not).
virtual void StartUpload(const GURL& url,
const std::string& json,
- const Callback& callback) = 0;
+ UploadCallback callback) = 0;
+
+ // Returns whether |request| is an upload request sent by this uploader.
+ virtual bool RequestIsUpload(const URLRequest& request) = 0;
// Creates a real implementation of |ReportingUploader| that uploads reports
// using |context|.
diff --git a/chromium/net/reporting/reporting_uploader_unittest.cc b/chromium/net/reporting/reporting_uploader_unittest.cc
index a3a1526ed4a..9fcda4d0915 100644
--- a/chromium/net/reporting/reporting_uploader_unittest.cc
+++ b/chromium/net/reporting/reporting_uploader_unittest.cc
@@ -65,9 +65,9 @@ class TestUploadCallback {
public:
TestUploadCallback() : called_(false), waiting_(false) {}
- ReportingUploader::Callback callback() {
- return base::Bind(&TestUploadCallback::OnUploadComplete,
- base::Unretained(this));
+ ReportingUploader::UploadCallback callback() {
+ return base::BindOnce(&TestUploadCallback::OnUploadComplete,
+ base::Unretained(this));
}
void WaitForCall() {
@@ -104,8 +104,8 @@ class TestUploadCallback {
};
TEST_F(ReportingUploaderTest, Upload) {
- server_.RegisterRequestMonitor(base::Bind(&CheckUpload));
- server_.RegisterRequestHandler(base::Bind(&ReturnResponse, HTTP_OK));
+ server_.RegisterRequestMonitor(base::BindRepeating(&CheckUpload));
+ server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -114,7 +114,7 @@ TEST_F(ReportingUploaderTest, Upload) {
}
TEST_F(ReportingUploaderTest, Success) {
- server_.RegisterRequestHandler(base::Bind(&ReturnResponse, HTTP_OK));
+ server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -137,7 +137,7 @@ TEST_F(ReportingUploaderTest, NetworkError1) {
}
TEST_F(ReportingUploaderTest, NetworkError2) {
- server_.RegisterRequestHandler(base::Bind(&ReturnInvalidResponse));
+ server_.RegisterRequestHandler(base::BindRepeating(&ReturnInvalidResponse));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -149,7 +149,7 @@ TEST_F(ReportingUploaderTest, NetworkError2) {
TEST_F(ReportingUploaderTest, ServerError) {
server_.RegisterRequestHandler(
- base::Bind(&ReturnResponse, HTTP_INTERNAL_SERVER_ERROR));
+ base::BindRepeating(&ReturnResponse, HTTP_INTERNAL_SERVER_ERROR));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -160,7 +160,8 @@ TEST_F(ReportingUploaderTest, ServerError) {
}
TEST_F(ReportingUploaderTest, RemoveEndpoint) {
- server_.RegisterRequestHandler(base::Bind(&ReturnResponse, HTTP_GONE));
+ server_.RegisterRequestHandler(
+ base::BindRepeating(&ReturnResponse, HTTP_GONE));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -199,8 +200,10 @@ std::unique_ptr<test_server::HttpResponse> CheckRedirect(
TEST_F(ReportingUploaderTest, FollowHttpsRedirect) {
bool followed = false;
- server_.RegisterRequestHandler(base::Bind(&ReturnRedirect, kRedirectPath));
- server_.RegisterRequestHandler(base::Bind(&CheckRedirect, &followed));
+ server_.RegisterRequestHandler(
+ base::BindRepeating(&ReturnRedirect, kRedirectPath));
+ server_.RegisterRequestHandler(
+ base::BindRepeating(&CheckRedirect, &followed));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -215,11 +218,13 @@ TEST_F(ReportingUploaderTest, DontFollowHttpRedirect) {
bool followed = false;
test_server::EmbeddedTestServer http_server_;
- http_server_.RegisterRequestHandler(base::Bind(&CheckRedirect, &followed));
+ http_server_.RegisterRequestHandler(
+ base::BindRepeating(&CheckRedirect, &followed));
ASSERT_TRUE(http_server_.Start());
const GURL target = http_server_.GetURL(kRedirectPath);
- server_.RegisterRequestHandler(base::Bind(&ReturnRedirect, target.spec()));
+ server_.RegisterRequestHandler(
+ base::BindRepeating(&ReturnRedirect, target.spec()));
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
@@ -236,15 +241,15 @@ void CheckNoCookie(const test_server::HttpRequest& request) {
}
TEST_F(ReportingUploaderTest, DontSendCookies) {
- server_.RegisterRequestMonitor(base::Bind(&CheckNoCookie));
- server_.RegisterRequestHandler(base::Bind(&ReturnResponse, HTTP_OK));
+ server_.RegisterRequestMonitor(base::BindRepeating(&CheckNoCookie));
+ server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
ASSERT_TRUE(server_.Start());
ResultSavingCookieCallback<bool> cookie_callback;
context_.cookie_store()->SetCookieWithOptionsAsync(
server_.GetURL("/"), "foo=bar", CookieOptions(),
- base::Bind(&ResultSavingCookieCallback<bool>::Run,
- base::Unretained(&cookie_callback)));
+ base::BindRepeating(&ResultSavingCookieCallback<bool>::Run,
+ base::Unretained(&cookie_callback)));
cookie_callback.WaitUntilDone();
ASSERT_TRUE(cookie_callback.result());
@@ -265,7 +270,7 @@ std::unique_ptr<test_server::HttpResponse> SendCookie(
}
TEST_F(ReportingUploaderTest, DontSaveCookies) {
- server_.RegisterRequestHandler(base::Bind(&SendCookie));
+ server_.RegisterRequestHandler(base::BindRepeating(&SendCookie));
ASSERT_TRUE(server_.Start());
TestUploadCallback upload_callback;
@@ -276,8 +281,8 @@ TEST_F(ReportingUploaderTest, DontSaveCookies) {
GetCookieListCallback cookie_callback;
context_.cookie_store()->GetCookieListWithOptionsAsync(
server_.GetURL("/"), CookieOptions(),
- base::Bind(&GetCookieListCallback::Run,
- base::Unretained(&cookie_callback)));
+ base::BindRepeating(&GetCookieListCallback::Run,
+ base::Unretained(&cookie_callback)));
cookie_callback.WaitUntilDone();
EXPECT_TRUE(cookie_callback.cookies().empty());
@@ -302,7 +307,7 @@ std::unique_ptr<test_server::HttpResponse> ReturnCacheableResponse(
TEST_F(ReportingUploaderTest, DontCacheResponse) {
int request_count = 0;
server_.RegisterRequestHandler(
- base::Bind(&ReturnCacheableResponse, &request_count));
+ base::BindRepeating(&ReturnCacheableResponse, &request_count));
ASSERT_TRUE(server_.Start());
{
diff --git a/chromium/net/server/http_server_unittest.cc b/chromium/net/server/http_server_unittest.cc
index cd60a7fcdd6..aca53999a12 100644
--- a/chromium/net/server/http_server_unittest.cc
+++ b/chromium/net/server/http_server_unittest.cc
@@ -123,9 +123,9 @@ class TestHttpClient {
private:
void Write() {
int result = socket_->Write(
- write_buffer_.get(),
- write_buffer_->BytesRemaining(),
- base::Bind(&TestHttpClient::OnWrite, base::Unretained(this)));
+ write_buffer_.get(), write_buffer_->BytesRemaining(),
+ base::Bind(&TestHttpClient::OnWrite, base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
if (result != ERR_IO_PENDING)
OnWrite(result);
}
@@ -579,6 +579,7 @@ class MockStreamSocket : public StreamSocket {
NOTIMPLEMENTED();
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
// Socket
int Read(IOBuffer* buf,
@@ -600,9 +601,11 @@ class MockStreamSocket : public StreamSocket {
pending_read_data_.erase(0, read_len);
return read_len;
}
+
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_NOT_IMPLEMENTED;
}
int SetReceiveBufferSize(int32_t size) override {
diff --git a/chromium/net/socket/client_socket_handle.h b/chromium/net/socket/client_socket_handle.h
index 53e471972c4..1a0afb96e88 100644
--- a/chromium/net/socket/client_socket_handle.h
+++ b/chromium/net/socket/client_socket_handle.h
@@ -28,6 +28,8 @@
namespace net {
+class SocketTag;
+
// A container for a StreamSocket.
//
// The handle's |group_name| uniquely identifies the origin and type of the
@@ -80,6 +82,7 @@ class NET_EXPORT ClientSocketHandle {
int Init(const std::string& group_name,
const scoped_refptr<typename PoolType::SocketParams>& socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const CompletionCallback& callback,
PoolType* pool,
@@ -240,6 +243,7 @@ int ClientSocketHandle::Init(
const std::string& group_name,
const scoped_refptr<typename PoolType::SocketParams>& socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const CompletionCallback& callback,
PoolType* pool,
@@ -251,8 +255,9 @@ int ClientSocketHandle::Init(
ResetErrorState();
pool_ = pool;
group_name_ = group_name;
- int rv = pool_->RequestSocket(group_name, &socket_params, priority,
- respect_limits, this, callback_, net_log);
+ int rv =
+ pool_->RequestSocket(group_name, &socket_params, priority, socket_tag,
+ respect_limits, this, callback_, net_log);
if (rv == ERR_IO_PENDING) {
user_callback_ = callback;
} else {
diff --git a/chromium/net/socket/client_socket_pool.h b/chromium/net/socket/client_socket_pool.h
index 8652bce23bb..c52188016d6 100644
--- a/chromium/net/socket/client_socket_pool.h
+++ b/chromium/net/socket/client_socket_pool.h
@@ -104,6 +104,7 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
virtual int RequestSocket(const std::string& group_name,
const void* params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
diff --git a/chromium/net/socket/client_socket_pool_base.cc b/chromium/net/socket/client_socket_pool_base.cc
index d80dc8e30e5..1067aae8203 100644
--- a/chromium/net/socket/client_socket_pool_base.cc
+++ b/chromium/net/socket/client_socket_pool_base.cc
@@ -51,12 +51,14 @@ void SetSocketMotivation(StreamSocket* socket,
ConnectJob::ConnectJob(const std::string& group_name,
base::TimeDelta timeout_duration,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
Delegate* delegate,
const NetLogWithSource& net_log)
: group_name_(group_name),
timeout_duration_(timeout_duration),
priority_(priority),
+ socket_tag_(socket_tag),
respect_limits_(respect_limits),
delegate_(delegate),
net_log_(net_log),
@@ -146,6 +148,7 @@ ClientSocketPoolBaseHelper::Request::Request(
ClientSocketHandle* handle,
const CompletionCallback& callback,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
Flags flags,
const NetLogWithSource& net_log)
@@ -154,7 +157,8 @@ ClientSocketPoolBaseHelper::Request::Request(
priority_(priority),
respect_limits_(respect_limits),
flags_(flags),
- net_log_(net_log) {
+ net_log_(net_log),
+ socket_tag_(socket_tag) {
if (respect_limits_ == ClientSocketPool::RespectLimits::DISABLED)
DCHECK_EQ(priority_, MAXIMUM_PRIORITY);
}
@@ -292,6 +296,9 @@ int ClientSocketPoolBaseHelper::RequestSocket(
int rv = RequestSocketInternal(group_name, *request,
HttpRequestInfo::NORMAL_MOTIVATION);
if (rv != ERR_IO_PENDING) {
+ if (rv == OK) {
+ request->handle()->socket()->ApplySocketTag(request->socket_tag());
+ }
request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
rv);
CHECK(!request->handle()->is_initialized());
@@ -965,7 +972,8 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
connect_timing, request->handle(), base::TimeDelta(), group,
request->net_log());
request->net_log().EndEvent(NetLogEventType::SOCKET_POOL);
- InvokeUserCallbackLater(request->handle(), request->callback(), result);
+ InvokeUserCallbackLater(request->handle(), request->callback(), result,
+ request->socket_tag());
} else {
AddIdleSocket(std::move(socket), group);
OnAvailableSocketSlot(group_name, group);
@@ -988,7 +996,8 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
}
request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
result);
- InvokeUserCallbackLater(request->handle(), request->callback(), result);
+ InvokeUserCallbackLater(request->handle(), request->callback(), result,
+ request->socket_tag());
} else {
RemoveConnectJob(job, group);
}
@@ -1052,7 +1061,8 @@ void ClientSocketPoolBaseHelper::ProcessPendingRequest(
request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
rv);
- InvokeUserCallbackLater(request->handle(), request->callback(), rv);
+ InvokeUserCallbackLater(request->handle(), request->callback(), rv,
+ request->socket_tag());
}
}
@@ -1130,7 +1140,8 @@ void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) {
std::unique_ptr<Request> request = group->PopNextPendingRequest();
if (!request)
break;
- InvokeUserCallbackLater(request->handle(), request->callback(), error);
+ InvokeUserCallbackLater(request->handle(), request->callback(), error,
+ request->socket_tag());
}
// Delete group if no longer needed.
@@ -1197,9 +1208,15 @@ bool ClientSocketPoolBaseHelper::CloseOneIdleConnectionInHigherLayeredPool() {
}
void ClientSocketPoolBaseHelper::InvokeUserCallbackLater(
- ClientSocketHandle* handle, const CompletionCallback& callback, int rv) {
+ ClientSocketHandle* handle,
+ const CompletionCallback& callback,
+ int rv,
+ const SocketTag& socket_tag) {
CHECK(!base::ContainsKey(pending_callback_map_, handle));
pending_callback_map_[handle] = CallbackResultPair(callback, rv);
+ if (rv == OK) {
+ handle->socket()->ApplySocketTag(socket_tag);
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback,
weak_factory_.GetWeakPtr(), handle));
diff --git a/chromium/net/socket/client_socket_pool_base.h b/chromium/net/socket/client_socket_pool_base.h
index b363741fbbc..88ee1baf58b 100644
--- a/chromium/net/socket/client_socket_pool_base.h
+++ b/chromium/net/socket/client_socket_pool_base.h
@@ -89,6 +89,7 @@ class NET_EXPORT_PRIVATE ConnectJob {
ConnectJob(const std::string& group_name,
base::TimeDelta timeout_duration,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
Delegate* delegate,
const NetLogWithSource& net_log);
@@ -130,6 +131,7 @@ class NET_EXPORT_PRIVATE ConnectJob {
protected:
RequestPriority priority() const { return priority_; }
+ const SocketTag& socket_tag() const { return socket_tag_; }
ClientSocketPool::RespectLimits respect_limits() const {
return respect_limits_;
}
@@ -154,6 +156,7 @@ class NET_EXPORT_PRIVATE ConnectJob {
const base::TimeDelta timeout_duration_;
// TODO(akalin): Support reprioritization.
const RequestPriority priority_;
+ const SocketTag socket_tag_;
const ClientSocketPool::RespectLimits respect_limits_;
// Timer to abort jobs that take too long.
base::OneShotTimer timer_;
@@ -191,6 +194,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
Request(ClientSocketHandle* handle,
const CompletionCallback& callback,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
Flags flags,
const NetLogWithSource& net_log);
@@ -206,6 +210,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
}
Flags flags() const { return flags_; }
const NetLogWithSource& net_log() const { return net_log_; }
+ const SocketTag& socket_tag() const { return socket_tag_; }
// TODO(eroman): Temporary until crbug.com/467797 is solved.
void CrashIfInvalid() const;
@@ -223,6 +228,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
const ClientSocketPool::RespectLimits respect_limits_;
const Flags flags_;
const NetLogWithSource net_log_;
+ const SocketTag socket_tag_;
// TODO(eroman): Temporary until crbug.com/467797 is solved.
Liveness liveness_ = ALIVE;
@@ -624,9 +630,12 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
// Posts a task to call InvokeUserCallback() on the next iteration through the
// current message loop. Inserts |callback| into |pending_callback_map_|,
- // keyed by |handle|.
- void InvokeUserCallbackLater(
- ClientSocketHandle* handle, const CompletionCallback& callback, int rv);
+ // keyed by |handle|. Apply |socket_tag| to the socket if socket successfully
+ // created.
+ void InvokeUserCallbackLater(ClientSocketHandle* handle,
+ const CompletionCallback& callback,
+ int rv,
+ const SocketTag& socket_tag);
// Invokes the user callback for |handle|. By the time this task has run,
// it's possible that the request has been cancelled, so |handle| may not
@@ -702,6 +711,7 @@ class ClientSocketPoolBase {
Request(ClientSocketHandle* handle,
const CompletionCallback& callback,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
internal::ClientSocketPoolBaseHelper::Flags flags,
const scoped_refptr<SocketParams>& params,
@@ -709,6 +719,7 @@ class ClientSocketPoolBase {
: internal::ClientSocketPoolBaseHelper::Request(handle,
callback,
priority,
+ socket_tag,
respect_limits,
flags,
net_log),
@@ -775,12 +786,13 @@ class ClientSocketPoolBase {
int RequestSocket(const std::string& group_name,
const scoped_refptr<SocketParams>& params,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
const NetLogWithSource& net_log) {
std::unique_ptr<Request> request(new Request(
- handle, callback, priority, respect_limits,
+ handle, callback, priority, socket_tag, respect_limits,
internal::ClientSocketPoolBaseHelper::NORMAL, params, net_log));
return helper_.RequestSocket(group_name, std::move(request));
}
@@ -794,7 +806,7 @@ class ClientSocketPoolBase {
const NetLogWithSource& net_log,
HttpRequestInfo::RequestMotivation motivation) {
const Request request(nullptr /* no handle */, CompletionCallback(), IDLE,
- ClientSocketPool::RespectLimits::ENABLED,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS,
params, net_log);
helper_.RequestSockets(group_name, request, num_sockets, motivation);
diff --git a/chromium/net/socket/client_socket_pool_base_unittest.cc b/chromium/net/socket/client_socket_pool_base_unittest.cc
index 41dbccf7f83..7c9f22bbdcd 100644
--- a/chromium/net/socket/client_socket_pool_base_unittest.cc
+++ b/chromium/net/socket/client_socket_pool_base_unittest.cc
@@ -41,10 +41,12 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -151,9 +153,11 @@ class MockClientSocket : public StreamSocket {
return ERR_UNEXPECTED;
}
- int Write(IOBuffer* /* buf */,
- int len,
- const CompletionCallback& /* callback */) override {
+ int Write(
+ IOBuffer* /* buf */,
+ int len,
+ const CompletionCallback& /* callback */,
+ const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
was_used_to_convey_data_ = true;
return len;
}
@@ -201,6 +205,7 @@ class MockClientSocket : public StreamSocket {
NOTIMPLEMENTED();
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
private:
bool connected_;
@@ -293,6 +298,7 @@ class TestConnectJob : public ConnectJob {
group_name,
timeout_duration,
request.priority(),
+ request.socket_tag(),
request.respect_limits(),
delegate,
NetLogWithSource::Make(net_log,
@@ -517,6 +523,7 @@ class TestClientSocketPool : public ClientSocketPool {
int RequestSocket(const std::string& group_name,
const void* params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -524,7 +531,8 @@ class TestClientSocketPool : public ClientSocketPool {
const scoped_refptr<TestSocketParams>* casted_socket_params =
static_cast<const scoped_refptr<TestSocketParams>*>(params);
return base_.RequestSocket(group_name, *casted_socket_params, priority,
- respect_limits, handle, callback, net_log);
+ socket_tag, respect_limits, handle, callback,
+ net_log);
}
void RequestSockets(const std::string& group_name,
@@ -770,7 +778,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
TestConnectJobDelegate delegate;
ClientSocketHandle ignored;
TestClientSocketPoolBase::Request request(
- &ignored, CompletionCallback(), DEFAULT_PRIORITY,
+ &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
internal::ClientSocketPoolBaseHelper::NORMAL, params_,
NetLogWithSource());
@@ -787,7 +795,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
TestNetLog log;
TestClientSocketPoolBase::Request request(
- &ignored, CompletionCallback(), DEFAULT_PRIORITY,
+ &ignored, CompletionCallback(), DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
internal::ClientSocketPoolBaseHelper::NORMAL, params_,
NetLogWithSource());
@@ -832,7 +840,7 @@ TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
BoundTestNetLog log;
TestLoadTimingInfoNotConnected(handle);
- EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound()));
EXPECT_TRUE(handle.is_initialized());
@@ -870,7 +878,7 @@ TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
info.headers = new HttpResponseHeaders(std::string());
handle.set_ssl_error_response_info(info);
EXPECT_EQ(ERR_CONNECTION_FAILED,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound()));
EXPECT_FALSE(handle.socket());
@@ -1206,7 +1214,7 @@ TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -1215,7 +1223,7 @@ TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
TestCompletionCallback callback;
EXPECT_EQ(
ERR_IO_PENDING,
- handles[i].Init("b", params_, DEFAULT_PRIORITY,
+ handles[i].Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
}
@@ -1235,18 +1243,18 @@ TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
ClientSocketHandle handles[kDefaultMaxSockets];
TestCompletionCallback callbacks[kDefaultMaxSockets];
for (int i = 0; i < kDefaultMaxSockets; ++i) {
- EXPECT_EQ(OK,
- handles[i].Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
- callbacks[i].callback(), pool_.get(),
- NetLogWithSource()));
+ EXPECT_EQ(OK, handles[i].Init(base::IntToString(i), params_,
+ DEFAULT_PRIORITY, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callbacks[i].callback(), pool_.get(),
+ NetLogWithSource()));
}
// Force a stalled group.
ClientSocketHandle stalled_handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
+ stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(),
NetLogWithSource()));
@@ -1273,10 +1281,10 @@ TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
for (int i = 0; i < kDefaultMaxSockets; ++i) {
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handles[i].Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(),
- NetLogWithSource()));
+ handles[i].Init(
+ base::IntToString(i), params_, DEFAULT_PRIORITY,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource()));
}
// Force a stalled group.
@@ -1284,7 +1292,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
ClientSocketHandle stalled_handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
+ stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(),
NetLogWithSource()));
@@ -1327,7 +1335,7 @@ TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
for (int i = 0; i < kDefaultMaxSockets; ++i) {
TestCompletionCallback callback;
EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
- params_, DEFAULT_PRIORITY,
+ params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(),
NetLogWithSource()));
@@ -1339,7 +1347,7 @@ TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
// Now we will hit the socket limit.
EXPECT_EQ(ERR_IO_PENDING,
- stalled_handle.Init("foo", params_, DEFAULT_PRIORITY,
+ stalled_handle.Init("foo", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(),
NetLogWithSource()));
@@ -1367,7 +1375,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
TestCompletionCallback callback;
EXPECT_EQ(
OK, handle.Init(base::IntToString(i), params_, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
}
@@ -1384,7 +1392,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
// which is the one which we would close an idle socket for. We shouldn't
// close an idle socket though, since we should reuse the idle socket.
EXPECT_EQ(OK,
- handle.Init("0", params_, DEFAULT_PRIORITY,
+ handle.Init("0", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -1455,7 +1463,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
handle.Reset();
@@ -1469,7 +1477,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -1477,7 +1485,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -1545,7 +1553,7 @@ void RequestSocketOnComplete(ClientSocketHandle* handle,
scoped_refptr<TestSocketParams> params(new TestSocketParams());
TestCompletionCallback callback;
- int rv = handle->Init("a", params, LOWEST,
+ int rv = handle->Init("a", params, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
nested_callback, pool, NetLogWithSource());
if (rv != ERR_IO_PENDING) {
@@ -1566,7 +1574,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
ClientSocketHandle handle;
TestCompletionCallback second_result_callback;
int rv = handle.Init(
- "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
+ "a", params_, DEFAULT_PRIORITY, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
connect_job_factory_, TestConnectJob::kMockPendingJob,
second_result_callback.callback()),
@@ -1586,7 +1595,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
ClientSocketHandle handle;
TestCompletionCallback second_result_callback;
int rv = handle.Init(
- "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
+ "a", params_, DEFAULT_PRIORITY, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
base::Bind(&RequestSocketOnComplete, &handle, pool_.get(),
connect_job_factory_, TestConnectJob::kMockPendingJob,
second_result_callback.callback()),
@@ -1675,7 +1685,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1683,7 +1693,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
// Cancel the active request.
handle.Reset();
- rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1699,7 +1709,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
ClientSocketHandle handle;
TestCompletionCallback callback;
BoundTestNetLog log;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsOk());
@@ -1713,16 +1723,16 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
TestCompletionCallback callback;
BoundTestNetLog log;
ClientSocketHandle handle1;
- int rv = handle1.Init("a", params_, LOWEST,
+ int rv = handle1.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsOk());
ClientSocketHandle handle2;
- rv = handle2.Init("a", params_, LOWEST,
+ rv = handle2.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
ClientSocketHandle handle3;
- rv = handle3.Init("b", params_, LOWEST,
+ rv = handle3.Init("b", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsOk());
@@ -1739,7 +1749,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
ClientSocketHandle handle;
TestCompletionCallback callback;
BoundTestNetLog log;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsOk());
@@ -1750,7 +1760,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
// Disconnect socket now to make the socket unusable.
socket->Disconnect();
ClientSocketHandle handle2;
- rv = handle2.Init("a", params_, LOWEST,
+ rv = handle2.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsOk());
@@ -1801,7 +1811,7 @@ TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
ClientSocketHandle handle;
TestCompletionCallback callback;
BoundTestNetLog log;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1844,7 +1854,7 @@ TEST_F(ClientSocketPoolBaseTest,
info.headers = new HttpResponseHeaders(std::string());
handle.set_ssl_error_response_info(info);
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), log.bound()));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
@@ -1891,13 +1901,13 @@ TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
BoundTestNetLog log2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -1946,9 +1956,10 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
std::vector<TestSocketRequest*> request_order;
size_t completion_count; // unused
TestSocketRequest req1(&request_order, &completion_count);
- int rv = req1.handle()->Init(
- "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
- req1.callback(), pool_.get(), NetLogWithSource());
+ int rv =
+ req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ req1.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(req1.WaitForResult(), IsOk());
@@ -1957,12 +1968,12 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
TestSocketRequest req2(&request_order, &completion_count);
- rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY,
+ rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
req2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
TestSocketRequest req3(&request_order, &completion_count);
- rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY,
+ rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
req3.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1998,13 +2009,14 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
std::vector<TestSocketRequest*> request_order;
size_t completion_count; // unused
TestSocketRequest req1(&request_order, &completion_count);
- int rv = req1.handle()->Init(
- "a", params_, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED,
- req1.callback(), pool_.get(), NetLogWithSource());
+ int rv =
+ req1.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ req1.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
TestSocketRequest req2(&request_order, &completion_count);
- rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY,
+ rv = req2.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
req2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2013,7 +2025,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
TestSocketRequest req3(&request_order, &completion_count);
- rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY,
+ rv = req3.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
req3.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2035,7 +2047,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2056,7 +2068,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2064,7 +2076,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
+ rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2089,14 +2101,14 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequestsChangeSecondRequestState) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
+ rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2119,7 +2131,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, MEDIUM,
+ int rv = handle.Init("a", params_, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2129,7 +2141,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
// The first request should now be stalled at the socket group limit.
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("a", params_, HIGHEST,
+ rv = handle2.Init("a", params_, HIGHEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2161,7 +2173,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2169,7 +2181,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
// Request for socket from another pool.
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("b", params_, DEFAULT_PRIORITY,
+ rv = handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2178,7 +2190,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
// socket pool limit.
ClientSocketHandle handle3;
TestCompletionCallback callback3;
- rv = handle3.Init("a", params_, DEFAULT_PRIORITY,
+ rv = handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2211,7 +2223,7 @@ TEST_F(ClientSocketPoolBaseTest, Recoverable) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_TRUE(handle.is_initialized());
@@ -2226,7 +2238,7 @@ TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
@@ -2243,7 +2255,7 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_CONNECTION_FAILED,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_FALSE(handle.is_initialized());
@@ -2260,7 +2272,7 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
@@ -2282,7 +2294,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2300,7 +2312,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
// Request a new socket. This should reuse the old socket and complete
// synchronously.
BoundTestNetLog log;
- rv = handle.Init("a", params_, LOWEST,
+ rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), pool_.get(), log.bound());
ASSERT_THAT(rv, IsOk());
@@ -2338,7 +2350,7 @@ TEST_F(ClientSocketPoolBaseTest, MAYBE_CleanupTimedOutIdleSocketsNoReuse) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2346,7 +2358,7 @@ TEST_F(ClientSocketPoolBaseTest, MAYBE_CleanupTimedOutIdleSocketsNoReuse) {
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("a", params_, LOWEST,
+ rv = handle2.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2377,7 +2389,7 @@ TEST_F(ClientSocketPoolBaseTest, MAYBE_CleanupTimedOutIdleSocketsNoReuse) {
// A new socket will be created rather than reusing the idle one.
BoundTestNetLog log;
TestCompletionCallback callback3;
- rv = handle.Init("a", params_, LOWEST,
+ rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), log.bound());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2409,28 +2421,28 @@ TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv = handle.Init("a", params_, LOWEST,
+ int rv = handle.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- rv = handle2.Init("a", params_, LOWEST,
+ rv = handle2.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
ClientSocketHandle handle3;
TestCompletionCallback callback3;
- rv = handle3.Init("a", params_, LOWEST,
+ rv = handle3.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ClientSocketHandle handle4;
TestCompletionCallback callback4;
- rv = handle4.Init("a", params_, LOWEST,
+ rv = handle4.Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback4.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2467,11 +2479,11 @@ TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
TestCompletionCallback callback_b[4];
for (int i = 0; i < 2; ++i) {
- EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST,
+ EXPECT_EQ(OK, handle_a[i].Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_a[i].callback(), pool_.get(),
NetLogWithSource()));
- EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST,
+ EXPECT_EQ(OK, handle_b[i].Init("b", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_b[i].callback(), pool_.get(),
NetLogWithSource()));
@@ -2481,12 +2493,12 @@ TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
for (int i = 2; i < 4; ++i) {
EXPECT_EQ(ERR_IO_PENDING,
- handle_a[i].Init("a", params_, LOWEST,
+ handle_a[i].Init("a", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_a[i].callback(), pool_.get(),
NetLogWithSource()));
EXPECT_EQ(ERR_IO_PENDING,
- handle_b[i].Init("b", params_, LOWEST,
+ handle_b[i].Init("b", params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_b[i].callback(), pool_.get(),
NetLogWithSource()));
@@ -2574,7 +2586,7 @@ class TestReleasingSocketRequest : public TestCompletionCallbackBase {
scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
EXPECT_EQ(expected_result_,
- handle2_.Init("a", con_params, DEFAULT_PRIORITY,
+ handle2_.Init("a", con_params, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2_.callback(), pool_, NetLogWithSource()));
}
@@ -2604,7 +2616,7 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
TestReleasingSocketRequest req(pool_.get(), OK, false);
EXPECT_EQ(
ERR_IO_PENDING,
- req.handle()->Init("a", params_, DEFAULT_PRIORITY,
+ req.handle()->Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
req.callback(), pool_.get(), NetLogWithSource()));
// The next job should complete synchronously
@@ -2632,7 +2644,7 @@ TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -2649,7 +2661,7 @@ TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -2661,7 +2673,7 @@ TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -2694,7 +2706,7 @@ class ConnectWithinCallback : public TestCompletionCallbackBase {
SetResult(result);
EXPECT_EQ(
ERR_IO_PENDING,
- handle_.Init(group_name_, params_, DEFAULT_PRIORITY,
+ handle_.Init(group_name_, params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
nested_callback_.callback(), pool_, NetLogWithSource()));
}
@@ -2718,7 +2730,7 @@ TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
ClientSocketHandle handle;
ConnectWithinCallback callback("a", params_, pool_.get());
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -2743,7 +2755,7 @@ TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("bar", params_, DEFAULT_PRIORITY,
+ handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -2752,7 +2764,7 @@ TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
ClientSocketHandle handles[kDefaultMaxSockets];
for (int i = 1; i < kDefaultMaxSockets; ++i) {
TestCompletionCallback callback;
- EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY,
+ EXPECT_EQ(OK, handles[i].Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(),
NetLogWithSource()));
@@ -2781,7 +2793,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("bar", params_, DEFAULT_PRIORITY,
+ handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
ASSERT_TRUE(pool_->HasGroup("bar"));
@@ -2809,7 +2821,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("bar", params_, DEFAULT_PRIORITY,
+ handle.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
@@ -2817,7 +2829,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("bar", params_, DEFAULT_PRIORITY,
+ handle2.Init("bar", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
ASSERT_TRUE(pool_->HasGroup("bar"));
@@ -2844,7 +2856,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
ClientSocketHandle handle1;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -2857,7 +2869,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
ClientSocketHandle handle2;
EXPECT_EQ(ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
// No idle sockets, and one connecting job.
@@ -2896,7 +2908,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
ClientSocketHandle handle1;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -2909,7 +2921,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
ClientSocketHandle handle2;
EXPECT_EQ(ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
// No idle sockets, and one connecting job.
@@ -2950,7 +2962,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
ClientSocketHandle handle1;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -2963,7 +2975,7 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
ClientSocketHandle handle2;
EXPECT_EQ(ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
// No idle sockets, and one connecting job.
@@ -3008,7 +3020,7 @@ TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
@@ -3022,7 +3034,7 @@ TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
// when created.
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -3042,7 +3054,7 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3050,14 +3062,14 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
ClientSocketHandle handle3;
TestCompletionCallback callback3;
EXPECT_EQ(
ERR_IO_PENDING,
- handle3.Init("a", params_, DEFAULT_PRIORITY,
+ handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource()));
@@ -3074,15 +3086,15 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
handle3.Reset();
EXPECT_EQ(
- OK, handle1.Init("a", params_, DEFAULT_PRIORITY,
+ OK, handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(
- OK, handle2.Init("a", params_, DEFAULT_PRIORITY,
+ OK, handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(
- OK, handle3.Init("a", params_, DEFAULT_PRIORITY,
+ OK, handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource()));
@@ -3107,7 +3119,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3115,7 +3127,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -3141,7 +3153,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3161,7 +3173,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -3188,7 +3200,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3196,7 +3208,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("a", params_, DEFAULT_PRIORITY,
+ handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -3204,7 +3216,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback3;
EXPECT_EQ(
ERR_IO_PENDING,
- handle3.Init("a", params_, DEFAULT_PRIORITY,
+ handle3.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource()));
@@ -3286,7 +3298,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
ASSERT_THAT(callback1.WaitForResult(), IsOk());
@@ -3313,7 +3325,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
ASSERT_THAT(callback1.WaitForResult(), IsOk());
@@ -3392,14 +3404,14 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
ASSERT_THAT(callback1.WaitForResult(), IsOk());
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- int rv = handle2.Init("a", params_, DEFAULT_PRIORITY,
+ int rv = handle2.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource());
if (rv != OK) {
@@ -3473,7 +3485,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3507,7 +3519,7 @@ TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(OK,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -3534,7 +3546,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
TestCompletionCallback callback1;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("a", params_, DEFAULT_PRIORITY,
+ handle1.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3547,12 +3559,12 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
TestCompletionCallback callback2;
EXPECT_EQ(
ERR_IO_PENDING,
- handle1.Init("b", params_, DEFAULT_PRIORITY,
+ handle1.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(
ERR_IO_PENDING,
- handle2.Init("b", params_, DEFAULT_PRIORITY,
+ handle2.Init("b", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
@@ -3641,7 +3653,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
// Timer has started, but the backup connect job shouldn't be created yet.
@@ -3679,7 +3691,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(OK,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -3714,7 +3726,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectSetsMotivation) {
TestCompletionCallback callback;
EXPECT_EQ(
ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
@@ -3753,7 +3765,7 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectPreservesExistingMotivation) {
for (size_t i = 0; i < 3; ++i) {
EXPECT_EQ(ERR_IO_PENDING,
- handles[i].Init("a", params_, DEFAULT_PRIORITY,
+ handles[i].Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callbacks[i].callback(), pool_.get(),
NetLogWithSource()));
@@ -3794,14 +3806,14 @@ class MockLayeredPool : public HigherLayeredPool {
int RequestSocket(TestClientSocketPool* pool) {
scoped_refptr<TestSocketParams> params(new TestSocketParams());
- return handle_.Init(group_name_, params, DEFAULT_PRIORITY,
+ return handle_.Init(group_name_, params, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback_.callback(), pool, NetLogWithSource());
}
int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
scoped_refptr<TestSocketParams> params(new TestSocketParams());
- return handle_.Init(group_name_, params, MAXIMUM_PRIORITY,
+ return handle_.Init(group_name_, params, MAXIMUM_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::DISABLED,
callback_.callback(), pool, NetLogWithSource());
}
@@ -3866,7 +3878,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -3887,7 +3899,7 @@ TEST_F(ClientSocketPoolBaseTest,
ClientSocketHandle handle1;
TestCompletionCallback callback1;
EXPECT_EQ(
- OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
+ OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3899,7 +3911,7 @@ TEST_F(ClientSocketPoolBaseTest,
ClientSocketHandle handle;
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("group2", params_, DEFAULT_PRIORITY,
+ handle.Init("group2", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback2.WaitForResult(), IsOk());
@@ -3920,7 +3932,7 @@ TEST_F(ClientSocketPoolBaseTest,
ClientSocketHandle handle1;
TestCompletionCallback callback1;
EXPECT_EQ(
- OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
+ OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3936,7 +3948,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback3;
EXPECT_EQ(
ERR_IO_PENDING,
- handle3.Init("group3", params_, DEFAULT_PRIORITY,
+ handle3.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource()));
@@ -3951,7 +3963,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback4;
EXPECT_EQ(
ERR_IO_PENDING,
- handle4.Init("group3", params_, DEFAULT_PRIORITY,
+ handle4.Init("group3", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback4.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback3.WaitForResult(), IsOk());
@@ -3981,7 +3993,7 @@ TEST_F(ClientSocketPoolBaseTest,
ClientSocketHandle handle1;
TestCompletionCallback callback1;
EXPECT_EQ(
- OK, handle1.Init("group1", params_, DEFAULT_PRIORITY,
+ OK, handle1.Init("group1", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), pool_.get(), NetLogWithSource()));
@@ -3997,7 +4009,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback3;
EXPECT_EQ(
ERR_IO_PENDING,
- handle3.Init("group3", params_, MEDIUM,
+ handle3.Init("group3", params_, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback3.callback(), pool_.get(), NetLogWithSource()));
@@ -4011,7 +4023,7 @@ TEST_F(ClientSocketPoolBaseTest,
TestCompletionCallback callback4;
EXPECT_EQ(
ERR_IO_PENDING,
- handle4.Init("group3", params_, HIGHEST,
+ handle4.Init("group3", params_, HIGHEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback4.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback4.WaitForResult(), IsOk());
@@ -4041,7 +4053,7 @@ TEST_F(ClientSocketPoolBaseTest,
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, DEFAULT_PRIORITY,
+ handle.Init("a", params_, DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsOk());
diff --git a/chromium/net/socket/client_socket_pool_manager.cc b/chromium/net/socket/client_socket_pool_manager.cc
index ffec16ff294..4bc94e61805 100644
--- a/chromium/net/socket/client_socket_pool_manager.cc
+++ b/chromium/net/socket/client_socket_pool_manager.cc
@@ -76,6 +76,7 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
const SSLConfig& ssl_config_for_proxy,
bool force_tunnel,
PrivacyMode privacy_mode,
+ const SocketTag& socket_tag,
const NetLogWithSource& net_log,
int num_preconnect_streams,
ClientSocketHandle* socket_handle,
@@ -153,6 +154,14 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
non_ssl_combine_connect_and_write_policy));
if (proxy_info.is_http() || proxy_info.is_https()) {
+ // TODO(mmenke): Would it be better to split these into two different
+ // socket pools? And maybe socks4/socks5 as well?
+ if (proxy_info.is_http()) {
+ connection_group = "http_proxy/" + connection_group;
+ } else {
+ connection_group = "https_proxy/" + connection_group;
+ }
+
std::string user_agent;
request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
&user_agent);
@@ -177,8 +186,7 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
proxy_tcp_params, ssl_params, QUIC_VERSION_UNSUPPORTED, user_agent,
origin_host_port, session->http_auth_cache(),
session->http_auth_handler_factory(), session->spdy_session_pool(),
- session->quic_stream_factory(), force_tunnel || using_ssl,
- session->context().proxy_delegate);
+ session->quic_stream_factory(), force_tunnel || using_ssl);
} else {
DCHECK(proxy_info.is_socks());
char socks_version;
@@ -189,9 +197,9 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
connection_group = base::StringPrintf(
"socks%c/%s", socks_version, connection_group.c_str());
- socks_params = new SOCKSSocketParams(proxy_tcp_params,
- socks_version == '5',
- origin_host_port);
+ socks_params = new SOCKSSocketParams(
+ proxy_tcp_params, socks_version == '5', origin_host_port,
+ proxy_info.traffic_annotation());
}
}
@@ -225,7 +233,8 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
}
return socket_handle->Init(connection_group, ssl_params, request_priority,
- respect_limits, callback, ssl_pool, net_log);
+ socket_tag, respect_limits, callback, ssl_pool,
+ net_log);
}
// Finally, get the connection started.
@@ -240,8 +249,8 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
}
return socket_handle->Init(connection_group, http_proxy_params,
- request_priority, respect_limits, callback, pool,
- net_log);
+ request_priority, socket_tag, respect_limits,
+ callback, pool, net_log);
}
if (proxy_info.is_socks()) {
@@ -254,7 +263,8 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
}
return socket_handle->Init(connection_group, socks_params, request_priority,
- respect_limits, callback, pool, net_log);
+ socket_tag, respect_limits, callback, pool,
+ net_log);
}
DCHECK(proxy_info.is_direct());
@@ -270,7 +280,8 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
}
return socket_handle->Init(connection_group, tcp_params, request_priority,
- respect_limits, callback, pool, net_log);
+ socket_tag, respect_limits, callback, pool,
+ net_log);
}
} // namespace
@@ -353,6 +364,7 @@ int InitSocketHandleForHttpRequest(
const SSLConfig& ssl_config_for_origin,
const SSLConfig& ssl_config_for_proxy,
PrivacyMode privacy_mode,
+ const SocketTag& socket_tag,
const NetLogWithSource& net_log,
ClientSocketHandle* socket_handle,
const OnHostResolutionCallback& resolution_callback,
@@ -362,7 +374,7 @@ int InitSocketHandleForHttpRequest(
group_type, endpoint, request_extra_headers, request_load_flags,
request_priority, session, proxy_info, expect_spdy, quic_version,
ssl_config_for_origin, ssl_config_for_proxy, /*force_tunnel=*/false,
- privacy_mode, net_log, 0, socket_handle,
+ privacy_mode, socket_tag, net_log, 0, socket_handle,
HttpNetworkSession::NORMAL_SOCKET_POOL, resolution_callback, callback,
HttpRequestInfo::NORMAL_MOTIVATION);
}
@@ -388,9 +400,9 @@ int InitSocketHandleForWebSocketRequest(
group_type, endpoint, request_extra_headers, request_load_flags,
request_priority, session, proxy_info, expect_spdy,
QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin, ssl_config_for_proxy,
- /*force_tunnel=*/true, privacy_mode, net_log, 0, socket_handle,
- HttpNetworkSession::WEBSOCKET_SOCKET_POOL, resolution_callback, callback,
- HttpRequestInfo::NORMAL_MOTIVATION);
+ /*force_tunnel=*/true, privacy_mode, SocketTag(), net_log, 0,
+ socket_handle, HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
+ resolution_callback, callback, HttpRequestInfo::NORMAL_MOTIVATION);
}
int InitSocketHandleForRawConnect(const HostPortPair& host_port_pair,
@@ -411,7 +423,7 @@ int InitSocketHandleForRawConnect(const HostPortPair& host_port_pair,
request_extra_headers, request_load_flags, request_priority, session,
proxy_info, /*expect_spdy=*/false, QUIC_VERSION_UNSUPPORTED,
ssl_config_for_origin, ssl_config_for_proxy, /*force_tunnel=*/true,
- privacy_mode, net_log, 0, socket_handle,
+ privacy_mode, SocketTag(), net_log, 0, socket_handle,
HttpNetworkSession::NORMAL_SOCKET_POOL, OnHostResolutionCallback(),
callback, HttpRequestInfo::NORMAL_MOTIVATION);
}
@@ -433,8 +445,8 @@ int InitSocketHandleForTlsConnect(const HostPortPair& endpoint,
ClientSocketPoolManager::SSL_GROUP, endpoint, request_extra_headers,
request_load_flags, request_priority, session, proxy_info,
/*expect_spdy=*/false, QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin,
- ssl_config_for_proxy, /*force_tunnel=*/true, privacy_mode, net_log, 0,
- socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
+ ssl_config_for_proxy, /*force_tunnel=*/true, privacy_mode, SocketTag(),
+ net_log, 0, socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
OnHostResolutionCallback(), callback, HttpRequestInfo::NORMAL_MOTIVATION);
}
@@ -457,9 +469,9 @@ int PreconnectSocketsForHttpRequest(
group_type, endpoint, request_extra_headers, request_load_flags,
request_priority, session, proxy_info, expect_spdy,
QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin, ssl_config_for_proxy,
- /*force_tunnel=*/false, privacy_mode, net_log, num_preconnect_streams,
- NULL, HttpNetworkSession::NORMAL_SOCKET_POOL, OnHostResolutionCallback(),
- CompletionCallback(), motivation);
+ /*force_tunnel=*/false, privacy_mode, SocketTag(), net_log,
+ num_preconnect_streams, NULL, HttpNetworkSession::NORMAL_SOCKET_POOL,
+ OnHostResolutionCallback(), CompletionCallback(), motivation);
}
} // namespace net
diff --git a/chromium/net/socket/client_socket_pool_manager.h b/chromium/net/socket/client_socket_pool_manager.h
index e813854f14b..6412fe1bdb5 100644
--- a/chromium/net/socket/client_socket_pool_manager.h
+++ b/chromium/net/socket/client_socket_pool_manager.h
@@ -118,6 +118,7 @@ int InitSocketHandleForHttpRequest(
const SSLConfig& ssl_config_for_origin,
const SSLConfig& ssl_config_for_proxy,
PrivacyMode privacy_mode,
+ const SocketTag& socket_tag,
const NetLogWithSource& net_log,
ClientSocketHandle* socket_handle,
const OnHostResolutionCallback& resolution_callback,
diff --git a/chromium/net/socket/datagram_client_socket.h b/chromium/net/socket/datagram_client_socket.h
index dbec1c2b3b4..ca656b361df 100644
--- a/chromium/net/socket/datagram_client_socket.h
+++ b/chromium/net/socket/datagram_client_socket.h
@@ -13,6 +13,7 @@
namespace net {
class IPEndPoint;
+class SocketTag;
class NET_EXPORT_PRIVATE DatagramClientSocket : public DatagramSocket,
public Socket {
@@ -41,6 +42,8 @@ class NET_EXPORT_PRIVATE DatagramClientSocket : public DatagramSocket,
// ConnectUsingNetwork() or ConnectUsingDefaultNetwork().
virtual NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const = 0;
+ // Apply |tag| to this socket.
+ virtual void ApplySocketTag(const SocketTag& tag) = 0;
};
} // namespace net
diff --git a/chromium/net/socket/fuzzed_datagram_client_socket.cc b/chromium/net/socket/fuzzed_datagram_client_socket.cc
index 85db48582a6..65043f505e3 100644
--- a/chromium/net/socket/fuzzed_datagram_client_socket.cc
+++ b/chromium/net/socket/fuzzed_datagram_client_socket.cc
@@ -15,6 +15,7 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -64,6 +65,8 @@ FuzzedDatagramClientSocket::GetBoundNetwork() const {
return NetworkChangeNotifier::kInvalidNetworkHandle;
}
+void FuzzedDatagramClientSocket::ApplySocketTag(const SocketTag& tag) {}
+
void FuzzedDatagramClientSocket::Close() {
connected_ = false;
read_pending_ = false;
@@ -130,9 +133,11 @@ int FuzzedDatagramClientSocket::Read(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int FuzzedDatagramClientSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FuzzedDatagramClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
CHECK(!callback.is_null());
CHECK(!write_pending_);
diff --git a/chromium/net/socket/fuzzed_datagram_client_socket.h b/chromium/net/socket/fuzzed_datagram_client_socket.h
index a354e8ed790..6d195626ad9 100644
--- a/chromium/net/socket/fuzzed_datagram_client_socket.h
+++ b/chromium/net/socket/fuzzed_datagram_client_socket.h
@@ -14,6 +14,7 @@
#include "net/base/ip_endpoint.h"
#include "net/base/network_change_notifier.h"
#include "net/log/net_log_with_source.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
class FuzzedDataProvider;
@@ -38,6 +39,7 @@ class FuzzedDatagramClientSocket : public DatagramClientSocket {
const IPEndPoint& address) override;
int ConnectUsingDefaultNetwork(const IPEndPoint& address) override;
NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// DatagramSocket implementation:
void Close() override;
@@ -52,7 +54,8 @@ class FuzzedDatagramClientSocket : public DatagramClientSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
diff --git a/chromium/net/socket/fuzzed_socket.cc b/chromium/net/socket/fuzzed_socket.cc
index 08be4bf2aa4..be62fff5a8b 100644
--- a/chromium/net/socket/fuzzed_socket.cc
+++ b/chromium/net/socket/fuzzed_socket.cc
@@ -13,6 +13,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/io_buffer.h"
#include "net/log/net_log_source_type.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -89,9 +90,11 @@ int FuzzedSocket::Read(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int FuzzedSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int FuzzedSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
DCHECK(!connect_pending_);
DCHECK(!write_pending_);
@@ -240,6 +243,8 @@ int64_t FuzzedSocket::GetTotalReceivedBytes() const {
return total_bytes_read_;
}
+void FuzzedSocket::ApplySocketTag(const net::SocketTag& tag) {}
+
Error FuzzedSocket::ConsumeReadWriteErrorFromData() {
return data_provider_->PickValueInArray(kReadWriteErrors);
}
diff --git a/chromium/net/socket/fuzzed_socket.h b/chromium/net/socket/fuzzed_socket.h
index 2da0b03cb5d..3340e4349d7 100644
--- a/chromium/net/socket/fuzzed_socket.h
+++ b/chromium/net/socket/fuzzed_socket.h
@@ -15,6 +15,7 @@
#include "net/base/net_errors.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
class FuzzedDataProvider;
@@ -63,7 +64,8 @@ class FuzzedSocket : public StreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -86,6 +88,7 @@ class FuzzedSocket : public StreamSocket {
void ClearConnectionAttempts() override;
void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const net::SocketTag& tag) override;
private:
// Returns a net::Error that can be returned by a read or a write. Reads and
diff --git a/chromium/net/socket/fuzzed_socket_factory.cc b/chromium/net/socket/fuzzed_socket_factory.cc
index 55ffd99125c..ca158aea386 100644
--- a/chromium/net/socket/fuzzed_socket_factory.cc
+++ b/chromium/net/socket/fuzzed_socket_factory.cc
@@ -16,6 +16,7 @@
#include "net/socket/fuzzed_datagram_client_socket.h"
#include "net/socket/fuzzed_socket.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -39,7 +40,8 @@ class FailingSSLClientSocket : public SSLClientSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
NOTREACHED();
return ERR_UNEXPECTED;
}
@@ -88,6 +90,8 @@ class FailingSSLClientSocket : public SSLClientSocket {
int64_t GetTotalReceivedBytes() const override { return 0; }
+ void ApplySocketTag(const net::SocketTag& tag) override {}
+
// SSLSocket implementation:
int ExportKeyingMaterial(const base::StringPiece& label,
bool has_context,
diff --git a/chromium/net/socket/sequenced_socket_data_unittest.cc b/chromium/net/socket/sequenced_socket_data_unittest.cc
index 4d54f23322f..e2bae3a93e1 100644
--- a/chromium/net/socket/sequenced_socket_data_unittest.cc
+++ b/chromium/net/socket/sequenced_socket_data_unittest.cc
@@ -12,6 +12,7 @@
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/test/gtest_util.h"
@@ -267,7 +268,7 @@ void SequencedSocketDataTest::Initialize(MockRead* reads,
EXPECT_EQ(OK,
connection_.Init(
- endpoint_.ToString(), tcp_params_, LOWEST,
+ endpoint_.ToString(), tcp_params_, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, CompletionCallback(),
reinterpret_cast<TransportClientSocketPool*>(&socket_pool_),
NetLogWithSource()));
@@ -671,8 +672,8 @@ TEST_F(SequencedSocketDataTest, SingleSyncWriteTooSmall) {
static const char* kExpectedFailures[] = {
"Expected: (data.length()) >= (expected_data.length())",
- "To be equal to: actual_data",
- "To be equal to: sock_->Write(buf.get(), len, failing_callback_)"};
+ "Value of: actual_data == expected_data\n Actual: false\nExpected: true",
+ "Expected equality of these values:\n rv"};
ASSERT_EQ(arraysize(kExpectedFailures),
static_cast<size_t>(gtest_failures.size()));
diff --git a/chromium/net/socket/socket.h b/chromium/net/socket/socket.h
index 8f5fed6dea0..1d0ab9297d7 100644
--- a/chromium/net/socket/socket.h
+++ b/chromium/net/socket/socket.h
@@ -10,6 +10,7 @@
#include "base/feature_list.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -62,8 +63,14 @@ class NET_EXPORT Socket {
// closed. Implementations of this method should not modify the contents
// of the actual buffer that is written to the socket. If the socket is
// Disconnected before the write completes, the callback will not be invoked.
- virtual int Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) = 0;
+ // |traffic_annotation| provides the required description for auditing. Please
+ // refer to //docs/network_traffic_annotations.md for more details.
+ // TODO(crbug.com/656607): Remove default value.
+ virtual int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation =
+ NO_TRAFFIC_ANNOTATION_BUG_656607) = 0;
// Set the receive buffer size (in bytes) for the socket.
// Note: changing this value can affect the TCP window size on some platforms.
diff --git a/chromium/net/socket/socket_posix.cc b/chromium/net/socket/socket_posix.cc
index ae9bb1e3b78..91ce4e82e7a 100644
--- a/chromium/net/socket/socket_posix.cc
+++ b/chromium/net/socket/socket_posix.cc
@@ -20,6 +20,7 @@
#include "net/base/net_errors.h"
#include "net/base/sockaddr_storage.h"
#include "net/base/trace_constants.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#if defined(OS_FUCHSIA)
#include <poll.h>
@@ -346,9 +347,11 @@ int SocketPosix::ReadIfReady(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int SocketPosix::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int SocketPosix::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_NE(kInvalidSocket, socket_fd_);
DCHECK(!waiting_connect_);
diff --git a/chromium/net/socket/socket_posix.h b/chromium/net/socket/socket_posix.h
index 04ef7f6cb95..cdccc8c04bf 100644
--- a/chromium/net/socket/socket_posix.h
+++ b/chromium/net/socket/socket_posix.h
@@ -15,6 +15,7 @@
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/socket/socket_descriptor.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -75,7 +76,10 @@ class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
int ReadIfReady(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback);
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Waits for next write event. This is called by TCPSocketPosix for TCP
// fastopen after sending first data. Returns ERR_IO_PENDING if it starts
diff --git a/chromium/net/socket/socket_tag_unittest.cc b/chromium/net/socket/socket_tag_unittest.cc
index 59b0f69db3b..93bd8b3be23 100644
--- a/chromium/net/socket/socket_tag_unittest.cc
+++ b/chromium/net/socket/socket_tag_unittest.cc
@@ -12,64 +12,17 @@
#include <sys/types.h>
#endif
-#include <inttypes.h> // For SCNx64
#include <stdint.h>
-#include <stdio.h>
-#include <string>
-
-#include "base/files/file_util.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/sockaddr_storage.h"
+#include "net/socket/socket_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
-namespace {
-
-#if defined(OS_ANDROID)
-// Query the system to find out how many bytes were received with tag
-// |expected_tag| for our UID. Return the count of recieved bytes.
-uint64_t GetTaggedBytes(int32_t expected_tag) {
- // To determine how many bytes the system saw with a particular tag read
- // the /proc/net/xt_qtaguid/stats file which contains the kernel's
- // dump of all the UIDs and their tags sent and received bytes.
- uint64_t bytes = 0;
- std::string contents;
- EXPECT_TRUE(base::ReadFileToString(
- base::FilePath::FromUTF8Unsafe("/proc/net/xt_qtaguid/stats"), &contents));
- for (size_t i = contents.find('\n'); // Skip first line which is headers.
- i != std::string::npos && i < contents.length();) {
- uint64_t tag, rx_bytes;
- uid_t uid;
- int n;
- // Parse out the numbers we care about. For reference here's the column
- // headers:
- // idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes
- // tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets
- // rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes
- // tx_udp_packets tx_other_bytes tx_other_packets
- EXPECT_EQ(sscanf(contents.c_str() + i,
- "%*d %*s 0x%" SCNx64 " %d %*d %" SCNu64
- " %*d %*d %*d %*d %*d %*d %*d %*d "
- "%*d %*d %*d %*d %*d %*d %*d%n",
- &tag, &uid, &rx_bytes, &n),
- 3);
- // If this line matches our UID and |expected_tag| then add it to the total.
- if (uid == getuid() && (int32_t)(tag >> 32) == expected_tag) {
- bytes += rx_bytes;
- }
- // Move |i| to the next line.
- i += n + 1;
- }
- return bytes;
-}
-#endif
-
-} // namespace
-
// Test that SocketTag's comparison function work.
TEST(SocketTagTest, Compares) {
SocketTag unset1;
@@ -126,20 +79,24 @@ TEST(SocketTagTest, Apply) {
ASSERT_EQ(connect(s, addr.addr, addr.addr_len), 0);
EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
- // Verify socket can be retagged and with our UID.
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
int32_t tag_val2 = 0x87654321;
old_traffic = GetTaggedBytes(tag_val2);
SocketTag tag2(getuid(), tag_val2);
tag2.Apply(s);
- const char kRequest1[] = "GET /";
- ASSERT_EQ(send(s, kRequest1, strlen(kRequest1), 0), (int)strlen(kRequest1));
+ const char kRequest1[] = "GET / HTTP/1.0";
+ ASSERT_EQ(send(s, kRequest1, strlen(kRequest1), 0),
+ static_cast<int>(strlen(kRequest1)));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
- // Verify socket can be retagged and with our UID.
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
old_traffic = GetTaggedBytes(tag_val1);
tag1.Apply(s);
const char kRequest2[] = "\n\n";
- ASSERT_EQ(send(s, kRequest2, strlen(kRequest2), 0), (int)strlen(kRequest2));
+ ASSERT_EQ(send(s, kRequest2, strlen(kRequest2), 0),
+ static_cast<int>(strlen(kRequest2)));
EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
ASSERT_EQ(close(s), 0);
diff --git a/chromium/net/socket/socket_test_util.cc b/chromium/net/socket/socket_test_util.cc
index e6b52532489..daa5a898588 100644
--- a/chromium/net/socket/socket_test_util.cc
+++ b/chromium/net/socket/socket_test_util.cc
@@ -4,7 +4,12 @@
#include "net/socket/socket_test_util.h"
+#include <inttypes.h> // For SCNx64
+#include <stdint.h>
+#include <stdio.h>
+
#include <algorithm>
+#include <string>
#include <utility>
#include <vector>
@@ -12,6 +17,7 @@
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
+#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/run_loop.h"
@@ -21,6 +27,7 @@
#include "net/base/address_family.h"
#include "net/base/address_list.h"
#include "net/base/auth.h"
+#include "net/base/hex_utils.h"
#include "net/base/ip_address.h"
#include "net/base/load_timing_info.h"
#include "net/http/http_network_session.h"
@@ -33,6 +40,7 @@
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_info.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#define NET_TRACE(level, s) VLOG(level) << s << __FUNCTION__ << "() "
@@ -222,7 +230,9 @@ bool StaticSocketDataHelper::VerifyWriteData(const std::string& data) {
std::string expected_data(next_write.data, next_write.data_len);
std::string actual_data(data.substr(0, next_write.data_len));
EXPECT_GE(data.length(), expected_data.length());
- EXPECT_EQ(expected_data, actual_data);
+ EXPECT_TRUE(actual_data == expected_data)
+ << "Actual write data:\n" << HexDump(actual_data)
+ << "Expected write data:\n" << HexDump(expected_data);
return expected_data == actual_data;
}
@@ -259,10 +269,10 @@ MockWriteResult StaticSocketDataProvider::OnWrite(const std::string& data) {
// Not using mock writes; succeed synchronously.
return MockWriteResult(SYNCHRONOUS, data.length());
}
- EXPECT_FALSE(helper_.AllWriteDataConsumed());
+ EXPECT_FALSE(helper_.AllWriteDataConsumed())
+ << "No more mock data to match write:\n"
+ << HexDump(data);
if (helper_.AllWriteDataConsumed()) {
- // Show what the extra write actually consists of.
- EXPECT_EQ("<unexpected write>", data);
return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED);
}
@@ -438,7 +448,9 @@ MockRead SequencedSocketData::OnRead() {
MockWriteResult SequencedSocketData::OnWrite(const std::string& data) {
CHECK_EQ(IDLE, write_state_);
- CHECK(!helper_.AllWriteDataConsumed());
+ CHECK(!helper_.AllWriteDataConsumed())
+ << "\nNo more mock data to match write:\n"
+ << HexDump(data);
NET_TRACE(1, " *** ") << "sequence_number: " << sequence_number_;
const MockWrite& next_write = helper_.PeekWrite();
@@ -917,8 +929,11 @@ int MockTCPClientSocket::ReadIfReady(IOBuffer* buf,
return ReadIfReadyImpl(buf, buf_len, callback);
}
-int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int MockTCPClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
DCHECK(buf);
DCHECK_GT(buf_len, 0);
@@ -1189,24 +1204,24 @@ int MockSSLClientSocket::ReadIfReady(IOBuffer* buf,
return transport_->socket()->ReadIfReady(buf, buf_len, callback);
}
-int MockSSLClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
- return transport_->socket()->Write(buf, buf_len, callback);
+int MockSSLClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ return transport_->socket()->Write(buf, buf_len, callback,
+ traffic_annotation);
}
int MockSSLClientSocket::Connect(const CompletionCallback& callback) {
- int rv = transport_->socket()->Connect(
- base::Bind(&ConnectCallback, base::Unretained(this), callback));
- if (rv == OK) {
- if (data_->connect.result == OK)
- connected_ = true;
- if (data_->connect.mode == ASYNC) {
- RunCallbackAsync(callback, data_->connect.result);
- return ERR_IO_PENDING;
- }
- return data_->connect.result;
+ DCHECK(transport_->socket()->IsConnected());
+ if (data_->connect.result == OK)
+ connected_ = true;
+ if (data_->connect.mode == ASYNC) {
+ RunCallbackAsync(callback, data_->connect.result);
+ return ERR_IO_PENDING;
}
- return rv;
+ return data_->connect.result;
}
void MockSSLClientSocket::Disconnect() {
@@ -1245,6 +1260,10 @@ bool MockSSLClientSocket::GetSSLInfo(SSLInfo* requested_ssl_info) {
return true;
}
+void MockSSLClientSocket::ApplySocketTag(const SocketTag& tag) {
+ return transport_->socket()->ApplySocketTag(tag);
+}
+
void MockSSLClientSocket::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
DCHECK(cert_request_info);
@@ -1336,8 +1355,11 @@ int MockUDPClientSocket::Read(IOBuffer* buf,
return CompleteRead();
}
-int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int MockUDPClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
DCHECK(buf);
DCHECK_GT(buf_len, 0);
@@ -1427,6 +1449,8 @@ NetworkChangeNotifier::NetworkHandle MockUDPClientSocket::GetBoundNetwork()
return network_;
}
+void MockUDPClientSocket::ApplySocketTag(const SocketTag& tag) {}
+
void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
if (!data_)
return;
@@ -1580,12 +1604,17 @@ void ClientSocketPoolTest::ReleaseAllConnections(KeepAlive keep_alive) {
MockTransportClientSocketPool::MockConnectJob::MockConnectJob(
std::unique_ptr<StreamSocket> socket,
ClientSocketHandle* handle,
+ const SocketTag& socket_tag,
const CompletionCallback& callback)
- : socket_(std::move(socket)), handle_(handle), user_callback_(callback) {}
+ : socket_(std::move(socket)),
+ handle_(handle),
+ socket_tag_(socket_tag),
+ user_callback_(callback) {}
MockTransportClientSocketPool::MockConnectJob::~MockConnectJob() = default;
int MockTransportClientSocketPool::MockConnectJob::Connect() {
+ socket_->ApplySocketTag(socket_tag_);
int rv = socket_->Connect(base::Bind(&MockConnectJob::OnConnect,
base::Unretained(this)));
if (rv != ERR_IO_PENDING) {
@@ -1659,6 +1688,7 @@ int MockTransportClientSocketPool::RequestSocket(
const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -1667,7 +1697,8 @@ int MockTransportClientSocketPool::RequestSocket(
std::unique_ptr<StreamSocket> socket =
client_socket_factory_->CreateTransportClientSocket(
AddressList(), NULL, net_log.net_log(), NetLogSource());
- MockConnectJob* job = new MockConnectJob(std::move(socket), handle, callback);
+ MockConnectJob* job =
+ new MockConnectJob(std::move(socket), handle, socket_tag, callback);
job_list_.push_back(base::WrapUnique(job));
handle->set_pool_id(1);
return job->Connect();
@@ -1714,13 +1745,14 @@ MockSOCKSClientSocketPool::~MockSOCKSClientSocketPool() = default;
int MockSOCKSClientSocketPool::RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
const NetLogWithSource& net_log) {
return transport_pool_->RequestSocket(group_name, socket_params, priority,
- respect_limits, handle, callback,
- net_log);
+ socket_tag, respect_limits, handle,
+ callback, net_log);
}
void MockSOCKSClientSocketPool::SetPriority(const std::string& group_name,
@@ -1757,6 +1789,144 @@ ScopedWebSocketEndpointZeroUnlockDelay::
EXPECT_EQ(active_delay, base::TimeDelta());
}
+WrappedStreamSocket::WrappedStreamSocket(
+ std::unique_ptr<StreamSocket> transport)
+ : transport_(std::move(transport)) {}
+WrappedStreamSocket::~WrappedStreamSocket() {}
+
+int WrappedStreamSocket::Connect(const CompletionCallback& callback) {
+ return transport_->Connect(callback);
+}
+
+void WrappedStreamSocket::Disconnect() {
+ transport_->Disconnect();
+}
+
+bool WrappedStreamSocket::IsConnected() const {
+ return transport_->IsConnected();
+}
+
+bool WrappedStreamSocket::IsConnectedAndIdle() const {
+ return transport_->IsConnectedAndIdle();
+}
+
+int WrappedStreamSocket::GetPeerAddress(IPEndPoint* address) const {
+ return transport_->GetPeerAddress(address);
+}
+
+int WrappedStreamSocket::GetLocalAddress(IPEndPoint* address) const {
+ return transport_->GetLocalAddress(address);
+}
+
+const NetLogWithSource& WrappedStreamSocket::NetLog() const {
+ return transport_->NetLog();
+}
+
+void WrappedStreamSocket::SetSubresourceSpeculation() {
+ transport_->SetSubresourceSpeculation();
+}
+
+void WrappedStreamSocket::SetOmniboxSpeculation() {
+ transport_->SetOmniboxSpeculation();
+}
+
+bool WrappedStreamSocket::WasEverUsed() const {
+ return transport_->WasEverUsed();
+}
+
+bool WrappedStreamSocket::WasAlpnNegotiated() const {
+ return transport_->WasAlpnNegotiated();
+}
+
+NextProto WrappedStreamSocket::GetNegotiatedProtocol() const {
+ return transport_->GetNegotiatedProtocol();
+}
+
+bool WrappedStreamSocket::GetSSLInfo(SSLInfo* ssl_info) {
+ return transport_->GetSSLInfo(ssl_info);
+}
+
+void WrappedStreamSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
+ transport_->GetConnectionAttempts(out);
+}
+
+void WrappedStreamSocket::ClearConnectionAttempts() {
+ transport_->ClearConnectionAttempts();
+}
+
+void WrappedStreamSocket::AddConnectionAttempts(
+ const ConnectionAttempts& attempts) {
+ transport_->AddConnectionAttempts(attempts);
+}
+
+int64_t WrappedStreamSocket::GetTotalReceivedBytes() const {
+ return transport_->GetTotalReceivedBytes();
+}
+
+void WrappedStreamSocket::ApplySocketTag(const SocketTag& tag) {
+ transport_->ApplySocketTag(tag);
+}
+
+int WrappedStreamSocket::Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ return transport_->Read(buf, buf_len, callback);
+}
+
+int WrappedStreamSocket::ReadIfReady(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) {
+ return transport_->ReadIfReady(buf, buf_len, callback);
+}
+
+int WrappedStreamSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ return transport_->Write(buf, buf_len, callback);
+}
+
+int WrappedStreamSocket::SetReceiveBufferSize(int32_t size) {
+ return transport_->SetReceiveBufferSize(size);
+}
+
+int WrappedStreamSocket::SetSendBufferSize(int32_t size) {
+ return transport_->SetSendBufferSize(size);
+}
+
+int MockTaggingStreamSocket::Connect(const CompletionCallback& callback) {
+ connected_ = true;
+ return WrappedStreamSocket::Connect(callback);
+}
+
+void MockTaggingStreamSocket::ApplySocketTag(const SocketTag& tag) {
+ tagged_before_connected_ &= !connected_ || tag == tag_;
+ tag_ = tag;
+ transport_->ApplySocketTag(tag);
+}
+
+std::unique_ptr<StreamSocket>
+MockTaggingClientSocketFactory::CreateTransportClientSocket(
+ const AddressList& addresses,
+ std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
+ NetLog* net_log,
+ const NetLogSource& source) {
+ std::unique_ptr<MockTaggingStreamSocket> socket(new MockTaggingStreamSocket(
+ MockClientSocketFactory::CreateTransportClientSocket(
+ addresses, std::move(socket_performance_watcher), net_log, source)));
+ socket_ = socket.get();
+ return std::move(socket);
+}
+
+const char kSOCKS4OkRequestLocalHostPort80[] = {0x04, 0x01, 0x00, 0x50, 127,
+ 0, 0, 1, 0};
+const int kSOCKS4OkRequestLocalHostPort80Length =
+ arraysize(kSOCKS4OkRequestLocalHostPort80);
+
+const char kSOCKS4OkReply[] = {0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0};
+const int kSOCKS4OkReplyLength = arraysize(kSOCKS4OkReply);
+
const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
const int kSOCKS5GreetRequestLength = arraysize(kSOCKS5GreetRequest);
@@ -1785,4 +1955,41 @@ int64_t CountWriteBytes(const MockWrite writes[], size_t writes_size) {
return total;
}
+#if defined(OS_ANDROID)
+uint64_t GetTaggedBytes(int32_t expected_tag) {
+ // To determine how many bytes the system saw with a particular tag read
+ // the /proc/net/xt_qtaguid/stats file which contains the kernel's
+ // dump of all the UIDs and their tags sent and received bytes.
+ uint64_t bytes = 0;
+ std::string contents;
+ EXPECT_TRUE(base::ReadFileToString(
+ base::FilePath::FromUTF8Unsafe("/proc/net/xt_qtaguid/stats"), &contents));
+ for (size_t i = contents.find('\n'); // Skip first line which is headers.
+ i != std::string::npos && i < contents.length();) {
+ uint64_t tag, rx_bytes;
+ uid_t uid;
+ int n;
+ // Parse out the numbers we care about. For reference here's the column
+ // headers:
+ // idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes
+ // tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets
+ // rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes
+ // tx_udp_packets tx_other_bytes tx_other_packets
+ EXPECT_EQ(sscanf(contents.c_str() + i,
+ "%*d %*s 0x%" SCNx64 " %d %*d %" SCNu64
+ " %*d %*d %*d %*d %*d %*d %*d %*d "
+ "%*d %*d %*d %*d %*d %*d %*d%n",
+ &tag, &uid, &rx_bytes, &n),
+ 3);
+ // If this line matches our UID and |expected_tag| then add it to the total.
+ if (uid == getuid() && (int32_t)(tag >> 32) == expected_tag) {
+ bytes += rx_bytes;
+ }
+ // Move |i| to the next line.
+ i += n + 1;
+ }
+ return bytes;
+}
+#endif
+
} // namespace net
diff --git a/chromium/net/socket/socket_test_util.h b/chromium/net/socket/socket_test_util.h
index ce0ccf58e07..1e8ea79afcb 100644
--- a/chromium/net/socket/socket_test_util.h
+++ b/chromium/net/socket/socket_test_util.h
@@ -21,6 +21,7 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -33,11 +34,13 @@
#include "net/socket/connection_attempts.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/ssl/ssl_config_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
@@ -570,7 +573,8 @@ class MockClientSocket : public SSLClientSocket {
const CompletionCallback& callback) override = 0;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override = 0;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override = 0;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -590,6 +594,7 @@ class MockClientSocket : public SSLClientSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override {}
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
@@ -641,7 +646,8 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override;
@@ -721,7 +727,8 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
// StreamSocket implementation.
int Connect(const CompletionCallback& callback) override;
@@ -733,6 +740,7 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
bool WasAlpnNegotiated() const override;
NextProto GetNegotiatedProtocol() const override;
bool GetSSLInfo(SSLInfo* ssl_info) override;
+ void ApplySocketTag(const SocketTag& tag) override;
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
@@ -772,7 +780,8 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
@@ -790,6 +799,7 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
const IPEndPoint& address) override;
int ConnectUsingDefaultNetwork(const IPEndPoint& address) override;
NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// AsyncSocket implementation.
void OnReadComplete(const MockRead& data) override;
@@ -879,9 +889,9 @@ class ClientSocketPoolTest {
TestSocketRequest* request(
new TestSocketRequest(&request_order_, &completion_count_));
requests_.push_back(base::WrapUnique(request));
- int rv = request->handle()->Init(group_name, socket_params, priority,
- respect_limits, request->callback(),
- socket_pool, NetLogWithSource());
+ int rv = request->handle()->Init(
+ group_name, socket_params, priority, SocketTag(), respect_limits,
+ request->callback(), socket_pool, NetLogWithSource());
if (rv != ERR_IO_PENDING)
request_order_.push_back(request);
return rv;
@@ -935,6 +945,7 @@ class MockTransportClientSocketPool : public TransportClientSocketPool {
public:
MockConnectJob(std::unique_ptr<StreamSocket> socket,
ClientSocketHandle* handle,
+ const SocketTag& socket_tag,
const CompletionCallback& callback);
~MockConnectJob();
@@ -946,6 +957,7 @@ class MockTransportClientSocketPool : public TransportClientSocketPool {
std::unique_ptr<StreamSocket> socket_;
ClientSocketHandle* handle_;
+ const SocketTag socket_tag_;
CompletionCallback user_callback_;
DISALLOW_COPY_AND_ASSIGN(MockConnectJob);
@@ -967,6 +979,7 @@ class MockTransportClientSocketPool : public TransportClientSocketPool {
int RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -1002,6 +1015,7 @@ class MockSOCKSClientSocketPool : public SOCKSClientSocketPool {
int RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -1033,6 +1047,113 @@ class ScopedWebSocketEndpointZeroUnlockDelay {
base::TimeDelta old_delay_;
};
+// WrappedStreamSocket is a base class that wraps an existing StreamSocket,
+// forwarding the Socket and StreamSocket interfaces to the underlying
+// transport.
+// This is to provide a common base class for subclasses to override specific
+// StreamSocket methods for testing, while still communicating with a 'real'
+// StreamSocket.
+class WrappedStreamSocket : public StreamSocket {
+ public:
+ explicit WrappedStreamSocket(std::unique_ptr<StreamSocket> transport);
+ ~WrappedStreamSocket() override;
+
+ // StreamSocket implementation:
+ int Connect(const CompletionCallback& callback) override;
+ void Disconnect() override;
+ bool IsConnected() const override;
+ bool IsConnectedAndIdle() const override;
+ int GetPeerAddress(IPEndPoint* address) const override;
+ int GetLocalAddress(IPEndPoint* address) const override;
+ const NetLogWithSource& NetLog() const override;
+ void SetSubresourceSpeculation() override;
+ void SetOmniboxSpeculation() override;
+ bool WasEverUsed() const override;
+ bool WasAlpnNegotiated() const override;
+ NextProto GetNegotiatedProtocol() const override;
+ bool GetSSLInfo(SSLInfo* ssl_info) override;
+ void GetConnectionAttempts(ConnectionAttempts* out) const override;
+ void ClearConnectionAttempts() override;
+ void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
+ int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
+
+ // Socket implementation:
+ int Read(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int ReadIfReady(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) override;
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation =
+ NO_TRAFFIC_ANNOTATION_BUG_656607) override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
+
+ protected:
+ std::unique_ptr<StreamSocket> transport_;
+};
+
+// StreamSocket that wraps another StreamSocket, but keeps track of any
+// SocketTag applied to the socket.
+class MockTaggingStreamSocket : public WrappedStreamSocket {
+ public:
+ explicit MockTaggingStreamSocket(std::unique_ptr<StreamSocket> transport)
+ : WrappedStreamSocket(std::move(transport)) {}
+ ~MockTaggingStreamSocket() override {}
+
+ // StreamSocket implementation.
+ int Connect(const CompletionCallback& callback) override;
+ void ApplySocketTag(const SocketTag& tag) override;
+
+ // Returns false if socket's tag was changed after the socket was connected,
+ // otherwise returns true.
+ bool tagged_before_connected() const { return tagged_before_connected_; }
+
+ // Returns last tag applied to socket.
+ SocketTag tag() const { return tag_; }
+
+ private:
+ bool connected_ = false;
+ bool tagged_before_connected_ = true;
+ SocketTag tag_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockTaggingStreamSocket);
+};
+
+// Extend MockClientSocketFactory to return MockTaggingStreamSockets and
+// keep track of last socket produced for test inspection.
+class MockTaggingClientSocketFactory : public MockClientSocketFactory {
+ public:
+ MockTaggingClientSocketFactory() = default;
+
+ std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ const AddressList& addresses,
+ std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
+ NetLog* net_log,
+ const NetLogSource& source) override;
+
+ // Returns a pointer to last socket produced by this factory.
+ // NOTE: Socket must still exist, or pointer will be to freed memory.
+ MockTaggingStreamSocket* GetLastProducedSocket() { return socket_; }
+
+ private:
+ MockTaggingStreamSocket* socket_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(MockTaggingClientSocketFactory);
+};
+
+// Constants for a successful SOCKS v4 handshake (connecting to localhost on
+// port 80, for the request).
+extern const char kSOCKS4OkRequestLocalHostPort80[];
+extern const int kSOCKS4OkRequestLocalHostPort80Length;
+
+extern const char kSOCKS4OkReply[];
+extern const int kSOCKS4OkReplyLength;
+
// Constants for a successful SOCKS v5 handshake.
extern const char kSOCKS5GreetRequest[];
extern const int kSOCKS5GreetRequestLength;
@@ -1052,6 +1173,12 @@ int64_t CountReadBytes(const MockRead reads[], size_t reads_size);
// Helper function to get the total data size of the MockWrites in |writes|.
int64_t CountWriteBytes(const MockWrite writes[], size_t writes_size);
+#if defined(OS_ANDROID)
+// Query the system to find out how many bytes were received with tag
+// |expected_tag| for our UID. Return the count of recieved bytes.
+uint64_t GetTaggedBytes(int32_t expected_tag);
+#endif
+
} // namespace net
#endif // NET_SOCKET_SOCKET_TEST_UTIL_H_
diff --git a/chromium/net/socket/socks5_client_socket.cc b/chromium/net/socket/socks5_client_socket.cc
index 19cdfddbe0c..6b436878f78 100644
--- a/chromium/net/socket/socks5_client_socket.cc
+++ b/chromium/net/socket/socks5_client_socket.cc
@@ -16,6 +16,7 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_handle.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -31,7 +32,8 @@ static_assert(sizeof(struct in6_addr) == 16, "incorrect system size of IPv6");
SOCKS5ClientSocket::SOCKS5ClientSocket(
std::unique_ptr<ClientSocketHandle> transport_socket,
- const HostResolver::RequestInfo& req_info)
+ const HostResolver::RequestInfo& req_info,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete,
base::Unretained(this))),
transport_(std::move(transport_socket)),
@@ -42,7 +44,8 @@ SOCKS5ClientSocket::SOCKS5ClientSocket(
read_header_size(kReadHeaderSize),
was_ever_used_(false),
host_request_info_(req_info),
- net_log_(transport_->socket()->NetLog()) {}
+ net_log_(transport_->socket()->NetLog()),
+ traffic_annotation_(traffic_annotation) {}
SOCKS5ClientSocket::~SOCKS5ClientSocket() {
Disconnect();
@@ -146,6 +149,10 @@ int64_t SOCKS5ClientSocket::GetTotalReceivedBytes() const {
return transport_->socket()->GetTotalReceivedBytes();
}
+void SOCKS5ClientSocket::ApplySocketTag(const SocketTag& tag) {
+ return transport_->socket()->ApplySocketTag(tag);
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len,
@@ -166,8 +173,11 @@ int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len,
// Write is called by the transport layer. This can only be done if the
// SOCKS handshake is complete.
-int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int SOCKS5ClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(completed_handshake_);
DCHECK_EQ(STATE_NONE, next_state_);
DCHECK(user_callback_.is_null());
@@ -176,7 +186,8 @@ int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len,
int rv = transport_->socket()->Write(
buf, buf_len,
base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete,
- base::Unretained(this), callback));
+ base::Unretained(this), callback),
+ traffic_annotation);
if (rv > 0)
was_ever_used_ = true;
return rv;
@@ -295,8 +306,8 @@ int SOCKS5ClientSocket::DoGreetWrite() {
handshake_buf_ = new IOBuffer(handshake_buf_len);
memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_],
handshake_buf_len);
- return transport_->socket()
- ->Write(handshake_buf_.get(), handshake_buf_len, io_callback_);
+ return transport_->socket()->Write(handshake_buf_.get(), handshake_buf_len,
+ io_callback_, traffic_annotation_);
}
int SOCKS5ClientSocket::DoGreetWriteComplete(int result) {
@@ -394,8 +405,8 @@ int SOCKS5ClientSocket::DoHandshakeWrite() {
handshake_buf_ = new IOBuffer(handshake_buf_len);
memcpy(handshake_buf_->data(), &buffer_[bytes_sent_],
handshake_buf_len);
- return transport_->socket()
- ->Write(handshake_buf_.get(), handshake_buf_len, io_callback_);
+ return transport_->socket()->Write(handshake_buf_.get(), handshake_buf_len,
+ io_callback_, traffic_annotation_);
}
int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) {
diff --git a/chromium/net/socket/socks5_client_socket.h b/chromium/net/socket/socks5_client_socket.h
index afef312d001..364ac53391d 100644
--- a/chromium/net/socket/socks5_client_socket.h
+++ b/chromium/net/socket/socks5_client_socket.h
@@ -20,6 +20,7 @@
#include "net/dns/host_resolver.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
@@ -37,7 +38,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
// always pass it a hostname. This means the DNS resolving is done
// proxy side.
SOCKS5ClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
- const HostResolver::RequestInfo& req_info);
+ const HostResolver::RequestInfo& req_info,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// On destruction Disconnect() is called.
~SOCKS5ClientSocket() override;
@@ -60,6 +62,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -67,7 +70,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -155,6 +159,9 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket {
NetLogWithSource net_log_;
+ // Traffic annotation for socket control.
+ NetworkTrafficAnnotationTag traffic_annotation_;
+
DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocket);
};
diff --git a/chromium/net/socket/socks5_client_socket_fuzzer.cc b/chromium/net/socket/socks5_client_socket_fuzzer.cc
index 272e37dfdea..fb9c7b5528a 100644
--- a/chromium/net/socket/socks5_client_socket_fuzzer.cc
+++ b/chromium/net/socket/socks5_client_socket_fuzzer.cc
@@ -16,6 +16,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/fuzzed_socket.h"
#include "net/socket/socks5_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
// Fuzzer for Socks5ClientSocket. Only covers the SOCKS5 greeet and
// handshake.
@@ -38,7 +39,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
socket_handle->SetSocket(std::move(fuzzed_socket));
net::HostResolver::RequestInfo request_info(net::HostPortPair("foo", 80));
- net::SOCKS5ClientSocket socket(std::move(socket_handle), request_info);
+ net::SOCKS5ClientSocket socket(std::move(socket_handle), request_info,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
int result = socket.Connect(callback.callback());
callback.GetResult(result);
return 0;
diff --git a/chromium/net/socket/socks5_client_socket_unittest.cc b/chromium/net/socket/socks5_client_socket_unittest.cc
index 4cf98cffe42..fea734f67ea 100644
--- a/chromium/net/socket/socks5_client_socket_unittest.cc
+++ b/chromium/net/socket/socks5_client_socket_unittest.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/sys_byteorder.h"
+#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
@@ -23,6 +24,7 @@
#include "net/socket/socket_test_util.h"
#include "net/socket/tcp_client_socket.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -116,7 +118,8 @@ std::unique_ptr<SOCKS5ClientSocket> SOCKS5ClientSocketTest::BuildMockSocket(
connection->SetSocket(std::unique_ptr<StreamSocket>(tcp_sock_));
return std::unique_ptr<SOCKS5ClientSocket>(new SOCKS5ClientSocket(
std::move(connection),
- HostResolver::RequestInfo(HostPortPair(hostname, port))));
+ HostResolver::RequestInfo(HostPortPair(hostname, port)),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
}
// Tests a complete SOCKS5 handshake and the disconnection.
@@ -172,8 +175,8 @@ TEST_F(SOCKS5ClientSocketTest, CompleteHandshake) {
scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size()));
memcpy(buffer->data(), payload_write.data(), payload_write.size());
- rv = user_sock_->Write(
- buffer.get(), payload_write.size(), callback_.callback());
+ rv = user_sock_->Write(buffer.get(), payload_write.size(),
+ callback_.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rv = callback_.WaitForResult();
EXPECT_EQ(static_cast<int>(payload_write.size()), rv);
@@ -384,6 +387,30 @@ TEST_F(SOCKS5ClientSocketTest, PartialReadWrites) {
}
}
+TEST_F(SOCKS5ClientSocketTest, Tag) {
+ StaticSocketDataProvider data;
+ TestNetLog log;
+ MockTaggingStreamSocket* tagging_sock =
+ new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>(
+ new MockTCPClientSocket(address_list_, &log, &data)));
+
+ std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+ // |connection| takes ownership of |tagging_sock|, but keep a
+ // non-owning pointer to it.
+ connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
+ SOCKS5ClientSocket socket(
+ std::move(connection),
+ HostResolver::RequestInfo(HostPortPair("localhost", 80)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ EXPECT_EQ(tagging_sock->tag(), SocketTag());
+#if defined(OS_ANDROID)
+ SocketTag tag(0x12345678, 0x87654321);
+ socket.ApplySocketTag(tag);
+ EXPECT_EQ(tagging_sock->tag(), tag);
+#endif // OS_ANDROID
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/socks_client_socket.cc b/chromium/net/socket/socks_client_socket.cc
index 027d18ab7c1..3e5d6eb0aa4 100644
--- a/chromium/net/socket/socks_client_socket.cc
+++ b/chromium/net/socket/socks_client_socket.cc
@@ -14,6 +14,7 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_handle.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -61,7 +62,8 @@ SOCKSClientSocket::SOCKSClientSocket(
std::unique_ptr<ClientSocketHandle> transport_socket,
const HostResolver::RequestInfo& req_info,
RequestPriority priority,
- HostResolver* host_resolver)
+ HostResolver* host_resolver,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: transport_(std::move(transport_socket)),
next_state_(STATE_NONE),
completed_handshake_(false),
@@ -71,7 +73,8 @@ SOCKSClientSocket::SOCKSClientSocket(
host_resolver_(host_resolver),
host_request_info_(req_info),
priority_(priority),
- net_log_(transport_->socket()->NetLog()) {}
+ net_log_(transport_->socket()->NetLog()),
+ traffic_annotation_(traffic_annotation) {}
SOCKSClientSocket::~SOCKSClientSocket() {
Disconnect();
@@ -175,6 +178,10 @@ int64_t SOCKSClientSocket::GetTotalReceivedBytes() const {
return transport_->socket()->GetTotalReceivedBytes();
}
+void SOCKSClientSocket::ApplySocketTag(const SocketTag& tag) {
+ return transport_->socket()->ApplySocketTag(tag);
+}
+
// Read is called by the transport layer above to read. This can only be done
// if the SOCKS handshake is complete.
int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len,
@@ -195,8 +202,11 @@ int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len,
// Write is called by the transport layer. This can only be done if the
// SOCKS handshake is complete.
-int SOCKSClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int SOCKSClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(completed_handshake_);
DCHECK_EQ(STATE_NONE, next_state_);
DCHECK(user_callback_.is_null());
@@ -205,7 +215,8 @@ int SOCKSClientSocket::Write(IOBuffer* buf, int buf_len,
int rv = transport_->socket()->Write(
buf, buf_len,
base::Bind(&SOCKSClientSocket::OnReadWriteComplete,
- base::Unretained(this), callback));
+ base::Unretained(this), callback),
+ traffic_annotation);
if (rv > 0)
was_ever_used_ = true;
return rv;
@@ -352,9 +363,9 @@ int SOCKSClientSocket::DoHandshakeWrite() {
memcpy(handshake_buf_->data(), &buffer_[bytes_sent_],
handshake_buf_len);
return transport_->socket()->Write(
- handshake_buf_.get(),
- handshake_buf_len,
- base::Bind(&SOCKSClientSocket::OnIOComplete, base::Unretained(this)));
+ handshake_buf_.get(), handshake_buf_len,
+ base::Bind(&SOCKSClientSocket::OnIOComplete, base::Unretained(this)),
+ traffic_annotation_);
}
int SOCKSClientSocket::DoHandshakeWriteComplete(int result) {
diff --git a/chromium/net/socket/socks_client_socket.h b/chromium/net/socket/socks_client_socket.h
index c2999ffa17b..f39f2646579 100644
--- a/chromium/net/socket/socks_client_socket.h
+++ b/chromium/net/socket/socks_client_socket.h
@@ -21,6 +21,7 @@
#include "net/dns/host_resolver.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -34,7 +35,8 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
SOCKSClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
const HostResolver::RequestInfo& req_info,
RequestPriority priority,
- HostResolver* host_resolver);
+ HostResolver* host_resolver,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// On destruction Disconnect() is called.
~SOCKSClientSocket() override;
@@ -57,6 +59,7 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -64,7 +67,8 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -138,6 +142,9 @@ class NET_EXPORT_PRIVATE SOCKSClientSocket : public StreamSocket {
NetLogWithSource net_log_;
+ // Traffic annotation for socket control.
+ NetworkTrafficAnnotationTag traffic_annotation_;
+
DISALLOW_COPY_AND_ASSIGN(SOCKSClientSocket);
};
diff --git a/chromium/net/socket/socks_client_socket_fuzzer.cc b/chromium/net/socket/socks_client_socket_fuzzer.cc
index dd02f51fe67..feaa18282d1 100644
--- a/chromium/net/socket/socks_client_socket_fuzzer.cc
+++ b/chromium/net/socket/socks_client_socket_fuzzer.cc
@@ -18,6 +18,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/fuzzed_socket.h"
#include "net/socket/socks_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
// Fuzzer for SocksClientSocket. Only covers the SOCKS4 handshake.
//
@@ -58,8 +59,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
socket_handle->SetSocket(std::move(fuzzed_socket));
net::HostResolver::RequestInfo request_info(net::HostPortPair("foo", 80));
+
net::SOCKSClientSocket socket(std::move(socket_handle), request_info,
- net::DEFAULT_PRIORITY, &mock_host_resolver);
+ net::DEFAULT_PRIORITY, &mock_host_resolver,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
int result = socket.Connect(callback.callback());
callback.GetResult(result);
return 0;
diff --git a/chromium/net/socket/socks_client_socket_pool.cc b/chromium/net/socket/socks_client_socket_pool.cc
index 86b4ac0d109..0e16d7eecb8 100644
--- a/chromium/net/socket/socks_client_socket_pool.cc
+++ b/chromium/net/socket/socks_client_socket_pool.cc
@@ -27,11 +27,12 @@ class NetLog;
SOCKSSocketParams::SOCKSSocketParams(
const scoped_refptr<TransportSocketParams>& proxy_server,
bool socks_v5,
- const HostPortPair& host_port_pair)
+ const HostPortPair& host_port_pair,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: transport_params_(proxy_server),
destination_(host_port_pair),
- socks_v5_(socks_v5) {
-}
+ socks_v5_(socks_v5),
+ traffic_annotation_(traffic_annotation) {}
SOCKSSocketParams::~SOCKSSocketParams() = default;
@@ -42,6 +43,7 @@ static const int kSOCKSConnectJobTimeoutInSeconds = 30;
SOCKSConnectJob::SOCKSConnectJob(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<SOCKSSocketParams>& socks_params,
const base::TimeDelta& timeout_duration,
@@ -53,6 +55,7 @@ SOCKSConnectJob::SOCKSConnectJob(
group_name,
timeout_duration,
priority,
+ socket_tag,
respect_limits,
delegate,
NetLogWithSource::Make(net_log, NetLogSourceType::SOCKS_CONNECT_JOB)),
@@ -125,7 +128,7 @@ int SOCKSConnectJob::DoTransportConnect() {
next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
transport_socket_handle_.reset(new ClientSocketHandle());
return transport_socket_handle_->Init(
- group_name(), socks_params_->transport_params(), priority(),
+ group_name(), socks_params_->transport_params(), priority(), socket_tag(),
respect_limits(), callback_, transport_pool_, net_log());
}
@@ -147,11 +150,12 @@ int SOCKSConnectJob::DoSOCKSConnect() {
// Add a SOCKS connection on top of the tcp socket.
if (socks_params_->is_socks_v5()) {
socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_),
- socks_params_->destination()));
+ socks_params_->destination(),
+ socks_params_->traffic_annotation()));
} else {
- socket_.reset(new SOCKSClientSocket(std::move(transport_socket_handle_),
- socks_params_->destination(),
- priority(), resolver_));
+ socket_.reset(new SOCKSClientSocket(
+ std::move(transport_socket_handle_), socks_params_->destination(),
+ priority(), resolver_, socks_params_->traffic_annotation()));
}
return socket_->Connect(
base::Bind(&SOCKSConnectJob::OnIOComplete, base::Unretained(this)));
@@ -178,9 +182,9 @@ SOCKSClientSocketPool::SOCKSConnectJobFactory::NewConnectJob(
const PoolBase::Request& request,
ConnectJob::Delegate* delegate) const {
return std::unique_ptr<ConnectJob>(new SOCKSConnectJob(
- group_name, request.priority(), request.respect_limits(),
- request.params(), ConnectionTimeout(), transport_pool_, host_resolver_,
- delegate, net_log_));
+ group_name, request.priority(), request.socket_tag(),
+ request.respect_limits(), request.params(), ConnectionTimeout(),
+ transport_pool_, host_resolver_, delegate, net_log_));
}
base::TimeDelta
@@ -214,6 +218,7 @@ SOCKSClientSocketPool::~SOCKSClientSocketPool() = default;
int SOCKSClientSocketPool::RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -222,7 +227,8 @@ int SOCKSClientSocketPool::RequestSocket(const std::string& group_name,
static_cast<const scoped_refptr<SOCKSSocketParams>*>(socket_params);
return base_.RequestSocket(group_name, *casted_socket_params, priority,
- respect_limits, handle, callback, net_log);
+ socket_tag, respect_limits, handle, callback,
+ net_log);
}
void SOCKSClientSocketPool::RequestSockets(
diff --git a/chromium/net/socket/socks_client_socket_pool.h b/chromium/net/socket/socks_client_socket_pool.h
index 4eb72e8e4fe..d67e0d480f2 100644
--- a/chromium/net/socket/socks_client_socket_pool.h
+++ b/chromium/net/socket/socks_client_socket_pool.h
@@ -17,6 +17,7 @@
#include "net/dns/host_resolver.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/client_socket_pool_base.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -29,7 +30,9 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams
: public base::RefCounted<SOCKSSocketParams> {
public:
SOCKSSocketParams(const scoped_refptr<TransportSocketParams>& proxy_server,
- bool socks_v5, const HostPortPair& host_port_pair);
+ bool socks_v5,
+ const HostPortPair& host_port_pair,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
const scoped_refptr<TransportSocketParams>& transport_params() const {
return transport_params_;
@@ -37,6 +40,10 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams
const HostResolver::RequestInfo& destination() const { return destination_; }
bool is_socks_v5() const { return socks_v5_; }
+ const NetworkTrafficAnnotationTag traffic_annotation() {
+ return traffic_annotation_;
+ }
+
private:
friend class base::RefCounted<SOCKSSocketParams>;
~SOCKSSocketParams();
@@ -47,6 +54,8 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams
HostResolver::RequestInfo destination_;
const bool socks_v5_;
+ NetworkTrafficAnnotationTag traffic_annotation_;
+
DISALLOW_COPY_AND_ASSIGN(SOCKSSocketParams);
};
@@ -56,6 +65,7 @@ class SOCKSConnectJob : public ConnectJob {
public:
SOCKSConnectJob(const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<SOCKSSocketParams>& params,
const base::TimeDelta& timeout_duration,
@@ -122,6 +132,7 @@ class NET_EXPORT_PRIVATE SOCKSClientSocketPool
int RequestSocket(const std::string& group_name,
const void* connect_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
diff --git a/chromium/net/socket/socks_client_socket_pool_unittest.cc b/chromium/net/socket/socks_client_socket_pool_unittest.cc
index eaafb9d9f7e..8836d0b762b 100644
--- a/chromium/net/socket/socks_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/socks_client_socket_pool_unittest.cc
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/run_loop.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
@@ -17,8 +18,10 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -56,15 +59,15 @@ scoped_refptr<TransportSocketParams> CreateProxyHostParams() {
}
scoped_refptr<SOCKSSocketParams> CreateSOCKSv4Params() {
- return new SOCKSSocketParams(
- CreateProxyHostParams(), false /* socks_v5 */,
- HostPortPair("host", 80));
+ return new SOCKSSocketParams(CreateProxyHostParams(), false /* socks_v5 */,
+ HostPortPair("host", 80),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
scoped_refptr<SOCKSSocketParams> CreateSOCKSv5Params() {
- return new SOCKSSocketParams(
- CreateProxyHostParams(), true /* socks_v5 */,
- HostPortPair("host", 80));
+ return new SOCKSSocketParams(CreateProxyHostParams(), true /* socks_v5 */,
+ HostPortPair("host", 80),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
class SOCKSClientSocketPoolTest : public testing::Test {
@@ -137,7 +140,7 @@ TEST_F(SOCKSClientSocketPoolTest, Simple) {
transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
ClientSocketHandle handle;
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsOk());
@@ -158,7 +161,7 @@ TEST_F(SOCKSClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
ClientSocketHandle handle;
EXPECT_EQ(OK,
- handle.Init("a", CreateSOCKSv5Params(), priority,
+ handle.Init("a", CreateSOCKSv5Params(), priority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource()));
EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
@@ -178,7 +181,7 @@ TEST_F(SOCKSClientSocketPoolTest, SetResolvePriorityOnInit) {
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", CreateSOCKSv4Params(), priority,
+ handle.Init("a", CreateSOCKSv4Params(), priority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource()));
EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
@@ -193,7 +196,7 @@ TEST_F(SOCKSClientSocketPoolTest, Async) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -213,7 +216,7 @@ TEST_F(SOCKSClientSocketPoolTest, TransportConnectError) {
transport_client_socket_factory_.AddSocketDataProvider(&socket_data);
ClientSocketHandle handle;
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
@@ -228,7 +231,7 @@ TEST_F(SOCKSClientSocketPoolTest, AsyncTransportConnectError) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -251,7 +254,7 @@ TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
ClientSocketHandle handle;
EXPECT_EQ(0, transport_socket_pool_.release_count());
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_SOCKS_CONNECTION_FAILED));
@@ -272,7 +275,7 @@ TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(0, transport_socket_pool_.release_count());
- int rv = handle.Init("a", CreateSOCKSv5Params(), LOW,
+ int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -356,6 +359,82 @@ TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
// It would be nice to also test the timeouts in SOCKSClientSocketPool.
+// Test that SocketTag passed into SOCKSClientSocketPool is applied to returned
+// sockets.
+#if defined(OS_ANDROID)
+TEST_F(SOCKSClientSocketPoolTest, Tag) {
+ MockTaggingClientSocketFactory socket_factory;
+ MockTransportClientSocketPool transport_socket_pool(
+ kMaxSockets, kMaxSocketsPerGroup, &socket_factory);
+ SOCKSClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup, &host_resolver_,
+ &transport_socket_pool, NULL, NULL);
+ SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
+ SocketTag tag2(getuid(), 0x87654321);
+ scoped_refptr<TransportSocketParams> tcp_params(new TransportSocketParams(
+ HostPortPair("proxy", 80), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<SOCKSSocketParams> params(new SOCKSSocketParams(
+ tcp_params, true /* socks_v5 */, HostPortPair("host", 80),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+
+ // Test socket is tagged when created synchronously.
+ SOCKS5MockData data_sync(SYNCHRONOUS);
+ data_sync.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ socket_factory.AddSocketDataProvider(data_sync.data_provider());
+ ClientSocketHandle handle;
+ int rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle.is_initialized());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_EQ(socket_factory.GetLastProducedSocket()->tag(), tag1);
+ EXPECT_TRUE(
+ socket_factory.GetLastProducedSocket()->tagged_before_connected());
+
+ // Test socket is tagged when reused synchronously.
+ StreamSocket* socket = handle.socket();
+ handle.Reset();
+ rv = handle.Init("a", params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_EQ(handle.socket(), socket);
+ EXPECT_EQ(socket_factory.GetLastProducedSocket()->tag(), tag2);
+ handle.socket()->Disconnect();
+ handle.Reset();
+
+ // Test socket is tagged when created asynchronously.
+ SOCKS5MockData data_async(ASYNC);
+ socket_factory.AddSocketDataProvider(data_async.data_provider());
+ TestCompletionCallback callback;
+ rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+ EXPECT_TRUE(handle.is_initialized());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_EQ(socket_factory.GetLastProducedSocket()->tag(), tag1);
+ EXPECT_TRUE(
+ socket_factory.GetLastProducedSocket()->tagged_before_connected());
+
+ // Test socket is tagged when reused after being created asynchronously.
+ socket = handle.socket();
+ handle.Reset();
+ rv = handle.Init("a", params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_EQ(handle.socket(), socket);
+ EXPECT_EQ(socket_factory.GetLastProducedSocket()->tag(), tag2);
+}
+#endif
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/socks_client_socket_unittest.cc b/chromium/net/socket/socks_client_socket_unittest.cc
index 63183845e69..63b82c0ad74 100644
--- a/chromium/net/socket/socks_client_socket_unittest.cc
+++ b/chromium/net/socket/socks_client_socket_unittest.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/macros.h"
+#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
@@ -21,6 +22,7 @@
#include "net/socket/socket_test_util.h"
#include "net/socket/tcp_client_socket.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -34,9 +36,6 @@ namespace net {
class NetLog;
-const char kSOCKSOkRequest[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
-const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
-
class SOCKSClientSocketTest : public PlatformTest {
public:
SOCKSClientSocketTest();
@@ -99,7 +98,7 @@ std::unique_ptr<SOCKSClientSocket> SOCKSClientSocketTest::BuildMockSocket(
return std::unique_ptr<SOCKSClientSocket>(new SOCKSClientSocket(
std::move(connection),
HostResolver::RequestInfo(HostPortPair(hostname, port)), DEFAULT_PRIORITY,
- host_resolver));
+ host_resolver, TRAFFIC_ANNOTATION_FOR_TESTS));
}
// Implementation of HostResolver that never completes its resolve request.
@@ -130,6 +129,21 @@ class HangingHostResolverWithCancel : public HostResolver {
return ERR_UNEXPECTED;
}
+ int ResolveStaleFromCache(const RequestInfo& info,
+ AddressList* addresses,
+ HostCache::EntryStaleness* stale_info,
+ const NetLogWithSource& net_log) override {
+ NOTIMPLEMENTED();
+ return ERR_UNEXPECTED;
+ }
+
+ bool HasCached(base::StringPiece hostname,
+ HostCache::Entry::Source* source_out,
+ HostCache::EntryStaleness* stale_out) const override {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
void RemoveRequest(Request* req) {
EXPECT_TRUE(HasOutstandingRequest());
EXPECT_EQ(outstanding_request_, req);
@@ -165,11 +179,12 @@ TEST_F(SOCKSClientSocketTest, CompleteHandshake) {
const std::string payload_read = "moar random data";
MockWrite data_writes[] = {
- MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)),
- MockWrite(ASYNC, payload_write.data(), payload_write.size()) };
+ MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
+ kSOCKS4OkRequestLocalHostPort80Length),
+ MockWrite(ASYNC, payload_write.data(), payload_write.size())};
MockRead data_reads[] = {
- MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)),
- MockRead(ASYNC, payload_read.data(), payload_read.size()) };
+ MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength),
+ MockRead(ASYNC, payload_read.data(), payload_read.size())};
TestNetLog log;
user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
@@ -199,8 +214,8 @@ TEST_F(SOCKSClientSocketTest, CompleteHandshake) {
scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size()));
memcpy(buffer->data(), payload_write.data(), payload_write.size());
- rv = user_sock_->Write(
- buffer.get(), payload_write.size(), callback_.callback());
+ rv = user_sock_->Write(buffer.get(), payload_write.size(),
+ callback_.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rv = callback_.WaitForResult();
EXPECT_EQ(static_cast<int>(payload_write.size()), rv);
@@ -241,7 +256,8 @@ TEST_F(SOCKSClientSocketTest, HandshakeFailures) {
for (size_t i = 0; i < arraysize(tests); ++i) {
MockWrite data_writes[] = {
- MockWrite(SYNCHRONOUS, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) };
+ MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
+ kSOCKS4OkRequestLocalHostPort80Length)};
MockRead data_reads[] = {
MockRead(SYNCHRONOUS, tests[i].fail_reply,
arraysize(tests[i].fail_reply)) };
@@ -277,8 +293,8 @@ TEST_F(SOCKSClientSocketTest, PartialServerReads) {
const char kSOCKSPartialReply1[] = { 0x00 };
const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
- MockWrite data_writes[] = {
- MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) };
+ MockWrite data_writes[] = {MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
+ kSOCKS4OkRequestLocalHostPort80Length)};
MockRead data_reads[] = {
MockRead(ASYNC, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)),
MockRead(ASYNC, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) };
@@ -318,7 +334,7 @@ TEST_F(SOCKSClientSocketTest, PartialClientWrites) {
MockWrite(ASYNC, kSOCKSPartialRequest2, arraysize(kSOCKSPartialRequest2)),
};
MockRead data_reads[] = {
- MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)) };
+ MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength)};
TestNetLog log;
user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
@@ -344,12 +360,12 @@ TEST_F(SOCKSClientSocketTest, PartialClientWrites) {
// Tests the case when the server sends a smaller sized handshake data
// and closes the connection.
TEST_F(SOCKSClientSocketTest, FailedSocketRead) {
- MockWrite data_writes[] = {
- MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) };
+ MockWrite data_writes[] = {MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
+ kSOCKS4OkRequestLocalHostPort80Length)};
MockRead data_reads[] = {
- MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2),
+ MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength - 2),
// close connection unexpectedly
- MockRead(SYNCHRONOUS, 0) };
+ MockRead(SYNCHRONOUS, 0)};
TestNetLog log;
user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
@@ -468,4 +484,29 @@ TEST_F(SOCKSClientSocketTest, NoIPv6RealResolver) {
callback_.GetResult(user_sock_->Connect(callback_.callback())));
}
+TEST_F(SOCKSClientSocketTest, Tag) {
+ StaticSocketDataProvider data;
+ TestNetLog log;
+ MockTaggingStreamSocket* tagging_sock =
+ new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>(
+ new MockTCPClientSocket(address_list_, &log, &data)));
+
+ std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+ // |connection| takes ownership of |tagging_sock|, but keep a
+ // non-owning pointer to it.
+ connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
+ MockHostResolver host_resolver;
+ SOCKSClientSocket socket(
+ std::move(connection),
+ HostResolver::RequestInfo(HostPortPair("localhost", 80)),
+ DEFAULT_PRIORITY, &host_resolver, TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ EXPECT_EQ(tagging_sock->tag(), SocketTag());
+#if defined(OS_ANDROID)
+ SocketTag tag(0x12345678, 0x87654321);
+ socket.ApplySocketTag(tag);
+ EXPECT_EQ(tagging_sock->tag(), tag);
+#endif // OS_ANDROID
+}
+
} // namespace net
diff --git a/chromium/net/socket/ssl_client_socket_impl.cc b/chromium/net/socket/ssl_client_socket_impl.cc
index 54c0c560c96..c584e8e0f77 100644
--- a/chromium/net/socket/ssl_client_socket_impl.cc
+++ b/chromium/net/socket/ssl_client_socket_impl.cc
@@ -8,6 +8,7 @@
#include <string.h>
#include <algorithm>
+#include <map>
#include <utility>
#include "base/bind.h"
@@ -17,8 +18,9 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
@@ -36,8 +38,10 @@
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_policy_status.h"
#include "net/cert/ct_verifier.h"
+#include "net/cert/internal/parse_certificate.h"
#include "net/cert/x509_certificate_net_log_param.h"
#include "net/cert/x509_util.h"
+#include "net/der/parse_values.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
@@ -49,6 +53,7 @@
#include "net/ssl/ssl_info.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/token_binding.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/boringssl/src/include/openssl/bio.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/err.h"
@@ -84,6 +89,9 @@ const uint8_t kTbProtocolVersionMinor = 13;
const uint8_t kTbMinProtocolVersionMajor = 0;
const uint8_t kTbMinProtocolVersionMinor = 10;
+const base::Feature kPostQuantumPadding{"PostQuantumPadding",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback(
uint16_t algorithm,
NetLogCaptureMode mode) {
@@ -195,6 +203,95 @@ std::unique_ptr<base::Value> NetLogSSLMessageCallback(
return std::move(dict);
}
+// This enum is used in histograms, so values may not be reused.
+enum class RSAKeyUsage {
+ // The TLS cipher suite was not RSA or ECDHE_RSA.
+ kNotRSA = 0,
+ // The Key Usage extension is not present, which is consistent with TLS usage.
+ kOKNoExtension = 1,
+ // The Key Usage extension has both the digitalSignature and keyEncipherment
+ // bits, which is consistent with TLS usage.
+ kOKHaveBoth = 2,
+ // The Key Usage extension contains only the digitalSignature bit, which is
+ // consistent with TLS usage.
+ kOKHaveDigitalSignature = 3,
+ // The Key Usage extension contains only the keyEncipherment bit, which is
+ // consistent with TLS usage.
+ kOKHaveKeyEncipherment = 4,
+ // The Key Usage extension is missing the digitalSignature bit.
+ kMissingDigitalSignature = 5,
+ // The Key Usage extension is missing the keyEncipherment bit.
+ kMissingKeyEncipherment = 6,
+ // There was an error processing the certificate.
+ kError = 7,
+
+ kLastValue = kError,
+};
+
+RSAKeyUsage CheckRSAKeyUsage(const X509Certificate* cert,
+ const SSL_CIPHER* cipher) {
+ bool need_key_encipherment = false;
+ switch (SSL_CIPHER_get_kx_nid(cipher)) {
+ case NID_kx_rsa:
+ need_key_encipherment = true;
+ break;
+ case NID_kx_ecdhe:
+ if (SSL_CIPHER_get_auth_nid(cipher) != NID_auth_rsa) {
+ return RSAKeyUsage::kNotRSA;
+ }
+ break;
+ default:
+ return RSAKeyUsage::kNotRSA;
+ }
+
+ const CRYPTO_BUFFER* buffer = cert->cert_buffer();
+ der::Input tbs_certificate_tlv;
+ der::Input signature_algorithm_tlv;
+ der::BitString signature_value;
+ ParsedTbsCertificate tbs;
+ if (!ParseCertificate(
+ der::Input(CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer)),
+ &tbs_certificate_tlv, &signature_algorithm_tlv, &signature_value,
+ nullptr) ||
+ !ParseTbsCertificate(tbs_certificate_tlv,
+ x509_util::DefaultParseCertificateOptions(), &tbs,
+ nullptr)) {
+ return RSAKeyUsage::kError;
+ }
+
+ if (!tbs.has_extensions) {
+ return RSAKeyUsage::kOKNoExtension;
+ }
+
+ std::map<der::Input, ParsedExtension> extensions;
+ if (!ParseExtensions(tbs.extensions_tlv, &extensions)) {
+ return RSAKeyUsage::kError;
+ }
+ ParsedExtension key_usage_ext;
+ if (!ConsumeExtension(KeyUsageOid(), &extensions, &key_usage_ext)) {
+ return RSAKeyUsage::kOKNoExtension;
+ }
+ der::BitString key_usage;
+ if (!ParseKeyUsage(key_usage_ext.value, &key_usage)) {
+ return RSAKeyUsage::kError;
+ }
+
+ bool have_digital_signature =
+ key_usage.AssertsBit(KEY_USAGE_BIT_DIGITAL_SIGNATURE);
+ bool have_key_encipherment =
+ key_usage.AssertsBit(KEY_USAGE_BIT_KEY_ENCIPHERMENT);
+ if (have_digital_signature && have_key_encipherment) {
+ return RSAKeyUsage::kOKHaveBoth;
+ }
+
+ if (need_key_encipherment) {
+ return have_key_encipherment ? RSAKeyUsage::kOKHaveKeyEncipherment
+ : RSAKeyUsage::kMissingKeyEncipherment;
+ }
+ return have_digital_signature ? RSAKeyUsage::kOKHaveDigitalSignature
+ : RSAKeyUsage::kMissingDigitalSignature;
+}
+
} // namespace
class SSLClientSocketImpl::SSLContext {
@@ -412,6 +509,7 @@ SSLClientSocketImpl::SSLClientSocketImpl(
transport_security_state_(context.transport_security_state),
policy_enforcer_(context.ct_policy_enforcer),
pkp_bypassed_(false),
+ is_fatal_cert_error_(false),
connect_error_details_(SSLErrorDetails::kOther),
net_log_(transport_->socket()->NetLog()),
weak_factory_(this) {
@@ -673,7 +771,7 @@ bool SSLClientSocketImpl::GetSSLInfo(SSLInfo* ssl_info) {
ssl_info->token_binding_key_param = tb_negotiated_param_;
ssl_info->pinning_failure_log = pinning_failure_log_;
ssl_info->ocsp_result = server_cert_verify_result_.ocsp_result;
-
+ ssl_info->is_fatal_cert_error = is_fatal_cert_error_;
AddCTInfoToSSLInfo(ssl_info);
const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_.get());
@@ -718,6 +816,10 @@ void SSLClientSocketImpl::DumpMemoryStats(SocketMemoryStats* stats) const {
stats->total_size = stats->buffer_size + stats->cert_size;
}
+void SSLClientSocketImpl::ApplySocketTag(const SocketTag& tag) {
+ return transport_->socket()->ApplySocketTag(tag);
+}
+
// static
void SSLClientSocketImpl::DumpSSLClientSessionMemoryStats(
base::trace_event::ProcessMemoryDump* pmd) {
@@ -749,9 +851,11 @@ int SSLClientSocketImpl::ReadIfReady(IOBuffer* buf,
return rv;
}
-int SSLClientSocketImpl::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int SSLClientSocketImpl::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
user_write_buf_ = buf;
user_write_buf_len_ = buf_len;
@@ -844,18 +948,21 @@ int SSLClientSocketImpl::Init() {
}
switch (ssl_config_.tls13_variant) {
- case kTLS13VariantDraft:
- SSL_set_tls13_variant(ssl_.get(), tls13_default);
+ case kTLS13VariantDraft22:
+ SSL_set_tls13_variant(ssl_.get(), tls13_draft22);
break;
- case kTLS13VariantExperiment:
- SSL_set_tls13_variant(ssl_.get(), tls13_experiment);
+ case kTLS13VariantDraft23:
+ SSL_set_tls13_variant(ssl_.get(), tls13_default);
break;
case kTLS13VariantExperiment2:
SSL_set_tls13_variant(ssl_.get(), tls13_experiment2);
break;
- case kTLS13VariantExperiment3:
- SSL_set_tls13_variant(ssl_.get(), tls13_experiment3);
- break;
+ }
+
+ const int dummy_pq_padding_len = base::GetFieldTrialParamByFeatureAsInt(
+ kPostQuantumPadding, "length", 0 /* default value */);
+ if (dummy_pq_padding_len > 0 && dummy_pq_padding_len < 15000) {
+ SSL_set_dummy_pq_padding_size(ssl_.get(), dummy_pq_padding_len);
}
// OpenSSL defaults some options to on, others to off. To avoid ambiguity,
@@ -1098,8 +1205,7 @@ int SSLClientSocketImpl::DoHandshakeComplete(int result) {
uint16_t signature_algorithm = SSL_get_peer_signature_algorithm(ssl_.get());
if (signature_algorithm != 0) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLSignatureAlgorithm",
- signature_algorithm);
+ base::UmaHistogramSparse("Net.SSLSignatureAlgorithm", signature_algorithm);
}
// Verify the certificate.
@@ -1231,6 +1337,10 @@ int SSLClientSocketImpl::DoVerifyCertComplete(int result) {
result = ct_result;
}
+ is_fatal_cert_error_ =
+ IsCertStatusError(cert_status) && !IsCertStatusMinorError(cert_status) &&
+ transport_security_state_->ShouldSSLErrorsBeFatal(host_and_port_.host());
+
if (result == OK) {
DCHECK(!certificate_verified_);
certificate_verified_ = true;
@@ -1247,6 +1357,22 @@ int SSLClientSocketImpl::DoVerifyCertComplete(int result) {
transport_security_state_->CheckExpectStaple(host_and_port_, ssl_info,
ocsp_response);
+
+ // 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 {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.SSLRSAKeyUsage.UnknownRoot", rsa_key_usage,
+ static_cast<int>(RSAKeyUsage::kLastValue) + 1);
+ }
+ }
}
completed_connect_ = true;
@@ -1495,8 +1621,8 @@ int SSLClientSocketImpl::VerifyCT() {
// gets all the data it needs for SCT verification and does not do any
// external communication.
cert_transparency_verifier_->Verify(
- server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
- &ct_verify_result_.scts, net_log_);
+ host_and_port().host(), server_cert_verify_result_.verified_cert.get(),
+ ocsp_response, sct_list, &ct_verify_result_.scts, net_log_);
SCTList verified_scts =
ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK);
@@ -1613,7 +1739,7 @@ int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
NetLog::IntCallback(
"cert_count",
- 1 + ssl_config_.client_cert->GetIntermediateCertificates().size()));
+ 1 + ssl_config_.client_cert->intermediate_buffers().size()));
return 1;
}
#endif // defined(OS_IOS)
diff --git a/chromium/net/socket/ssl_client_socket_impl.h b/chromium/net/socket/ssl_client_socket_impl.h
index 0d162d37879..40b5d9763ea 100644
--- a/chromium/net/socket/ssl_client_socket_impl.h
+++ b/chromium/net/socket/ssl_client_socket_impl.h
@@ -32,6 +32,7 @@
#include "net/ssl/openssl_ssl_util.h"
#include "net/ssl/ssl_client_cert_type.h"
#include "net/ssl/ssl_config_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/boringssl/src/include/openssl/base.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
@@ -116,6 +117,7 @@ class SSLClientSocketImpl : public SSLClientSocket,
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
void DumpMemoryStats(SocketMemoryStats* stats) const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Dumps memory allocation stats. |pmd| is the browser process memory dump.
static void DumpSSLClientSessionMemoryStats(
@@ -130,7 +132,8 @@ class SSLClientSocketImpl : public SSLClientSocket,
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -349,6 +352,10 @@ class SSLClientSocketImpl : public SSLClientSocket,
// True if PKP is bypassed due to a local trust anchor.
bool pkp_bypassed_;
+ // True if there was a certificate error which should be treated as fatal,
+ // and false otherwise.
+ bool is_fatal_cert_error_;
+
SSLErrorDetails connect_error_details_;
NetLogWithSource net_log_;
diff --git a/chromium/net/socket/ssl_client_socket_pool.cc b/chromium/net/socket/ssl_client_socket_pool.cc
index 8eb860fafe4..b6a45f509a7 100644
--- a/chromium/net/socket/ssl_client_socket_pool.cc
+++ b/chromium/net/socket/ssl_client_socket_pool.cc
@@ -10,8 +10,8 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
@@ -100,6 +100,7 @@ static const int kSSLHandshakeTimeoutInSeconds = 30;
SSLConnectJob::SSLConnectJob(const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<SSLSocketParams>& params,
const base::TimeDelta& timeout_duration,
@@ -114,6 +115,7 @@ SSLConnectJob::SSLConnectJob(const std::string& group_name,
group_name,
timeout_duration,
priority,
+ socket_tag,
respect_limits,
delegate,
NetLogWithSource::Make(net_log, NetLogSourceType::SSL_CONNECT_JOB)),
@@ -236,8 +238,8 @@ int SSLConnectJob::DoTransportConnect() {
scoped_refptr<TransportSocketParams> direct_params =
params_->GetDirectConnectionParams();
return transport_socket_handle_->Init(group_name(), direct_params, priority(),
- respect_limits(), callback_,
- transport_pool_, net_log());
+ socket_tag(), respect_limits(),
+ callback_, transport_pool_, net_log());
}
int SSLConnectJob::DoTransportConnectComplete(int result) {
@@ -259,9 +261,9 @@ int SSLConnectJob::DoSOCKSConnect() {
transport_socket_handle_.reset(new ClientSocketHandle());
scoped_refptr<SOCKSSocketParams> socks_proxy_params =
params_->GetSocksProxyConnectionParams();
- return transport_socket_handle_->Init(group_name(), socks_proxy_params,
- priority(), respect_limits(), callback_,
- socks_pool_, net_log());
+ return transport_socket_handle_->Init(
+ group_name(), socks_proxy_params, priority(), socket_tag(),
+ respect_limits(), callback_, socks_pool_, net_log());
}
int SSLConnectJob::DoSOCKSConnectComplete(int result) {
@@ -278,9 +280,9 @@ int SSLConnectJob::DoTunnelConnect() {
transport_socket_handle_.reset(new ClientSocketHandle());
scoped_refptr<HttpProxySocketParams> http_proxy_params =
params_->GetHttpProxyConnectionParams();
- return transport_socket_handle_->Init(group_name(), http_proxy_params,
- priority(), respect_limits(), callback_,
- http_proxy_pool_, net_log());
+ return transport_socket_handle_->Init(
+ group_name(), http_proxy_params, priority(), socket_tag(),
+ respect_limits(), callback_, http_proxy_pool_, net_log());
}
int SSLConnectJob::DoTunnelConnectComplete(int result) {
@@ -366,8 +368,8 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
result == ERR_SSL_BAD_RECORD_MAC_ALERT) {
// Report the error code for each time a version interference probe is
// triggered.
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceProbeTrigger",
- std::abs(result));
+ base::UmaHistogramSparse("Net.SSLVersionInterferenceProbeTrigger",
+ std::abs(result));
net_log().AddEventWithNetErrorCode(
NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result);
SSLErrorDetails details = ssl_socket_->GetConnectErrorDetails();
@@ -417,11 +419,11 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
uint16_t cipher_suite =
SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_CipherSuite", cipher_suite);
+ base::UmaHistogramSparse("Net.SSL_CipherSuite", cipher_suite);
if (ssl_info.key_exchange_group != 0) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_KeyExchange.ECDHE",
- ssl_info.key_exchange_group);
+ base::UmaHistogramSparse("Net.SSL_KeyExchange.ECDHE",
+ ssl_info.key_exchange_group);
}
if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
@@ -469,24 +471,24 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
}
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error", std::abs(result));
+ base::UmaHistogramSparse("Net.SSL_Connection_Error", std::abs(result));
if (is_google) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_Google",
- std::abs(result));
+ base::UmaHistogramSparse("Net.SSL_Connection_Error_Google",
+ std::abs(result));
}
if (tls13_supported) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_TLS13Experiment",
- std::abs(result));
+ base::UmaHistogramSparse("Net.SSL_Connection_Error_TLS13Experiment",
+ std::abs(result));
}
if (result == ERR_SSL_VERSION_INTERFERENCE) {
// Record the error code version interference was detected at.
DCHECK(version_interference_probe_);
DCHECK_NE(OK, version_interference_error_);
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceError",
- std::abs(version_interference_error_));
+ base::UmaHistogramSparse("Net.SSLVersionInterferenceError",
+ std::abs(version_interference_error_));
if (tls13_supported) {
UMA_HISTOGRAM_ENUMERATION(
@@ -622,9 +624,10 @@ SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
const PoolBase::Request& request,
ConnectJob::Delegate* delegate) const {
return std::unique_ptr<ConnectJob>(new SSLConnectJob(
- group_name, request.priority(), request.respect_limits(),
- request.params(), ConnectionTimeout(), transport_pool_, socks_pool_,
- http_proxy_pool_, client_socket_factory_, context_, delegate, net_log_));
+ group_name, request.priority(), request.socket_tag(),
+ request.respect_limits(), request.params(), ConnectionTimeout(),
+ transport_pool_, socks_pool_, http_proxy_pool_, client_socket_factory_,
+ context_, delegate, net_log_));
}
base::TimeDelta SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout()
@@ -635,6 +638,7 @@ base::TimeDelta SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout()
int SSLClientSocketPool::RequestSocket(const std::string& group_name,
const void* socket_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -643,7 +647,8 @@ int SSLClientSocketPool::RequestSocket(const std::string& group_name,
static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params);
return base_.RequestSocket(group_name, *casted_socket_params, priority,
- respect_limits, handle, callback, net_log);
+ socket_tag, respect_limits, handle, callback,
+ net_log);
}
void SSLClientSocketPool::RequestSockets(
diff --git a/chromium/net/socket/ssl_client_socket_pool.h b/chromium/net/socket/ssl_client_socket_pool.h
index 097cf6c322b..6ec5c44f1ca 100644
--- a/chromium/net/socket/ssl_client_socket_pool.h
+++ b/chromium/net/socket/ssl_client_socket_pool.h
@@ -98,6 +98,7 @@ class SSLConnectJob : public ConnectJob {
// job.
SSLConnectJob(const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<SSLSocketParams>& params,
const base::TimeDelta& timeout_duration,
@@ -217,6 +218,7 @@ class NET_EXPORT_PRIVATE SSLClientSocketPool
int RequestSocket(const std::string& group_name,
const void* connect_params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
diff --git a/chromium/net/socket/ssl_client_socket_pool_unittest.cc b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
index 2715d394c49..c9fe46058af 100644
--- a/chromium/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
@@ -9,6 +9,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "net/base/auth.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
@@ -29,13 +30,16 @@
#include "net/proxy/proxy_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_session_pool.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/ssl/ssl_config_service_defaults.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
#include "net/test/test_certificate_data.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -48,6 +52,7 @@ namespace {
const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;
+const char kGroupName[] = "a";
// Make sure |handle|'s load times are set correctly. DNS and connect start
// times comes from mock client sockets in these tests, so primarily serves to
@@ -109,7 +114,8 @@ class SSLClientSocketPoolTest : public testing::Test {
socks_socket_params_(
new SOCKSSocketParams(proxy_transport_socket_params_,
true,
- HostPortPair("sockshost", 443))),
+ HostPortPair("sockshost", 443),
+ TRAFFIC_ANNOTATION_FOR_TESTS)),
socks_socket_pool_(kMaxSockets,
kMaxSocketsPerGroup,
&transport_socket_pool_),
@@ -123,8 +129,7 @@ class SSLClientSocketPoolTest : public testing::Test {
session_->http_auth_handler_factory(),
session_->spdy_session_pool(),
session_->quic_stream_factory(),
- true,
- NULL)),
+ true)),
http_proxy_socket_pool_(kMaxSockets,
kMaxSocketsPerGroup,
&transport_socket_pool_,
@@ -190,7 +195,7 @@ class SSLClientSocketPoolTest : public testing::Test {
MockClientSocketFactory socket_factory_;
MockCachingHostResolver host_resolver_;
- std::unique_ptr<CertVerifier> cert_verifier_;
+ std::unique_ptr<MockCertVerifier> cert_verifier_;
std::unique_ptr<TransportSecurityState> transport_security_state_;
MultiLogCTVerifier ct_verifier_;
CTPolicyEnforcer ct_policy_enforcer_;
@@ -225,9 +230,9 @@ TEST_F(SSLClientSocketPoolTest, TCPFail) {
false);
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- CompletionCallback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ CompletionCallback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_CONNECTION_FAILED));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -248,9 +253,9 @@ TEST_F(SSLClientSocketPoolTest, TCPFailAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -277,9 +282,9 @@ TEST_F(SSLClientSocketPoolTest, BasicDirect) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
@@ -305,7 +310,7 @@ TEST_F(SSLClientSocketPoolTest, SetSocketRequestPriorityOnInitDirect) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(
- OK, handle.Init("a", params, priority,
+ OK, handle.Init(kGroupName, params, priority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
@@ -325,9 +330,9 @@ TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -350,9 +355,9 @@ TEST_F(SSLClientSocketPoolTest, DirectCertError) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -375,9 +380,9 @@ TEST_F(SSLClientSocketPoolTest, DirectSSLError) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -401,9 +406,9 @@ TEST_F(SSLClientSocketPoolTest, DirectWithNPN) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -429,9 +434,9 @@ TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -455,9 +460,9 @@ TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -485,9 +490,9 @@ TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -513,9 +518,9 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFail) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_CONNECTION_FAILED));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -533,9 +538,9 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -559,9 +564,9 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasic) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
@@ -586,7 +591,7 @@ TEST_F(SSLClientSocketPoolTest, SetTransportPriorityOnInitSOCKS) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(OK,
- handle.Init("a", params, HIGHEST,
+ handle.Init(kGroupName, params, HIGHEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
@@ -604,9 +609,9 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -630,9 +635,9 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFail) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -650,9 +655,9 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -688,9 +693,9 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
@@ -725,7 +730,7 @@ TEST_F(SSLClientSocketPoolTest, SetTransportPriorityOnInitHTTP) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(OK,
- handle.Init("a", params, HIGHEST,
+ handle.Init(kGroupName, params, HIGHEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), pool_.get(), NetLogWithSource()));
EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
@@ -755,9 +760,9 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -793,9 +798,9 @@ TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) {
ClientSocketHandle handle;
TestCompletionCallback callback;
- int rv =
- handle.Init("a", params, MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), pool_.get(), NetLogWithSource());
+ int rv = handle.Init(kGroupName, params, MEDIUM, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), pool_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -944,6 +949,217 @@ TEST_F(SSLClientSocketPoolTest, IPPoolingChannelID) {
// It would be nice to also test the timeouts in SSLClientSocketPool.
+// Test that SocketTag passed into SSLClientSocketPool is applied to returned
+// sockets.
+#if defined(OS_ANDROID)
+TEST_F(SSLClientSocketPoolTest, Tag) {
+ // Start test server.
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ TransportClientSocketPool tcp_pool(
+ kMaxSockets, kMaxSocketsPerGroup, &host_resolver_,
+ ClientSocketFactory::GetDefaultFactory(), NULL, NULL);
+ cert_verifier_->set_default_result(OK);
+ SSLClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
+ cert_verifier_.get(), NULL /* channel_id_service */,
+ transport_security_state_.get(), &ct_verifier_,
+ &ct_policy_enforcer_,
+ std::string() /* ssl_session_cache_shard */,
+ ClientSocketFactory::GetDefaultFactory(), &tcp_pool,
+ NULL, NULL, NULL, NULL);
+ TestCompletionCallback callback;
+ ClientSocketHandle handle;
+ int32_t tag_val1 = 0x12345678;
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ int32_t tag_val2 = 0x87654321;
+ SocketTag tag2(getuid(), tag_val2);
+ scoped_refptr<TransportSocketParams> tcp_params(new TransportSocketParams(
+ test_server.host_port_pair(), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<SSLSocketParams> params(
+ new SSLSocketParams(tcp_params, NULL, NULL, test_server.host_port_pair(),
+ ssl_config_, PRIVACY_MODE_DISABLED, 0, false));
+
+ // Test socket is tagged before connected.
+ uint64_t old_traffic = GetTaggedBytes(tag_val1);
+ int rv = handle.Init(kGroupName, params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ // Test reused socket is retagged.
+ StreamSocket* socket = handle.socket();
+ handle.Reset();
+ old_traffic = GetTaggedBytes(tag_val2);
+ TestCompletionCallback callback2;
+ rv = handle.Init(kGroupName, params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback2.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_EQ(handle.socket(), socket);
+ const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
+ scoped_refptr<IOBuffer> write_buffer(new StringIOBuffer(kRequest));
+ rv =
+ handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(1));
+ rv = handle.socket()->Read(read_buffer.get(), read_buffer->size(),
+ callback.callback());
+ EXPECT_EQ(read_buffer->size(), callback.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+ // Disconnect socket to prevent reuse.
+ handle.socket()->Disconnect();
+ handle.Reset();
+}
+
+TEST_F(SSLClientSocketPoolTest, TagTwoSockets) {
+ // Start test server.
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ TransportClientSocketPool tcp_pool(
+ kMaxSockets, kMaxSocketsPerGroup, &host_resolver_,
+ ClientSocketFactory::GetDefaultFactory(), NULL, NULL);
+ cert_verifier_->set_default_result(OK);
+ SSLClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
+ cert_verifier_.get(), NULL /* channel_id_service */,
+ transport_security_state_.get(), &ct_verifier_,
+ &ct_policy_enforcer_,
+ std::string() /* ssl_session_cache_shard */,
+ ClientSocketFactory::GetDefaultFactory(), &tcp_pool,
+ NULL, NULL, NULL, NULL);
+ ClientSocketHandle handle;
+ int32_t tag_val1 = 0x12345678;
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ int32_t tag_val2 = 0x87654321;
+ SocketTag tag2(getuid(), tag_val2);
+ scoped_refptr<TransportSocketParams> tcp_params(new TransportSocketParams(
+ test_server.host_port_pair(), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<SSLSocketParams> params(
+ new SSLSocketParams(tcp_params, NULL, NULL, test_server.host_port_pair(),
+ ssl_config_, PRIVACY_MODE_DISABLED, 0, false));
+
+ // Test connect jobs that are orphaned and then adopted, appropriately apply
+ // new tag. Request socket with |tag1|.
+ TestCompletionCallback callback;
+ int rv = handle.Init(kGroupName, params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv;
+ // Abort and request socket with |tag2|.
+ handle.Reset();
+ TestCompletionCallback callback2;
+ rv = handle.Init(kGroupName, params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback2.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(callback2.GetResult(rv), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ // Verify socket has |tag2| applied.
+ uint64_t old_traffic = GetTaggedBytes(tag_val2);
+ const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
+ scoped_refptr<IOBuffer> write_buffer(new StringIOBuffer(kRequest));
+ rv = handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback2.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback2.GetResult(rv));
+ scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(1));
+ rv = handle.socket()->Read(read_buffer.get(), read_buffer->size(),
+ callback2.callback());
+ EXPECT_EQ(read_buffer->size(), callback2.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+}
+
+TEST_F(SSLClientSocketPoolTest, TagTwoSocketsFullPool) {
+ // Start test server.
+ EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ TransportClientSocketPool tcp_pool(
+ kMaxSockets, kMaxSocketsPerGroup, &host_resolver_,
+ ClientSocketFactory::GetDefaultFactory(), NULL, NULL);
+ cert_verifier_->set_default_result(OK);
+ SSLClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
+ cert_verifier_.get(), NULL /* channel_id_service */,
+ transport_security_state_.get(), &ct_verifier_,
+ &ct_policy_enforcer_,
+ std::string() /* ssl_session_cache_shard */,
+ ClientSocketFactory::GetDefaultFactory(), &tcp_pool,
+ NULL, NULL, NULL, NULL);
+ TestCompletionCallback callback;
+ ClientSocketHandle handle;
+ int32_t tag_val1 = 0x12345678;
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ int32_t tag_val2 = 0x87654321;
+ SocketTag tag2(getuid(), tag_val2);
+ scoped_refptr<TransportSocketParams> tcp_params(new TransportSocketParams(
+ test_server.host_port_pair(), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<SSLSocketParams> params(
+ new SSLSocketParams(tcp_params, NULL, NULL, test_server.host_port_pair(),
+ ssl_config_, PRIVACY_MODE_DISABLED, 0, false));
+
+ // Test that sockets paused by a full underlying socket pool are properly
+ // connected and tagged when underlying pool is freed up.
+ // Fill up all slots in TCP pool.
+ ClientSocketHandle tcp_handles[kMaxSocketsPerGroup];
+ int rv;
+ for (auto& tcp_handle : tcp_handles) {
+ rv = tcp_handle.Init(kGroupName, tcp_params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &tcp_pool, NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ EXPECT_TRUE(tcp_handle.socket());
+ EXPECT_TRUE(tcp_handle.socket()->IsConnected());
+ }
+ // Request two SSL sockets.
+ ClientSocketHandle handle_to_be_canceled;
+ rv = handle_to_be_canceled.Init(
+ kGroupName, params, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ rv = handle.Init(kGroupName, params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ // Cancel first request.
+ handle_to_be_canceled.Reset();
+ // Disconnect a TCP socket to free up a slot.
+ tcp_handles[0].socket()->Disconnect();
+ tcp_handles[0].Reset();
+ // Verify |handle| gets a valid tagged socket.
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ uint64_t old_traffic = GetTaggedBytes(tag_val2);
+ const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
+ scoped_refptr<IOBuffer> write_buffer(new StringIOBuffer(kRequest));
+ rv =
+ handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ scoped_refptr<IOBufferWithSize> read_buffer(new IOBufferWithSize(1));
+ EXPECT_EQ(handle.socket()->Read(read_buffer.get(), read_buffer->size(),
+ callback.callback()),
+ ERR_IO_PENDING);
+ EXPECT_THAT(callback.WaitForResult(), read_buffer->size());
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+}
+#endif
} // namespace
} // namespace net
diff --git a/chromium/net/socket/ssl_client_socket_unittest.cc b/chromium/net/socket/ssl_client_socket_unittest.cc
index d0527eea2b3..19576f43903 100644
--- a/chromium/net/socket/ssl_client_socket_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_unittest.cc
@@ -22,6 +22,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "crypto/rsa_private_key.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
@@ -37,6 +38,7 @@
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/cert/test_root_certs.h"
+#include "net/cert/x509_util.h"
#include "net/der/input.h"
#include "net/der/parser.h"
#include "net/der/tag.h"
@@ -66,6 +68,7 @@
#include "net/test/gtest_util.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -87,90 +90,6 @@ class NetLogWithSource;
namespace {
-// WrappedStreamSocket is a base class that wraps an existing StreamSocket,
-// forwarding the Socket and StreamSocket interfaces to the underlying
-// transport.
-// This is to provide a common base class for subclasses to override specific
-// StreamSocket methods for testing, while still communicating with a 'real'
-// StreamSocket.
-class WrappedStreamSocket : public StreamSocket {
- public:
- explicit WrappedStreamSocket(std::unique_ptr<StreamSocket> transport)
- : transport_(std::move(transport)) {}
- ~WrappedStreamSocket() override = default;
-
- // StreamSocket implementation:
- int Connect(const CompletionCallback& callback) override {
- return transport_->Connect(callback);
- }
- void Disconnect() override { transport_->Disconnect(); }
- bool IsConnected() const override { return transport_->IsConnected(); }
- bool IsConnectedAndIdle() const override {
- return transport_->IsConnectedAndIdle();
- }
- int GetPeerAddress(IPEndPoint* address) const override {
- return transport_->GetPeerAddress(address);
- }
- int GetLocalAddress(IPEndPoint* address) const override {
- return transport_->GetLocalAddress(address);
- }
- const NetLogWithSource& NetLog() const override {
- return transport_->NetLog();
- }
- void SetSubresourceSpeculation() override {
- transport_->SetSubresourceSpeculation();
- }
- void SetOmniboxSpeculation() override { transport_->SetOmniboxSpeculation(); }
- bool WasEverUsed() const override { return transport_->WasEverUsed(); }
- bool WasAlpnNegotiated() const override {
- return transport_->WasAlpnNegotiated();
- }
- NextProto GetNegotiatedProtocol() const override {
- return transport_->GetNegotiatedProtocol();
- }
- bool GetSSLInfo(SSLInfo* ssl_info) override {
- return transport_->GetSSLInfo(ssl_info);
- }
- void GetConnectionAttempts(ConnectionAttempts* out) const override {
- transport_->GetConnectionAttempts(out);
- }
- void ClearConnectionAttempts() override {
- transport_->ClearConnectionAttempts();
- }
- void AddConnectionAttempts(const ConnectionAttempts& attempts) override {
- transport_->AddConnectionAttempts(attempts);
- }
- int64_t GetTotalReceivedBytes() const override {
- return transport_->GetTotalReceivedBytes();
- }
-
- // Socket implementation:
- int Read(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override {
- return transport_->Read(buf, buf_len, callback);
- }
- int ReadIfReady(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override {
- return transport_->ReadIfReady(buf, buf_len, callback);
- }
- int Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) override {
- return transport_->Write(buf, buf_len, callback);
- }
- int SetReceiveBufferSize(int32_t size) override {
- return transport_->SetReceiveBufferSize(size);
- }
- int SetSendBufferSize(int32_t size) override {
- return transport_->SetSendBufferSize(size);
- }
-
- protected:
- std::unique_ptr<StreamSocket> transport_;
-};
-
// ReadBufferingStreamSocket is a wrapper for an existing StreamSocket that
// will ensure a certain amount of data is internally buffered before
// satisfying a Read() request. It exists to mimic OS-level internal
@@ -349,7 +268,8 @@ class SynchronousErrorStreamSocket : public WrappedStreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
// Sets the next Read() call and all future calls to return |error|.
// If there is already a pending asynchronous read, the configured error
@@ -398,9 +318,11 @@ int SynchronousErrorStreamSocket::ReadIfReady(
return transport_->ReadIfReady(buf, buf_len, callback);
}
-int SynchronousErrorStreamSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int SynchronousErrorStreamSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
if (have_write_error_)
return pending_write_error_;
return transport_->Write(buf, buf_len, callback);
@@ -425,7 +347,8 @@ class FakeBlockingStreamSocket : public WrappedStreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int pending_read_result() const { return pending_read_result_; }
IOBuffer* pending_read_buf() const { return pending_read_buf_.get(); }
@@ -559,9 +482,11 @@ int FakeBlockingStreamSocket::ReadIfReady(IOBuffer* buf,
return rv;
}
-int FakeBlockingStreamSocket::Write(IOBuffer* buf,
- int len,
- const CompletionCallback& callback) {
+int FakeBlockingStreamSocket::Write(
+ IOBuffer* buf,
+ int len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(buf);
DCHECK_LE(0, len);
@@ -713,7 +638,8 @@ class CountingStreamSocket : public WrappedStreamSocket {
}
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
write_count_++;
return transport_->Write(buf, buf_len, callback);
}
@@ -855,13 +781,15 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
// anything.
class MockCTVerifier : public CTVerifier {
public:
- MOCK_METHOD5(Verify,
- void(X509Certificate*,
+ MOCK_METHOD6(Verify,
+ void(base::StringPiece,
+ X509Certificate*,
base::StringPiece,
base::StringPiece,
SignedCertificateTimestampAndStatusList*,
const NetLogWithSource&));
MOCK_METHOD1(SetObserver, void(CTVerifier::Observer*));
+ MOCK_CONST_METHOD0(GetObserver, CTVerifier::Observer*());
};
// A mock CTPolicyEnforcer that returns a custom verification result.
@@ -2325,24 +2253,23 @@ TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) {
scoped_refptr<X509Certificate> server_certificate = ssl_info.unverified_cert;
// Get the intermediates as received client side.
- const X509Certificate::OSCertHandles& server_intermediates =
- server_certificate->GetIntermediateCertificates();
+ const auto& server_intermediates = server_certificate->intermediate_buffers();
// Check that the unverified server certificate chain is properly retrieved
// from the underlying ssl stack.
ASSERT_EQ(4U, server_certs.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- server_certificate->os_cert_handle(), server_certs[0]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(server_certificate->cert_buffer(),
+ server_certs[0]->cert_buffer()));
ASSERT_EQ(3U, server_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[0],
- server_certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[1],
- server_certs[2]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[2],
- server_certs[3]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[0].get(),
+ server_certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[1].get(),
+ server_certs[2]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(server_intermediates[2].get(),
+ server_certs[3]->cert_buffer()));
sock_->Disconnect();
EXPECT_FALSE(sock_->IsConnected());
@@ -2379,13 +2306,16 @@ TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) {
ASSERT_TRUE(certs[0]->Equals(unverified_certs[0].get()));
- X509Certificate::OSCertHandles temp_intermediates;
- temp_intermediates.push_back(certs[1]->os_cert_handle());
- temp_intermediates.push_back(certs[2]->os_cert_handle());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> temp_intermediates;
+ temp_intermediates.push_back(
+ x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ temp_intermediates.push_back(
+ x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
CertVerifyResult verify_result;
- verify_result.verified_cert = X509Certificate::CreateFromHandle(
- certs[0]->os_cert_handle(), temp_intermediates);
+ verify_result.verified_cert = X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(temp_intermediates));
ASSERT_TRUE(verify_result.verified_cert);
// Add a rule that maps the server cert (A) to the chain of A->B->C2
@@ -2418,29 +2348,28 @@ TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) {
// Verify that SSLInfo contains the corrected re-constructed chain A -> B
// -> C2.
ASSERT_TRUE(ssl_info.cert);
- const X509Certificate::OSCertHandles& intermediates =
- ssl_info.cert->GetIntermediateCertificates();
+ const auto& intermediates = ssl_info.cert->intermediate_buffers();
ASSERT_EQ(2U, intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(ssl_info.cert->os_cert_handle(),
- certs[0]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[0],
- certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[1],
- certs[2]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(ssl_info.cert->cert_buffer(),
+ certs[0]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(intermediates[0].get(),
+ certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(intermediates[1].get(),
+ certs[2]->cert_buffer()));
// Verify that SSLInfo also contains the chain as received from the server.
ASSERT_TRUE(ssl_info.unverified_cert);
- const X509Certificate::OSCertHandles& served_intermediates =
- ssl_info.unverified_cert->GetIntermediateCertificates();
+ const auto& served_intermediates =
+ ssl_info.unverified_cert->intermediate_buffers();
ASSERT_EQ(3U, served_intermediates.size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- ssl_info.cert->os_cert_handle(), unverified_certs[0]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- served_intermediates[0], unverified_certs[1]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- served_intermediates[1], unverified_certs[2]->os_cert_handle()));
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- served_intermediates[2], unverified_certs[3]->os_cert_handle()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(ssl_info.cert->cert_buffer(),
+ unverified_certs[0]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[0].get(),
+ unverified_certs[1]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[1].get(),
+ unverified_certs[2]->cert_buffer()));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(served_intermediates[2].get(),
+ unverified_certs[3]->cert_buffer()));
sock_->Disconnect();
EXPECT_FALSE(sock_->IsConnected());
@@ -2526,8 +2455,8 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) {
// Check that the SCT list is extracted from the TLS extension as expected,
// while also simulating that it was an unparsable response.
SignedCertificateTimestampAndStatusList sct_list;
- EXPECT_CALL(ct_verifier, Verify(_, _, sct_ext, _, _))
- .WillOnce(testing::SetArgPointee<3>(sct_list));
+ EXPECT_CALL(ct_verifier, Verify(_, _, _, sct_ext, _, _))
+ .WillOnce(testing::SetArgPointee<4>(sct_list));
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
@@ -2743,6 +2672,40 @@ TEST_F(SSLClientSocketTest, ReuseStates) {
// buffer. Call SSL_pending.
}
+// Tests that |is_fatal_cert_error| does not get set for a certificate error,
+// on a non-HSTS host.
+TEST_F(SSLClientSocketTest, IsFatalErrorNotSetOnNonFatalError) {
+ cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
+ SpawnedTestServer::SSLOptions ssl_options(
+ SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT);
+ ASSERT_TRUE(StartTestServer(ssl_options));
+ SSLConfig ssl_config;
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ SSLInfo ssl_info;
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+ EXPECT_FALSE(ssl_info.is_fatal_cert_error);
+}
+
+// Tests that |is_fatal_cert_error| gets set for a certificate error on an
+// HSTS host.
+TEST_F(SSLClientSocketTest, IsFatalErrorSetOnFatalError) {
+ cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
+ SpawnedTestServer::SSLOptions ssl_options(
+ SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT);
+ ASSERT_TRUE(StartTestServer(ssl_options));
+ SSLConfig ssl_config;
+ int rv;
+ const base::Time expiry =
+ base::Time::Now() + base::TimeDelta::FromSeconds(1000);
+ context_.transport_security_state->AddHSTS(
+ spawned_test_server()->host_port_pair().host(), expiry, true);
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
+ SSLInfo ssl_info;
+ ASSERT_TRUE(sock_->GetSSLInfo(&ssl_info));
+ EXPECT_TRUE(ssl_info.is_fatal_cert_error);
+}
+
// Tests that IsConnectedAndIdle treats a socket as idle even if a Write hasn't
// been flushed completely out of SSLClientSocket's internal buffers. This is a
// regression test for https://crbug.com/466147.
@@ -4420,4 +4383,28 @@ TEST_F(SSLClientSocketTest, SessionCacheShard) {
EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type);
}
+TEST_F(SSLClientSocketTest, Tag) {
+ ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
+
+ TestNetLog log;
+ std::unique_ptr<StreamSocket> transport(
+ new TCPClientSocket(addr(), NULL, &log, NetLogSource()));
+
+ MockTaggingStreamSocket* tagging_sock =
+ new MockTaggingStreamSocket(std::move(transport));
+
+ // |sock| takes ownership of |tagging_sock|, but keep a
+ // non-owning pointer to it.
+ std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
+ std::unique_ptr<StreamSocket>(tagging_sock),
+ spawned_test_server()->host_port_pair(), SSLConfig()));
+
+ EXPECT_EQ(tagging_sock->tag(), SocketTag());
+#if defined(OS_ANDROID)
+ SocketTag tag(0x12345678, 0x87654321);
+ sock->ApplySocketTag(tag);
+ EXPECT_EQ(tagging_sock->tag(), tag);
+#endif // OS_ANDROID
+}
+
} // namespace net
diff --git a/chromium/net/socket/ssl_server_socket.h b/chromium/net/socket/ssl_server_socket.h
index b61e6631761..92d2185305f 100644
--- a/chromium/net/socket/ssl_server_socket.h
+++ b/chromium/net/socket/ssl_server_socket.h
@@ -30,6 +30,7 @@ class RSAPrivateKey;
namespace net {
struct SSLServerConfig;
+class SSLPrivateKey;
class X509Certificate;
// A server socket that uses SSL as the transport layer.
@@ -70,6 +71,11 @@ NET_EXPORT std::unique_ptr<SSLServerContext> CreateSSLServerContext(
const crypto::RSAPrivateKey& key,
const SSLServerConfig& ssl_config);
+NET_EXPORT std::unique_ptr<SSLServerContext> CreateSSLServerContext(
+ X509Certificate* certificate,
+ scoped_refptr<SSLPrivateKey> key,
+ const SSLServerConfig& ssl_config);
+
} // namespace net
#endif // NET_SOCKET_SSL_SERVER_SOCKET_H_
diff --git a/chromium/net/socket/ssl_server_socket_impl.cc b/chromium/net/socket/ssl_server_socket_impl.cc
index cba12a6b80a..198f1650024 100644
--- a/chromium/net/socket/ssl_server_socket_impl.cc
+++ b/chromium/net/socket/ssl_server_socket_impl.cc
@@ -7,7 +7,9 @@
#include <utility>
#include "base/callback_helpers.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string_util.h"
#include "crypto/openssl_util.h"
#include "crypto/rsa_private_key.h"
@@ -21,6 +23,7 @@
#include "net/ssl/openssl_ssl_util.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_info.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/boringssl/src/include/openssl/err.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
@@ -29,6 +32,34 @@
namespace net {
+namespace {
+
+// This constant can be any non-negative/non-zero value (eg: it does not
+// overlap with any value of the net::Error range, including net::OK).
+const int kNoPendingResult = 1;
+
+class SocketDataIndex {
+ public:
+ static SocketDataIndex* GetInstance();
+ SocketDataIndex() {
+ ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
+ }
+
+ // This is the index used with SSL_get_ex_data to retrieve the owner
+ // SSLServerSocketImpl object from an SSL instance.
+ int ssl_socket_data_index_;
+};
+
+base::LazyInstance<SocketDataIndex>::Leaky g_ssl_socket_data_index_ =
+ LAZY_INSTANCE_INITIALIZER;
+
+// static
+SocketDataIndex* SocketDataIndex::GetInstance() {
+ return g_ssl_socket_data_index_.Pointer();
+}
+
+} // namespace
+
class SSLServerContextImpl::SocketImpl : public SSLServerSocket,
public SocketBIOAdapter::Delegate {
public:
@@ -52,7 +83,8 @@ class SSLServerContextImpl::SocketImpl : public SSLServerSocket,
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
@@ -74,9 +106,41 @@ class SSLServerContextImpl::SocketImpl : public SSLServerSocket,
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
+
static ssl_verify_result_t CertVerifyCallback(SSL* ssl, uint8_t* out_alert);
ssl_verify_result_t CertVerifyCallbackImpl(uint8_t* out_alert);
+ static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
+ static ssl_private_key_result_t PrivateKeySignCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ uint16_t algorithm,
+ const uint8_t* in,
+ size_t in_len);
+ static ssl_private_key_result_t PrivateKeyDecryptCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ const uint8_t* in,
+ size_t in_len);
+ static ssl_private_key_result_t PrivateKeyCompleteCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out);
+
+ ssl_private_key_result_t PrivateKeySignCallback(uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ uint16_t algorithm,
+ const uint8_t* in,
+ size_t in_len);
+ ssl_private_key_result_t PrivateKeyCompleteCallback(uint8_t* out,
+ size_t* out_len,
+ size_t max_out);
+ void OnPrivateKeyComplete(Error error, const std::vector<uint8_t>& signature);
+
// SocketBIOAdapter::Delegate implementation.
void OnReadReady() override;
void OnWriteReady() override;
@@ -109,6 +173,10 @@ class SSLServerContextImpl::SocketImpl : public SSLServerSocket,
CompletionCallback user_read_callback_;
CompletionCallback user_write_callback_;
+ // SSLPrivateKey signature.
+ int signature_result_;
+ std::vector<uint8_t> signature_;
+
// Used by Read function.
scoped_refptr<IOBuffer> user_read_buf_;
int user_read_buf_len_;
@@ -130,6 +198,8 @@ class SSLServerContextImpl::SocketImpl : public SSLServerSocket,
State next_handshake_state_;
bool completed_handshake_;
+ base::WeakPtrFactory<SocketImpl> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(SocketImpl);
};
@@ -137,11 +207,13 @@ SSLServerContextImpl::SocketImpl::SocketImpl(
SSLServerContextImpl* context,
std::unique_ptr<StreamSocket> transport_socket)
: context_(context),
+ signature_result_(kNoPendingResult),
user_read_buf_len_(0),
user_write_buf_len_(0),
transport_socket_(std::move(transport_socket)),
next_handshake_state_(STATE_NONE),
- completed_handshake_(false) {
+ completed_handshake_(false),
+ weak_factory_(this) {
ssl_.reset(SSL_new(context_->ssl_ctx_.get()));
SSL_set_app_data(ssl_.get(), this);
}
@@ -155,6 +227,108 @@ SSLServerContextImpl::SocketImpl::~SocketImpl() {
}
}
+// static
+const SSL_PRIVATE_KEY_METHOD
+ SSLServerContextImpl::SocketImpl::kPrivateKeyMethod = {
+ &SSLServerContextImpl::SocketImpl::PrivateKeySignCallback,
+ &SSLServerContextImpl::SocketImpl::PrivateKeyDecryptCallback,
+ &SSLServerContextImpl::SocketImpl::PrivateKeyCompleteCallback,
+};
+
+// static
+ssl_private_key_result_t
+SSLServerContextImpl::SocketImpl::PrivateKeySignCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ uint16_t algorithm,
+ const uint8_t* in,
+ size_t in_len) {
+ DCHECK(ssl);
+ SSLServerContextImpl::SocketImpl* socket =
+ static_cast<SSLServerContextImpl::SocketImpl*>(SSL_get_ex_data(
+ ssl, SocketDataIndex::GetInstance()->ssl_socket_data_index_));
+ DCHECK(socket);
+ return socket->PrivateKeySignCallback(out, out_len, max_out, algorithm, in,
+ in_len);
+}
+
+// static
+ssl_private_key_result_t
+SSLServerContextImpl::SocketImpl::PrivateKeyDecryptCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ const uint8_t* in,
+ size_t in_len) {
+ // Decrypt is not supported.
+ return ssl_private_key_failure;
+}
+
+// static
+ssl_private_key_result_t
+SSLServerContextImpl::SocketImpl::PrivateKeyCompleteCallback(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out) {
+ DCHECK(ssl);
+ SSLServerContextImpl::SocketImpl* socket =
+ static_cast<SSLServerContextImpl::SocketImpl*>(SSL_get_ex_data(
+ ssl, SocketDataIndex::GetInstance()->ssl_socket_data_index_));
+ DCHECK(socket);
+ return socket->PrivateKeyCompleteCallback(out, out_len, max_out);
+}
+
+ssl_private_key_result_t
+SSLServerContextImpl::SocketImpl::PrivateKeySignCallback(uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ uint16_t algorithm,
+ const uint8_t* in,
+ size_t in_len) {
+ DCHECK(context_);
+ DCHECK(context_->private_key_);
+ signature_result_ = ERR_IO_PENDING;
+ context_->private_key_->Sign(
+ algorithm, base::make_span(in, in_len),
+ base::BindRepeating(
+ &SSLServerContextImpl::SocketImpl::OnPrivateKeyComplete,
+ weak_factory_.GetWeakPtr()));
+ return ssl_private_key_retry;
+}
+
+ssl_private_key_result_t
+SSLServerContextImpl::SocketImpl::PrivateKeyCompleteCallback(uint8_t* out,
+ size_t* out_len,
+ size_t max_out) {
+ if (signature_result_ == ERR_IO_PENDING)
+ return ssl_private_key_retry;
+ if (signature_result_ != OK) {
+ OpenSSLPutNetError(FROM_HERE, signature_result_);
+ return ssl_private_key_failure;
+ }
+ if (signature_.size() > max_out) {
+ OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
+ return ssl_private_key_failure;
+ }
+ memcpy(out, signature_.data(), signature_.size());
+ *out_len = signature_.size();
+ signature_.clear();
+ return ssl_private_key_success;
+}
+
+void SSLServerContextImpl::SocketImpl::OnPrivateKeyComplete(
+ Error error,
+ const std::vector<uint8_t>& signature) {
+ DCHECK_EQ(ERR_IO_PENDING, signature_result_);
+ DCHECK(signature_.empty());
+
+ signature_result_ = error;
+ if (signature_result_ == OK)
+ signature_ = signature;
+ DoHandshakeLoop(ERR_IO_PENDING);
+}
+
int SSLServerContextImpl::SocketImpl::Handshake(
const CompletionCallback& callback) {
net_log_.BeginEvent(NetLogEventType::SSL_SERVER_HANDSHAKE);
@@ -236,7 +410,8 @@ int SSLServerContextImpl::SocketImpl::Read(IOBuffer* buf,
int SSLServerContextImpl::SocketImpl::Write(
IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(user_write_callback_.is_null());
DCHECK(!user_write_buf_);
DCHECK(!callback.is_null());
@@ -356,6 +531,10 @@ int64_t SSLServerContextImpl::SocketImpl::GetTotalReceivedBytes() const {
return transport_socket_->GetTotalReceivedBytes();
}
+void SSLServerContextImpl::SocketImpl::ApplySocketTag(const SocketTag& tag) {
+ NOTIMPLEMENTED();
+}
+
void SSLServerContextImpl::SocketImpl::OnReadReady() {
if (next_handshake_state_ == STATE_HANDSHAKE) {
// In handshake phase. The parameter to OnHandshakeIOComplete is unused.
@@ -471,7 +650,6 @@ int SSLServerContextImpl::SocketImpl::DoHandshake() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
int net_error = OK;
int rv = SSL_do_handshake(ssl_.get());
-
if (rv == 1) {
completed_handshake_ = true;
STACK_OF(CRYPTO_BUFFER)* certs = SSL_get0_peer_certificates(ssl_.get());
@@ -482,6 +660,13 @@ int SSLServerContextImpl::SocketImpl::DoHandshake() {
}
} else {
int ssl_error = SSL_get_error(ssl_.get(), rv);
+
+ if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
+ DCHECK(context_->private_key_);
+ GotoState(STATE_HANDSHAKE);
+ return ERR_IO_PENDING;
+ }
+
OpenSSLErrorInfo error_info;
net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
@@ -535,15 +720,30 @@ int SSLServerContextImpl::SocketImpl::Init() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- if (!ssl_)
+ if (!ssl_ ||
+ !SSL_set_ex_data(ssl_.get(),
+ SocketDataIndex::GetInstance()->ssl_socket_data_index_,
+ this))
return ERR_UNEXPECTED;
// Set certificate and private key.
- DCHECK(context_->cert_->os_cert_handle());
- DCHECK(context_->key_->key());
- if (!SetSSLChainAndKey(ssl_.get(), context_->cert_.get(),
- context_->key_->key(), nullptr)) {
- return ERR_UNEXPECTED;
+ if (context_->key_) {
+ DCHECK(context_->cert_->cert_buffer());
+ DCHECK(context_->key_->key());
+ if (!SetSSLChainAndKey(ssl_.get(), context_->cert_.get(),
+ context_->key_->key(), nullptr)) {
+ return ERR_UNEXPECTED;
+ }
+ } else {
+ DCHECK(context_->private_key_);
+ if (!SetSSLChainAndKey(ssl_.get(), context_->cert_.get(), nullptr,
+ &kPrivateKeyMethod)) {
+ return ERR_UNEXPECTED;
+ }
+ std::vector<uint16_t> preferences =
+ context_->private_key_->GetAlgorithmPreferences();
+ SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(),
+ preferences.size());
}
transport_adapter_.reset(new SocketBIOAdapter(
@@ -601,8 +801,26 @@ std::unique_ptr<SSLServerContext> CreateSSLServerContext(
X509Certificate* certificate,
const crypto::RSAPrivateKey& key,
const SSLServerConfig& ssl_server_config) {
- return std::unique_ptr<SSLServerContext>(
- new SSLServerContextImpl(certificate, key, ssl_server_config));
+ return std::make_unique<SSLServerContextImpl>(certificate, key,
+ ssl_server_config);
+}
+
+std::unique_ptr<SSLServerContext> CreateSSLServerContext(
+ X509Certificate* certificate,
+ scoped_refptr<SSLPrivateKey> key,
+ const SSLServerConfig& ssl_config) {
+ return std::make_unique<SSLServerContextImpl>(certificate, key, ssl_config);
+}
+
+SSLServerContextImpl::SSLServerContextImpl(
+ X509Certificate* certificate,
+ scoped_refptr<net::SSLPrivateKey> key,
+ const SSLServerConfig& ssl_server_config)
+ : ssl_server_config_(ssl_server_config),
+ cert_(certificate),
+ private_key_(key) {
+ CHECK(private_key_);
+ Init();
}
SSLServerContextImpl::SSLServerContextImpl(
@@ -613,6 +831,10 @@ SSLServerContextImpl::SSLServerContextImpl(
cert_(certificate),
key_(key.Copy()) {
CHECK(key_);
+ Init();
+}
+
+void SSLServerContextImpl::Init() {
crypto::EnsureOpenSSLInit();
ssl_ctx_.reset(SSL_CTX_new(TLS_with_buffers_method()));
SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_SERVER);
@@ -665,7 +887,8 @@ SSLServerContextImpl::SSLServerContextImpl(
// as the handshake hash.
std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK");
- if (ssl_server_config_.require_ecdhe)
+ // SSLPrivateKey only supports ECDHE-based ciphers because it lacks decrypt.
+ if (ssl_server_config_.require_ecdhe || (!key_ && private_key_))
command.append(":!kRSA");
// Remove any disabled ciphers.
@@ -695,8 +918,7 @@ SSLServerContextImpl::~SSLServerContextImpl() = default;
std::unique_ptr<SSLServerSocket> SSLServerContextImpl::CreateSSLServerSocket(
std::unique_ptr<StreamSocket> socket) {
- return std::unique_ptr<SSLServerSocket>(
- new SocketImpl(this, std::move(socket)));
+ return std::make_unique<SocketImpl>(this, std::move(socket));
}
} // namespace net
diff --git a/chromium/net/socket/ssl_server_socket_impl.h b/chromium/net/socket/ssl_server_socket_impl.h
index 7e9ca967d48..74ffbfa1429 100644
--- a/chromium/net/socket/ssl_server_socket_impl.h
+++ b/chromium/net/socket/ssl_server_socket_impl.h
@@ -23,6 +23,9 @@ class SSLServerContextImpl : public SSLServerContext {
SSLServerContextImpl(X509Certificate* certificate,
const crypto::RSAPrivateKey& key,
const SSLServerConfig& ssl_server_config);
+ SSLServerContextImpl(X509Certificate* certificate,
+ scoped_refptr<SSLPrivateKey> key,
+ const SSLServerConfig& ssl_server_config);
~SSLServerContextImpl() override;
std::unique_ptr<SSLServerSocket> CreateSSLServerSocket(
@@ -31,6 +34,8 @@ class SSLServerContextImpl : public SSLServerContext {
private:
class SocketImpl;
+ void Init();
+
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
// Options for the SSL socket.
@@ -40,7 +45,9 @@ class SSLServerContextImpl : public SSLServerContext {
scoped_refptr<X509Certificate> cert_;
// Private key used by the server.
+ // Only one representation should be set at any time.
std::unique_ptr<crypto::RSAPrivateKey> key_;
+ const scoped_refptr<SSLPrivateKey> private_key_;
};
} // namespace net
diff --git a/chromium/net/socket/ssl_server_socket_unittest.cc b/chromium/net/socket/ssl_server_socket_unittest.cc
index 73a038d61cc..b4465f77eab 100644
--- a/chromium/net/socket/ssl_server_socket_unittest.cc
+++ b/chromium/net/socket/ssl_server_socket_unittest.cc
@@ -66,6 +66,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -119,7 +120,10 @@ class FakeDataChannel {
return PropagateData(buf, buf_len);
}
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(write_callback_.is_null());
if (closed_) {
if (write_called_after_close_)
@@ -234,10 +238,12 @@ class FakeSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
// Write random number of bytes.
buf_len = rand() % buf_len + 1;
- return outgoing_->Write(buf, buf_len, callback);
+ return outgoing_->Write(buf, buf_len, callback,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
int SetReceiveBufferSize(int32_t size) override { return OK; }
@@ -291,6 +297,8 @@ class FakeSocket : public StreamSocket {
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
+
private:
NetLogWithSource net_log_;
FakeDataChannel* incoming_;
@@ -317,7 +325,8 @@ TEST(FakeSocketTest, DataTransfer) {
// Write then read.
int written =
- server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
+ server.Write(write_buf.get(), kTestDataSize, CompletionCallback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_GT(written, 0);
EXPECT_LE(written, kTestDataSize);
@@ -331,7 +340,8 @@ TEST(FakeSocketTest, DataTransfer) {
EXPECT_EQ(ERR_IO_PENDING,
server.Read(read_buf.get(), kReadBufSize, callback.callback()));
- written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
+ written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_GT(written, 0);
EXPECT_LE(written, kTestDataSize);
@@ -363,6 +373,13 @@ class SSLServerSocketTest : public PlatformTest {
server_private_key_ = ReadTestKey("unittest.key.bin");
ASSERT_TRUE(server_private_key_);
+ std::unique_ptr<crypto::RSAPrivateKey> key =
+ ReadTestKey("unittest.key.bin");
+ ASSERT_TRUE(key);
+ EVP_PKEY_up_ref(key->key());
+ server_ssl_private_key_ =
+ WrapOpenSSLPrivateKey(bssl::UniquePtr<EVP_PKEY>(key->key()));
+
client_ssl_config_.false_start_enabled = false;
client_ssl_config_.channel_id_enabled = false;
@@ -382,6 +399,16 @@ class SSLServerSocketTest : public PlatformTest {
server_cert_.get(), *server_private_key_, server_ssl_config_);
}
+ void CreateContextSSLPrivateKey() {
+ client_socket_.reset();
+ server_socket_.reset();
+ channel_1_.reset();
+ channel_2_.reset();
+ server_context_.reset();
+ server_context_ = CreateSSLServerContext(
+ server_cert_.get(), server_ssl_private_key_, server_ssl_config_);
+ }
+
void CreateSockets() {
client_socket_.reset();
server_socket_.reset();
@@ -479,6 +506,7 @@ class SSLServerSocketTest : public PlatformTest {
std::unique_ptr<MockCTPolicyEnforcer> ct_policy_enforcer_;
std::unique_ptr<SSLServerContext> server_context_;
std::unique_ptr<crypto::RSAPrivateKey> server_private_key_;
+ scoped_refptr<SSLPrivateKey> server_ssl_private_key_;
scoped_refptr<X509Certificate> server_cert_;
};
@@ -1088,4 +1116,80 @@ TEST_F(SSLServerSocketTest, RequireEcdheFlag) {
ASSERT_THAT(server_ret, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
}
+// This test executes Connect() on SSLClientSocket and Handshake() on
+// SSLServerSocket to make sure handshaking between the two sockets is
+// completed successfully. The server key is represented by SSLPrivateKey.
+TEST_F(SSLServerSocketTest, HandshakeServerSSLPrivateKey) {
+ ASSERT_NO_FATAL_FAILURE(CreateContextSSLPrivateKey());
+ ASSERT_NO_FATAL_FAILURE(CreateSockets());
+
+ TestCompletionCallback handshake_callback;
+ int server_ret = server_socket_->Handshake(handshake_callback.callback());
+
+ TestCompletionCallback connect_callback;
+ int client_ret = client_socket_->Connect(connect_callback.callback());
+
+ client_ret = connect_callback.GetResult(client_ret);
+ server_ret = handshake_callback.GetResult(server_ret);
+
+ ASSERT_THAT(client_ret, IsOk());
+ ASSERT_THAT(server_ret, IsOk());
+
+ // Make sure the cert status is expected.
+ SSLInfo ssl_info;
+ ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
+ EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
+
+ // The default cipher suite should be ECDHE and an AEAD.
+ uint16_t cipher_suite =
+ SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
+ const char* key_exchange;
+ const char* cipher;
+ const char* mac;
+ bool is_aead;
+ bool is_tls13;
+ SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13,
+ cipher_suite);
+ EXPECT_TRUE(is_aead);
+ ASSERT_FALSE(is_tls13);
+ EXPECT_STREQ("ECDHE_RSA", key_exchange);
+}
+
+// Verifies that non-ECDHE ciphers are disabled when using SSLPrivateKey as the
+// server key.
+TEST_F(SSLServerSocketTest, HandshakeServerSSLPrivateKeyRequireEcdhe) {
+ // Disable all ECDHE suites on the client side.
+ uint16_t kEcdheCiphers[] = {
+ 0xc007, // ECDHE_ECDSA_WITH_RC4_128_SHA
+ 0xc009, // ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ 0xc00a, // ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ 0xc011, // ECDHE_RSA_WITH_RC4_128_SHA
+ 0xc013, // ECDHE_RSA_WITH_AES_128_CBC_SHA
+ 0xc014, // ECDHE_RSA_WITH_AES_256_CBC_SHA
+ 0xc02b, // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ 0xc02f, // ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ 0xcca8, // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ 0xcca9, // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+ };
+ client_ssl_config_.disabled_cipher_suites.assign(
+ kEcdheCiphers, kEcdheCiphers + arraysize(kEcdheCiphers));
+ // TLS 1.3 always works with SSLPrivateKey.
+ client_ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+
+ ASSERT_NO_FATAL_FAILURE(CreateContextSSLPrivateKey());
+ ASSERT_NO_FATAL_FAILURE(CreateSockets());
+
+ TestCompletionCallback connect_callback;
+ int client_ret = client_socket_->Connect(connect_callback.callback());
+
+ TestCompletionCallback handshake_callback;
+ int server_ret = server_socket_->Handshake(handshake_callback.callback());
+
+ client_ret = connect_callback.GetResult(client_ret);
+ server_ret = handshake_callback.GetResult(server_ret);
+
+ ASSERT_THAT(client_ret, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
+ ASSERT_THAT(server_ret, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH));
+}
+
} // namespace net
diff --git a/chromium/net/socket/stream_socket.h b/chromium/net/socket/stream_socket.h
index 6ee0e40adcb..ddec9993b4e 100644
--- a/chromium/net/socket/stream_socket.h
+++ b/chromium/net/socket/stream_socket.h
@@ -18,6 +18,7 @@ namespace net {
class IPEndPoint;
class NetLogWithSource;
class SSLInfo;
+class SocketTag;
class NET_EXPORT_PRIVATE StreamSocket : public Socket {
public:
@@ -136,6 +137,18 @@ class NET_EXPORT_PRIVATE StreamSocket : public Socket {
// |stats|. Default implementation does nothing.
virtual void DumpMemoryStats(SocketMemoryStats* stats) const {}
+ // Apply |tag| to this socket. If socket isn't yet connected, tag will be
+ // applied when socket is later connected. If Connect() fails or socket
+ // is closed, tag is cleared. If this socket is layered upon or wraps an
+ // underlying socket, |tag| will be applied to the underlying socket in the
+ // same manner as if ApplySocketTag() was called on the underlying socket.
+ // The tag can be applied at any time, in other words active sockets can be
+ // retagged with a different tag. Sockets wrapping multiplexed sockets
+ // (e.g. sockets who proxy through a QUIC or Spdy stream) cannot be tagged as
+ // the tag would inadvertently affect other streams; calling ApplySocketTag()
+ // in this case will result in CHECK(false).
+ virtual void ApplySocketTag(const SocketTag& tag) = 0;
+
protected:
// The following class is only used to gather statistics about the history of
// a socket. It is only instantiated and used in basic sockets, such as
diff --git a/chromium/net/socket/tcp_client_socket.cc b/chromium/net/socket/tcp_client_socket.cc
index d6dce18f6b9..1b1831b625f 100644
--- a/chromium/net/socket/tcp_client_socket.cc
+++ b/chromium/net/socket/tcp_client_socket.cc
@@ -14,6 +14,7 @@
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -294,16 +295,18 @@ int TCPClientSocket::ReadIfReady(IOBuffer* buf,
return ReadCommon(buf, buf_len, callback, /*read_if_ready=*/true);
}
-int TCPClientSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int TCPClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(!callback.is_null());
// |socket_| is owned by this class and the callback won't be run once
// |socket_| is gone. Therefore, it is safe to use base::Unretained() here.
CompletionCallback write_callback = base::Bind(
&TCPClientSocket::DidCompleteWrite, base::Unretained(this), callback);
- int result = socket_->Write(buf, buf_len, write_callback);
+ int result = socket_->Write(buf, buf_len, write_callback, traffic_annotation);
if (result > 0)
use_history_.set_was_used_to_convey_data();
@@ -344,6 +347,10 @@ int64_t TCPClientSocket::GetTotalReceivedBytes() const {
return total_received_bytes_;
}
+void TCPClientSocket::ApplySocketTag(const SocketTag& tag) {
+ socket_->ApplySocketTag(tag);
+}
+
void TCPClientSocket::DidCompleteConnect(int result) {
DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE);
DCHECK_NE(result, ERR_IO_PENDING);
diff --git a/chromium/net/socket/tcp_client_socket.h b/chromium/net/socket/tcp_client_socket.h
index 8981fb066f5..cda599b52a4 100644
--- a/chromium/net/socket/tcp_client_socket.h
+++ b/chromium/net/socket/tcp_client_socket.h
@@ -17,6 +17,7 @@
#include "net/socket/connection_attempts.h"
#include "net/socket/stream_socket.h"
#include "net/socket/tcp_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -61,6 +62,11 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
bool WasAlpnNegotiated() const override;
NextProto GetNegotiatedProtocol() const override;
bool GetSSLInfo(SSLInfo* ssl_info) override;
+ void GetConnectionAttempts(ConnectionAttempts* out) const override;
+ void ClearConnectionAttempts() override;
+ void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
+ int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
// Multiple outstanding requests are not supported.
@@ -73,18 +79,14 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
virtual bool SetKeepAlive(bool enable, int delay);
virtual bool SetNoDelay(bool no_delay);
- void GetConnectionAttempts(ConnectionAttempts* out) const override;
- void ClearConnectionAttempts() override;
- void AddConnectionAttempts(const ConnectionAttempts& attempts) override;
- int64_t GetTotalReceivedBytes() const override;
-
private:
// State machine for connecting the socket.
enum ConnectState {
diff --git a/chromium/net/socket/tcp_client_socket_unittest.cc b/chromium/net/socket/tcp_client_socket_unittest.cc
index 1766d7f70ff..5a95bf9bd8c 100644
--- a/chromium/net/socket/tcp_client_socket_unittest.cc
+++ b/chromium/net/socket/tcp_client_socket_unittest.cc
@@ -10,14 +10,18 @@
#include <stddef.h>
+#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_source.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_test_util.h"
#include "net/socket/tcp_server_socket.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -164,6 +168,107 @@ TEST(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) {
EXPECT_EQ(kNumIPs - 1, watcher_ptr->connection_changed_count());
}
+// On Android, where socket tagging is supported, verify that
+// TCPClientSocket::Tag works as expected.
+#if defined(OS_ANDROID)
+TEST(TCPClientSocketTest, Tag) {
+ // Start test server.
+ EmbeddedTestServer test_server;
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ AddressList addr_list;
+ ASSERT_TRUE(test_server.GetAddressList(&addr_list));
+ TCPClientSocket s(addr_list, NULL, NULL, NetLogSource());
+
+ // Verify TCP connect packets are tagged and counted properly.
+ int32_t tag_val1 = 0x12345678;
+ uint64_t old_traffic = GetTaggedBytes(tag_val1);
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ s.ApplySocketTag(tag1);
+ TestCompletionCallback connect_callback;
+ int connect_result = s.Connect(connect_callback.callback());
+ EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ int32_t tag_val2 = 0x87654321;
+ old_traffic = GetTaggedBytes(tag_val2);
+ SocketTag tag2(getuid(), tag_val2);
+ s.ApplySocketTag(tag2);
+ const char kRequest1[] = "GET / HTTP/1.0";
+ scoped_refptr<IOBuffer> write_buffer1(new StringIOBuffer(kRequest1));
+ TestCompletionCallback write_callback1;
+ EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
+ write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest1)));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ old_traffic = GetTaggedBytes(tag_val1);
+ s.ApplySocketTag(tag1);
+ const char kRequest2[] = "\n\n";
+ scoped_refptr<IOBufferWithSize> write_buffer2(
+ new IOBufferWithSize(strlen(kRequest2)));
+ memmove(write_buffer2->data(), kRequest2, strlen(kRequest2));
+ TestCompletionCallback write_callback2;
+ EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
+ write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest2)));
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ s.Disconnect();
+}
+
+TEST(TCPClientSocketTest, TagAfterConnect) {
+ // Start test server.
+ EmbeddedTestServer test_server;
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ AddressList addr_list;
+ ASSERT_TRUE(test_server.GetAddressList(&addr_list));
+ TCPClientSocket s(addr_list, NULL, NULL, NetLogSource());
+
+ // Connect socket.
+ TestCompletionCallback connect_callback;
+ int connect_result = s.Connect(connect_callback.callback());
+ EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
+
+ // Verify socket can be tagged with a new value and the current process's
+ // UID.
+ int32_t tag_val2 = 0x87654321;
+ uint64_t old_traffic = GetTaggedBytes(tag_val2);
+ SocketTag tag2(getuid(), tag_val2);
+ s.ApplySocketTag(tag2);
+ const char kRequest1[] = "GET / HTTP/1.0";
+ scoped_refptr<IOBuffer> write_buffer1(new StringIOBuffer(kRequest1));
+ TestCompletionCallback write_callback1;
+ EXPECT_EQ(s.Write(write_buffer1.get(), strlen(kRequest1),
+ write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest1)));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ int32_t tag_val1 = 0x12345678;
+ old_traffic = GetTaggedBytes(tag_val1);
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ s.ApplySocketTag(tag1);
+ const char kRequest2[] = "\n\n";
+ scoped_refptr<IOBuffer> write_buffer2(new StringIOBuffer(kRequest2));
+ TestCompletionCallback write_callback2;
+ EXPECT_EQ(s.Write(write_buffer2.get(), strlen(kRequest2),
+ write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest2)));
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ s.Disconnect();
+}
+#endif
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/tcp_socket_posix.cc b/chromium/net/socket/tcp_socket_posix.cc
index b46ccadb5af..600462077b2 100644
--- a/chromium/net/socket/tcp_socket_posix.cc
+++ b/chromium/net/socket/tcp_socket_posix.cc
@@ -36,6 +36,8 @@
#include "net/socket/socket_net_log_params.h"
#include "net/socket/socket_options.h"
#include "net/socket/socket_posix.h"
+#include "net/socket/socket_tag.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
// If we don't have a definition for TCPI_OPT_SYN_DATA, create one.
#if !defined(TCPI_OPT_SYN_DATA)
@@ -148,11 +150,57 @@ base::LazyInstance<FastOpenProbe>::Leaky g_fast_open_probe =
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
#if defined(HAVE_TCP_INFO)
-bool GetTcpInfo(SocketDescriptor fd, tcp_info* info) {
+// Returns a zero value if the transport RTT is unavailable.
+base::TimeDelta GetTransportRtt(SocketDescriptor fd) {
+ tcp_info info;
+ // Reset |tcpi_rtt| to verify if getsockopt() actually updates |tcpi_rtt|.
+ info.tcpi_rtt = 0;
+
socklen_t info_len = sizeof(tcp_info);
- return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &info_len) == 0 &&
- info_len == sizeof(tcp_info);
+ if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) != 0)
+ return base::TimeDelta();
+
+ // Verify that |tcpi_rtt| in tcp_info struct was updated. Note that it's
+ // possible that |info_len| is shorter than |sizeof(tcp_info)| which implies
+ // that only a subset of values in |info| may have been updated by
+ // getsockopt().
+ if (info_len < static_cast<socklen_t>(offsetof(tcp_info, tcpi_rtt) +
+ sizeof(info.tcpi_rtt))) {
+ return base::TimeDelta();
+ }
+
+ return base::TimeDelta::FromMicroseconds(info.tcpi_rtt);
+}
+
+// Returns true if getsockopt() call was successful. Sets
+// |server_acked_syn_data| to true if SYN-ACK acked data in SYN sent or
+// received.
+bool GetServerAckedDataInSyn(SocketDescriptor fd, bool* server_acked_syn_data) {
+ tcp_info info;
+ // Reset |tcpi_options| to verify if getsockopt() actually updates
+ // |tcpi_options|.
+ info.tcpi_options = 0;
+
+ socklen_t info_len = sizeof(tcp_info);
+ if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &info_len) != 0) {
+ *server_acked_syn_data = false;
+ return false;
+ }
+
+ // Verify that |tcpi_options| in tcp_info struct was updated. Note that it's
+ // possible that |info_len| is shorter than |sizeof(tcp_info)| which implies
+ // that only a subset of values in |info| may have been updated by
+ // getsockopt().
+ if (info_len < static_cast<socklen_t>(offsetof(tcp_info, tcpi_options) +
+ sizeof(info.tcpi_options))) {
+ *server_acked_syn_data = false;
+ return false;
+ }
+
+ *server_acked_syn_data = (info.tcpi_options & TCPI_OPT_SYN_DATA);
+ return true;
}
+
#endif // defined(TCP_INFO)
} // namespace
@@ -193,6 +241,8 @@ int TCPSocketPosix::Open(AddressFamily family) {
int rv = socket_->Open(ConvertAddressFamily(family));
if (rv != OK)
socket_.reset();
+ if (rv == OK && tag_ != SocketTag())
+ tag_.Apply(socket_->socket_fd());
return rv;
}
@@ -211,6 +261,8 @@ int TCPSocketPosix::AdoptConnectedSocket(SocketDescriptor socket,
int rv = socket_->AdoptConnectedSocket(socket, storage);
if (rv != OK)
socket_.reset();
+ if (rv == OK && tag_ != SocketTag())
+ tag_.Apply(socket_->socket_fd());
return rv;
}
@@ -221,6 +273,8 @@ int TCPSocketPosix::AdoptUnconnectedSocket(SocketDescriptor socket) {
int rv = socket_->AdoptUnconnectedSocket(socket);
if (rv != OK)
socket_.reset();
+ if (rv == OK && tag_ != SocketTag())
+ tag_.Apply(socket_->socket_fd());
return rv;
}
@@ -340,9 +394,11 @@ int TCPSocketPosix::ReadIfReady(IOBuffer* buf,
return rv;
}
-int TCPSocketPosix::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int TCPSocketPosix::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(socket_);
DCHECK(!callback.is_null());
@@ -357,7 +413,7 @@ int TCPSocketPosix::Write(IOBuffer* buf,
if (use_tcp_fastopen_ && !tcp_fastopen_write_attempted_) {
rv = TcpFastOpenWrite(buf, buf_len, write_callback);
} else {
- rv = socket_->Write(buf, buf_len, write_callback);
+ rv = socket_->Write(buf, buf_len, write_callback, traffic_annotation);
}
if (rv != ERR_IO_PENDING)
@@ -476,6 +532,7 @@ void TCPSocketPosix::Close() {
tcp_fastopen_connected_ = false;
tcp_fastopen_write_attempted_ = false;
tcp_fastopen_status_ = TCP_FASTOPEN_STATUS_UNKNOWN;
+ tag_ = SocketTag();
}
void TCPSocketPosix::EnableTCPFastOpenIfSupported() {
@@ -525,6 +582,13 @@ SocketDescriptor TCPSocketPosix::ReleaseSocketDescriptorForTesting() {
return socket_descriptor;
}
+void TCPSocketPosix::ApplySocketTag(const SocketTag& tag) {
+ if (IsValid() && tag != tag_) {
+ tag.Apply(socket_->socket_fd());
+ }
+ tag_ = tag;
+}
+
void TCPSocketPosix::AcceptCompleted(
std::unique_ptr<TCPSocketPosix>* tcp_socket,
IPEndPoint* address,
@@ -580,6 +644,7 @@ int TCPSocketPosix::HandleConnectCompleted(int rv) {
if (rv != OK) {
net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT,
NetLog::IntCallback("os_error", errno));
+ tag_ = SocketTag();
} else {
net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT);
NotifySocketPerformanceWatcher();
@@ -783,20 +848,11 @@ void TCPSocketPosix::NotifySocketPerformanceWatcher() {
return;
}
- tcp_info info;
- if (!GetTcpInfo(socket_->socket_fd(), &info))
+ base::TimeDelta rtt = GetTransportRtt(socket_->socket_fd());
+ if (rtt.is_zero())
return;
- // Only notify the |socket_performance_watcher_| if the RTT in |tcp_info|
- // struct was populated. A value of 0 may be valid in certain cases
- // (on very fast networks), but it is discarded. This means that
- // some of the RTT values may be missed, but the values that are kept are
- // guaranteed to be correct.
- if (info.tcpi_rtt == 0 && info.tcpi_rttvar == 0)
- return;
-
- socket_performance_watcher_->OnUpdatedRTTAvailable(
- base::TimeDelta::FromMicroseconds(info.tcpi_rtt));
+ socket_performance_watcher_->OnUpdatedRTTAvailable(rtt);
#endif // defined(TCP_INFO)
}
@@ -814,24 +870,22 @@ void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() {
}
bool getsockopt_success = false;
- bool server_acked_data = false;
+ bool server_acked_syn_data = false;
#if defined(HAVE_TCP_INFO)
// Probe to see the if the socket used TCP FastOpen.
- tcp_info info;
- getsockopt_success = GetTcpInfo(socket_->socket_fd(), &info);
- server_acked_data =
- getsockopt_success && (info.tcpi_options & TCPI_OPT_SYN_DATA);
+ getsockopt_success =
+ GetServerAckedDataInSyn(socket_->socket_fd(), &server_acked_syn_data);
#endif // defined(TCP_INFO)
if (getsockopt_success) {
if (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN) {
- tcp_fastopen_status_ = (server_acked_data ?
- TCP_FASTOPEN_SYN_DATA_ACK :
- TCP_FASTOPEN_SYN_DATA_NACK);
+ tcp_fastopen_status_ =
+ (server_acked_syn_data ? TCP_FASTOPEN_SYN_DATA_ACK
+ : TCP_FASTOPEN_SYN_DATA_NACK);
} else {
- tcp_fastopen_status_ = (server_acked_data ?
- TCP_FASTOPEN_NO_SYN_DATA_ACK :
- TCP_FASTOPEN_NO_SYN_DATA_NACK);
+ tcp_fastopen_status_ =
+ (server_acked_syn_data ? TCP_FASTOPEN_NO_SYN_DATA_ACK
+ : TCP_FASTOPEN_NO_SYN_DATA_NACK);
}
} else {
tcp_fastopen_status_ =
@@ -847,15 +901,11 @@ bool TCPSocketPosix::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const {
return false;
#if defined(HAVE_TCP_INFO)
- tcp_info info;
- if (GetTcpInfo(socket_->socket_fd(), &info)) {
- // tcpi_rtt is zero when the kernel doesn't have an RTT estimate,
- // and possibly in other cases such as connections to localhost.
- if (info.tcpi_rtt > 0) {
- *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt);
- return true;
- }
- }
+ base::TimeDelta rtt = GetTransportRtt(socket_->socket_fd());
+ if (rtt.is_zero())
+ return false;
+ *out_rtt = rtt;
+ return true;
#endif // defined(TCP_INFO)
return false;
}
diff --git a/chromium/net/socket/tcp_socket_posix.h b/chromium/net/socket/tcp_socket_posix.h
index 031dd8cc97e..4e00fd9893c 100644
--- a/chromium/net/socket/tcp_socket_posix.h
+++ b/chromium/net/socket/tcp_socket_posix.h
@@ -18,6 +18,8 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_tag.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
class TimeDelta;
@@ -31,6 +33,7 @@ class IPEndPoint;
class SocketPosix;
class NetLog;
struct NetLogSource;
+class SocketTag;
class NET_EXPORT TCPSocketPosix {
public:
@@ -91,7 +94,10 @@ class NET_EXPORT TCPSocketPosix {
// Writes to the socket.
// Returns a net error code.
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Copies the local tcp address into |address| and returns a net error code.
int GetLocalAddress(IPEndPoint* address) const;
@@ -150,6 +156,9 @@ class NET_EXPORT TCPSocketPosix {
// write, or accept operations should be pending.
SocketDescriptor ReleaseSocketDescriptorForTesting();
+ // Apply |tag| to this socket.
+ void ApplySocketTag(const SocketTag& tag);
+
private:
// States that using a socket with TCP FastOpen can lead to.
enum TCPFastOpenStatus {
@@ -280,6 +289,10 @@ class NET_EXPORT TCPSocketPosix {
NetLogWithSource net_log_;
+ // Current socket tag if |socket_| is valid, otherwise the tag to apply when
+ // |socket_| is opened.
+ SocketTag tag_;
+
DISALLOW_COPY_AND_ASSIGN(TCPSocketPosix);
};
diff --git a/chromium/net/socket/tcp_socket_unittest.cc b/chromium/net/socket/tcp_socket_unittest.cc
index e170f3b5a5b..c9d4c716455 100644
--- a/chromium/net/socket/tcp_socket_unittest.cc
+++ b/chromium/net/socket/tcp_socket_unittest.cc
@@ -13,6 +13,7 @@
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
@@ -21,8 +22,11 @@
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_source.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_test_util.h"
#include "net/socket/tcp_client_socket.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -168,7 +172,8 @@ class TCPSocketTest : public PlatformTest {
TestCompletionCallback write_callback;
int write_result = accepted_socket->Write(
- write_buffer.get(), write_buffer->size(), write_callback.callback());
+ write_buffer.get(), write_buffer->size(), write_callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
scoped_refptr<IOBufferWithSize> read_buffer(
new IOBufferWithSize(message.size()));
@@ -388,7 +393,8 @@ TEST_F(TCPSocketTest, ReadWrite) {
TestCompletionCallback write_callback;
int write_result = accepted_socket->Write(
- write_buffer.get(), write_buffer->size(), write_callback.callback());
+ write_buffer.get(), write_buffer->size(), write_callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
write_result = write_callback.GetResult(write_result);
ASSERT_TRUE(write_result >= 0);
bytes_written += write_result;
@@ -429,5 +435,110 @@ TEST_F(TCPSocketTest, SPWNoAdvance) {
}
#endif // defined(TCP_INFO) || defined(OS_LINUX)
+// On Android, where socket tagging is supported, verify that TCPSocket::Tag
+// works as expected.
+#if defined(OS_ANDROID)
+TEST_F(TCPSocketTest, Tag) {
+ // Start test server.
+ EmbeddedTestServer test_server;
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ AddressList addr_list;
+ ASSERT_TRUE(test_server.GetAddressList(&addr_list));
+ EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
+
+ // Verify TCP connect packets are tagged and counted properly.
+ int32_t tag_val1 = 0x12345678;
+ uint64_t old_traffic = GetTaggedBytes(tag_val1);
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ socket_.ApplySocketTag(tag1);
+ TestCompletionCallback connect_callback;
+ int connect_result =
+ socket_.Connect(addr_list[0], connect_callback.callback());
+ EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ int32_t tag_val2 = 0x87654321;
+ old_traffic = GetTaggedBytes(tag_val2);
+ SocketTag tag2(getuid(), tag_val2);
+ socket_.ApplySocketTag(tag2);
+ const char kRequest1[] = "GET / HTTP/1.0";
+ scoped_refptr<IOBuffer> write_buffer1(new StringIOBuffer(kRequest1));
+ TestCompletionCallback write_callback1;
+ EXPECT_EQ(
+ socket_.Write(write_buffer1.get(), strlen(kRequest1),
+ write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest1)));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ old_traffic = GetTaggedBytes(tag_val1);
+ socket_.ApplySocketTag(tag1);
+ const char kRequest2[] = "\n\n";
+ scoped_refptr<IOBuffer> write_buffer2(new StringIOBuffer(kRequest2));
+ TestCompletionCallback write_callback2;
+ EXPECT_EQ(
+ socket_.Write(write_buffer2.get(), strlen(kRequest2),
+ write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest2)));
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ socket_.Close();
+}
+
+TEST_F(TCPSocketTest, TagAfterConnect) {
+ // Start test server.
+ EmbeddedTestServer test_server;
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ AddressList addr_list;
+ ASSERT_TRUE(test_server.GetAddressList(&addr_list));
+ EXPECT_EQ(socket_.Open(addr_list[0].GetFamily()), OK);
+
+ // Connect socket.
+ TestCompletionCallback connect_callback;
+ int connect_result =
+ socket_.Connect(addr_list[0], connect_callback.callback());
+ EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk());
+
+ // Verify socket can be tagged with a new value and the current process's
+ // UID.
+ int32_t tag_val2 = 0x87654321;
+ uint64_t old_traffic = GetTaggedBytes(tag_val2);
+ SocketTag tag2(getuid(), tag_val2);
+ socket_.ApplySocketTag(tag2);
+ const char kRequest1[] = "GET / HTTP/1.0";
+ scoped_refptr<IOBuffer> write_buffer1(new StringIOBuffer(kRequest1));
+ TestCompletionCallback write_callback1;
+ EXPECT_EQ(
+ socket_.Write(write_buffer1.get(), strlen(kRequest1),
+ write_callback1.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest1)));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ int32_t tag_val1 = 0x12345678;
+ old_traffic = GetTaggedBytes(tag_val1);
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ socket_.ApplySocketTag(tag1);
+ const char kRequest2[] = "\n\n";
+ scoped_refptr<IOBuffer> write_buffer2(new StringIOBuffer(kRequest2));
+ TestCompletionCallback write_callback2;
+ EXPECT_EQ(
+ socket_.Write(write_buffer2.get(), strlen(kRequest2),
+ write_callback2.callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
+ static_cast<int>(strlen(kRequest2)));
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ socket_.Close();
+}
+#endif
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/tcp_socket_win.cc b/chromium/net/socket/tcp_socket_win.cc
index 7612291cb75..4ecab0b6061 100644
--- a/chromium/net/socket/tcp_socket_win.cc
+++ b/chromium/net/socket/tcp_socket_win.cc
@@ -30,6 +30,7 @@
#include "net/socket/socket_descriptor.h"
#include "net/socket/socket_net_log_params.h"
#include "net/socket/socket_options.h"
+#include "net/socket/socket_tag.h"
namespace net {
@@ -517,9 +518,11 @@ int TCPSocketWin::ReadIfReady(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int TCPSocketWin::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int TCPSocketWin::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_NE(socket_, INVALID_SOCKET);
DCHECK(!waiting_write_);
@@ -1016,4 +1019,10 @@ bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const {
return false;
}
+void TCPSocketWin::ApplySocketTag(const SocketTag& tag) {
+ // Windows does not support any specific SocketTags so fail if any non-default
+ // tag is applied.
+ CHECK(tag == SocketTag());
+}
+
} // namespace net
diff --git a/chromium/net/socket/tcp_socket_win.h b/chromium/net/socket/tcp_socket_win.h
index 1c1b548490e..1cb2675a369 100644
--- a/chromium/net/socket/tcp_socket_win.h
+++ b/chromium/net/socket/tcp_socket_win.h
@@ -21,6 +21,7 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -29,6 +30,7 @@ class IOBuffer;
class IPEndPoint;
class NetLog;
struct NetLogSource;
+class SocketTag;
class NET_EXPORT TCPSocketWin : public base::win::ObjectWatcher::Delegate {
public:
@@ -68,7 +70,10 @@ class NET_EXPORT TCPSocketWin : public base::win::ObjectWatcher::Delegate {
int ReadIfReady(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback);
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
int GetLocalAddress(IPEndPoint* address) const;
int GetPeerAddress(IPEndPoint* address) const;
@@ -124,6 +129,9 @@ class NET_EXPORT TCPSocketWin : public base::win::ObjectWatcher::Delegate {
// write, or accept operations should be pending.
SocketDescriptor ReleaseSocketDescriptorForTesting();
+ // Apply |tag| to this socket.
+ void ApplySocketTag(const SocketTag& tag);
+
private:
class Core;
diff --git a/chromium/net/socket/transport_client_socket_pool.cc b/chromium/net/socket/transport_client_socket_pool.cc
index 53f2c154392..a7299062335 100644
--- a/chromium/net/socket/transport_client_socket_pool.cc
+++ b/chromium/net/socket/transport_client_socket_pool.cc
@@ -80,6 +80,7 @@ const int TransportConnectJob::kIPv6FallbackTimerInMs = 300;
TransportConnectJob::TransportConnectJob(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<TransportSocketParams>& params,
base::TimeDelta timeout_duration,
@@ -92,6 +93,7 @@ TransportConnectJob::TransportConnectJob(
group_name,
timeout_duration,
priority,
+ socket_tag,
respect_limits,
delegate,
NetLogWithSource::Make(net_log,
@@ -307,6 +309,8 @@ int TransportConnectJob::DoTransportConnect() {
transport_socket_->EnableTCPFastOpenIfSupported();
}
+ transport_socket_->ApplySocketTag(socket_tag());
+
int rv = transport_socket_->Connect(
base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this)));
if (rv == ERR_IO_PENDING && try_ipv6_connect_with_ipv4_fallback) {
@@ -453,9 +457,10 @@ TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob(
const PoolBase::Request& request,
ConnectJob::Delegate* delegate) const {
return std::unique_ptr<ConnectJob>(new TransportConnectJob(
- group_name, request.priority(), request.respect_limits(),
- request.params(), ConnectionTimeout(), client_socket_factory_,
- socket_performance_watcher_factory_, host_resolver_, delegate, net_log_));
+ group_name, request.priority(), request.socket_tag(),
+ request.respect_limits(), request.params(), ConnectionTimeout(),
+ client_socket_factory_, socket_performance_watcher_factory_,
+ host_resolver_, delegate, net_log_));
}
base::TimeDelta
@@ -488,6 +493,7 @@ TransportClientSocketPool::~TransportClientSocketPool() = default;
int TransportClientSocketPool::RequestSocket(const std::string& group_name,
const void* params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -497,7 +503,7 @@ int TransportClientSocketPool::RequestSocket(const std::string& group_name,
NetLogTcpClientSocketPoolRequestedSocket(net_log, casted_params);
- return base_.RequestSocket(group_name, *casted_params, priority,
+ return base_.RequestSocket(group_name, *casted_params, priority, socket_tag,
respect_limits, handle, callback, net_log);
}
diff --git a/chromium/net/socket/transport_client_socket_pool.h b/chromium/net/socket/transport_client_socket_pool.h
index 7633977779c..0df8883c311 100644
--- a/chromium/net/socket/transport_client_socket_pool.h
+++ b/chromium/net/socket/transport_client_socket_pool.h
@@ -18,6 +18,7 @@
#include "net/socket/client_socket_pool.h"
#include "net/socket/client_socket_pool_base.h"
#include "net/socket/connection_attempts.h"
+#include "net/socket/socket_tag.h"
namespace net {
@@ -102,6 +103,7 @@ class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob {
TransportConnectJob(
const std::string& group_name,
RequestPriority priority,
+ const SocketTag& socket_tag,
ClientSocketPool::RespectLimits respect_limits,
const scoped_refptr<TransportSocketParams>& params,
base::TimeDelta timeout_duration,
@@ -201,6 +203,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool : public ClientSocketPool {
int RequestSocket(const std::string& group_name,
const void* resolve_info,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
diff --git a/chromium/net/socket/transport_client_socket_pool_test_util.cc b/chromium/net/socket/transport_client_socket_pool_test_util.cc
index 361d7f8508a..7f872c6ea18 100644
--- a/chromium/net/socket/transport_client_socket_pool_test_util.cc
+++ b/chromium/net/socket/transport_client_socket_pool_test_util.cc
@@ -25,6 +25,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -85,6 +86,7 @@ class MockConnectClientSocket : public StreamSocket {
NOTIMPLEMENTED();
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
// Socket implementation.
int Read(IOBuffer* buf,
@@ -94,7 +96,8 @@ class MockConnectClientSocket : public StreamSocket {
}
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_FAILED;
}
int SetReceiveBufferSize(int32_t size) override { return OK; }
@@ -149,6 +152,7 @@ class MockFailingClientSocket : public StreamSocket {
NOTIMPLEMENTED();
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
// Socket implementation.
int Read(IOBuffer* buf,
@@ -159,7 +163,8 @@ class MockFailingClientSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_FAILED;
}
int SetReceiveBufferSize(int32_t size) override { return OK; }
@@ -276,6 +281,7 @@ class MockTriggerableClientSocket : public StreamSocket {
NOTIMPLEMENTED();
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
// Socket implementation.
int Read(IOBuffer* buf,
@@ -286,7 +292,8 @@ class MockTriggerableClientSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_FAILED;
}
int SetReceiveBufferSize(int32_t size) override { return OK; }
diff --git a/chromium/net/socket/transport_client_socket_pool_unittest.cc b/chromium/net/socket/transport_client_socket_pool_unittest.cc
index 313c5ba1a2d..bdd5df5e738 100644
--- a/chromium/net/socket/transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/transport_client_socket_pool_unittest.cc
@@ -11,6 +11,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/load_timing_info.h"
@@ -21,10 +22,13 @@
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/stream_socket.h"
#include "net/socket/transport_client_socket_pool_test_util.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -181,9 +185,9 @@ TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
TEST_F(TransportClientSocketPoolTest, Basic) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -203,7 +207,7 @@ TEST_F(TransportClientSocketPoolTest, SetResolvePriorityOnInit) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, priority,
+ handle.Init("a", params_, priority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_EQ(priority, host_resolver_->last_request_priority());
@@ -219,7 +223,7 @@ TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) {
host_port_pair, false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", dest, kDefaultPriority,
+ handle.Init("a", dest, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
@@ -235,7 +239,7 @@ TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
@@ -248,7 +252,7 @@ TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) {
// Make the host resolutions complete synchronously this time.
host_resolver_->set_synchronous_mode(true);
EXPECT_EQ(ERR_CONNECTION_FAILED,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
ASSERT_EQ(1u, handle.connection_attempts().size());
@@ -361,7 +365,7 @@ TEST_F(TransportClientSocketPoolTest, CancelRequestClearGroup) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
handle.Reset();
@@ -374,11 +378,11 @@ TEST_F(TransportClientSocketPoolTest, TwoRequestsCancelOne) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_EQ(ERR_IO_PENDING,
- handle2.Init("a", params_, kDefaultPriority,
+ handle2.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), &pool_, NetLogWithSource()));
@@ -394,7 +398,7 @@ TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
@@ -402,7 +406,7 @@ TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), &pool_, NetLogWithSource()));
@@ -515,7 +519,7 @@ class RequestSocketCallback : public TestCompletionCallbackBase {
scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
- int rv = handle_->Init("a", dest, LOWEST,
+ int rv = handle_->Init("a", dest, LOWEST, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback(), pool_, NetLogWithSource());
EXPECT_THAT(rv, IsOk());
@@ -536,9 +540,9 @@ TEST_F(TransportClientSocketPoolTest, RequestTwice) {
scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
- int rv =
- handle.Init("a", dest, LOWEST, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("a", dest, LOWEST, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
// The callback is going to request "www.google.com". We want it to complete
@@ -601,9 +605,9 @@ TEST_F(TransportClientSocketPoolTest, FailingActiveRequestWithPendingRequests) {
TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -620,7 +624,8 @@ TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) {
// Now we should have 1 idle socket.
EXPECT_EQ(1, pool_.IdleSocketCount());
- rv = handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
+ rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_EQ(0, pool_.IdleSocketCount());
@@ -630,9 +635,9 @@ TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) {
TEST_F(TransportClientSocketPoolTest, ResetIdleSocketsOnIPAddressChange) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -687,9 +692,9 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("b", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("b", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -730,9 +735,9 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketCancel) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("c", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("c", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -777,9 +782,9 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterStall) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("b", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("b", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -829,9 +834,9 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("b", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("b", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -886,9 +891,9 @@ TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -937,9 +942,9 @@ TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -978,9 +983,9 @@ TEST_F(TransportClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -1010,9 +1015,9 @@ TEST_F(TransportClientSocketPoolTest, IPv4HasNoFallback) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -1044,8 +1049,9 @@ TEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv4WithNoFallback) {
ClientSocketHandle handle;
// Enable TCP FastOpen in TransportSocketParams.
scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
- handle.Init("a", params, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ handle.Init("a", params, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
+ &pool, NetLogWithSource());
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_TRUE(socket_data.IsUsingTCPFastOpen());
}
@@ -1070,8 +1076,9 @@ TEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv6WithNoFallback) {
ClientSocketHandle handle;
// Enable TCP FastOpen in TransportSocketParams.
scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
- handle.Init("a", params, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ handle.Init("a", params, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
+ &pool, NetLogWithSource());
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_TRUE(socket_data.IsUsingTCPFastOpen());
}
@@ -1100,8 +1107,9 @@ TEST_F(TransportClientSocketPoolTest,
ClientSocketHandle handle;
// Enable TCP FastOpen in TransportSocketParams.
scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
- handle.Init("a", params, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ handle.Init("a", params, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
+ &pool, NetLogWithSource());
EXPECT_THAT(callback.WaitForResult(), IsOk());
// Verify that the socket used is connected to the fallback IPv4 address.
IPEndPoint endpoint;
@@ -1132,8 +1140,9 @@ TEST_F(TransportClientSocketPoolTest,
ClientSocketHandle handle;
// Enable TCP FastOpen in TransportSocketParams.
scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
- handle.Init("a", params, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ handle.Init("a", params, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
+ &pool, NetLogWithSource());
EXPECT_THAT(callback.WaitForResult(), IsOk());
IPEndPoint endpoint;
handle.socket()->GetPeerAddress(&endpoint);
@@ -1143,6 +1152,129 @@ TEST_F(TransportClientSocketPoolTest,
EXPECT_FALSE(socket_data.IsUsingTCPFastOpen());
}
+// Test that SocketTag passed into TransportClientSocketPool is applied to
+// returned sockets.
+#if defined(OS_ANDROID)
+TEST_F(TransportClientSocketPoolTest, Tag) {
+ // Start test server.
+ EmbeddedTestServer test_server;
+ test_server.AddDefaultHandlers(base::FilePath());
+ ASSERT_TRUE(test_server.Start());
+
+ TransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ ClientSocketFactory::GetDefaultFactory(), NULL, NULL);
+ ClientSocketHandle handle;
+ int32_t tag_val1 = 0x12345678;
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ int32_t tag_val2 = 0x87654321;
+ SocketTag tag2(getuid(), tag_val2);
+
+ // Test socket is tagged before connected.
+ uint64_t old_traffic = GetTaggedBytes(tag_val1);
+ scoped_refptr<TransportSocketParams> params(new TransportSocketParams(
+ test_server.host_port_pair(), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ TestCompletionCallback callback;
+ int rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ // Test reused socket is retagged.
+ StreamSocket* socket = handle.socket();
+ handle.Reset();
+ old_traffic = GetTaggedBytes(tag_val2);
+ rv = handle.Init("a", params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ EXPECT_EQ(handle.socket(), socket);
+ const char kRequest[] = "GET / HTTP/1.0\n\n";
+ scoped_refptr<IOBuffer> write_buffer(new StringIOBuffer(kRequest));
+ rv =
+ handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+ // Disconnect socket to prevent reuse.
+ handle.socket()->Disconnect();
+ handle.Reset();
+
+ // Test connect jobs that are orphaned and then adopted, appropriately apply
+ // new tag. Request socket with |tag1|.
+ TestCompletionCallback callback2;
+ rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback2.callback(), &pool, NetLogWithSource());
+ EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv;
+ // Abort and request socket with |tag2|.
+ handle.Reset();
+ rv = handle.Init("a", params, LOW, tag2,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ // Verify socket has |tag2| applied.
+ old_traffic = GetTaggedBytes(tag_val2);
+ rv =
+ handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+ // Disconnect socket to prevent reuse.
+ handle.socket()->Disconnect();
+ handle.Reset();
+ // Eat the left over connect job from the second request.
+ // TODO(pauljensen): remove when crbug.com/800731 fixed.
+ rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ // Disconnect socket to prevent reuse.
+ handle.socket()->Disconnect();
+ handle.Reset();
+
+ // Test two connect jobs of differing priorities. Start the lower priority one
+ // first but expect its socket to get vended to the higher priority request.
+ ClientSocketHandle handle_high_pri;
+ TestCompletionCallback callback_high_pri;
+ rv = handle.Init("a", params, LOW, tag1,
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
+ EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv;
+ int rv_high_pri = handle_high_pri.Init(
+ "a", params, HIGHEST, tag2, ClientSocketPool::RespectLimits::ENABLED,
+ callback_high_pri.callback(), &pool, NetLogWithSource());
+ EXPECT_THAT(callback_high_pri.GetResult(rv_high_pri), IsOk());
+ EXPECT_TRUE(handle_high_pri.socket());
+ EXPECT_TRUE(handle_high_pri.socket()->IsConnected());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ EXPECT_TRUE(handle.socket());
+ EXPECT_TRUE(handle.socket()->IsConnected());
+ // Verify |handle_high_pri| has |tag2| applied.
+ old_traffic = GetTaggedBytes(tag_val2);
+ rv = handle_high_pri.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+ // Verify |handle| has |tag1| applied.
+ old_traffic = GetTaggedBytes(tag_val1);
+ rv =
+ handle.socket()->Write(write_buffer.get(), strlen(kRequest),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+}
+#endif
+
} // namespace
} // namespace net
diff --git a/chromium/net/socket/udp_client_socket.cc b/chromium/net/socket/udp_client_socket.cc
index aac8ae06054..e2eccbb148c 100644
--- a/chromium/net/socket/udp_client_socket.cc
+++ b/chromium/net/socket/udp_client_socket.cc
@@ -5,6 +5,7 @@
#include "net/socket/udp_client_socket.h"
#include "net/base/net_errors.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -75,16 +76,22 @@ NetworkChangeNotifier::NetworkHandle UDPClientSocket::GetBoundNetwork() const {
return network_;
}
+void UDPClientSocket::ApplySocketTag(const SocketTag& tag) {
+ socket_.ApplySocketTag(tag);
+}
+
int UDPClientSocket::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
return socket_.Read(buf, buf_len, callback);
}
-int UDPClientSocket::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
- return socket_.Write(buf, buf_len, callback);
+int UDPClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ return socket_.Write(buf, buf_len, callback, traffic_annotation);
}
void UDPClientSocket::Close() {
diff --git a/chromium/net/socket/udp_client_socket.h b/chromium/net/socket/udp_client_socket.h
index 1a7adc43123..986898c51ba 100644
--- a/chromium/net/socket/udp_client_socket.h
+++ b/chromium/net/socket/udp_client_socket.h
@@ -12,6 +12,7 @@
#include "net/base/rand_callback.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/udp_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -33,12 +34,14 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
const IPEndPoint& address) override;
int ConnectUsingDefaultNetwork(const IPEndPoint& address) override;
NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
int Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
diff --git a/chromium/net/socket/udp_socket_perftest.cc b/chromium/net/socket/udp_socket_perftest.cc
index 190e157caac..25f0ba349a3 100644
--- a/chromium/net/socket/udp_socket_perftest.cc
+++ b/chromium/net/socket/udp_socket_perftest.cc
@@ -17,6 +17,7 @@
#include "net/socket/udp_socket.h"
#include "net/test/gtest_util.h"
#include "net/test/net_test_suite.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -75,7 +76,8 @@ void UDPSocketPerfTest::WritePacketsToSocket(UDPClientSocket* socket,
socket->Write(io_buffer.get(), io_buffer->size(),
base::Bind(&UDPSocketPerfTest::DoneWritePacketsToSocket,
weak_factory_.GetWeakPtr(), socket,
- num_of_packets - 1, done_callback));
+ num_of_packets - 1, done_callback),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
if (rv == ERR_IO_PENDING)
break;
--num_of_packets;
diff --git a/chromium/net/socket/udp_socket_posix.cc b/chromium/net/socket/udp_socket_posix.cc
index b0dfc16e883..f67eff8201d 100644
--- a/chromium/net/socket/udp_socket_posix.cc
+++ b/chromium/net/socket/udp_socket_posix.cc
@@ -17,7 +17,7 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
#include "base/trace_event/trace_event.h"
@@ -35,12 +35,12 @@
#include "net/log/net_log_source_type.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/socket_options.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/udp_net_log_parameters.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#if defined(OS_ANDROID)
#include <dlfcn.h>
-// This was added in Lollipop to dlfcn.h
-#define RTLD_NOLOAD 4
#include "base/android/build_info.h"
#include "base/native_library.h"
#include "base/strings/utf_string_conversions.h"
@@ -235,6 +235,8 @@ int UDPSocketPosix::Open(AddressFamily address_family) {
Close();
return err;
}
+ if (tag_ != SocketTag())
+ tag_.Apply(socket_);
return OK;
}
@@ -323,6 +325,7 @@ void UDPSocketPosix::Close() {
socket_ = kInvalidSocket;
addr_family_ = 0;
is_connected_ = false;
+ tag_ = SocketTag();
sent_activity_monitor_.OnClose();
received_activity_monitor_.OnClose();
@@ -408,9 +411,11 @@ int UDPSocketPosix::RecvFrom(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int UDPSocketPosix::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int UDPSocketPosix::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
return SendToOrWrite(buf, buf_len, NULL, callback);
}
@@ -461,6 +466,8 @@ int UDPSocketPosix::Connect(const IPEndPoint& address) {
int rv = InternalConnect(address);
net_log_.EndEventWithNetErrorCode(NetLogEventType::UDP_CONNECT, rv);
is_connected_ = (rv == OK);
+ if (rv != OK)
+ tag_ = SocketTag();
return rv;
}
@@ -481,7 +488,7 @@ int UDPSocketPosix::InternalConnect(const IPEndPoint& address) {
// else connect() does the DatagramSocket::DEFAULT_BIND
if (rv < 0) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", -rv);
+ base::UmaHistogramSparse("Net.UdpSocketRandomBindErrorCode", -rv);
return rv;
}
@@ -1077,4 +1084,12 @@ void UDPSocketPosix::DetachFromThread() {
DETACH_FROM_THREAD(thread_checker_);
}
+void UDPSocketPosix::ApplySocketTag(const SocketTag& tag) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (socket_ != kInvalidSocket && tag != tag_) {
+ tag.Apply(socket_);
+ }
+ tag_ = tag;
+}
+
} // namespace net
diff --git a/chromium/net/socket/udp_socket_posix.h b/chromium/net/socket/udp_socket_posix.h
index e094c434317..fac8d127c80 100644
--- a/chromium/net/socket/udp_socket_posix.h
+++ b/chromium/net/socket/udp_socket_posix.h
@@ -25,12 +25,15 @@
#include "net/socket/datagram_socket.h"
#include "net/socket/diff_serv_code_point.h"
#include "net/socket/socket_descriptor.h"
+#include "net/socket/socket_tag.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
class IPAddress;
class NetLog;
struct NetLogSource;
+class SocketTag;
class NET_EXPORT UDPSocketPosix {
public:
@@ -126,7 +129,10 @@ class NET_EXPORT UDPSocketPosix {
// Writes to the socket.
// Only usable from the client-side of a UDP socket, after the socket
// has been connected.
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Reads from a socket and receive sender address information.
// |buf| is the buffer to read data into.
@@ -238,6 +244,9 @@ class NET_EXPORT UDPSocketPosix {
// Resets the thread to be used for thread-safety checks.
void DetachFromThread();
+ // Apply |tag| to this socket.
+ void ApplySocketTag(const SocketTag& tag);
+
private:
enum SocketOptions {
SOCKET_OPTION_MULTICAST_LOOP = 1 << 0
@@ -370,6 +379,10 @@ class NET_EXPORT UDPSocketPosix {
SentActivityMonitor sent_activity_monitor_;
ReceivedActivityMonitor received_activity_monitor_;
+ // Current socket tag if |socket_| is valid, otherwise the tag to apply when
+ // |socket_| is opened.
+ SocketTag tag_;
+
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(UDPSocketPosix);
diff --git a/chromium/net/socket/udp_socket_unittest.cc b/chromium/net/socket/udp_socket_unittest.cc
index 100d94b087e..82423090bd6 100644
--- a/chromium/net/socket/udp_socket_unittest.cc
+++ b/chromium/net/socket/udp_socket_unittest.cc
@@ -24,16 +24,20 @@
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
+#include "net/socket/socket_test_util.h"
#include "net/socket/udp_client_socket.h"
#include "net/socket/udp_server_socket.h"
#include "net/test/gtest_util.h"
#include "net/test/net_test_suite.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
+#include "net/android/network_change_notifier_factory_android.h"
+#include "net/base/network_change_notifier.h"
#endif
#if defined(OS_IOS)
@@ -95,8 +99,8 @@ class UDPSocketTest : public PlatformTest {
int WriteSocket(UDPClientSocket* socket, const std::string& msg) {
scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
TestCompletionCallback callback;
- int rv =
- socket->Write(io_buffer.get(), io_buffer->size(), callback.callback());
+ int rv = socket->Write(io_buffer.get(), io_buffer->size(),
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
return callback.GetResult(rv);
}
@@ -734,6 +738,11 @@ TEST_F(UDPSocketTest, SetDSCP) {
TEST_F(UDPSocketTest, TestBindToNetwork) {
UDPSocket socket(DatagramSocket::RANDOM_BIND, base::Bind(&PrivilegedRand),
NULL, NetLogSource());
+#if defined(OS_ANDROID)
+ NetworkChangeNotifierFactoryAndroid ncn_factory;
+ NetworkChangeNotifier::DisableForTest ncn_disable_for_test;
+ std::unique_ptr<NetworkChangeNotifier> ncn(ncn_factory.CreateInstance());
+#endif
ASSERT_EQ(OK, socket.Open(ADDRESS_FAMILY_IPV4));
// Test unsuccessful binding, by attempting to bind to a bogus NetworkHandle.
int rv = socket.BindToNetwork(65536);
@@ -767,12 +776,11 @@ TEST_F(UDPSocketTest, TestBindToNetwork) {
socket.BindToNetwork(NetworkChangeNotifier::kInvalidNetworkHandle));
// Test successful binding, if possible.
- if (NetworkChangeNotifier::AreNetworkHandlesSupported()) {
- NetworkChangeNotifier::NetworkHandle network_handle =
- NetworkChangeNotifier::GetDefaultNetwork();
- if (network_handle != NetworkChangeNotifier::kInvalidNetworkHandle) {
- EXPECT_EQ(OK, socket.BindToNetwork(network_handle));
- }
+ EXPECT_TRUE(NetworkChangeNotifier::AreNetworkHandlesSupported());
+ NetworkChangeNotifier::NetworkHandle network_handle =
+ NetworkChangeNotifier::GetDefaultNetwork();
+ if (network_handle != NetworkChangeNotifier::kInvalidNetworkHandle) {
+ EXPECT_EQ(OK, socket.BindToNetwork(network_handle));
}
}
#endif
@@ -903,4 +911,77 @@ TEST_F(UDPSocketTest, SetDSCPFake) {
}
#endif
+// On Android, where socket tagging is supported, verify that UDPSocket::Tag
+// works as expected.
+#if defined(OS_ANDROID)
+TEST_F(UDPSocketTest, Tag) {
+ UDPServerSocket server(nullptr, NetLogSource());
+ ASSERT_THAT(server.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0)), IsOk());
+ IPEndPoint server_address;
+ ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
+
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
+ nullptr, NetLogSource());
+ ASSERT_THAT(client.Connect(server_address), IsOk());
+
+ // Verify UDP packets are tagged and counted properly.
+ int32_t tag_val1 = 0x12345678;
+ uint64_t old_traffic = GetTaggedBytes(tag_val1);
+ SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
+ client.ApplySocketTag(tag1);
+ // Client sends to the server.
+ std::string simple_message("hello world!");
+ int rv = WriteSocket(&client, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Server waits for message.
+ std::string str = RecvFromSocket(&server);
+ EXPECT_EQ(simple_message, str);
+ // Server echoes reply.
+ rv = SendToSocket(&server, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Client waits for response.
+ str = ReadSocket(&client);
+ EXPECT_EQ(simple_message, str);
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ int32_t tag_val2 = 0x87654321;
+ old_traffic = GetTaggedBytes(tag_val2);
+ SocketTag tag2(getuid(), tag_val2);
+ client.ApplySocketTag(tag2);
+ // Client sends to the server.
+ rv = WriteSocket(&client, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Server waits for message.
+ str = RecvFromSocket(&server);
+ EXPECT_EQ(simple_message, str);
+ // Server echoes reply.
+ rv = SendToSocket(&server, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Client waits for response.
+ str = ReadSocket(&client);
+ EXPECT_EQ(simple_message, str);
+ EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
+
+ // Verify socket can be retagged with a new value and the current process's
+ // UID.
+ old_traffic = GetTaggedBytes(tag_val1);
+ client.ApplySocketTag(tag1);
+ // Client sends to the server.
+ rv = WriteSocket(&client, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Server waits for message.
+ str = RecvFromSocket(&server);
+ EXPECT_EQ(simple_message, str);
+ // Server echoes reply.
+ rv = SendToSocket(&server, simple_message);
+ EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
+ // Client waits for response.
+ str = ReadSocket(&client);
+ EXPECT_EQ(simple_message, str);
+ EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
+}
+#endif
+
} // namespace net
diff --git a/chromium/net/socket/udp_socket_win.cc b/chromium/net/socket/udp_socket_win.cc
index e030cdc91ca..7790d6a4176 100644
--- a/chromium/net/socket/udp_socket_win.cc
+++ b/chromium/net/socket/udp_socket_win.cc
@@ -11,8 +11,8 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/rand_util.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
@@ -29,7 +29,9 @@
#include "net/log/net_log_source_type.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/socket_options.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/udp_net_log_parameters.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace {
@@ -405,9 +407,11 @@ int UDPSocketWin::RecvFrom(IOBuffer* buf,
return ERR_IO_PENDING;
}
-int UDPSocketWin::Write(IOBuffer* buf,
- int buf_len,
- const CompletionCallback& callback) {
+int UDPSocketWin::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
return SendToOrWrite(buf, buf_len, remote_address_.get(), callback);
}
@@ -468,7 +472,7 @@ int UDPSocketWin::InternalConnect(const IPEndPoint& address) {
// else connect() does the DatagramSocket::DEFAULT_BIND
if (rv < 0) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", -rv);
+ base::UmaHistogramSparse("Net.UdpSocketRandomBindErrorCode", -rv);
return rv;
}
@@ -1215,4 +1219,10 @@ void UDPSocketWin::UseNonBlockingIO() {
use_non_blocking_io_ = true;
}
+void UDPSocketWin::ApplySocketTag(const SocketTag& tag) {
+ // Windows does not support any specific SocketTags so fail if any non-default
+ // tag is applied.
+ CHECK(tag == SocketTag());
+}
+
} // namespace net
diff --git a/chromium/net/socket/udp_socket_win.h b/chromium/net/socket/udp_socket_win.h
index 8af9850d82b..71094d4dbde 100644
--- a/chromium/net/socket/udp_socket_win.h
+++ b/chromium/net/socket/udp_socket_win.h
@@ -28,12 +28,14 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/datagram_socket.h"
#include "net/socket/diff_serv_code_point.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
class IPAddress;
class NetLog;
struct NetLogSource;
+class SocketTag;
class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
public:
@@ -87,7 +89,10 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// Writes to the socket.
// Only usable from the client-side of a UDP socket, after the socket
// has been connected.
- int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
+ int Write(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Reads from a socket and receive sender address information.
// |buf| is the buffer to read data into.
@@ -200,6 +205,9 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// to switch to non-blocking IO.
void UseNonBlockingIO();
+ // Apply |tag| to this socket.
+ void ApplySocketTag(const SocketTag& tag);
+
private:
enum SocketOptions {
SOCKET_OPTION_MULTICAST_LOOP = 1 << 0
diff --git a/chromium/net/socket/unix_domain_client_socket_posix.cc b/chromium/net/socket/unix_domain_client_socket_posix.cc
index 037b0728dbc..72bf717bd3f 100644
--- a/chromium/net/socket/unix_domain_client_socket_posix.cc
+++ b/chromium/net/socket/unix_domain_client_socket_posix.cc
@@ -12,6 +12,7 @@
#include "net/base/net_errors.h"
#include "net/base/sockaddr_storage.h"
#include "net/socket/socket_posix.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -154,16 +155,23 @@ int64_t UnixDomainClientSocket::GetTotalReceivedBytes() const {
return 0;
}
+void UnixDomainClientSocket::ApplySocketTag(const SocketTag& tag) {
+ // Ignore socket tags as Unix domain sockets are local only.
+}
+
int UnixDomainClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(socket_);
return socket_->Read(buf, buf_len, callback);
}
-int UnixDomainClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int UnixDomainClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(socket_);
- return socket_->Write(buf, buf_len, callback);
+ return socket_->Write(buf, buf_len, callback, traffic_annotation);
}
int UnixDomainClientSocket::SetReceiveBufferSize(int32_t size) {
diff --git a/chromium/net/socket/unix_domain_client_socket_posix.h b/chromium/net/socket/unix_domain_client_socket_posix.h
index 47fb4fe2e8d..dbc513c3f9d 100644
--- a/chromium/net/socket/unix_domain_client_socket_posix.h
+++ b/chromium/net/socket/unix_domain_client_socket_posix.h
@@ -16,6 +16,7 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/stream_socket.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -59,6 +60,7 @@ class NET_EXPORT UnixDomainClientSocket : public StreamSocket {
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -66,7 +68,8 @@ class NET_EXPORT UnixDomainClientSocket : public StreamSocket {
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
index e7143ce3895..c80e780f3c1 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
+++ b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
@@ -16,6 +16,7 @@
#include "net/socket/socket_test_util.h"
#include "net/socket/stream_socket.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -73,6 +74,8 @@ class FakeStreamSocket : public StreamSocket {
return 0;
}
+ void ApplySocketTag(const SocketTag& tag) override {}
+
// Socket implementation
int Read(IOBuffer* buf,
int buf_len,
@@ -82,7 +85,8 @@ class FakeStreamSocket : public StreamSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_FAILED;
}
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.cc b/chromium/net/socket/websocket_transport_client_socket_pool.cc
index 3eb1bfc8a3c..5ef8809159a 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.cc
@@ -45,6 +45,7 @@ WebSocketTransportConnectJob::WebSocketTransportConnectJob(
: ConnectJob(group_name,
timeout_duration,
priority,
+ SocketTag(),
respect_limits,
delegate,
NetLogWithSource::Make(
@@ -324,6 +325,7 @@ int WebSocketTransportClientSocketPool::RequestSocket(
const std::string& group_name,
const void* params,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
@@ -339,6 +341,8 @@ int WebSocketTransportClientSocketPool::RequestSocket(
request_net_log.BeginEvent(NetLogEventType::SOCKET_POOL);
+ DCHECK(socket_tag == SocketTag());
+
if (ReachedMaxSocketsLimit() &&
respect_limits == ClientSocketPool::RespectLimits::ENABLED) {
request_net_log.AddEvent(NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS);
@@ -666,11 +670,12 @@ void WebSocketTransportClientSocketPool::ActivateStalledRequest() {
stalled_request_queue_.pop_front();
stalled_request_map_.erase(request.handle);
- int rv = RequestSocket("ignored", &request.params, request.priority,
- // Stalled requests can't have |respect_limits|
- // DISABLED.
- RespectLimits::ENABLED, request.handle,
- request.callback, request.net_log);
+ int rv =
+ RequestSocket("ignored", &request.params, request.priority, SocketTag(),
+ // Stalled requests can't have |respect_limits|
+ // DISABLED.
+ RespectLimits::ENABLED, request.handle, request.callback,
+ request.net_log);
// ActivateStalledRequest() never returns synchronously, so it is never
// called re-entrantly.
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.h b/chromium/net/socket/websocket_transport_client_socket_pool.h
index b6d73928937..c8248812f81 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.h
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.h
@@ -155,6 +155,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
int RequestSocket(const std::string& group_name,
const void* resolve_info,
RequestPriority priority,
+ const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
const CompletionCallback& callback,
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
index e8f78794a0e..65a51cfec93 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -24,6 +24,7 @@
#include "net/dns/mock_host_resolver.h"
#include "net/log/test_net_log.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/stream_socket.h"
#include "net/socket/transport_client_socket_pool_test_util.h"
@@ -79,12 +80,9 @@ class WebSocketTransportClientSocketPoolTest : public ::testing::Test {
static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
int StartRequest(const std::string& group_name, RequestPriority priority) {
- scoped_refptr<TransportSocketParams> params(
- new TransportSocketParams(
- HostPortPair("www.google.com", 80),
- false,
- OnHostResolutionCallback(),
- TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<TransportSocketParams> params(new TransportSocketParams(
+ HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
return test_base_.StartRequestUsingPool(
&pool_, group_name, priority, ClientSocketPool::RespectLimits::ENABLED,
params);
@@ -124,9 +122,9 @@ class WebSocketTransportClientSocketPoolTest : public ::testing::Test {
TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -145,7 +143,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, priority,
+ handle.Init("a", params_, priority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_EQ(priority, host_resolver_->last_request_priority());
@@ -161,7 +159,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
host_port_pair, false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", dest, kDefaultPriority,
+ handle.Init("a", dest, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
@@ -173,7 +171,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
@@ -181,7 +179,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
// Make the host resolutions complete synchronously this time.
host_resolver_->set_synchronous_mode(true);
EXPECT_EQ(ERR_CONNECTION_FAILED,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
}
@@ -258,7 +256,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
TestCompletionCallback callback;
ClientSocketHandle handle;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
handle.Reset();
@@ -271,11 +269,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
EXPECT_EQ(ERR_IO_PENDING,
- handle2.Init("a", params_, kDefaultPriority,
+ handle2.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), &pool_, NetLogWithSource()));
@@ -291,7 +289,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
ClientSocketHandle handle;
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), &pool_, NetLogWithSource()));
@@ -299,7 +297,7 @@ TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
TestCompletionCallback callback2;
EXPECT_EQ(ERR_IO_PENDING,
- handle.Init("a", params_, kDefaultPriority,
+ handle.Init("a", params_, kDefaultPriority, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), &pool_, NetLogWithSource()));
@@ -373,9 +371,9 @@ void RequestSocketOnComplete(ClientSocketHandle* handle,
scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
- int rv =
- handle->Init("a", dest, LOWEST, ClientSocketPool::RespectLimits::ENABLED,
- nested_callback, pool, NetLogWithSource());
+ int rv = handle->Init("a", dest, LOWEST, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ nested_callback, pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
if (ERR_IO_PENDING != rv)
nested_callback.Run(rv);
@@ -386,18 +384,15 @@ void RequestSocketOnComplete(ClientSocketHandle* handle,
// ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
ClientSocketHandle handle;
- scoped_refptr<TransportSocketParams> dest(
- new TransportSocketParams(
- HostPortPair("www.google.com", 80),
- false,
- OnHostResolutionCallback(),
- TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
+ scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
+ HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
+ TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
TestCompletionCallback second_result_callback;
- int rv =
- handle.Init("a", dest, LOWEST, ClientSocketPool::RespectLimits::ENABLED,
- base::Bind(&RequestSocketOnComplete, &handle, &pool_,
- second_result_callback.callback()),
- &pool_, NetLogWithSource());
+ int rv = handle.Init("a", dest, LOWEST, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ base::Bind(&RequestSocketOnComplete, &handle, &pool_,
+ second_result_callback.callback()),
+ &pool_, NetLogWithSource());
ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
@@ -468,9 +463,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
TestCompletionCallback callback;
std::unique_ptr<ClientSocketHandle> handle(new ClientSocketHandle);
- int rv =
- handle->Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool_, NetLogWithSource());
+ int rv = handle->Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool_, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(StartRequest("a", kDefaultPriority), IsError(ERR_IO_PENDING));
@@ -534,9 +529,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -575,9 +570,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -606,9 +601,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -635,9 +630,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
@@ -675,9 +670,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
host_resolver_->set_synchronous_mode(true);
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsOk());
ASSERT_TRUE(handle.socket());
@@ -710,9 +705,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_FALSE(handle.socket());
@@ -745,9 +740,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ASSERT_FALSE(handle.socket());
@@ -796,9 +791,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
TestCompletionCallback callback;
ClientSocketHandle handle;
base::TimeTicks start(base::TimeTicks::Now());
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
@@ -832,9 +827,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
TestCompletionCallback callback;
ClientSocketHandle handle;
- int rv =
- handle.Init("a", params_, LOW, ClientSocketPool::RespectLimits::ENABLED,
- callback.callback(), &pool, NetLogWithSource());
+ int rv = handle.Init("a", params_, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), &pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
index c6f5d42c573..a92c30472e3 100644
--- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
+++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
@@ -79,7 +79,7 @@ class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
not_expect_callback_(false),
on_failed_called_(false) {}
- ~TestDelegateBase() override {}
+ ~TestDelegateBase() override = default;
void OnStreamReady(bool request_headers_sent) override {
CHECK(!on_failed_called_);
diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.cc b/chromium/net/spdy/chromium/buffered_spdy_framer.cc
index 8da2d1080af..71a0eb36147 100644
--- a/chromium/net/spdy/chromium/buffered_spdy_framer.cc
+++ b/chromium/net/spdy/chromium/buffered_spdy_framer.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
+#include "net/spdy/chromium/spdy_flags.h"
#include "net/spdy/platform/api/spdy_estimate_memory_usage.h"
namespace net {
@@ -23,6 +24,7 @@ size_t kGoAwayDebugDataMaxSize = 1024;
BufferedSpdyFramer::BufferedSpdyFramer(uint32_t max_header_list_size,
const NetLogWithSource& net_log)
: spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
+ deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length),
visitor_(NULL),
frames_received_(0),
max_header_list_size_(max_header_list_size),
@@ -32,8 +34,7 @@ BufferedSpdyFramer::BufferedSpdyFramer(uint32_t max_header_list_size,
max_header_list_size_);
}
-BufferedSpdyFramer::~BufferedSpdyFramer() {
-}
+BufferedSpdyFramer::~BufferedSpdyFramer() = default;
void BufferedSpdyFramer::set_visitor(
BufferedSpdyFramerVisitorInterface* visitor) {
@@ -90,6 +91,12 @@ void BufferedSpdyFramer::OnStreamEnd(SpdyStreamId stream_id) {
visitor_->OnStreamEnd(stream_id);
}
+void BufferedSpdyFramer::OnStreamPadLength(SpdyStreamId stream_id,
+ size_t value) {
+ // Deliver the stream pad length byte for flow control handling.
+ visitor_->OnStreamPadding(stream_id, 1);
+}
+
void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
visitor_->OnStreamPadding(stream_id, len);
}
diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.h b/chromium/net/spdy/chromium/buffered_spdy_framer.h
index bdc15203a6e..84604467826 100644
--- a/chromium/net/spdy/chromium/buffered_spdy_framer.h
+++ b/chromium/net/spdy/chromium/buffered_spdy_framer.h
@@ -152,6 +152,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
const char* data,
size_t len) override;
void OnStreamEnd(SpdyStreamId stream_id) override;
+ void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
SpdyHeadersHandlerInterface* OnHeaderFrameStart(
SpdyStreamId stream_id) override;
diff --git a/chromium/net/spdy/chromium/http2_priority_dependencies.cc b/chromium/net/spdy/chromium/http2_priority_dependencies.cc
index 991924e4908..5874511ea6e 100644
--- a/chromium/net/spdy/chromium/http2_priority_dependencies.cc
+++ b/chromium/net/spdy/chromium/http2_priority_dependencies.cc
@@ -7,16 +7,17 @@
namespace net {
-Http2PriorityDependencies::Http2PriorityDependencies() {}
+Http2PriorityDependencies::Http2PriorityDependencies() = default;
-Http2PriorityDependencies::~Http2PriorityDependencies() {}
+Http2PriorityDependencies::~Http2PriorityDependencies() = default;
void Http2PriorityDependencies::OnStreamCreation(
SpdyStreamId id,
SpdyPriority priority,
SpdyStreamId* dependent_stream_id,
bool* exclusive) {
- DCHECK(entry_by_stream_id_.find(id) == entry_by_stream_id_.end());
+ if (entry_by_stream_id_.find(id) != entry_by_stream_id_.end())
+ return;
*dependent_stream_id = 0ul;
*exclusive = true;
@@ -97,6 +98,10 @@ Http2PriorityDependencies::OnStreamUpdate(SpdyStreamId id,
result.reserve(2);
EntryMap::iterator curr_entry = entry_by_stream_id_.find(id);
+ if (curr_entry == entry_by_stream_id_.end()) {
+ return result;
+ }
+
SpdyPriority old_priority = curr_entry->second->second;
if (old_priority == new_priority) {
return result;
@@ -151,7 +156,8 @@ Http2PriorityDependencies::OnStreamUpdate(SpdyStreamId id,
void Http2PriorityDependencies::OnStreamDestruction(SpdyStreamId id) {
EntryMap::iterator emit = entry_by_stream_id_.find(id);
- DCHECK(emit != entry_by_stream_id_.end());
+ if (emit == entry_by_stream_id_.end())
+ return;
IdList::iterator it = emit->second;
id_priority_lists_[it->second].erase(it);
diff --git a/chromium/net/spdy/chromium/http2_push_promise_index.cc b/chromium/net/spdy/chromium/http2_push_promise_index.cc
index 876b1ca9804..f0f280c6a95 100644
--- a/chromium/net/spdy/chromium/http2_push_promise_index.cc
+++ b/chromium/net/spdy/chromium/http2_push_promise_index.cc
@@ -3,91 +3,151 @@
// found in the LICENSE file.
#include "net/spdy/chromium/http2_push_promise_index.h"
+#include "base/trace_event/memory_usage_estimator.h"
+#include <algorithm>
#include <utility>
-#include "net/spdy/chromium/spdy_session.h"
-
namespace net {
-Http2PushPromiseIndex::Http2PushPromiseIndex() {}
+Http2PushPromiseIndex::Http2PushPromiseIndex() = default;
Http2PushPromiseIndex::~Http2PushPromiseIndex() {
DCHECK(unclaimed_pushed_streams_.empty());
}
-base::WeakPtr<SpdySession> Http2PushPromiseIndex::Find(
- const SpdySessionKey& key,
- const GURL& url) const {
+bool Http2PushPromiseIndex::RegisterUnclaimedPushedStream(
+ const GURL& url,
+ SpdyStreamId stream_id,
+ Delegate* delegate) {
DCHECK(!url.is_empty());
-
- UnclaimedPushedStreamMap::const_iterator url_it =
- unclaimed_pushed_streams_.find(url);
-
- if (url_it == unclaimed_pushed_streams_.end()) {
- return base::WeakPtr<SpdySession>();
+ DCHECK_GT(stream_id, kNoPushedStreamFound);
+ DCHECK(delegate);
+
+ // Find the entry with |url| for |delegate| if such exists (there can be at
+ // most one such entry). It is okay to cast away const from |delegate|,
+ // because it is only used for lookup.
+ auto it = unclaimed_pushed_streams_.lower_bound(UnclaimedPushedStream{
+ url, const_cast<Delegate*>(delegate), kNoPushedStreamFound});
+ // If such entry is found, do not allow registering another one.
+ if (it != unclaimed_pushed_streams_.end() && it->url == url &&
+ it->delegate == delegate) {
+ return false;
}
- DCHECK(url.SchemeIsCryptographic());
- for (const auto& session : url_it->second) {
- const SpdySessionKey& spdy_session_key = session->spdy_session_key();
- if (spdy_session_key.proxy_server() != key.proxy_server() ||
- spdy_session_key.privacy_mode() != key.privacy_mode()) {
- continue;
- }
- if (!session->VerifyDomainAuthentication(key.host_port_pair().host())) {
- continue;
- }
- return session;
- }
+ unclaimed_pushed_streams_.insert(
+ it, UnclaimedPushedStream{url, delegate, stream_id});
- return base::WeakPtr<SpdySession>();
+ return true;
}
-void Http2PushPromiseIndex::RegisterUnclaimedPushedStream(
+bool Http2PushPromiseIndex::UnregisterUnclaimedPushedStream(
const GURL& url,
- base::WeakPtr<SpdySession> spdy_session) {
+ SpdyStreamId stream_id,
+ Delegate* delegate) {
DCHECK(!url.is_empty());
- DCHECK(url.SchemeIsCryptographic());
-
- // Use lower_bound() so that if key does not exists, then insertion can use
- // its return value as a hint.
- UnclaimedPushedStreamMap::iterator url_it =
- unclaimed_pushed_streams_.lower_bound(url);
- if (url_it == unclaimed_pushed_streams_.end() || url_it->first != url) {
- WeakSessionList list;
- list.push_back(std::move(spdy_session));
- UnclaimedPushedStreamMap::value_type value(url, std::move(list));
- unclaimed_pushed_streams_.insert(url_it, std::move(value));
- return;
+ DCHECK_GT(stream_id, kNoPushedStreamFound);
+ DCHECK(delegate);
+
+ size_t result = unclaimed_pushed_streams_.erase(
+ UnclaimedPushedStream{url, delegate, stream_id});
+
+ return result == 1;
+}
+
+// The runtime of this method is linear in unclaimed_pushed_streams_.size(),
+// which is acceptable, because it is only used in NetLog, tests, and DCHECKs.
+size_t Http2PushPromiseIndex::CountStreamsForSession(
+ const Delegate* delegate) const {
+ DCHECK(delegate);
+
+ return std::count_if(unclaimed_pushed_streams_.begin(),
+ unclaimed_pushed_streams_.end(),
+ [&delegate](const UnclaimedPushedStream& entry) {
+ return entry.delegate == delegate;
+ });
+}
+
+SpdyStreamId Http2PushPromiseIndex::FindStream(const GURL& url,
+ const Delegate* delegate) const {
+ // Find the entry with |url| for |delegate| if such exists (there can be at
+ // most one such entry). It is okay to cast away const from |delegate|,
+ // because it is only used for lookup.
+ auto it = unclaimed_pushed_streams_.lower_bound(UnclaimedPushedStream{
+ url, const_cast<Delegate*>(delegate), kNoPushedStreamFound});
+
+ if (it == unclaimed_pushed_streams_.end() || it->url != url ||
+ it->delegate != delegate) {
+ return kNoPushedStreamFound;
}
- url_it->second.push_back(spdy_session);
+
+ return it->stream_id;
}
-void Http2PushPromiseIndex::UnregisterUnclaimedPushedStream(
+void Http2PushPromiseIndex::ClaimPushedStream(
+ const SpdySessionKey& key,
const GURL& url,
- SpdySession* spdy_session) {
+ const HttpRequestInfo& request_info,
+ base::WeakPtr<SpdySession>* session,
+ SpdyStreamId* stream_id) {
DCHECK(!url.is_empty());
- DCHECK(url.SchemeIsCryptographic());
- UnclaimedPushedStreamMap::iterator url_it =
- unclaimed_pushed_streams_.find(url);
- if (url_it == unclaimed_pushed_streams_.end()) {
- NOTREACHED();
- return;
- }
- for (WeakSessionList::iterator it = url_it->second.begin();
- it != url_it->second.end();) {
- if (it->get() == spdy_session) {
- url_it->second.erase(it);
- if (url_it->second.empty()) {
- unclaimed_pushed_streams_.erase(url_it);
- }
+ *session = nullptr;
+ *stream_id = kNoPushedStreamFound;
+
+ // Find the first entry for |url|, if such exists.
+ auto it = unclaimed_pushed_streams_.lower_bound(
+ UnclaimedPushedStream{url, nullptr, kNoPushedStreamFound});
+
+ while (it != unclaimed_pushed_streams_.end() && it->url == url) {
+ if (it->delegate->ValidatePushedStream(it->stream_id, url, request_info,
+ key)) {
+ *session = it->delegate->GetWeakPtrToSession();
+ *stream_id = it->stream_id;
+ unclaimed_pushed_streams_.erase(it);
return;
}
++it;
}
- NOTREACHED();
+}
+
+size_t Http2PushPromiseIndex::EstimateMemoryUsage() const {
+ return base::trace_event::EstimateMemoryUsage(unclaimed_pushed_streams_);
+}
+
+size_t Http2PushPromiseIndex::UnclaimedPushedStream::EstimateMemoryUsage()
+ const {
+ return base::trace_event::EstimateMemoryUsage(url) + sizeof(SpdyStreamId) +
+ sizeof(Delegate*);
+}
+
+bool Http2PushPromiseIndex::CompareByUrl::operator()(
+ const UnclaimedPushedStream& a,
+ const UnclaimedPushedStream& b) const {
+ // Compare by URL first.
+ if (a.url < b.url)
+ return true;
+ if (a.url > b.url)
+ return false;
+ // For identical URL, put an entry with delegate == nullptr first.
+ // The C++ standard dictates that comparisons between |nullptr| and other
+ // pointers are unspecified, hence the need to handle this case separately.
+ if (a.delegate == nullptr && b.delegate != nullptr) {
+ return true;
+ }
+ if (a.delegate != nullptr && b.delegate == nullptr) {
+ return false;
+ }
+ // Then compare by Delegate.
+ // The C++ standard guarantees that both |nullptr < nullptr| and
+ // |nullptr > nullptr| are false, so there is no need to handle that case
+ // separately.
+ if (a.delegate < b.delegate)
+ return true;
+ if (a.delegate > b.delegate)
+ return false;
+ // If URL and Delegate are identical, then compare by stream ID.
+ return a.stream_id < b.stream_id;
}
} // namespace net
diff --git a/chromium/net/spdy/chromium/http2_push_promise_index.h b/chromium/net/spdy/chromium/http2_push_promise_index.h
index a50ef42044b..e9f8f2e66db 100644
--- a/chromium/net/spdy/chromium/http2_push_promise_index.h
+++ b/chromium/net/spdy/chromium/http2_push_promise_index.h
@@ -5,53 +5,128 @@
#ifndef NET_SPDY_CHROMIUM_HTTP2_PUSH_PROMISE_INDEX_H_
#define NET_SPDY_CHROMIUM_HTTP2_PUSH_PROMISE_INDEX_H_
-#include <map>
-#include <vector>
+#include <set>
+#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
+#include "net/http/http_request_info.h"
#include "net/spdy/chromium/spdy_session_key.h"
+#include "net/spdy/core/spdy_protocol.h"
#include "url/gurl.h"
namespace net {
class SpdySession;
-// This class manages cross-origin unclaimed pushed streams (push promises) from
-// the receipt of PUSH_PROMISE frame until they are matched to a request. Each
-// SpdySessionPool owns one instance of this class, which then allows requests
-// to be matched with a pushed stream regardless of which HTTP/2 connection the
-// stream is on.
-// Only pushed streams with cryptographic schemes (for example, https) are
-// allowed to be shared across connections. Non-cryptographic scheme pushes
-// (for example, http) are fully managed within each SpdySession.
+namespace test {
+
+class Http2PushPromiseIndexPeer;
+
+} // namespace test
+
+// Value returned by ClaimPushedStream() and FindStream() if no stream is found.
+const SpdyStreamId kNoPushedStreamFound = 0;
+
+// This class manages unclaimed pushed streams (push promises) from the receipt
+// of PUSH_PROMISE frame until they are matched to a request.
+// Each SpdySessionPool owns one instance of this class.
+// SpdySession uses this class to register, unregister and query pushed streams.
+// HttpStreamFactoryImpl::Job uses this class to find a SpdySession with a
+// pushed stream matching the request, if such exists.
class NET_EXPORT Http2PushPromiseIndex {
public:
+ // Interface for validating pushed streams, signaling when a pushed stream is
+ // claimed, and generating SpdySession weak pointer.
+ class NET_EXPORT Delegate {
+ public:
+ Delegate() {}
+ virtual ~Delegate() {}
+
+ // Return true if a pushed stream with |url| can be used for a request with
+ // |key|.
+ virtual bool ValidatePushedStream(SpdyStreamId stream_id,
+ const GURL& url,
+ const HttpRequestInfo& request_info,
+ const SpdySessionKey& key) const = 0;
+
+ // Generate weak pointer. Guaranateed to be called synchronously after
+ // ValidatePushedStream() is called and returns true.
+ virtual base::WeakPtr<SpdySession> GetWeakPtrToSession() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+ };
+
Http2PushPromiseIndex();
~Http2PushPromiseIndex();
- // Returns a session with |key| that has an unclaimed push stream for |url| if
- // such exists. Returns nullptr otherwise.
- base::WeakPtr<SpdySession> Find(const SpdySessionKey& key,
- const GURL& url) const;
+ // Tries to register a Delegate with an unclaimed pushed stream for |url|.
+ // Caller must make sure |delegate| stays valid by unregistering the exact
+ // same entry before |delegate| is destroyed.
+ // Returns true if there is no unclaimed pushed stream with the same URL for
+ // the same Delegate, in which case the stream is registered.
+ bool RegisterUnclaimedPushedStream(const GURL& url,
+ SpdyStreamId stream_id,
+ Delegate* delegate) WARN_UNUSED_RESULT;
- // (Un)registers a SpdySession with an unclaimed pushed stream for |url|.
- void RegisterUnclaimedPushedStream(const GURL& url,
- base::WeakPtr<SpdySession> spdy_session);
- void UnregisterUnclaimedPushedStream(const GURL& url,
- SpdySession* spdy_session);
+ // Tries to unregister a Delegate with an unclaimed pushed stream for |url|
+ // with given |stream_id|.
+ // Returns true if this exact entry is found, in which case it is removed.
+ bool UnregisterUnclaimedPushedStream(const GURL& url,
+ SpdyStreamId stream_id,
+ Delegate* delegate) WARN_UNUSED_RESULT;
+
+ // Returns the number of pushed streams registered for |delegate|.
+ size_t CountStreamsForSession(const Delegate* delegate) const;
+
+ // Returns the stream ID of the entry registered for |delegate| with |url|,
+ // or kNoPushedStreamFound if no such entry exists.
+ SpdyStreamId FindStream(const GURL& url, const Delegate* delegate) const;
+
+ // If there exists a session compatible with |key| that has an unclaimed push
+ // stream for |url|, then sets |*session| and |*stream| to one such session
+ // and stream, and removes entry from index. Makes no guarantee on which
+ // (session, stream_id) pair is claimed if there are multiple matches. Sets
+ // |*session| to nullptr and |*stream| to kNoPushedStreamFound if no such
+ // session exists.
+ void ClaimPushedStream(const SpdySessionKey& key,
+ const GURL& url,
+ const HttpRequestInfo& request_info,
+ base::WeakPtr<SpdySession>* session,
+ SpdyStreamId* stream_id);
+
+ // Return the estimate of dynamically allocated memory in bytes.
+ size_t EstimateMemoryUsage() const;
private:
- typedef std::vector<base::WeakPtr<SpdySession>> WeakSessionList;
- typedef std::map<GURL, WeakSessionList> UnclaimedPushedStreamMap;
-
- // A multimap of all SpdySessions that have an unclaimed pushed stream for a
- // GURL. SpdySession must unregister its streams before destruction,
- // therefore all weak pointers must be valid. A single SpdySession can only
- // have at most one pushed stream for each GURL, but it is possible that
- // multiple SpdySessions have pushed streams for the same GURL.
- UnclaimedPushedStreamMap unclaimed_pushed_streams_;
+ friend test::Http2PushPromiseIndexPeer;
+
+ // An unclaimed pushed stream entry.
+ struct NET_EXPORT UnclaimedPushedStream {
+ GURL url;
+ Delegate* delegate;
+ SpdyStreamId stream_id;
+ size_t EstimateMemoryUsage() const;
+ };
+
+ // Function object satisfying the requirements of "Compare", see
+ // http://en.cppreference.com/w/cpp/concept/Compare.
+ // A set ordered by this function object supports O(log n) lookup
+ // of the first entry with a given URL, by calling lower_bound() with an entry
+ // with that URL and with delegate = nullptr.
+ struct NET_EXPORT CompareByUrl {
+ bool operator()(const UnclaimedPushedStream& a,
+ const UnclaimedPushedStream& b) const;
+ };
+
+ // Collection of all unclaimed pushed streams. Delegate must unregister
+ // its streams before destruction, so that all pointers remain valid.
+ // Each Delegate can have at most one pushed stream for each URL (but each
+ // Delegate can have pushed streams for different URLs, and different
+ // Delegates can have pushed streams for the same GURL).
+ std::set<UnclaimedPushedStream, CompareByUrl> unclaimed_pushed_streams_;
DISALLOW_COPY_AND_ASSIGN(Http2PushPromiseIndex);
};
diff --git a/chromium/net/spdy/chromium/http2_push_promise_index_test.cc b/chromium/net/spdy/chromium/http2_push_promise_index_test.cc
index d1cd077f3ff..6777cb50b37 100644
--- a/chromium/net/spdy/chromium/http2_push_promise_index_test.cc
+++ b/chromium/net/spdy/chromium/http2_push_promise_index_test.cc
@@ -4,175 +4,463 @@
#include "net/spdy/chromium/http2_push_promise_index.h"
-#include "base/run_loop.h"
#include "net/base/host_port_pair.h"
#include "net/base/privacy_mode.h"
-#include "net/log/test_net_log.h"
-#include "net/socket/socket_test_util.h"
-#include "net/spdy/chromium/spdy_session.h"
-#include "net/spdy/chromium/spdy_test_util_common.h"
-#include "net/test/cert_test_util.h"
-#include "net/test/test_data_directory.h"
+#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+// For simplicity, these tests do not create SpdySession instances
+// (necessary for a non-null WeakPtr<SpdySession>), instead they use nullptr.
+// Streams are identified by SpdyStreamId only.
+
+using ::testing::Return;
+using ::testing::_;
+
namespace net {
namespace test {
+namespace {
+
+// Delegate implementation for tests that requires exact match of SpdySessionKey
+// in ValidatePushedStream(). Note that SpdySession, unlike TestDelegate,
+// allows cross-origin pooling.
+class TestDelegate : public Http2PushPromiseIndex::Delegate {
+ public:
+ TestDelegate() = delete;
+ TestDelegate(const SpdySessionKey& key) : key_(key) {}
+ ~TestDelegate() override {}
+
+ bool ValidatePushedStream(SpdyStreamId stream_id,
+ const GURL& url,
+ const HttpRequestInfo& request_info,
+ const SpdySessionKey& key) const override {
+ return key == key_;
+ }
+
+ base::WeakPtr<SpdySession> GetWeakPtrToSession() override { return nullptr; }
+
+ private:
+ SpdySessionKey key_;
+};
+
+} // namespace
+
+class Http2PushPromiseIndexPeer {
+ public:
+ using UnclaimedPushedStream = Http2PushPromiseIndex::UnclaimedPushedStream;
+ using CompareByUrl = Http2PushPromiseIndex::CompareByUrl;
+};
class Http2PushPromiseIndexTest : public testing::Test {
protected:
Http2PushPromiseIndexTest()
: url1_("https://www.example.org"),
url2_("https://mail.example.com"),
- host_port_pair1_(HostPortPair::FromURL(url1_)),
- host_port_pair2_(HostPortPair::FromURL(url2_)),
- key1_(host_port_pair1_, ProxyServer::Direct(), PRIVACY_MODE_ENABLED),
- key2_(host_port_pair2_, ProxyServer::Direct(), PRIVACY_MODE_ENABLED),
- http_network_session_(
- SpdySessionDependencies::SpdyCreateSession(&session_deps_)) {}
-
- NetLogWithSource log_;
+ key1_(HostPortPair::FromURL(url1_),
+ ProxyServer::Direct(),
+ PRIVACY_MODE_ENABLED),
+ key2_(HostPortPair::FromURL(url2_),
+ ProxyServer::Direct(),
+ PRIVACY_MODE_ENABLED) {}
+
const GURL url1_;
const GURL url2_;
- const HostPortPair host_port_pair1_;
- const HostPortPair host_port_pair2_;
const SpdySessionKey key1_;
const SpdySessionKey key2_;
- SpdySessionDependencies session_deps_;
- std::unique_ptr<HttpNetworkSession> http_network_session_;
Http2PushPromiseIndex index_;
};
-TEST_F(Http2PushPromiseIndexTest, Empty) {
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
+// RegisterUnclaimedPushedStream() returns false
+// if there is already a registered entry with same delegate and URL.
+TEST_F(Http2PushPromiseIndexTest, CannotRegisterSameEntryTwice) {
+ TestDelegate delegate(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate));
+ EXPECT_FALSE(index_.RegisterUnclaimedPushedStream(url1_, 4, &delegate));
+ // Unregister first entry so that DCHECK() does not fail in destructor.
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate));
}
-TEST_F(Http2PushPromiseIndexTest, FindMultipleSessionsWithDifferentUrl) {
- MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- ssl.ssl_info.cert =
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
- ASSERT_TRUE(ssl.ssl_info.cert);
- // For first session.
- SequencedSocketData data1(reads, arraysize(reads), nullptr, 0);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
- // For second session.
- SequencedSocketData data2(reads, arraysize(reads), nullptr, 0);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
+// UnregisterUnclaimedPushedStream() returns false
+// if there is no identical entry registered.
+// Case 1: no streams for the given URL.
+TEST_F(Http2PushPromiseIndexTest, CannotUnregisterNonexistingEntry) {
+ TestDelegate delegate(key1_);
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate));
+}
- base::WeakPtr<SpdySession> spdy_session1 =
- CreateSpdySession(http_network_session_.get(), key1_, log_);
- base::WeakPtr<SpdySession> spdy_session2 =
- CreateSpdySession(http_network_session_.get(), key2_, log_);
- // Read hanging socket data.
- base::RunLoop().RunUntilIdle();
+// UnregisterUnclaimedPushedStream() returns false
+// if there is no identical entry registered.
+// Case 2: there is a stream for the given URL with the same Delegate,
+// but the stream ID does not match.
+TEST_F(Http2PushPromiseIndexTest, CannotUnregisterEntryIfStreamIdDoesNotMatch) {
+ TestDelegate delegate(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate));
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 4, &delegate));
+ // Unregister first entry so that DCHECK() does not fail in destructor.
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate));
+}
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
+// UnregisterUnclaimedPushedStream() returns false
+// if there is no identical entry registered.
+// Case 3: there is a stream for the given URL with the same stream ID,
+// but the delegate does not match.
+TEST_F(Http2PushPromiseIndexTest, CannotUnregisterEntryIfDelegateDoesNotMatch) {
+ TestDelegate delegate1(key1_);
+ TestDelegate delegate2(key2_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate2));
+ // Unregister first entry so that DCHECK() does not fail in destructor.
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
+}
- index_.RegisterUnclaimedPushedStream(url1_, spdy_session1);
+TEST_F(Http2PushPromiseIndexTest, CountStreamsForSession) {
+ TestDelegate delegate1(key1_);
+ TestDelegate delegate2(key2_);
- EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get());
- EXPECT_FALSE(index_.Find(key2_, url2_));
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate2));
- index_.RegisterUnclaimedPushedStream(url2_, spdy_session2);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
- EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get());
- EXPECT_EQ(spdy_session2.get(), index_.Find(key2_, url2_).get());
+ EXPECT_EQ(1u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate2));
- index_.UnregisterUnclaimedPushedStream(url1_, spdy_session1.get());
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url2_, 4, &delegate1));
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_EQ(spdy_session2.get(), index_.Find(key2_, url2_).get());
+ EXPECT_EQ(2u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate2));
- index_.UnregisterUnclaimedPushedStream(url2_, spdy_session2.get());
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 6, &delegate2));
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
+ EXPECT_EQ(2u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(1u, index_.CountStreamsForSession(&delegate2));
- // SpdySession weak pointers must still be valid,
- // otherwise comparisons above are not meaningful.
- EXPECT_TRUE(spdy_session1);
- EXPECT_TRUE(spdy_session2);
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
- EXPECT_TRUE(data1.AllReadDataConsumed());
- EXPECT_TRUE(data1.AllWriteDataConsumed());
- EXPECT_TRUE(data2.AllReadDataConsumed());
- EXPECT_TRUE(data2.AllWriteDataConsumed());
+ EXPECT_EQ(1u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(1u, index_.CountStreamsForSession(&delegate2));
+
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url2_, 4, &delegate1));
+
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(1u, index_.CountStreamsForSession(&delegate2));
+
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 6, &delegate2));
+
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate1));
+ EXPECT_EQ(0u, index_.CountStreamsForSession(&delegate2));
}
-TEST_F(Http2PushPromiseIndexTest, MultipleSessionsForSingleUrl) {
- MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- ssl.ssl_info.cert =
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
- ASSERT_TRUE(ssl.ssl_info.cert);
- // For first session.
- SequencedSocketData data1(reads, arraysize(reads), nullptr, 0);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
- // For second session.
- SequencedSocketData data2(reads, arraysize(reads), nullptr, 0);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
-
- base::WeakPtr<SpdySession> spdy_session1 =
- CreateSpdySession(http_network_session_.get(), key1_, log_);
- base::WeakPtr<SpdySession> spdy_session2 =
- CreateSpdySession(http_network_session_.get(), key2_, log_);
- // Read hanging socket data.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_FALSE(index_.Find(key2_, url1_));
- EXPECT_FALSE(index_.Find(key1_, url2_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
-
- index_.RegisterUnclaimedPushedStream(url1_, spdy_session1);
-
- // Note that Find() only uses its SpdySessionKey argument to verify proxy and
- // privacy mode. Cross-origin pooling is supported, therefore HostPortPair of
- // SpdySessionKey does not matter.
- EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get());
- EXPECT_EQ(spdy_session1.get(), index_.Find(key2_, url1_).get());
- EXPECT_FALSE(index_.Find(key1_, url2_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
-
- index_.RegisterUnclaimedPushedStream(url1_, spdy_session2);
-
- // Find returns the first SpdySession if there are multiple for the same URL.
- EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get());
- EXPECT_EQ(spdy_session1.get(), index_.Find(key2_, url1_).get());
- EXPECT_FALSE(index_.Find(key1_, url2_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
-
- index_.UnregisterUnclaimedPushedStream(url1_, spdy_session1.get());
-
- EXPECT_EQ(spdy_session2.get(), index_.Find(key1_, url1_).get());
- EXPECT_EQ(spdy_session2.get(), index_.Find(key2_, url1_).get());
- EXPECT_FALSE(index_.Find(key1_, url2_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
-
- index_.UnregisterUnclaimedPushedStream(url1_, spdy_session2.get());
-
- EXPECT_FALSE(index_.Find(key1_, url1_));
- EXPECT_FALSE(index_.Find(key2_, url1_));
- EXPECT_FALSE(index_.Find(key1_, url2_));
- EXPECT_FALSE(index_.Find(key2_, url2_));
-
- // SpdySession weak pointers must still be valid,
- // otherwise comparisons above are not meaningful.
- EXPECT_TRUE(spdy_session1);
- EXPECT_TRUE(spdy_session2);
-
- EXPECT_TRUE(data1.AllReadDataConsumed());
- EXPECT_TRUE(data1.AllWriteDataConsumed());
- EXPECT_TRUE(data2.AllReadDataConsumed());
- EXPECT_TRUE(data2.AllWriteDataConsumed());
+TEST_F(Http2PushPromiseIndexTest, FindStream) {
+ TestDelegate delegate1(key1_);
+ TestDelegate delegate2(key2_);
+
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+
+ EXPECT_EQ(2u, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url2_, 4, &delegate1));
+
+ EXPECT_EQ(2u, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(4u, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 6, &delegate2));
+
+ EXPECT_EQ(2u, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(4u, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(6u, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
+
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(4u, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(6u, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url2_, 4, &delegate1));
+
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(6u, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+
+ EXPECT_TRUE(index_.UnregisterUnclaimedPushedStream(url1_, 6, &delegate2));
+
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate1));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url1_, &delegate2));
+ EXPECT_EQ(kNoPushedStreamFound, index_.FindStream(url2_, &delegate2));
+}
+
+// If |index_| is empty, then ClaimPushedStream() should set its |stream_id|
+// outparam to kNoPushedStreamFound for any values of inparams.
+TEST_F(Http2PushPromiseIndexTest, Empty) {
+ base::WeakPtr<SpdySession> session;
+ SpdyStreamId stream_id = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ stream_id = 2;
+ index_.ClaimPushedStream(key2_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
}
+// Create two entries, both with a delegate that requires |key| to be equal to
+// |key1_|. Register the two entries with different URLs. Check that they can
+// be found by their respective URLs.
+TEST_F(Http2PushPromiseIndexTest, FindMultipleStreamsWithDifferentUrl) {
+ // Register first entry.
+ TestDelegate delegate1(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+
+ // No entry found for |url2_|.
+ base::WeakPtr<SpdySession> session;
+ SpdyStreamId stream_id = 2;
+ index_.ClaimPushedStream(key1_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ // Claim first entry.
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(2u, stream_id);
+
+ // ClaimPushedStream() unregistered first entry, cannot claim it again.
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ // Register two entries. Second entry uses same key.
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ TestDelegate delegate2(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url2_, 4, &delegate2));
+
+ // Retrieve each entry by their respective URLs.
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(2u, stream_id);
+
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(4u, stream_id);
+
+ // ClaimPushedStream() calls unregistered both entries,
+ // cannot claim them again.
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url2_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url2_, 4, &delegate2));
+}
+
+// Create two entries with delegates that validate different SpdySessionKeys.
+// Register the two entries with the same URL. Check that they can be found by
+// their respective SpdySessionKeys.
+TEST_F(Http2PushPromiseIndexTest, MultipleStreamsWithDifferentKeys) {
+ // Register first entry.
+ TestDelegate delegate1(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+
+ // No entry found for |key2_|.
+ base::WeakPtr<SpdySession> session;
+ SpdyStreamId stream_id = 2;
+ index_.ClaimPushedStream(key2_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ // Claim first entry.
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(2u, stream_id);
+
+ // ClaimPushedStream() unregistered first entry, cannot claim it again.
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ // Register two entries. Second entry uses same URL.
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ TestDelegate delegate2(key2_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 4, &delegate2));
+
+ // Retrieve each entry by their respective SpdySessionKeys.
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(2u, stream_id);
+
+ stream_id = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key2_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(4u, stream_id);
+
+ // ClaimPushedStream() calls unregistered both entries,
+ // cannot claim them again.
+ stream_id = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ stream_id = 2;
+ index_.ClaimPushedStream(key2_, url1_, HttpRequestInfo(), &session,
+ &stream_id);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id);
+
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 4, &delegate2));
+}
+
+TEST_F(Http2PushPromiseIndexTest, MultipleMatchingStreams) {
+ // Register two entries with identical URLs that have delegates that accept
+ // the same SpdySessionKey.
+ TestDelegate delegate1(key1_);
+ TestDelegate delegate2(key1_);
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ EXPECT_TRUE(index_.RegisterUnclaimedPushedStream(url1_, 4, &delegate2));
+
+ // Test that ClaimPushedStream() returns one of the two entries.
+ // ClaimPushedStream() makes no guarantee about which entry it returns if
+ // there are multiple matches.
+ base::WeakPtr<SpdySession> session;
+ SpdyStreamId stream_id1 = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id1);
+ EXPECT_NE(kNoPushedStreamFound, stream_id1);
+
+ // First call to ClaimPushedStream() unregistered one of the entries.
+ // Second call to ClaimPushedStream() must return the other entry.
+ SpdyStreamId stream_id2 = kNoPushedStreamFound;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id2);
+ EXPECT_NE(kNoPushedStreamFound, stream_id2);
+ EXPECT_NE(stream_id1, stream_id2);
+
+ // Two calls to ClaimPushedStream() unregistered both entries.
+ SpdyStreamId stream_id3 = 2;
+ index_.ClaimPushedStream(key1_, url1_, HttpRequestInfo(), &session,
+ &stream_id3);
+ EXPECT_EQ(kNoPushedStreamFound, stream_id3);
+
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 2, &delegate1));
+ EXPECT_FALSE(index_.UnregisterUnclaimedPushedStream(url1_, 4, &delegate2));
+}
+
+// Test that an entry is equivalent to itself.
+TEST(Http2PushPromiseIndexCompareByUrlTest, Reflexivity) {
+ // Test with two entries: with and without a pushed stream.
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry1{GURL(), nullptr, 2};
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry2{GURL(), nullptr,
+ kNoPushedStreamFound};
+
+ // For "Compare", it is a requirement that comp(A, A) == false, see
+ // http://en.cppreference.com/w/cpp/concept/Compare. This will in fact imply
+ // that equiv(A, A) == true.
+ EXPECT_FALSE(Http2PushPromiseIndexPeer::CompareByUrl()(entry1, entry1));
+ EXPECT_FALSE(Http2PushPromiseIndexPeer::CompareByUrl()(entry2, entry2));
+
+ std::set<Http2PushPromiseIndexPeer::UnclaimedPushedStream,
+ Http2PushPromiseIndexPeer::CompareByUrl>
+ entries;
+ bool success;
+ std::tie(std::ignore, success) = entries.insert(entry1);
+ EXPECT_TRUE(success);
+
+ // Test that |entry1| is considered equivalent to itself by ensuring that
+ // a second insertion fails.
+ std::tie(std::ignore, success) = entries.insert(entry1);
+ EXPECT_FALSE(success);
+
+ // Test that |entry1| and |entry2| are not equivalent.
+ std::tie(std::ignore, success) = entries.insert(entry2);
+ EXPECT_TRUE(success);
+
+ // Test that |entry2| is equivalent to an existing entry
+ // (which then must be |entry2|).
+ std::tie(std::ignore, success) = entries.insert(entry2);
+ EXPECT_FALSE(success);
+};
+
+TEST(Http2PushPromiseIndexCompareByUrlTest, LookupByURL) {
+ const GURL url1("https://example.com:1");
+ const GURL url2("https://example.com:2");
+ const GURL url3("https://example.com:3");
+ // This test relies on the order of these GURLs.
+ ASSERT_LT(url1, url2);
+ ASSERT_LT(url2, url3);
+
+ // Create four entries, two for the middle URL, with distinct stream IDs not
+ // in ascending order.
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry1{url1, nullptr, 8};
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry2{url2, nullptr, 4};
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry3{url2, nullptr, 6};
+ Http2PushPromiseIndexPeer::UnclaimedPushedStream entry4{url3, nullptr, 2};
+
+ // Fill up a set.
+ std::set<Http2PushPromiseIndexPeer::UnclaimedPushedStream,
+ Http2PushPromiseIndexPeer::CompareByUrl>
+ entries;
+ entries.insert(entry1);
+ entries.insert(entry2);
+ entries.insert(entry3);
+ entries.insert(entry4);
+ ASSERT_EQ(4u, entries.size());
+
+ // Test that entries are ordered by URL first, not stream ID.
+ std::set<Http2PushPromiseIndexPeer::UnclaimedPushedStream,
+ Http2PushPromiseIndexPeer::CompareByUrl>::iterator it =
+ entries.begin();
+ EXPECT_EQ(8u, it->stream_id);
+ ++it;
+ EXPECT_EQ(4u, it->stream_id);
+ ++it;
+ EXPECT_EQ(6u, it->stream_id);
+ ++it;
+ EXPECT_EQ(2u, it->stream_id);
+ ++it;
+ EXPECT_TRUE(it == entries.end());
+
+ // Test that kNoPushedStreamFound can be used to look up the first entry for a
+ // given URL. In particular, the first entry with |url2| is |entry2|.
+ EXPECT_TRUE(
+ entries.lower_bound(Http2PushPromiseIndexPeer::UnclaimedPushedStream{
+ url2, nullptr, kNoPushedStreamFound}) == entries.find(entry2));
+};
+
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/chromium/multiplexed_http_stream.cc b/chromium/net/spdy/chromium/multiplexed_http_stream.cc
index 3148fed8d4c..0a685946f68 100644
--- a/chromium/net/spdy/chromium/multiplexed_http_stream.cc
+++ b/chromium/net/spdy/chromium/multiplexed_http_stream.cc
@@ -14,7 +14,7 @@ MultiplexedHttpStream::MultiplexedHttpStream(
std::unique_ptr<MultiplexedSessionHandle> session)
: session_(std::move(session)) {}
-MultiplexedHttpStream::~MultiplexedHttpStream() {}
+MultiplexedHttpStream::~MultiplexedHttpStream() = default;
bool MultiplexedHttpStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
return session_->GetRemoteEndpoint(endpoint);
diff --git a/chromium/net/spdy/chromium/multiplexed_session.cc b/chromium/net/spdy/chromium/multiplexed_session.cc
index e49e69ba0e5..8b380265952 100644
--- a/chromium/net/spdy/chromium/multiplexed_session.cc
+++ b/chromium/net/spdy/chromium/multiplexed_session.cc
@@ -12,7 +12,7 @@ MultiplexedSessionHandle::MultiplexedSessionHandle(
SaveSSLInfo();
}
-MultiplexedSessionHandle::~MultiplexedSessionHandle() {}
+MultiplexedSessionHandle::~MultiplexedSessionHandle() = default;
bool MultiplexedSessionHandle::GetRemoteEndpoint(IPEndPoint* endpoint) {
if (!session_)
diff --git a/chromium/net/spdy/chromium/spdy_buffer_producer.cc b/chromium/net/spdy/chromium/spdy_buffer_producer.cc
index 08847ecc523..294d826c1dc 100644
--- a/chromium/net/spdy/chromium/spdy_buffer_producer.cc
+++ b/chromium/net/spdy/chromium/spdy_buffer_producer.cc
@@ -13,14 +13,14 @@
namespace net {
-SpdyBufferProducer::SpdyBufferProducer() {}
+SpdyBufferProducer::SpdyBufferProducer() = default;
-SpdyBufferProducer::~SpdyBufferProducer() {}
+SpdyBufferProducer::~SpdyBufferProducer() = default;
SimpleBufferProducer::SimpleBufferProducer(std::unique_ptr<SpdyBuffer> buffer)
: buffer_(std::move(buffer)) {}
-SimpleBufferProducer::~SimpleBufferProducer() {}
+SimpleBufferProducer::~SimpleBufferProducer() = default;
std::unique_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() {
DCHECK(buffer_);
diff --git a/chromium/net/spdy/chromium/spdy_flags.cc b/chromium/net/spdy/chromium/spdy_flags.cc
index a1d57cb1105..fd4a669fcf9 100644
--- a/chromium/net/spdy/chromium/spdy_flags.cc
+++ b/chromium/net/spdy/chromium/spdy_flags.cc
@@ -6,4 +6,7 @@
namespace net {
+// Deliver OnPaddingLength separately from OnPadding.
+bool FLAGS_chromium_http2_flag_h2_on_stream_pad_length = true;
+
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_flags.h b/chromium/net/spdy/chromium/spdy_flags.h
index 7006618e388..5b188d3b8df 100644
--- a/chromium/net/spdy/chromium/spdy_flags.h
+++ b/chromium/net/spdy/chromium/spdy_flags.h
@@ -9,6 +9,9 @@
namespace net {
+NET_EXPORT_PRIVATE extern bool
+ FLAGS_chromium_http2_flag_h2_on_stream_pad_length;
+
} // namespace net
#endif // NET_SPDY_CHROMIUM_SPDY_FLAGS_H_
diff --git a/chromium/net/spdy/chromium/spdy_http_stream.cc b/chromium/net/spdy/chromium/spdy_http_stream.cc
index 17a12834348..c8207afd236 100644
--- a/chromium/net/spdy/chromium/spdy_http_stream.cc
+++ b/chromium/net/spdy/chromium/spdy_http_stream.cc
@@ -33,11 +33,13 @@ namespace net {
const size_t SpdyHttpStream::kRequestBodyBufferSize = 1 << 14; // 16KB
SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session,
+ SpdyStreamId pushed_stream_id,
bool direct,
NetLogSource source_dependency)
: MultiplexedHttpStream(
std::make_unique<MultiplexedSessionHandle>(spdy_session)),
spdy_session_(spdy_session),
+ pushed_stream_id_(pushed_stream_id),
is_reused_(spdy_session_->IsReused()),
source_dependency_(source_dependency),
stream_(nullptr),
@@ -68,6 +70,7 @@ SpdyHttpStream::~SpdyHttpStream() {
}
int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& stream_net_log,
const CompletionCallback& callback) {
@@ -76,11 +79,10 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
return ERR_CONNECTION_CLOSED;
request_info_ = request_info;
- // TODO(bnc): Remove this condition once pushed headers are properly
- // validated. https://crbug.com/554220.
- if (request_info_->method == "GET") {
- int error = spdy_session_->GetPushStream(request_info_->url, priority,
- &stream_, stream_net_log);
+ if (pushed_stream_id_ != kNoPushedStreamFound) {
+ int error =
+ spdy_session_->GetPushedStream(request_info_->url, pushed_stream_id_,
+ priority, &stream_, stream_net_log);
if (error != OK)
return error;
diff --git a/chromium/net/spdy/chromium/spdy_http_stream.h b/chromium/net/spdy/chromium/spdy_http_stream.h
index fabdbaa8a2d..4eb48c522e6 100644
--- a/chromium/net/spdy/chromium/spdy_http_stream.h
+++ b/chromium/net/spdy/chromium/spdy_http_stream.h
@@ -36,6 +36,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
static const size_t kRequestBodyBufferSize;
// |spdy_session| must not be NULL.
SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session,
+ SpdyStreamId pushed_stream_id,
bool direct,
NetLogSource source_dependency);
~SpdyHttpStream() override;
@@ -48,6 +49,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
// HttpStream implementation.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override;
@@ -133,6 +135,12 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
bool ShouldWaitForMoreBufferedData() const;
const base::WeakPtr<SpdySession> spdy_session_;
+
+ // The ID of the pushed stream if one is claimed by this request.
+ // In this case, the request fails if it cannot use that pushed stream.
+ // Otherwise set to kNoPushedStreamFound.
+ const SpdyStreamId pushed_stream_id_;
+
bool is_reused_;
SpdyStreamRequest stream_request_;
const NetLogSource source_dependency_;
diff --git a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
index 1db24232eb2..83f92b9580a 100644
--- a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
@@ -130,7 +130,7 @@ class SpdyHttpStreamTest : public testing::Test {
session_deps_.net_log = &net_log_;
}
- ~SpdyHttpStreamTest() override {}
+ ~SpdyHttpStreamTest() override = default;
protected:
void TearDown() override {
@@ -197,14 +197,14 @@ TEST_F(SpdyHttpStreamTest, SendRequest) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
// Make sure getting load timing information the stream early does not crash.
LoadTimingInfo load_timing_info;
EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info));
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ ASSERT_THAT(http_stream->InitializeStream(&request, true, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info));
@@ -254,12 +254,13 @@ TEST_F(SpdyHttpStreamTest, RequestInfoDestroyedBeforeRead) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(request.get(), DEFAULT_PRIORITY,
- net_log, CompletionCallback()),
- IsOk());
+ ASSERT_THAT(
+ http_stream->InitializeStream(request.get(), true, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
+ IsOk());
EXPECT_THAT(http_stream->SendRequest(headers, &response, callback.callback()),
IsError(ERR_IO_PENDING));
EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key_));
@@ -316,8 +317,8 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) {
HttpResponseInfo response1;
HttpRequestHeaders headers1;
NetLogWithSource net_log;
- auto http_stream1 =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
+ auto http_stream1 = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
HttpRequestInfo request2;
request2.method = "GET";
@@ -325,11 +326,11 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) {
TestCompletionCallback callback2;
HttpResponseInfo response2;
HttpRequestHeaders headers2;
- auto http_stream2 =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
+ auto http_stream2 = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
// First write.
- ASSERT_THAT(http_stream1->InitializeStream(&request1, DEFAULT_PRIORITY,
+ ASSERT_THAT(http_stream1->InitializeStream(&request1, true, DEFAULT_PRIORITY,
net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(
@@ -346,7 +347,7 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) {
EXPECT_FALSE(http_stream2->GetLoadTimingInfo(&load_timing_info2));
// Second write.
- ASSERT_THAT(http_stream2->InitializeStream(&request2, DEFAULT_PRIORITY,
+ ASSERT_THAT(http_stream2->InitializeStream(&request2, true, DEFAULT_PRIORITY,
net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(
@@ -423,9 +424,10 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPost) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()),
@@ -478,9 +480,10 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPostLastEmpty) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()),
IsError(ERR_IO_PENDING));
@@ -532,9 +535,10 @@ TEST_F(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()),
@@ -600,10 +604,10 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPost) {
upload_stream.AppendData(kUploadData, kUploadDataSize, false);
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
+ ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
TestCompletionCallback callback;
@@ -695,10 +699,10 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) {
upload_stream.AppendData(kUploadData, kUploadDataSize, false);
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
+ ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
TestCompletionCallback callback;
@@ -779,10 +783,10 @@ TEST_F(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) {
upload_stream.AppendData("", 0, true);
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
+ ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
TestCompletionCallback callback;
@@ -839,10 +843,10 @@ TEST_F(SpdyHttpStreamTest, SpdyURLTest) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
+ ASSERT_THAT(http_stream->InitializeStream(&request, true, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
EXPECT_THAT(http_stream->SendRequest(headers, &response, callback.callback()),
@@ -892,10 +896,10 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) {
IsOk());
NetLogWithSource net_log;
- auto http_stream =
- std::make_unique<SpdyHttpStream>(session_, true, net_log.source());
- ASSERT_THAT(http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ auto http_stream = std::make_unique<SpdyHttpStream>(
+ session_, kNoPushedStreamFound, true, net_log.source());
+ ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
HttpRequestHeaders headers;
@@ -997,9 +1001,10 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorSynchronous) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
int result = http_stream.SendRequest(headers, &response, callback.callback());
@@ -1050,9 +1055,10 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorAsynchronous) {
HttpResponseInfo response;
HttpRequestHeaders headers;
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
int result = http_stream.SendRequest(headers, &response, callback.callback());
@@ -1092,9 +1098,10 @@ TEST_F(SpdyHttpStreamTest, RequestCallbackCancelsStream) {
upload_stream.AppendData("", 0, true);
NetLogWithSource net_log;
- SpdyHttpStream http_stream(session_, true, net_log.source());
- ASSERT_THAT(http_stream.InitializeStream(&request, DEFAULT_PRIORITY, net_log,
- CompletionCallback()),
+ SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true,
+ net_log.source());
+ ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY,
+ net_log, CompletionCallback()),
IsOk());
CancelStreamCallback callback(&http_stream);
diff --git a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
index 6d4e16fded3..0da92cf6a27 100644
--- a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
@@ -22,6 +22,7 @@
#include "net/base/test_proxy_delegate.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_file_element_reader.h"
+#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_session_peer.h"
@@ -392,8 +393,8 @@ class SpdyNetworkTransactionTest : public ::testing::Test {
session->spdy_session_pool()->FindAvailableSession(
key, /* enable_ip_based_pooling = */ true, log_);
ASSERT_TRUE(spdy_session);
- EXPECT_EQ(0u, spdy_session->num_active_streams());
- EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams(spdy_session));
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
}
void RunServerPushTest(SequencedSocketData* data,
@@ -518,6 +519,28 @@ class SpdyNetworkTransactionTest : public ::testing::Test {
return SpdyString(kDefaultUrl) + path;
}
+ size_t num_active_streams(base::WeakPtr<SpdySession> session) {
+ return session->active_streams_.size();
+ }
+
+ static size_t num_unclaimed_pushed_streams(
+ base::WeakPtr<SpdySession> session) {
+ return session->pool_->push_promise_index()->CountStreamsForSession(
+ session.get());
+ }
+
+ static bool has_unclaimed_pushed_stream_for_url(
+ base::WeakPtr<SpdySession> session,
+ const GURL& url) {
+ return session->pool_->push_promise_index()->FindStream(
+ url, session.get()) != kNoPushedStreamFound;
+ }
+
+ static SpdyStreamId spdy_stream_hi_water_mark(
+ base::WeakPtr<SpdySession> session) {
+ return session->stream_hi_water_mark_;
+ }
+
const GURL default_url_;
const HostPortPair host_port_pair_;
HttpRequestInfo request_;
@@ -1237,7 +1260,7 @@ class KillerCallback : public TestCompletionCallbackBase {
base::Unretained(this))) {
}
- ~KillerCallback() override {}
+ ~KillerCallback() override = default;
const CompletionCallback& callback() const { return callback_; }
@@ -2114,7 +2137,7 @@ TEST_F(SpdyNetworkTransactionTest,
&push_headers);
SpdySerializedFrame push_init_frame(
- spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1));
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
SpdySerializedFrame push_headers_frame(
spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
@@ -2372,6 +2395,138 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
EXPECT_EQ("HTTP/1.1 200", response2.headers->GetStatusLine());
}
+TEST_F(SpdyNetworkTransactionTest, ServerPushHeadMethod) {
+ SpdySerializedFrame req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)};
+
+ SpdyHeaderBlock push_promise_header_block;
+ push_promise_header_block[kHttp2MethodHeader] = "HEAD";
+ spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
+ &push_promise_header_block);
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
+
+ SpdyHeaderBlock push_response_headers;
+ push_response_headers[kHttp2StatusHeader] = "200";
+ push_response_headers["foo"] = "bar";
+ SpdyHeadersIR headers_ir(2, std::move(push_response_headers));
+ SpdySerializedFrame push_headers(spdy_util_.SerializeFrame(headers_ir));
+
+ SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
+ MockRead reads[] = {
+ CreateMockRead(push_promise, 1), CreateMockRead(push_headers, 3),
+ CreateMockRead(resp, 4), CreateMockRead(body, 5),
+ // Do not close the connection after first request is done.
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ // Run first request. This reads PUSH_PROMISE.
+ helper.RunDefaultTest();
+
+ // Request the pushed resource.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
+ HttpRequestInfo request = CreateGetPushRequest();
+ request.method = "HEAD";
+ TestCompletionCallback callback;
+ int rv = trans.Start(&request, callback.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ rv = callback.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(response->was_fetched_via_spdy);
+ EXPECT_TRUE(response->was_alpn_negotiated);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string value;
+ EXPECT_TRUE(response->headers->GetNormalizedHeader("foo", &value));
+ EXPECT_EQ("bar", value);
+
+ helper.VerifyDataConsumed();
+}
+
+TEST_F(SpdyNetworkTransactionTest, ServerPushHeadDoesNotMatchGetRequest) {
+ SpdySerializedFrame req1(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
+ SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(
+ GetDefaultUrlWithPath("/foo.dat").c_str(), 3, LOWEST));
+ MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 2),
+ CreateMockWrite(req2, 6)};
+
+ SpdyHeaderBlock push_promise_header_block;
+ push_promise_header_block[kHttp2MethodHeader] = "HEAD";
+ spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
+ &push_promise_header_block);
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
+
+ SpdyHeaderBlock push_response_headers;
+ push_response_headers[kHttp2StatusHeader] = "200";
+ push_response_headers["foo"] = "bar";
+ SpdyHeadersIR headers_ir(2, std::move(push_response_headers));
+ SpdySerializedFrame push_headers(spdy_util_.SerializeFrame(headers_ir));
+
+ SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
+ SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
+ SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
+ MockRead reads[] = {CreateMockRead(push_promise, 1),
+ CreateMockRead(push_headers, 3),
+ CreateMockRead(resp1, 4),
+ CreateMockRead(body1, 5),
+ CreateMockRead(resp2, 7),
+ CreateMockRead(body2, 8),
+ MockRead(ASYNC, 0, 9)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ // Run first request. This reads PUSH_PROMISE.
+ helper.RunDefaultTest();
+
+ // Request the pushed resource.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session());
+ HttpRequestInfo request = CreateGetPushRequest();
+ TestCompletionCallback callback;
+ int rv = trans.Start(&request, callback.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+ rv = callback.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(response->was_fetched_via_spdy);
+ EXPECT_TRUE(response->was_alpn_negotiated);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string value;
+ EXPECT_FALSE(response->headers->GetNormalizedHeader("foo", &value));
+ std::string result;
+ ReadResult(&trans, &result);
+ EXPECT_EQ("hello!", result);
+
+ // Read EOF.
+ base::RunLoop().RunUntilIdle();
+
+ helper.VerifyDataConsumed();
+}
+
TEST_F(SpdyNetworkTransactionTest, ServerPushBeforeHeaders) {
SpdySerializedFrame stream1_syn(
spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
@@ -2780,15 +2935,13 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidUrl) {
// Can't use ConstructSpdyPush here since it wants to parse a URL and
// split it into the appropriate :header pieces. So we have to hand-fill
// those pieces in.
- SpdyFramer response_spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
SpdyHeaderBlock push_promise_header_block;
push_promise_header_block[kHttp2AuthorityHeader] = "";
push_promise_header_block[kHttp2SchemeHeader] = "";
push_promise_header_block[kHttp2PathHeader] = "/index.html";
- SpdyPushPromiseIR push_promise(1, 2, std::move(push_promise_header_block));
- SpdySerializedFrame push_promise_frame(
- response_spdy_framer.SerializeFrame(push_promise));
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
SpdySerializedFrame stream2_rst(
spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
@@ -2796,7 +2949,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidUrl) {
MockWrite writes[] = {CreateMockWrite(req, 0),
CreateMockWrite(stream2_rst, 2)};
MockRead reads[] = {
- CreateMockRead(push_promise_frame, 1), MockRead(ASYNC, 0, 3) /* EOF */
+ CreateMockRead(push_promise, 1), MockRead(ASYNC, 0, 3) /* EOF */
};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
RunBrokenPushTest(&data, ERR_CONNECTION_CLOSED);
@@ -2861,8 +3014,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushNoURL) {
SpdyHeaderBlock incomplete_headers;
incomplete_headers[kHttp2StatusHeader] = "200 OK";
incomplete_headers["hello"] = "bye";
- SpdySerializedFrame stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
- std::move(incomplete_headers), 2, 1));
+ SpdySerializedFrame stream2_syn(
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(incomplete_headers)));
MockRead reads[] = {
CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
CreateMockRead(stream1_body, 4),
@@ -2957,15 +3110,14 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) {
SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
2, ERROR_CODE_PROTOCOL_ERROR,
"Received pushed stream id 4 on invalid stream id 2 (must be odd)."));
- MockWrite writes[] = {
- CreateMockWrite(stream1_syn, 0), CreateMockWrite(stream2_priority, 3),
- CreateMockWrite(goaway, 8),
- };
+ MockWrite writes[] = {CreateMockWrite(stream1_syn, 0),
+ CreateMockWrite(stream2_priority, 3),
+ CreateMockWrite(goaway, 8)};
- SpdySerializedFrame stream1_reply(
- spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
+ SpdySerializedFrame stream1_reply(
+ spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
const char kPushedData[] = "pushed";
SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
@@ -2974,10 +3126,9 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) {
nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str()));
MockRead reads[] = {
- CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2),
+ CreateMockRead(stream2_syn, 1), CreateMockRead(stream1_reply, 2),
CreateMockRead(stream1_body, 4), CreateMockRead(stream2_body, 5),
- MockRead(ASYNC, ERR_IO_PENDING, 6), CreateMockRead(stream3_syn, 7),
- };
+ MockRead(ASYNC, ERR_IO_PENDING, 6), CreateMockRead(stream3_syn, 7)};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
@@ -3013,6 +3164,216 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) {
EXPECT_TRUE(data.AllWriteDataConsumed());
}
+TEST_F(SpdyNetworkTransactionTest, ServerCancelsPush) {
+ SpdySerializedFrame req1(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ spdy_util_.UpdateWithStreamDestruction(1);
+ SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(
+ GetDefaultUrlWithPath("/foo.dat").c_str(), 3, LOWEST));
+ MockWrite writes1[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 3),
+ CreateMockWrite(req2, 6)};
+
+ SpdySerializedFrame reply1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
+ nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
+ SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
+ SpdySerializedFrame rst(
+ spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_INTERNAL_ERROR));
+ SpdySerializedFrame reply2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
+ SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
+ MockRead reads1[] = {CreateMockRead(reply1, 1), CreateMockRead(push, 2),
+ CreateMockRead(body1, 4), CreateMockRead(rst, 5),
+ CreateMockRead(reply2, 7), CreateMockRead(body2, 8),
+ MockRead(ASYNC, 0, 9)};
+
+ SequencedSocketData data(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ // First request opens up connection.
+ HttpNetworkTransaction* trans1 = helper.trans();
+ TestCompletionCallback callback1;
+ int rv = trans1->Start(&request_, callback1.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Read until response body arrives. PUSH_PROMISE comes earlier.
+ rv = callback1.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+ const HttpResponseInfo* response = trans1->GetResponseInfo();
+ EXPECT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string result1;
+ ReadResult(trans1, &result1);
+ EXPECT_EQ("hello!", result1);
+
+ SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+ SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ base::WeakPtr<SpdySession> spdy_session =
+ spdy_session_pool->FindAvailableSession(
+ key, /* enable_ip_based_pooling = */ true, log_);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
+
+ // Create request matching pushed stream.
+ HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
+ HttpRequestInfo request2 = CreateGetPushRequest();
+ TestCompletionCallback callback2;
+ rv = trans2.Start(&request2, callback2.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Pushed stream is now claimed by second request.
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
+
+ // Second request receives RST_STREAM and is retried on the same connection.
+ rv = callback2.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+ response = trans2.GetResponseInfo();
+ EXPECT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string result2;
+ ReadResult(&trans2, &result2);
+ EXPECT_EQ("hello!", result2);
+
+ // Read EOF.
+ base::RunLoop().RunUntilIdle();
+
+ helper.VerifyDataConsumed();
+}
+
+// Regression test for https://crbug.com/776415.
+// A client-initiated request can only pool to an existing HTTP/2 connection if
+// the IP address matches. However, a resource can be pushed by the server on a
+// connection even if the IP address does not match. This test verifies that if
+// the request binds to such a pushed stream, and after that the server resets
+// the stream before SpdySession::GetPushedStream() is called, then the retry
+// (using a client-initiated stream) does not pool to this connection.
+TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) {
+ const char* kUrl1 = "https://www.example.org";
+ const char* kUrl2 = "https://mail.example.org";
+
+ auto resolver = std::make_unique<MockHostResolver>();
+ resolver->rules()->ClearRules();
+ resolver->rules()->AddRule("www.example.org", "127.0.0.1");
+ resolver->rules()->AddRule("mail.example.org", "127.0.0.2");
+
+ auto session_deps = std::make_unique<SpdySessionDependencies>();
+ session_deps->host_resolver = std::move(resolver);
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
+ std::move(session_deps));
+
+ SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(kUrl1, 1, LOWEST));
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ MockWrite writes1[] = {CreateMockWrite(req1, 0),
+ CreateMockWrite(priority, 3)};
+
+ SpdySerializedFrame reply1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame push(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kUrl2));
+ SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
+ SpdySerializedFrame rst(
+ spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_INTERNAL_ERROR));
+ MockRead reads1[] = {
+ CreateMockRead(reply1, 1), CreateMockRead(push, 2),
+ CreateMockRead(body1, 4), CreateMockRead(rst, 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7)};
+
+ SequencedSocketData data1(reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+
+ SpdyTestUtil spdy_util2;
+ SpdySerializedFrame req2(spdy_util2.ConstructSpdyGet(kUrl2, 1, LOWEST));
+ MockWrite writes2[] = {CreateMockWrite(req2, 0)};
+
+ SpdySerializedFrame reply2(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
+ base::StringPiece kData("Response on the second connection.");
+ SpdySerializedFrame body2(
+ spdy_util2.ConstructSpdyDataFrame(1, kData.data(), kData.size(), true));
+ MockRead reads2[] = {CreateMockRead(reply2, 1), CreateMockRead(body2, 2),
+ MockRead(ASYNC, 0, 3)};
+
+ SequencedSocketData data2(reads2, arraysize(reads2), writes2,
+ arraysize(writes2));
+
+ helper.RunPreTestSetup();
+ helper.AddData(&data1);
+ helper.AddData(&data2);
+
+ // First request opens up connection to www.example.org.
+ HttpNetworkTransaction* trans1 = helper.trans();
+ HttpRequestInfo request1;
+ request1.method = "GET";
+ request1.url = GURL(kUrl1);
+ TestCompletionCallback callback1;
+ int rv = trans1->Start(&request1, callback1.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Read until response body arrives. PUSH_PROMISE comes earlier.
+ rv = callback1.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+ const HttpResponseInfo* response = trans1->GetResponseInfo();
+ EXPECT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string result1;
+ ReadResult(trans1, &result1);
+ EXPECT_EQ("hello!", result1);
+
+ SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool();
+ SpdySessionKey key1(HostPortPair::FromURL(GURL(kUrl1)), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ base::WeakPtr<SpdySession> spdy_session1 =
+ spdy_session_pool->FindAvailableSession(
+ key1, /* enable_ip_based_pooling = */ true, log_);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1));
+
+ // While cross-origin push for kUrl2 is allowed on spdy_session1,
+ // a client-initiated request would not pool to this connection,
+ // because the IP address does not match.
+ SpdySessionKey key2(HostPortPair::FromURL(GURL(kUrl2)), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ EXPECT_FALSE(spdy_session_pool->FindAvailableSession(
+ key2, /* enable_ip_based_pooling = */ true, log_));
+
+ // Create request matching pushed stream.
+ HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
+ HttpRequestInfo request2;
+ request2.method = "GET";
+ request2.url = GURL(kUrl2);
+ TestCompletionCallback callback2;
+ rv = trans2.Start(&request2, callback2.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Pushed stream is now claimed by second request.
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session1));
+
+ // Second request receives RST_STREAM and is retried on a new connection.
+ rv = callback2.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+ response = trans2.GetResponseInfo();
+ EXPECT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ std::string result2;
+ ReadResult(&trans2, &result2);
+ EXPECT_EQ("Response on the second connection.", result2);
+
+ // Make sure that the first connection is still open. This is important in
+ // order to test that the retry created its own connection (because the IP
+ // address does not match), instead of using the connection of the cancelled
+ // pushed stream.
+ EXPECT_TRUE(spdy_session1);
+
+ // Read EOF.
+ data1.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ helper.VerifyDataConsumed();
+}
+
// Regression test for https://crbug.com/727653.
TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) {
SpdySerializedFrame req(
@@ -3024,16 +3385,15 @@ TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) {
SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
SpdyHeaderBlock push_promise_header_block;
- spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat").c_str(),
+ spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
&push_promise_header_block);
- SpdyPushPromiseIR push_promise(1, 2, std::move(push_promise_header_block));
- SpdySerializedFrame push_promise_frame(
- spdy_util_.SerializeFrame(push_promise));
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
- MockRead reads[] = {
- CreateMockRead(reply, 1), CreateMockRead(push_promise_frame, 2),
- CreateMockRead(body, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
+ MockRead reads[] = {CreateMockRead(reply, 1), CreateMockRead(push_promise, 2),
+ CreateMockRead(body, 4),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
@@ -3052,16 +3412,15 @@ TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithInvalidMethod) {
SpdyHeaderBlock push_promise_header_block;
push_promise_header_block[":method"] = "POST";
- spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat").c_str(),
+ spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
&push_promise_header_block);
- SpdyPushPromiseIR push_promise(1, 2, std::move(push_promise_header_block));
- SpdySerializedFrame push_promise_frame(
- spdy_util_.SerializeFrame(push_promise));
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
- MockRead reads[] = {
- CreateMockRead(reply, 1), CreateMockRead(push_promise_frame, 2),
- CreateMockRead(body, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
+ MockRead reads[] = {CreateMockRead(reply, 1), CreateMockRead(push_promise, 2),
+ CreateMockRead(body, 4),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5)};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
@@ -4607,8 +4966,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
initial_headers[":method"] = "GET";
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
&initial_headers);
- SpdySerializedFrame stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
- std::move(initial_headers), 2, 1));
+ SpdySerializedFrame stream2_syn(
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(initial_headers)));
SpdyHeaderBlock late_headers;
late_headers[kHttp2StatusHeader] = "200";
@@ -4666,8 +5025,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
initial_headers[":method"] = "GET";
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
&initial_headers);
- SpdySerializedFrame stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
- std::move(initial_headers), 2, 1));
+ SpdySerializedFrame stream2_syn(
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(initial_headers)));
SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
SpdyHeaderBlock late_headers;
late_headers[kHttp2StatusHeader] = "200";
@@ -4973,9 +5332,9 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) {
spdy_session_pool->FindAvailableSession(
key, /* enable_ip_based_pooling = */ true, log_);
- EXPECT_EQ(1u, spdy_session->unclaimed_pushed_streams_.size());
- EXPECT_EQ(1u,
- spdy_session->unclaimed_pushed_streams_.count(GURL(url_to_push)));
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
+ EXPECT_TRUE(
+ has_unclaimed_pushed_stream_for_url(spdy_session, GURL(url_to_push)));
HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session());
HttpRequestInfo push_request;
@@ -4986,7 +5345,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) {
rv = callback1.GetResult(rv);
EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(spdy_session->unclaimed_pushed_streams_.empty());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
HttpResponseInfo response = *trans0->GetResponseInfo();
EXPECT_TRUE(response.headers);
@@ -5113,7 +5472,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) {
spdy_session_pool->FindAvailableSession(
key0, /* enable_ip_based_pooling = */ true, log_);
- EXPECT_TRUE(spdy_session0->unclaimed_pushed_streams_.empty());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session0));
HostPortPair host_port_pair1("docs.example.org", 443);
SpdySessionKey key1(host_port_pair1, ProxyServer::Direct(),
@@ -5122,9 +5481,9 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) {
spdy_session_pool->FindAvailableSession(
key1, /* enable_ip_based_pooling = */ true, log_);
- EXPECT_EQ(1u, spdy_session1->unclaimed_pushed_streams_.size());
- EXPECT_EQ(1u,
- spdy_session1->unclaimed_pushed_streams_.count(GURL(url_to_push)));
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1));
+ EXPECT_TRUE(
+ has_unclaimed_pushed_stream_for_url(spdy_session1, GURL(url_to_push)));
// Request |url_to_push|, which should be served from the pushed resource.
HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session());
@@ -5136,8 +5495,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) {
rv = callback2.GetResult(rv);
EXPECT_THAT(rv, IsOk());
- EXPECT_TRUE(spdy_session0->unclaimed_pushed_streams_.empty());
- EXPECT_TRUE(spdy_session1->unclaimed_pushed_streams_.empty());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session0));
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session1));
HttpResponseInfo response0 = *trans0->GetResponseInfo();
EXPECT_TRUE(response0.headers);
@@ -6160,7 +6519,7 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) {
SpdyHeaderBlock push_headers;
spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat", &push_headers);
SpdySerializedFrame push(
- spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 3, 1));
+ spdy_util_.ConstructSpdyPushPromise(1, 3, std::move(push_headers)));
MockRead reads[] = {CreateMockRead(push, 1)};
SpdySerializedFrame req(
@@ -6186,8 +6545,8 @@ TEST_F(SpdyNetworkTransactionTest,
SpdyHeaderBlock push_b_headers;
spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/b.dat"),
&push_b_headers);
- SpdySerializedFrame push_b(spdy_util_.ConstructInitialSpdyPushFrame(
- std::move(push_b_headers), 2, 1));
+ SpdySerializedFrame push_b(
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_b_headers)));
MockRead reads[] = {
CreateMockRead(push_a, 1), CreateMockRead(push_b, 3),
};
@@ -6559,4 +6918,101 @@ TEST_F(SpdyNetworkTransactionTest, RequestHeadersCallback) {
EXPECT_TRUE(raw_headers.request_line().empty());
}
+// A request that has adopted a push promise and later got reset by the server
+// should be retried on a new stream.
+// Regression test for https://crbug.com/798508.
+TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) {
+ const char pushed_url[] = "https://www.example.org/a.dat";
+ // Construct a request to the default URL on stream 1.
+ SpdySerializedFrame req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
+ SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(pushed_url, 3, LOWEST));
+ // Construct a priority frame for stream 2.
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
+ CreateMockWrite(req2, 6)};
+
+ // Construct a Push Promise frame, with no response.
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, spdy_util_.ConstructGetHeaderBlock(pushed_url)));
+ // Construct a RST frame, canceling stream 2.
+ SpdySerializedFrame rst_server(
+ spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_CANCEL));
+ // Construct response headers and bodies.
+ SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
+ SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
+ SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
+ MockRead reads[] = {
+ CreateMockRead(push_promise, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
+ CreateMockRead(rst_server, 4), MockRead(ASYNC, ERR_IO_PENDING, 5),
+ CreateMockRead(resp1, 7), CreateMockRead(body1, 8),
+ CreateMockRead(resp2, 9), CreateMockRead(body2, 10),
+ MockRead(ASYNC, 0, 11)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ HttpNetworkTransaction* trans = helper.trans();
+
+ // First request to start the connection.
+ TestCompletionCallback callback1;
+ int rv = trans->Start(&request_, callback1.callback(), log_);
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ data.RunUntilPaused();
+
+ // Get a SpdySession.
+ SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ HttpNetworkSession* session = helper.session();
+ base::WeakPtr<SpdySession> spdy_session =
+ session->spdy_session_pool()->FindAvailableSession(
+ key, /* enable_ip_based_pooling = */ true, log_);
+
+ // Verify that there is one unclaimed push stream.
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session));
+
+ // Claim the pushed stream.
+ HttpNetworkTransaction transaction2(DEFAULT_PRIORITY, session);
+ TestCompletionCallback callback2;
+ HttpRequestInfo request2;
+ request2.method = "GET";
+ request2.url = GURL(pushed_url);
+ transaction2.Start(&request2, callback2.callback(), log_);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3u, spdy_stream_hi_water_mark(spdy_session));
+
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
+
+ // Continue reading and get the RST.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ // Make sure we got the RST and retried the request.
+ EXPECT_EQ(2u, num_active_streams(spdy_session));
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session));
+ EXPECT_EQ(5u, spdy_stream_hi_water_mark(spdy_session));
+
+ data.Resume();
+
+ // Test that transactions succeeded.
+ rv = callback1.WaitForResult();
+ ASSERT_THAT(rv, IsOk());
+
+ rv = callback2.WaitForResult();
+ ASSERT_THAT(rv, IsOk());
+
+ // Read EOF.
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that all data was read and written.
+ helper.VerifyDataConsumed();
+}
+
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc b/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc
index fb1168aa059..e23640ca3f3 100644
--- a/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc
+++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc
@@ -26,6 +26,7 @@
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
#include "net/spdy/chromium/spdy_http_utils.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
@@ -189,6 +190,11 @@ int64_t SpdyProxyClientSocket::GetTotalReceivedBytes() const {
return 0;
}
+void SpdyProxyClientSocket::ApplySocketTag(const SocketTag& tag) {
+ // Underlying SpdySession can be tagged, but |spdy_stream_| cannot.
+ CHECK(false);
+}
+
int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
DCHECK(read_callback_.is_null());
@@ -219,8 +225,11 @@ size_t SpdyProxyClientSocket::PopulateUserReadBuffer(char* data, size_t len) {
return read_buffer_queue_.Dequeue(data, len);
}
-int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len,
- const CompletionCallback& callback) {
+int SpdyProxyClientSocket::Write(
+ IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(write_callback_.is_null());
if (next_state_ != STATE_OPEN)
return ERR_SOCKET_NOT_CONNECTED;
diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket.h b/chromium/net/spdy/chromium/spdy_proxy_client_socket.h
index 60c095a9962..d95589dc7a2 100644
--- a/chromium/net/spdy/chromium/spdy_proxy_client_socket.h
+++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket.h
@@ -31,6 +31,7 @@
#include "net/spdy/chromium/spdy_stream.h"
#include "net/spdy/core/spdy_protocol.h"
#include "net/spdy/platform/api/spdy_string.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -78,6 +79,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
void ClearConnectionAttempts() override {}
void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
int64_t GetTotalReceivedBytes() const override;
+ void ApplySocketTag(const SocketTag& tag) override;
// Socket implementation.
int Read(IOBuffer* buf,
@@ -85,7 +87,8 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
const CompletionCallback& callback) override;
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int GetPeerAddress(IPEndPoint* address) const override;
diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc
index df25f48c75b..e8eccf49e0e 100644
--- a/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc
@@ -33,6 +33,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -286,8 +287,8 @@ void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
int len,
int rv) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
- EXPECT_EQ(rv,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ EXPECT_EQ(rv, sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
}
void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
@@ -590,7 +591,8 @@ TEST_F(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
big_data.length()));
EXPECT_EQ(ERR_IO_PENDING,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
}
@@ -1055,7 +1057,8 @@ TEST_F(SpdyProxyClientSocketTest, WriteOnClosedStream) {
ResumeAndRun();
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
- sock_->Write(buf.get(), buf->size(), CompletionCallback()));
+ sock_->Write(buf.get(), buf->size(), CompletionCallback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
}
// Calling Write() on a disconnected socket is an error.
@@ -1081,7 +1084,8 @@ TEST_F(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
- sock_->Write(buf.get(), buf->size(), CompletionCallback()));
+ sock_->Write(buf.get(), buf->size(), CompletionCallback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
// Let the RST_STREAM write while |rst| is in-scope.
base::RunLoop().RunUntilIdle();
@@ -1109,7 +1113,8 @@ TEST_F(SpdyProxyClientSocketTest, WritePendingOnClose) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_IO_PENDING,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
// Make sure the write actually starts.
base::RunLoop().RunUntilIdle();
@@ -1141,7 +1146,8 @@ TEST_F(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
EXPECT_EQ(ERR_IO_PENDING,
- sock_->Write(buf.get(), buf->size(), write_callback_.callback()));
+ sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
sock_->Disconnect();
@@ -1213,10 +1219,9 @@ TEST_F(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
- EXPECT_EQ(
- ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(), write_buf->size(), write_callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf.get(), write_buf->size(),
+ write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
ResumeAndRun();
@@ -1299,7 +1304,7 @@ class DeleteSockCallback : public TestCompletionCallbackBase {
callback_(base::Bind(&DeleteSockCallback::OnComplete,
base::Unretained(this))) {}
- ~DeleteSockCallback() override {}
+ ~DeleteSockCallback() override = default;
const CompletionCallback& callback() const { return callback_; }
@@ -1345,10 +1350,9 @@ TEST_F(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
- EXPECT_EQ(
- ERR_IO_PENDING,
- sock_->Write(
- write_buf.get(), write_buf->size(), write_callback_.callback()));
+ EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf.get(), write_buf->size(),
+ write_callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS));
ResumeAndRun();
diff --git a/chromium/net/spdy/chromium/spdy_session.cc b/chromium/net/spdy/chromium/spdy_session.cc
index 420ec31090b..682dde85439 100644
--- a/chromium/net/spdy/chromium/spdy_session.cc
+++ b/chromium/net/spdy/chromium/spdy_session.cc
@@ -13,8 +13,8 @@
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -57,6 +57,7 @@
#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_connection_status_flags.h"
+#include "url/url_constants.h"
namespace net {
@@ -746,7 +747,6 @@ SpdySession::SpdySession(
transport_security_state_(transport_security_state),
stream_hi_water_mark_(kFirstStreamId),
last_accepted_push_stream_id_(0),
- unclaimed_pushed_streams_(this),
push_delegate_(push_delegate),
num_pushed_streams_(0u),
num_active_pushed_streams_(0u),
@@ -818,20 +818,35 @@ SpdySession::~SpdySession() {
net_log_.EndEvent(NetLogEventType::HTTP2_SESSION);
}
-int SpdySession::GetPushStream(const GURL& url,
- RequestPriority priority,
- SpdyStream** stream,
- const NetLogWithSource& stream_net_log) {
+int SpdySession::GetPushedStream(const GURL& url,
+ SpdyStreamId pushed_stream_id,
+ RequestPriority priority,
+ SpdyStream** stream,
+ const NetLogWithSource& stream_net_log) {
CHECK(!in_io_loop_);
+ // |pushed_stream_id| must be valid.
+ DCHECK_NE(pushed_stream_id, kNoPushedStreamFound);
+ // |pushed_stream_id| must already have been claimed.
+ DCHECK_NE(pushed_stream_id,
+ pool_->push_promise_index()->FindStream(url, this));
if (availability_state_ == STATE_DRAINING) {
*stream = nullptr;
return ERR_CONNECTION_CLOSED;
}
- *stream = GetActivePushStream(url);
- if (!*stream)
- return OK;
+ ActiveStreamMap::iterator active_it = active_streams_.find(pushed_stream_id);
+ if (active_it == active_streams_.end()) {
+ // A previously claimed pushed stream might not be available, for example,
+ // if the server has reset it in the meanwhile.
+ return ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE;
+ }
+
+ net_log_.AddEvent(
+ NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM,
+ base::Bind(&NetLogSpdyAdoptedPushStreamCallback, pushed_stream_id, &url));
+
+ *stream = active_it->second;
DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_);
streams_pushed_and_claimed_count_++;
@@ -857,12 +872,11 @@ int SpdySession::GetPushStream(const GURL& url,
}
void SpdySession::CancelPush(const GURL& url) {
- UnclaimedPushedStreamContainer::const_iterator unclaimed_it =
- unclaimed_pushed_streams_.find(url);
- if (unclaimed_it == unclaimed_pushed_streams_.end())
+ const SpdyStreamId stream_id =
+ pool_->push_promise_index()->FindStream(url, this);
+ if (stream_id == kNoPushedStreamFound)
return;
- const SpdyStreamId stream_id = unclaimed_it->second;
DCHECK(active_streams_.find(stream_id) != active_streams_.end());
ResetStream(stream_id, ERROR_CODE_CANCEL, "Cancelled push stream.");
}
@@ -912,7 +926,7 @@ void SpdySession::InitializeWithSocket(
READ_STATE_DO_READ, OK));
}
-bool SpdySession::VerifyDomainAuthentication(const SpdyString& domain) {
+bool SpdySession::VerifyDomainAuthentication(const SpdyString& domain) const {
if (availability_state_ == STATE_DRAINING)
return false;
@@ -1254,7 +1268,7 @@ std::unique_ptr<base::Value> SpdySession::GetInfoAsValue() const {
dict->SetInteger("active_streams", active_streams_.size());
dict->SetInteger("unclaimed_pushed_streams",
- unclaimed_pushed_streams_.size());
+ pool_->push_promise_index()->CountStreamsForSession(this));
dict->SetString(
"negotiated_protocol",
@@ -1289,15 +1303,6 @@ bool SpdySession::GetLoadTimingInfo(SpdyStreamId stream_id,
load_timing_info);
}
-size_t SpdySession::num_unclaimed_pushed_streams() const {
- return unclaimed_pushed_streams_.size();
-}
-
-size_t SpdySession::count_unclaimed_pushed_streams_for_url(
- const GURL& url) const {
- return unclaimed_pushed_streams_.count(url);
-}
-
int SpdySession::GetPeerAddress(IPEndPoint* address) const {
if (connection_->socket())
return connection_->socket()->GetPeerAddress(address);
@@ -1352,6 +1357,48 @@ bool SpdySession::CloseOneIdleConnection() {
return false;
}
+bool SpdySession::ValidatePushedStream(SpdyStreamId stream_id,
+ const GURL& url,
+ const HttpRequestInfo& request_info,
+ const SpdySessionKey& key) const {
+ // Proxy server and privacy mode must match.
+ if (key.proxy_server() != spdy_session_key_.proxy_server() ||
+ key.privacy_mode() != spdy_session_key_.privacy_mode()) {
+ return false;
+ }
+ // Certificate must match for encrypted schemes only.
+ if (url.SchemeIsCryptographic() &&
+ !VerifyDomainAuthentication(key.host_port_pair().host())) {
+ return false;
+ }
+
+ ActiveStreamMap::const_iterator stream_it = active_streams_.find(stream_id);
+ if (stream_it == active_streams_.end()) {
+ // Only active streams should be in Http2PushPromiseIndex.
+ NOTREACHED();
+ return false;
+ }
+ const SpdyHeaderBlock& request_headers = stream_it->second->request_headers();
+ SpdyHeaderBlock::const_iterator method_it =
+ request_headers.find(kHttp2MethodHeader);
+ if (method_it == request_headers.end()) {
+ // TryCreatePushStream() would have reset the stream if it had no method.
+ NOTREACHED();
+ return false;
+ }
+
+ // Request method must match.
+ if (request_info.method != method_it->second) {
+ return false;
+ }
+
+ return true;
+}
+
+base::WeakPtr<SpdySession> SpdySession::GetWeakPtrToSession() {
+ return GetWeakPtr();
+}
+
size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
bool* is_session_active) const {
// TODO(xunjieli): Include |pending_create_stream_queues_| when WeakPtr is
@@ -1366,7 +1413,6 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
SpdyEstimateMemoryUsage(spdy_session_key_) +
SpdyEstimateMemoryUsage(pooled_aliases_) +
SpdyEstimateMemoryUsage(active_streams_) +
- SpdyEstimateMemoryUsage(unclaimed_pushed_streams_) +
SpdyEstimateMemoryUsage(created_streams_) +
SpdyEstimateMemoryUsage(write_queue_) +
SpdyEstimateMemoryUsage(in_flight_write_) +
@@ -1376,55 +1422,6 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
SpdyEstimateMemoryUsage(priority_dependency_state_);
}
-SpdySession::UnclaimedPushedStreamContainer::UnclaimedPushedStreamContainer(
- SpdySession* spdy_session)
- : spdy_session_(spdy_session) {}
-SpdySession::UnclaimedPushedStreamContainer::~UnclaimedPushedStreamContainer() {
-}
-
-bool SpdySession::UnclaimedPushedStreamContainer::erase(const GURL& url) {
- const_iterator it = find(url);
- if (it == end())
- return false;
-
- erase(it);
- return true;
-}
-
-SpdySession::UnclaimedPushedStreamContainer::iterator
-SpdySession::UnclaimedPushedStreamContainer::erase(const_iterator it) {
- DCHECK(spdy_session_->pool_);
- DCHECK(it != end());
- // Only allow cross-origin push for secure resources.
- if (it->first.SchemeIsCryptographic()) {
- spdy_session_->pool_->push_promise_index()->UnregisterUnclaimedPushedStream(
- it->first, spdy_session_);
- }
- return streams_.erase(it);
-}
-
-bool SpdySession::UnclaimedPushedStreamContainer::insert(
- const GURL& url,
- SpdyStreamId stream_id) {
- DCHECK(spdy_session_->pool_);
- auto result = streams_.insert(std::make_pair(url, stream_id));
- if (!result.second) {
- // Only one pushed stream is allowed for each URL.
- return false;
- }
- // Only allow cross-origin push for https resources.
- if (url.SchemeIsCryptographic()) {
- spdy_session_->pool_->push_promise_index()->RegisterUnclaimedPushedStream(
- url, spdy_session_->GetWeakPtr());
- }
- return true;
-}
-
-size_t SpdySession::UnclaimedPushedStreamContainer::EstimateMemoryUsage()
- const {
- return SpdyEstimateMemoryUsage(streams_);
-}
-
// {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is
// being created in response to another being closed due to received data.
@@ -1627,6 +1624,12 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
}
DCHECK(gurl.is_valid());
+ if (!gurl.SchemeIs(url::kHttpScheme) && !gurl.SchemeIs(url::kHttpsScheme)) {
+ EnqueueResetStreamFrame(stream_id, request_priority,
+ ERROR_CODE_REFUSED_STREAM,
+ "Only http and https resources can be pushed.");
+ return;
+ }
// Cross-origin push validation.
GURL associated_url(associated_it->second->GetUrlFromHeaders());
@@ -1634,15 +1637,15 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
if (proxy_delegate_ &&
proxy_delegate_->IsTrustedSpdyProxy(
ProxyServer(ProxyServer::SCHEME_HTTPS, host_port_pair()))) {
- // Disallow pushing of HTTPS content by trusted proxy.
- if (gurl.SchemeIs("https")) {
+ if (!gurl.SchemeIs(url::kHttpScheme)) {
EnqueueResetStreamFrame(
stream_id, request_priority, ERROR_CODE_REFUSED_STREAM,
- "Cross origin HTTPS content from trusted proxy.");
+ "Only http scheme allowed for cross origin push by trusted proxy.");
return;
}
} else {
- if (!gurl.SchemeIs("https") || !associated_url.SchemeIs("https")) {
+ if (!gurl.SchemeIs(url::kHttpsScheme) ||
+ !associated_url.SchemeIs(url::kHttpsScheme)) {
EnqueueResetStreamFrame(
stream_id, request_priority, ERROR_CODE_REFUSED_STREAM,
"Both pushed URL and associated URL must have https scheme.");
@@ -1663,8 +1666,7 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
// "Promised requests MUST be cacheable and MUST be safe [...]" (RFC7540
// Section 8.2). Only cacheable safe request methods are GET and HEAD.
SpdyHeaderBlock::const_iterator it = headers.find(kHttp2MethodHeader);
- if (it == headers.end() ||
- (it->second.compare("GET") != 0 && it->second.compare("HEAD") != 0)) {
+ if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) {
EnqueueResetStreamFrame(stream_id, request_priority,
ERROR_CODE_REFUSED_STREAM,
"Inadequate request method.");
@@ -1672,7 +1674,8 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
}
// Insertion fails if there already is a pushed stream with the same path.
- if (!unclaimed_pushed_streams_.insert(gurl, stream_id)) {
+ if (!pool_->push_promise_index()->RegisterUnclaimedPushedStream(
+ gurl, stream_id, this)) {
EnqueueResetStreamFrame(stream_id, request_priority,
ERROR_CODE_REFUSED_STREAM,
"Duplicate pushed stream with url: " + gurl.spec());
@@ -1742,7 +1745,8 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
// push is hardly used. Write tests for this and fix this. (See
// http://crbug.com/261712 .)
if (owned_stream->type() == SPDY_PUSH_STREAM) {
- if (unclaimed_pushed_streams_.erase(owned_stream->url())) {
+ if (pool_->push_promise_index()->UnregisterUnclaimedPushedStream(
+ owned_stream->url(), owned_stream->stream_id(), this)) {
bytes_pushed_and_unclaimed_count_ += owned_stream->recv_bytes();
}
bytes_pushed_count_ += owned_stream->recv_bytes();
@@ -2417,28 +2421,6 @@ void SpdySession::DeleteStream(std::unique_ptr<SpdyStream> stream, int status) {
}
}
-SpdyStream* SpdySession::GetActivePushStream(const GURL& url) {
- UnclaimedPushedStreamContainer::const_iterator unclaimed_it =
- unclaimed_pushed_streams_.find(url);
- if (unclaimed_it == unclaimed_pushed_streams_.end())
- return nullptr;
-
- const SpdyStreamId stream_id = unclaimed_it->second;
- unclaimed_pushed_streams_.erase(unclaimed_it);
-
- ActiveStreamMap::iterator active_it = active_streams_.find(stream_id);
- if (active_it == active_streams_.end()) {
- NOTREACHED();
- return nullptr;
- }
-
- SpdyStream* stream = active_it->second;
- net_log_.AddEvent(
- NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM,
- base::Bind(&NetLogSpdyAdoptedPushStreamCallback, stream_id, &url));
- return stream;
-}
-
void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) {
UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyPing.RTT", duration,
base::TimeDelta::FromMilliseconds(1),
@@ -2493,7 +2475,7 @@ void SpdySession::DcheckDraining() const {
DcheckGoingAway();
DCHECK_EQ(availability_state_, STATE_DRAINING);
DCHECK(active_streams_.empty());
- DCHECK(unclaimed_pushed_streams_.empty());
+ DCHECK_EQ(0u, pool_->push_promise_index()->CountStreamsForSession(this));
}
void SpdySession::DoDrainSession(Error err, const SpdyString& description) {
@@ -2532,7 +2514,7 @@ void SpdySession::DoDrainSession(Error err, const SpdyString& description) {
NetLogEventType::HTTP2_SESSION_CLOSE,
base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err);
+ base::UmaHistogramSparse("Net.SpdySession.ClosedOnError", -err);
if (err == OK) {
// We ought to be going away already, as this is a graceful close.
@@ -2586,21 +2568,17 @@ void SpdySession::CancelPushedStreamIfUnclaimed(SpdyStreamId stream_id) {
if (active_it == active_streams_.end())
return;
- // Grab URL for faster lookup in unclaimed_pushed_streams_.
- const GURL& url = active_it->second->url();
- UnclaimedPushedStreamContainer::const_iterator unclaimed_it =
- unclaimed_pushed_streams_.find(url);
// Make sure to cancel the correct stream. It is possible that the pushed
// stream |stream_id| is already claimed, and another stream has been pushed
// for the same URL.
- if (unclaimed_it == unclaimed_pushed_streams_.end() ||
- unclaimed_it->second != stream_id) {
+ const GURL& url = active_it->second->url();
+ if (pool_->push_promise_index()->FindStream(url, this) != stream_id) {
return;
}
LogAbandonedActiveStream(active_it, ERR_TIMED_OUT);
// CloseActiveStreamIterator() will remove the stream from
- // |unclaimed_pushed_streams_|.
+ // |pool_->push_promise_index()|.
ResetStreamIterator(active_it, ERROR_CODE_REFUSED_STREAM,
"Stream not claimed.");
}
@@ -2676,9 +2654,13 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id,
return;
}
+ DCHECK(it->second);
CHECK_EQ(it->second->stream_id(), stream_id);
- if (error_code == ERROR_CODE_NO_ERROR) {
+ if (it->second->ShouldRetryRSTPushStream()) {
+ CloseActiveStreamIterator(it,
+ ERR_SPDY_CLAIMED_PUSHED_STREAM_RESET_BY_SERVER);
+ } else if (error_code == ERROR_CODE_NO_ERROR) {
CloseActiveStreamIterator(it, ERR_SPDY_RST_STREAM_NO_ERROR_RECEIVED);
} else if (error_code == ERROR_CODE_REFUSED_STREAM) {
CloseActiveStreamIterator(it, ERR_SPDY_SERVER_REFUSED_STREAM);
@@ -2713,7 +2695,8 @@ void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
net_log_.AddEvent(
NetLogEventType::HTTP2_SESSION_RECV_GOAWAY,
base::Bind(&NetLogSpdyRecvGoAwayCallback, last_accepted_stream_id,
- active_streams_.size(), unclaimed_pushed_streams_.size(),
+ active_streams_.size(),
+ pool_->push_promise_index()->CountStreamsForSession(this),
error_code, debug_data));
MakeUnavailable();
if (error_code == ERROR_CODE_HTTP_1_1_REQUIRED) {
@@ -2976,7 +2959,7 @@ void SpdySession::OnAltSvc(
if (origin.empty())
return;
const GURL gurl(origin);
- if (!gurl.SchemeIs("https"))
+ if (!gurl.SchemeIs(url::kHttpsScheme))
return;
SSLInfo ssl_info;
if (!GetSSLInfo(&ssl_info))
@@ -2993,7 +2976,7 @@ void SpdySession::OnAltSvc(
if (it == active_streams_.end())
return;
const GURL& gurl(it->second->url());
- if (!gurl.SchemeIs("https"))
+ if (!gurl.SchemeIs(url::kHttpsScheme))
return;
scheme_host_port = url::SchemeHostPort(gurl);
}
diff --git a/chromium/net/spdy/chromium/spdy_session.h b/chromium/net/spdy/chromium/spdy_session.h
index d90c2b9dd8c..dae7d2ae9fa 100644
--- a/chromium/net/spdy/chromium/spdy_session.h
+++ b/chromium/net/spdy/chromium/spdy_session.h
@@ -13,7 +13,6 @@
#include <set>
#include <vector>
-#include "base/compiler_specific.h"
#include "base/containers/circular_deque.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -234,7 +233,8 @@ class NET_EXPORT_PRIVATE SpdyStreamRequest {
class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
public SpdyFramerDebugVisitorInterface,
public MultiplexedSession,
- public HigherLayeredPool {
+ public HigherLayeredPool,
+ public Http2PushPromiseIndex::Delegate {
public:
// TODO(akalin): Use base::TickClock when it becomes available.
typedef base::TimeTicks (*TimeFunc)(void);
@@ -284,12 +284,22 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// reset). Returns an error (not ERR_IO_PENDING) otherwise, and
// resets |spdy_stream|.
//
+ // If |pushed_stream_id != kNoPushedStreamFound|, then the pushed stream with
+ // pushed_stream_id is used. An error is returned if that stream is not
+ // available.
+ //
+ // If |pushed_stream_id == kNoPushedStreamFound|, then any matching pushed
+ // stream that has not been claimed by another request can be used. This can
+ // happen, for example, with http scheme pushed streams, or if the pushed
+ // stream was received from the server in the meanwhile.
+ //
// If a stream was found and the stream is still open, the priority
// of that stream is updated to match |priority|.
- int GetPushStream(const GURL& url,
- RequestPriority priority,
- SpdyStream** spdy_stream,
- const NetLogWithSource& stream_net_log);
+ int GetPushedStream(const GURL& url,
+ SpdyStreamId pushed_stream_id,
+ RequestPriority priority,
+ SpdyStream** spdy_stream,
+ const NetLogWithSource& stream_net_log);
// Called when the pushed stream should be cancelled. If the pushed stream is
// not claimed and active, sends RST to the server to cancel the stream.
@@ -316,7 +326,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// TODO(wtc): rename this function and the Net.SpdyIPPoolDomainMatch
// histogram because this function does more than verifying domain
// authentication now.
- bool VerifyDomainAuthentication(const SpdyString& domain);
+ bool VerifyDomainAuthentication(const SpdyString& domain) const;
// Pushes the given producer into the write queue for
// |stream|. |stream| is guaranteed to be activated before the
@@ -446,29 +456,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
return !active_streams_.empty() || !created_streams_.empty();
}
- // Access to the number of active and pending streams. These are primarily
- // available for testing and diagnostics.
- size_t num_active_streams() const { return active_streams_.size(); }
- size_t num_unclaimed_pushed_streams() const;
- size_t num_created_streams() const { return created_streams_.size(); }
- size_t count_unclaimed_pushed_streams_for_url(const GURL& url) const;
-
- size_t num_pushed_streams() const { return num_pushed_streams_; }
- size_t num_active_pushed_streams() const {
- return num_active_pushed_streams_;
- }
-
- size_t pending_create_stream_queue_size(RequestPriority priority) const {
- DCHECK_GE(priority, MINIMUM_PRIORITY);
- DCHECK_LE(priority, MAXIMUM_PRIORITY);
- return pending_create_stream_queues_[priority].size();
- }
-
- // Returns the current |stream_initial_send_window_size_|.
- int32_t stream_initial_send_window_size() const {
- return stream_initial_send_window_size_;
- }
-
// Returns true if no stream in the session can send data due to
// session flow control.
bool IsSendStalled() const { return session_send_window_size_ == 0; }
@@ -493,12 +480,19 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// standards for TLS.
bool HasAcceptableTransportSecurity() const;
- // Must be used only by |pool_|.
+ // Must be used only by |pool_| (including |pool_.push_promise_index_|).
base::WeakPtr<SpdySession> GetWeakPtr();
// HigherLayeredPool implementation:
bool CloseOneIdleConnection() override;
+ // Http2PushPromiseIndex::Delegate implementation:
+ bool ValidatePushedStream(SpdyStreamId stream_id,
+ const GURL& url,
+ const HttpRequestInfo& request_info,
+ const SpdySessionKey& key) const override;
+ base::WeakPtr<SpdySession> GetWeakPtrToSession() override;
+
// Dumps memory allocation stats to |stats|. Sets |*is_session_active| to
// indicate whether session is active.
// |stats| can be assumed as being default initialized upon entry.
@@ -516,44 +510,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
friend class SpdyHttpStreamTest;
friend class SpdyNetworkTransactionTest;
friend class SpdyProxyClientSocketTest;
+ friend class SpdySessionPoolTest;
friend class SpdySessionTest;
friend class SpdyStreamRequest;
- // Allow tests to access our innards for testing purposes.
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, ClientPing);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, FailedPing);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, WaitingForWrongPing);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, CancelPushBeforeClaimed);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, CancelPushAfterSessionGoesAway);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, CancelPushAfterExpired);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, ClaimPushedStreamBeforeExpires);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, ProtocolNegotiation);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, AdjustRecvWindowSize);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, AdjustSendWindowSize);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, SessionFlowControlInactiveStream);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, SessionFlowControlPadding);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest,
- SessionFlowControlTooMuchDataTwoDataFrames);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest,
- StreamFlowControlTooMuchDataTwoDataFrames);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, SessionFlowControlNoReceiveLeaks);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, SessionFlowControlNoSendLeaks);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, SessionFlowControlEndToEnd);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, StreamIdSpaceExhausted);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, MaxConcurrentStreamsZero);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, UnstallRacesWithStreamCreation);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, GoAwayOnSessionFlowControlError);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest,
- RejectPushedStreamExceedingConcurrencyLimit);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, IgnoreReservedRemoteStreamsCount);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest,
- CancelReservedStreamOnHeadersReceived);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, RejectInvalidUnknownFrames);
- FRIEND_TEST_ALL_PREFIXES(SpdySessionPoolTest, IPAddressChanged);
- FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
- ServerPushValidCrossOrigin);
- FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
- ServerPushValidCrossOriginWithOpenSession);
FRIEND_TEST_ALL_PREFIXES(RecordPushedStreamHistogramTest, VaryResponseHeader);
using PendingStreamRequestQueue =
@@ -587,52 +547,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
WRITE_STATE_DO_WRITE_COMPLETE,
};
- // Container class for unclaimed pushed streams on a SpdySession. Guarantees
- // that |spdy_session_.pool_| gets notified every time a stream is pushed or
- // an unclaimed pushed stream is claimed.
- class UnclaimedPushedStreamContainer {
- public:
- using PushedStreamMap = std::map<GURL, SpdyStreamId>;
- using iterator = PushedStreamMap::iterator;
- using const_iterator = PushedStreamMap::const_iterator;
-
- UnclaimedPushedStreamContainer() = delete;
- explicit UnclaimedPushedStreamContainer(SpdySession* spdy_session);
- ~UnclaimedPushedStreamContainer();
-
- bool empty() const { return streams_.empty(); }
- size_t size() const { return streams_.size(); }
- const_iterator begin() const { return streams_.begin(); }
- const_iterator end() const { return streams_.end(); }
- const_iterator find(const GURL& url) const { return streams_.find(url); }
- size_t count(const GURL& url) const { return streams_.count(url); }
- const_iterator lower_bound(const GURL& url) const {
- return streams_.lower_bound(url);
- }
-
- // Return true if there was an element with |url|, which was then erased.
- bool erase(const GURL& url);
-
- // Return the iterator following |it|.
- iterator erase(const_iterator it);
-
- // Return true if there was not already an entry with |url|,
- // in which case the insertion was successful.
- bool insert(const GURL& url, SpdyStreamId stream_id) WARN_UNUSED_RESULT;
-
- size_t EstimateMemoryUsage() const;
-
- private:
- SpdySession* spdy_session_;
-
- // (Bijective) map from the URL to the ID of the streams that have
- // already started to be pushed by the server, but do not have
- // consumers yet. Contains a subset of |active_streams_|.
- PushedStreamMap streams_;
-
- DISALLOW_COPY_AND_ASSIGN(UnclaimedPushedStreamContainer);
- };
-
// Called by SpdyStreamRequest to start a request to create a
// stream. If OK is returned, then |stream| will be filled in with a
// valid stream. If ERR_IO_PENDING is returned, then
@@ -793,11 +707,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// that |stream| may hold the last reference to the session.
void DeleteStream(std::unique_ptr<SpdyStream> stream, int status);
- // Check if we have a pending pushed-stream for this url
- // Returns the stream if found (and returns it from the pending
- // list). Returns NULL otherwise.
- SpdyStream* GetActivePushStream(const GURL& url);
-
void RecordPingRTTHistogram(base::TimeDelta duration);
void RecordHistograms();
void RecordProtocolErrorHistogram(SpdyProtocolErrorDetails details);
@@ -950,30 +859,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// empty.
SpdyStreamId PopStreamToPossiblyResume();
- // --------------------------
- // Helper methods for testing
- // --------------------------
-
- void set_connection_at_risk_of_loss_time(base::TimeDelta duration) {
- connection_at_risk_of_loss_time_ = duration;
- }
-
- void set_hung_interval(base::TimeDelta duration) {
- hung_interval_ = duration;
- }
-
- void set_max_concurrent_pushed_streams(size_t value) {
- max_concurrent_pushed_streams_ = value;
- }
-
- int64_t pings_in_flight() const { return pings_in_flight_; }
-
- SpdyPingId next_ping_id() const { return next_ping_id_; }
-
- base::TimeTicks last_read_time() const { return last_read_time_; }
-
- bool check_ping_status_pending() const { return check_ping_status_pending_; }
-
// Whether Do{Read,Write}Loop() is in the call stack. Useful for
// making sure we don't destroy ourselves prematurely in that case.
bool in_io_loop_;
@@ -1020,8 +905,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// them?
ActiveStreamMap active_streams_;
- UnclaimedPushedStreamContainer unclaimed_pushed_streams_;
-
// Not owned. |push_delegate_| outlives the session and handles server pushes
// received by session.
ServerPushDelegate* push_delegate_;
diff --git a/chromium/net/spdy/chromium/spdy_session_key.cc b/chromium/net/spdy/chromium/spdy_session_key.cc
index 42e260c25e0..be206e5a9b3 100644
--- a/chromium/net/spdy/chromium/spdy_session_key.cc
+++ b/chromium/net/spdy/chromium/spdy_session_key.cc
@@ -12,8 +12,7 @@
namespace net {
-SpdySessionKey::SpdySessionKey() : privacy_mode_(PRIVACY_MODE_DISABLED) {
-}
+SpdySessionKey::SpdySessionKey() = default;
SpdySessionKey::SpdySessionKey(const HostPortPair& host_port_pair,
const ProxyServer& proxy_server,
@@ -25,18 +24,9 @@ SpdySessionKey::SpdySessionKey(const HostPortPair& host_port_pair,
<< ", privacy=" << privacy_mode;
}
-SpdySessionKey::SpdySessionKey(const HostPortProxyPair& host_port_proxy_pair,
- PrivacyMode privacy_mode)
- : host_port_proxy_pair_(host_port_proxy_pair),
- privacy_mode_(privacy_mode) {
- DVLOG(1) << "SpdySessionKey(hppp=" << host_port_proxy_pair.first.ToString()
- << "," << host_port_proxy_pair.second.ToURI()
- << ", privacy=" << privacy_mode;
-}
-
SpdySessionKey::SpdySessionKey(const SpdySessionKey& other) = default;
-SpdySessionKey::~SpdySessionKey() {}
+SpdySessionKey::~SpdySessionKey() = default;
bool SpdySessionKey::operator<(const SpdySessionKey& other) const {
return std::tie(privacy_mode_, host_port_proxy_pair_.first,
@@ -45,7 +35,7 @@ bool SpdySessionKey::operator<(const SpdySessionKey& other) const {
other.host_port_proxy_pair_.second);
}
-bool SpdySessionKey::Equals(const SpdySessionKey& other) const {
+bool SpdySessionKey::operator==(const SpdySessionKey& other) const {
return privacy_mode_ == other.privacy_mode_ &&
host_port_proxy_pair_.first.Equals(other.host_port_proxy_pair_.first) &&
host_port_proxy_pair_.second == other.host_port_proxy_pair_.second;
diff --git a/chromium/net/spdy/chromium/spdy_session_key.h b/chromium/net/spdy/chromium/spdy_session_key.h
index 7aa59a0c8bf..ef5ac192fac 100644
--- a/chromium/net/spdy/chromium/spdy_session_key.h
+++ b/chromium/net/spdy/chromium/spdy_session_key.h
@@ -19,10 +19,6 @@ class NET_EXPORT_PRIVATE SpdySessionKey {
const ProxyServer& proxy_server,
PrivacyMode privacy_mode);
- // Temporary hack for implicit copy constructor
- SpdySessionKey(const HostPortProxyPair& host_port_proxy_pair,
- PrivacyMode privacy_mode);
-
SpdySessionKey(const SpdySessionKey& other);
~SpdySessionKey();
@@ -30,8 +26,8 @@ class NET_EXPORT_PRIVATE SpdySessionKey {
// Comparator function so this can be placed in a std::map.
bool operator<(const SpdySessionKey& other) const;
- // Equality test of contents. (Probably another violation of style guide).
- bool Equals(const SpdySessionKey& other) const;
+ // Equality test of contents.
+ bool operator==(const SpdySessionKey& other) const;
const HostPortProxyPair& host_port_proxy_pair() const {
return host_port_proxy_pair_;
@@ -55,7 +51,7 @@ class NET_EXPORT_PRIVATE SpdySessionKey {
private:
HostPortProxyPair host_port_proxy_pair_;
// If enabled, then session cannot be tracked by the server.
- PrivacyMode privacy_mode_;
+ PrivacyMode privacy_mode_ = PRIVACY_MODE_DISABLED;
};
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_session_pool.cc b/chromium/net/spdy/chromium/spdy_session_pool.cc
index e0e7d35435a..312e581ac3f 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool.cc
+++ b/chromium/net/spdy/chromium/spdy_session_pool.cc
@@ -4,6 +4,7 @@
#include "net/spdy/chromium/spdy_session_pool.h"
+#include <algorithm>
#include <utility>
#include "base/logging.h"
@@ -13,6 +14,7 @@
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/trace_constants.h"
#include "net/http/http_network_session.h"
@@ -77,6 +79,8 @@ SpdySessionPool::SpdySessionPool(
SpdySessionPool::~SpdySessionPool() {
DCHECK(spdy_session_request_map_.empty());
+ // TODO(bnc): CloseAllSessions() is also called in HttpNetworkSession
+ // destructor, one of the two calls should be removed.
CloseAllSessions();
while (!sessions_.empty()) {
@@ -138,7 +142,7 @@ base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
const NetLogWithSource& net_log) {
AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key);
if (it != available_sessions_.end()) {
- if (key.Equals(it->second->spdy_session_key())) {
+ if (key == it->second->spdy_session_key()) {
UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING,
SPDY_SESSION_GET_MAX);
net_log.AddEvent(
@@ -270,7 +274,9 @@ void SpdySessionPool::CloseCurrentIdleSessions() {
}
void SpdySessionPool::CloseAllSessions() {
- while (!available_sessions_.empty()) {
+ auto is_draining = [](const SpdySession* s) { return s->IsDraining(); };
+ // Repeat until every SpdySession owned by |this| is draining.
+ while (!std::all_of(sessions_.begin(), sessions_.end(), is_draining)) {
CloseCurrentSessionsHelper(ERR_ABORTED, "Closing all sessions.",
false /* idle_only */);
}
@@ -286,7 +292,7 @@ std::unique_ptr<base::Value> SpdySessionPool::SpdySessionPoolInfoToValue()
// host_port_proxy_pair (not an alias).
const SpdySessionKey& key = it->first;
const SpdySessionKey& session_key = it->second->spdy_session_key();
- if (key.Equals(session_key))
+ if (key == session_key)
list->Append(it->second->GetInfoAsValue());
}
return std::move(list);
@@ -358,7 +364,8 @@ void SpdySessionPool::OnNewSpdySessionReady(
direct || request->url().SchemeIs(url::kHttpsScheme);
request->OnStreamReadyOnPooledConnection(
used_ssl_config, used_proxy_info,
- std::make_unique<SpdyHttpStream>(spdy_session, use_relative_url,
+ std::make_unique<SpdyHttpStream>(spdy_session, kNoPushedStreamFound,
+ use_relative_url,
source_dependency));
}
}
@@ -439,7 +446,8 @@ void SpdySessionPool::DumpMemoryStats(
num_active_sessions++;
}
total_size += SpdyEstimateMemoryUsage(ObtainHpackHuffmanTable()) +
- SpdyEstimateMemoryUsage(ObtainHpackStaticTable());
+ SpdyEstimateMemoryUsage(ObtainHpackStaticTable()) +
+ SpdyEstimateMemoryUsage(push_promise_index_);
base::trace_event::MemoryAllocatorDump* dump =
pmd->CreateAllocatorDump(SpdyStringPrintf(
"%s/spdy_session_pool", parent_dump_absolute_name.c_str()));
@@ -498,7 +506,7 @@ void SpdySessionPool::RemoveAliases(const SpdySessionKey& key) {
// Walk the aliases map, find references to this pair.
// TODO(mbelshe): Figure out if this is too expensive.
for (AliasMap::iterator it = aliases_.begin(); it != aliases_.end(); ) {
- if (it->second.Equals(key)) {
+ if (it->second == key) {
AliasMap::iterator old_it = it;
++it;
aliases_.erase(old_it);
@@ -521,16 +529,20 @@ void SpdySessionPool::CloseCurrentSessionsHelper(Error error,
const SpdyString& description,
bool idle_only) {
WeakSessionList current_sessions = GetCurrentSessions();
- for (WeakSessionList::const_iterator it = current_sessions.begin();
- it != current_sessions.end(); ++it) {
- if (!*it)
+ for (base::WeakPtr<SpdySession>& session : current_sessions) {
+ if (!session)
continue;
- if (idle_only && (*it)->is_active())
+ if (idle_only && session->is_active())
continue;
- (*it)->CloseSessionOnError(error, description);
- DCHECK(!IsSessionAvailable(*it));
+ if (session->IsDraining())
+ continue;
+
+ session->CloseSessionOnError(error, description);
+
+ DCHECK(!IsSessionAvailable(session));
+ DCHECK(!session || session->IsDraining());
}
}
diff --git a/chromium/net/spdy/chromium/spdy_session_pool.h b/chromium/net/spdy/chromium/spdy_session_pool.h
index 223b5ae5af3..09f3a826912 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool.h
+++ b/chromium/net/spdy/chromium/spdy_session_pool.h
@@ -111,6 +111,10 @@ class NET_EXPORT SpdySessionPool
void RemoveUnavailableSession(
const base::WeakPtr<SpdySession>& unavailable_session);
+ // Note that the next three methods close sessions, potentially notifing
+ // delegates of error or synchronously invoking callbacks, which might trigger
+ // retries, thus opening new sessions.
+
// Close only the currently existing SpdySessions with |error|.
// Let any new ones created while this method is running continue to
// live.
@@ -121,8 +125,9 @@ class NET_EXPORT SpdySessionPool
// live.
void CloseCurrentIdleSessions();
- // Close all SpdySessions, including any new ones created in the process of
- // closing the current ones.
+ // Repeatedly close all SpdySessions until all of them (including new ones
+ // created in the process of closing the current ones, and new ones created in
+ // the process of closing those new ones, etc.) are unavailable.
void CloseAllSessions();
// Creates a Value summary of the state of the spdy session pool.
diff --git a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
index 0d9cc49fa57..74169d9afff 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
@@ -13,6 +13,7 @@
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event_argument.h"
+#include "build/build_config.h"
#include "net/dns/host_cache.h"
#include "net/http/http_network_session.h"
#include "net/log/net_log_with_source.h"
@@ -66,6 +67,10 @@ class SpdySessionPoolTest : public ::testing::Test {
void RunIPPoolingTest(SpdyPoolCloseSessionsType close_sessions_type);
+ size_t num_active_streams(base::WeakPtr<SpdySession> session) {
+ return session->active_streams_.size();
+ }
+
SpdySessionDependencies session_deps_;
std::unique_ptr<HttpNetworkSession> http_session_;
SpdySessionPool* spdy_session_pool_;
@@ -80,7 +85,7 @@ class SessionOpeningDelegate : public SpdyStream::Delegate {
: spdy_session_pool_(spdy_session_pool),
key_(key) {}
- ~SessionOpeningDelegate() override {}
+ ~SessionOpeningDelegate() override = default;
void OnHeadersSent() override {}
@@ -778,7 +783,7 @@ TEST_F(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_TRUE(sessionC->IsDraining());
EXPECT_EQ(1u,
- sessionA->num_active_streams()); // Active stream is still active.
+ num_active_streams(sessionA)); // Active stream is still active.
EXPECT_FALSE(delegateA.StreamIsClosed());
EXPECT_TRUE(delegateB.StreamIsClosed()); // Created stream was closed.
@@ -802,6 +807,114 @@ TEST_F(SpdySessionPoolTest, IPAddressChanged) {
#endif // defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
}
+// Regression test for https://crbug.com/789791.
+TEST_F(SpdySessionPoolTest, HandleIPAddressChangeThenShutdown) {
+ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
+ SpdyTestUtil spdy_util;
+ SpdySerializedFrame req(spdy_util.ConstructSpdyGet(kDefaultUrl, 1, MEDIUM));
+ MockWrite writes[] = {CreateMockWrite(req, 1)};
+ StaticSocketDataProvider data(reads, arraysize(reads), writes,
+ arraysize(writes));
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+
+ const GURL url(kDefaultUrl);
+ SpdySessionKey key(HostPortPair::FromURL(url), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ base::WeakPtr<SpdySession> session =
+ CreateSpdySession(http_session_.get(), key, NetLogWithSource());
+
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_BIDIRECTIONAL_STREAM, session, url, MEDIUM, NetLogWithSource());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ SpdyHeaderBlock headers(spdy_util.ConstructGetHeaderBlock(url.spec()));
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(delegate.send_headers_completed());
+
+ spdy_session_pool_->OnIPAddressChanged();
+
+#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
+ EXPECT_EQ(1u, num_active_streams(session));
+ EXPECT_TRUE(session->IsGoingAway());
+ EXPECT_FALSE(session->IsDraining());
+#else
+ EXPECT_EQ(0u, num_active_streams(session));
+ EXPECT_FALSE(session->IsGoingAway());
+ EXPECT_TRUE(session->IsDraining());
+#endif // defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
+
+ http_session_.reset();
+
+ data.AllReadDataConsumed();
+ data.AllWriteDataConsumed();
+}
+
+// Regression test for https://crbug.com/789791.
+TEST_F(SpdySessionPoolTest, HandleGracefulGoawayThenShutdown) {
+ SpdyTestUtil spdy_util;
+ SpdySerializedFrame goaway(spdy_util.ConstructSpdyGoAway(
+ 0x7fffffff, ERROR_CODE_NO_ERROR, "Graceful shutdown."));
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
+ MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, OK, 4)};
+ SpdySerializedFrame req(spdy_util.ConstructSpdyGet(kDefaultUrl, 1, MEDIUM));
+ MockWrite writes[] = {CreateMockWrite(req, 0)};
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ data.set_connect_data(connect_data);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+
+ const GURL url(kDefaultUrl);
+ SpdySessionKey key(HostPortPair::FromURL(url), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ base::WeakPtr<SpdySession> session =
+ CreateSpdySession(http_session_.get(), key, NetLogWithSource());
+
+ base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
+ SPDY_BIDIRECTIONAL_STREAM, session, url, MEDIUM, NetLogWithSource());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ SpdyHeaderBlock headers(spdy_util.ConstructGetHeaderBlock(url.spec()));
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+
+ // Send headers.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(delegate.send_headers_completed());
+
+ EXPECT_EQ(1u, num_active_streams(session));
+ EXPECT_FALSE(session->IsGoingAway());
+ EXPECT_FALSE(session->IsDraining());
+
+ // Read GOAWAY.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1u, num_active_streams(session));
+ EXPECT_TRUE(session->IsGoingAway());
+ EXPECT_FALSE(session->IsDraining());
+
+ http_session_.reset();
+
+ data.AllReadDataConsumed();
+ data.AllWriteDataConsumed();
+}
+
class SpdySessionMemoryDumpTest
: public SpdySessionPoolTest,
public testing::WithParamInterface<
diff --git a/chromium/net/spdy/chromium/spdy_session_unittest.cc b/chromium/net/spdy/chromium/spdy_session_unittest.cc
index c4fb3dc94dd..60e54bc8ff2 100644
--- a/chromium/net/spdy/chromium/spdy_session_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_session_unittest.cc
@@ -22,6 +22,7 @@
#include "net/base/test_data_stream.h"
#include "net/base/test_proxy_delegate.h"
#include "net/cert/ct_policy_status.h"
+#include "net/http/http_request_info.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/log/test_net_log.h"
@@ -29,6 +30,7 @@
#include "net/log/test_net_log_util.h"
#include "net/proxy/proxy_server.h"
#include "net/socket/client_socket_pool_manager.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_http_utils.h"
#include "net/spdy/chromium/spdy_session_pool.h"
@@ -53,6 +55,7 @@ namespace {
const char kHttpURLFromAnotherOrigin[] = "http://www.example2.org/a.dat";
const char kHttpsURLFromAnotherOrigin[] = "https://www.example2.org/b.dat";
+const char kPushedUrl[] = "https://www.example.org/a.dat";
const char kBodyData[] = "Body data";
const size_t kBodyDataSize = arraysize(kBodyData);
@@ -175,14 +178,14 @@ class SpdySessionTest : public PlatformTest {
void StallSessionSend() {
// Reduce the send window size to 0 to stall.
- while (session_->session_send_window_size_ > 0) {
- session_->DecreaseSendWindowSize(std::min(
- kMaxSpdyFrameChunkSize, session_->session_send_window_size_));
+ while (session_send_window_size() > 0) {
+ DecreaseSendWindowSize(
+ std::min(kMaxSpdyFrameChunkSize, session_send_window_size()));
}
}
void UnstallSessionSend(int32_t delta_window_size) {
- session_->IncreaseSendWindowSize(delta_window_size);
+ IncreaseSendWindowSize(delta_window_size);
}
void StallStreamSend(SpdyStream* stream) {
@@ -201,6 +204,135 @@ class SpdySessionTest : public PlatformTest {
const base::Callback<void(SpdyStream*)>& stall_function,
const base::Callback<void(SpdyStream*, int32_t)>& unstall_function);
+ // SpdySession private methods.
+
+ void MaybeSendPrefacePing() { session_->MaybeSendPrefacePing(); }
+
+ void WritePingFrame(SpdyPingId unique_id, bool is_ack) {
+ session_->WritePingFrame(unique_id, is_ack);
+ }
+
+ void CheckPingStatus(base::TimeTicks last_check_time) {
+ session_->CheckPingStatus(last_check_time);
+ }
+
+ bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) {
+ return session_->OnUnknownFrame(stream_id, frame_type);
+ }
+
+ void IncreaseSendWindowSize(int delta_window_size) {
+ session_->IncreaseSendWindowSize(delta_window_size);
+ }
+
+ void DecreaseSendWindowSize(int32_t delta_window_size) {
+ session_->DecreaseSendWindowSize(delta_window_size);
+ }
+
+ void IncreaseRecvWindowSize(int delta_window_size) {
+ session_->IncreaseRecvWindowSize(delta_window_size);
+ }
+
+ void DecreaseRecvWindowSize(int32_t delta_window_size) {
+ session_->DecreaseRecvWindowSize(delta_window_size);
+ }
+
+ // Accessors for SpdySession private members.
+
+ void set_in_io_loop(bool in_io_loop) { session_->in_io_loop_ = in_io_loop; }
+
+ void set_stream_hi_water_mark(SpdyStreamId stream_hi_water_mark) {
+ session_->stream_hi_water_mark_ = stream_hi_water_mark;
+ }
+
+ void set_last_accepted_push_stream_id(
+ SpdyStreamId last_accepted_push_stream_id) {
+ session_->last_accepted_push_stream_id_ = last_accepted_push_stream_id;
+ }
+
+ size_t num_pushed_streams() { return session_->num_pushed_streams_; }
+
+ size_t num_active_pushed_streams() {
+ return session_->num_active_pushed_streams_;
+ }
+
+ size_t max_concurrent_streams() { return session_->max_concurrent_streams_; }
+
+ void set_max_concurrent_streams(size_t max_concurrent_streams) {
+ session_->max_concurrent_streams_ = max_concurrent_streams;
+ }
+
+ void set_max_concurrent_pushed_streams(size_t max_concurrent_pushed_streams) {
+ session_->max_concurrent_pushed_streams_ = max_concurrent_pushed_streams;
+ }
+
+ int64_t pings_in_flight() { return session_->pings_in_flight_; }
+
+ SpdyPingId next_ping_id() { return session_->next_ping_id_; }
+
+ base::TimeTicks last_read_time() { return session_->last_read_time_; }
+
+ void set_last_read_time(base::TimeTicks last_read_time) {
+ session_->last_read_time_ = last_read_time;
+ }
+
+ bool check_ping_status_pending() {
+ return session_->check_ping_status_pending_;
+ }
+
+ void set_check_ping_status_pending(bool check_ping_status_pending) {
+ session_->check_ping_status_pending_ = check_ping_status_pending;
+ }
+
+ int32_t session_send_window_size() {
+ return session_->session_send_window_size_;
+ }
+
+ int32_t session_recv_window_size() {
+ return session_->session_recv_window_size_;
+ }
+
+ void set_session_recv_window_size(int32_t session_recv_window_size) {
+ session_->session_recv_window_size_ = session_recv_window_size;
+ }
+
+ int32_t session_unacked_recv_window_bytes() {
+ return session_->session_unacked_recv_window_bytes_;
+ }
+
+ int32_t stream_initial_send_window_size() {
+ return session_->stream_initial_send_window_size_;
+ }
+
+ void set_connection_at_risk_of_loss_time(base::TimeDelta duration) {
+ session_->connection_at_risk_of_loss_time_ = duration;
+ }
+
+ void set_hung_interval(base::TimeDelta duration) {
+ session_->hung_interval_ = duration;
+ }
+
+ // Quantities derived from SpdySession private members.
+
+ size_t pending_create_stream_queue_size(RequestPriority priority) {
+ DCHECK_GE(priority, MINIMUM_PRIORITY);
+ DCHECK_LE(priority, MAXIMUM_PRIORITY);
+ return session_->pending_create_stream_queues_[priority].size();
+ }
+
+ size_t num_active_streams() { return session_->active_streams_.size(); }
+
+ size_t num_created_streams() { return session_->created_streams_.size(); }
+
+ size_t num_unclaimed_pushed_streams() {
+ return spdy_session_pool_->push_promise_index()->CountStreamsForSession(
+ session_.get());
+ }
+
+ bool has_unclaimed_pushed_stream_for_url(const GURL& url) {
+ return spdy_session_pool_->push_promise_index()->FindStream(
+ url, session_.get()) != kNoPushedStreamFound;
+ }
+
// Original socket limits. Some tests set these. Safest to always restore
// them once each test has been run.
int old_max_group_sockets_;
@@ -238,9 +370,9 @@ namespace {
// given SpdyStreamRequest.
class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
public:
- StreamRequestDestroyingCallback() {}
+ StreamRequestDestroyingCallback() = default;
- ~StreamRequestDestroyingCallback() override {}
+ ~StreamRequestDestroyingCallback() override = default;
void SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request) {
request_ = std::move(request);
@@ -892,24 +1024,23 @@ TEST_F(SpdySessionTest, ClientPing) {
base::TimeTicks before_ping_time = base::TimeTicks::Now();
- session_->set_connection_at_risk_of_loss_time(
- base::TimeDelta::FromSeconds(-1));
- session_->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
+ set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(-1));
+ set_hung_interval(base::TimeDelta::FromMilliseconds(50));
- session_->MaybeSendPrefacePing();
+ MaybeSendPrefacePing();
- EXPECT_EQ(1, session_->pings_in_flight());
- EXPECT_EQ(2u, session_->next_ping_id());
- EXPECT_TRUE(session_->check_ping_status_pending());
+ EXPECT_EQ(1, pings_in_flight());
+ EXPECT_EQ(2u, next_ping_id());
+ EXPECT_TRUE(check_ping_status_pending());
base::RunLoop().RunUntilIdle();
- session_->CheckPingStatus(before_ping_time);
+ CheckPingStatus(before_ping_time);
- EXPECT_EQ(0, session_->pings_in_flight());
- EXPECT_EQ(2u, session_->next_ping_id());
- EXPECT_FALSE(session_->check_ping_status_pending());
- EXPECT_GE(session_->last_read_time(), before_ping_time);
+ EXPECT_EQ(0, pings_in_flight());
+ EXPECT_EQ(2u, next_ping_id());
+ EXPECT_FALSE(check_ping_status_pending());
+ EXPECT_GE(last_read_time(), before_ping_time);
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -1050,9 +1181,9 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
CreateSpdySession();
// Fix stream_hi_water_mark_ to allow for two stream activations.
- session_->stream_hi_water_mark_ = kLastStreamId - 2;
+ set_stream_hi_water_mark(kLastStreamId - 2);
// Fix max_concurrent_streams to allow for three stream creations.
- session_->max_concurrent_streams_ = 3;
+ set_max_concurrent_streams(3);
// Create three streams synchronously, and begin a fourth (which is stalled).
base::WeakPtr<SpdyStream> stream1 =
@@ -1081,9 +1212,9 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
MEDIUM, NetLogWithSource(), callback4.callback()));
// Streams 1-3 were created. 4th is stalled. No streams are active yet.
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(3u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(3u, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
// Activate stream 1. One ID remains available.
stream1->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
@@ -1091,9 +1222,9 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(2u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(2u, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
// Activate stream 2. ID space is exhausted.
stream2->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
@@ -1102,14 +1233,14 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
// Active streams remain active.
EXPECT_EQ(kLastStreamId, stream2->stream_id());
- EXPECT_EQ(2u, session_->num_active_streams());
+ EXPECT_EQ(2u, num_active_streams());
// Session is going away. Created and stalled streams were aborted.
- EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session_->availability_state_);
+ EXPECT_TRUE(session_->IsGoingAway());
EXPECT_THAT(delegate3.WaitForClose(), IsError(ERR_ABORTED));
EXPECT_THAT(callback4.WaitForResult(), IsError(ERR_ABORTED));
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
// Read responses on remaining active streams.
data.Resume();
@@ -1175,7 +1306,7 @@ TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) {
// Receive SETTINGS frame that sets max_concurrent_streams to zero.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, session_->max_concurrent_streams_);
+ EXPECT_EQ(0u, max_concurrent_streams());
// Start request.
SpdyStreamRequest request;
@@ -1186,17 +1317,17 @@ TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) {
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
// Stream is stalled.
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(MEDIUM));
- EXPECT_EQ(0u, session_->num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(0u, num_created_streams());
// Receive SETTINGS frame that sets max_concurrent_streams to one.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, session_->max_concurrent_streams_);
+ EXPECT_EQ(1u, max_concurrent_streams());
// Stream is created.
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
- EXPECT_EQ(1u, session_->num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_created_streams());
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -1238,7 +1369,7 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) {
CreateSpdySession();
// Fix max_concurrent_streams to allow for one open stream.
- session_->max_concurrent_streams_ = 1;
+ set_max_concurrent_streams(1);
// Create two streams: one synchronously, and one which stalls.
base::WeakPtr<SpdyStream> stream1 =
@@ -1252,36 +1383,36 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) {
request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_,
MEDIUM, NetLogWithSource(), callback2.callback()));
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
// Cancel the first stream. A callback to unstall the second stream was
// posted. Don't run it yet.
stream1->Cancel();
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
// Create a third stream prior to the second stream's callback.
base::WeakPtr<SpdyStream> stream3 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
test_url_, MEDIUM, NetLogWithSource());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
// Now run the message loop. The unstalled stream will re-stall itself.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
// Cancel the third stream and run the message loop. Verify that the second
// stream creation now completes.
stream3->Cancel();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(MEDIUM));
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
EXPECT_THAT(callback2.WaitForResult(), IsOk());
}
@@ -1294,8 +1425,8 @@ TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) {
spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)};
- SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdySerializedFrame push_body(spdy_util_.ConstructSpdyDataFrame(2, false));
MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 3),
MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -1321,14 +1452,14 @@ TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) {
base::RunLoop().RunUntilIdle();
// Verify that there is one unclaimed push stream.
- EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams());
- EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url(
- GURL("https://www.example.org/a.dat")));
+ const GURL pushed_url(kPushedUrl);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+ EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));
// Unclaimed push body consumes bytes from the session window.
EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Read and process EOF.
data.Resume();
@@ -1336,8 +1467,7 @@ TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) {
// Cancel the push after session goes away. The test must not crash.
EXPECT_FALSE(session_);
- EXPECT_TRUE(
- test_push_delegate_->CancelPush(GURL("https://www.example.org/a.dat")));
+ EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));
histogram_tester.ExpectBucketCount("Net.SpdyStreamsPushedPerSession", 1, 1);
histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
@@ -1362,8 +1492,8 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
CreateMockWrite(rst, 5),
};
- SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdySerializedFrame push_body(spdy_util_.ConstructSpdyDataFrame(2, false));
MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -1390,7 +1520,7 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
transport_params, nullptr, nullptr, key_.host_port_pair(), SSLConfig(),
key_.privacy_mode(), 0, false);
int rv = connection->Init(
- key_.host_port_pair().ToString(), ssl_params, MEDIUM,
+ key_.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
http_session_->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
log_.bound());
@@ -1421,14 +1551,14 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
task_runner->RunUntilIdle();
// Verify that there is one unclaimed push stream.
- const GURL pushed_url("https://www.example.org/a.dat");
- EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams());
- EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url(pushed_url));
+ const GURL pushed_url(kPushedUrl);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+ EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));
// Unclaimed push body consumes bytes from the session window.
EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Fast forward to CancelPushedStreamIfUnclaimed() that was posted with a
// delay.
@@ -1436,16 +1566,16 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
task_runner->RunUntilIdle();
// Verify that pushed stream is cancelled.
- EXPECT_EQ(0u, session_->num_unclaimed_pushed_streams());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
// Verify that the session window reclaimed the evicted stream body.
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());
// Try to cancel the expired push after its expiration: must not crash.
EXPECT_TRUE(session_);
EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));
- EXPECT_EQ(0u, session_->num_unclaimed_pushed_streams());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
// Read and process EOF.
data.Resume();
@@ -1470,8 +1600,8 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) {
spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3)};
- SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdySerializedFrame push_body(spdy_util_.ConstructSpdyDataFrame(2, false));
MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -1498,7 +1628,7 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) {
transport_params, nullptr, nullptr, key_.host_port_pair(), SSLConfig(),
key_.privacy_mode(), 0, false);
int rv = connection->Init(
- key_.host_port_pair().ToString(), ssl_params, MEDIUM,
+ key_.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
http_session_->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
log_.bound());
@@ -1529,27 +1659,39 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) {
task_runner->RunUntilIdle();
// Verify that there is one unclaimed push stream.
- const GURL pushed_url("https://www.example.org/a.dat");
- EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams());
- EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url(pushed_url));
+ const GURL pushed_url(kPushedUrl);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+ EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));
// Unclaimed push body consumes bytes from the session window.
EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
+
+ // Claim pushed stream from Http2PushPromiseIndex.
+ HttpRequestInfo push_request;
+ push_request.url = pushed_url;
+ push_request.method = "GET";
+ base::WeakPtr<SpdySession> session_with_pushed_stream;
+ SpdyStreamId pushed_stream_id;
+ spdy_session_pool_->push_promise_index()->ClaimPushedStream(
+ key_, pushed_url, push_request, &session_with_pushed_stream,
+ &pushed_stream_id);
+ EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
+ EXPECT_EQ(2u, pushed_stream_id);
+
+ // Verify that pushed stream is claimed.
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
SpdyStream* spdy_stream2;
- rv = session_->GetPushStream(pushed_url, MEDIUM, &spdy_stream2,
- NetLogWithSource());
+ rv = session_->GetPushedStream(pushed_url, pushed_stream_id, MEDIUM,
+ &spdy_stream2, NetLogWithSource());
ASSERT_THAT(rv, IsOk());
ASSERT_TRUE(spdy_stream2);
test::StreamDelegateDoNothing delegate2(spdy_stream2->GetWeakPtr());
spdy_stream2->SetDelegate(&delegate2);
- // Verify that pushed stream is claimed.
- EXPECT_EQ(0u, session_->num_unclaimed_pushed_streams());
-
// Fast forward to CancelPushedStreamIfUnclaimed() that was posted with a
// delay. CancelPushedStreamIfUnclaimed() must be a no-op.
task_runner->FastForwardUntilNoTasksRemain();
@@ -1579,8 +1721,8 @@ TEST_F(SpdySessionTest, CancelPushBeforeClaimed) {
MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
CreateMockWrite(rst, 5)};
- SpdySerializedFrame push(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdySerializedFrame push_body(spdy_util_.ConstructSpdyDataFrame(2, false));
MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -1606,23 +1748,23 @@ TEST_F(SpdySessionTest, CancelPushBeforeClaimed) {
base::RunLoop().RunUntilIdle();
// Verify that there is one unclaimed push stream.
- const GURL pushed_url("https://www.example.org/a.dat");
- EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams());
- EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url(pushed_url));
+ const GURL pushed_url(kPushedUrl);
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+ EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));
// Unclaimed push body consumes bytes from the session window.
EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Cancel the push before it is claimed.
EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));
- EXPECT_EQ(0u, session_->num_unclaimed_pushed_streams());
- EXPECT_EQ(0u, session_->count_unclaimed_pushed_streams_for_url(pushed_url));
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
+ EXPECT_FALSE(has_unclaimed_pushed_stream_for_url(pushed_url));
// Verify that the session window reclaimed the evicted stream body.
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());
EXPECT_TRUE(session_);
@@ -1664,30 +1806,28 @@ TEST_F(SpdySessionTest, FailedPing) {
test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
spdy_stream1->SetDelegate(&delegate);
- session_->set_connection_at_risk_of_loss_time(
- base::TimeDelta::FromSeconds(0));
- session_->set_hung_interval(base::TimeDelta::FromSeconds(0));
+ set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
+ set_hung_interval(base::TimeDelta::FromSeconds(0));
// Send a PING frame.
- session_->WritePingFrame(1, false);
- EXPECT_LT(0, session_->pings_in_flight());
- EXPECT_EQ(2u, session_->next_ping_id());
- EXPECT_TRUE(session_->check_ping_status_pending());
+ WritePingFrame(1, false);
+ EXPECT_LT(0, pings_in_flight());
+ EXPECT_EQ(2u, next_ping_id());
+ EXPECT_TRUE(check_ping_status_pending());
// Assert session is not closed.
EXPECT_TRUE(session_->IsAvailable());
- EXPECT_LT(0u,
- session_->num_active_streams() + session_->num_created_streams());
+ EXPECT_LT(0u, num_active_streams() + num_created_streams());
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
// We set last time we have received any data in 1 sec less than now.
// CheckPingStatus will trigger timeout because hung interval is zero.
base::TimeTicks now = base::TimeTicks::Now();
- session_->last_read_time_ = now - base::TimeDelta::FromSeconds(1);
- session_->CheckPingStatus(now);
+ set_last_read_time(now - base::TimeDelta::FromSeconds(1));
+ CheckPingStatus(now);
// Set check_ping_status_pending_ so that DCHECK in pending CheckPingStatus()
// on message loop does not fail.
- session_->check_ping_status_pending_ = true;
+ set_check_ping_status_pending(true);
// Execute pending CheckPingStatus() and drain session.
base::RunLoop().RunUntilIdle();
@@ -1719,11 +1859,10 @@ TEST_F(SpdySessionTest, WaitingForWrongPing) {
CreateSpdySession();
// Negative value means a preface ping will always be sent.
- session_->set_connection_at_risk_of_loss_time(
- base::TimeDelta::FromSeconds(-1));
+ set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(-1));
const base::TimeDelta hung_interval = base::TimeDelta::FromMilliseconds(100);
- session_->set_hung_interval(hung_interval);
+ set_hung_interval(hung_interval);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
@@ -1732,31 +1871,31 @@ TEST_F(SpdySessionTest, WaitingForWrongPing) {
test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
spdy_stream1->SetDelegate(&delegate);
- EXPECT_EQ(0, session_->pings_in_flight());
- EXPECT_EQ(1u, session_->next_ping_id());
- EXPECT_FALSE(session_->check_ping_status_pending());
+ EXPECT_EQ(0, pings_in_flight());
+ EXPECT_EQ(1u, next_ping_id());
+ EXPECT_FALSE(check_ping_status_pending());
// Send preface ping and post CheckPingStatus() task with delay.
- session_->MaybeSendPrefacePing();
+ MaybeSendPrefacePing();
- EXPECT_EQ(1, session_->pings_in_flight());
- EXPECT_EQ(2u, session_->next_ping_id());
- EXPECT_TRUE(session_->check_ping_status_pending());
+ EXPECT_EQ(1, pings_in_flight());
+ EXPECT_EQ(2u, next_ping_id());
+ EXPECT_TRUE(check_ping_status_pending());
// Read PING ACK.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0, session_->pings_in_flight());
- EXPECT_TRUE(session_->check_ping_status_pending());
+ EXPECT_EQ(0, pings_in_flight());
+ EXPECT_TRUE(check_ping_status_pending());
// Fast forward mock time and send another preface ping.
// This will not post another CheckPingStatus().
g_time_delta = base::TimeDelta::FromMilliseconds(150);
- session_->MaybeSendPrefacePing();
+ MaybeSendPrefacePing();
- EXPECT_EQ(0, session_->pings_in_flight());
- EXPECT_EQ(2u, session_->next_ping_id());
- EXPECT_TRUE(session_->check_ping_status_pending());
+ EXPECT_EQ(0, pings_in_flight());
+ EXPECT_EQ(2u, next_ping_id());
+ EXPECT_TRUE(check_ping_status_pending());
// Read EOF.
data.Resume();
@@ -1768,7 +1907,7 @@ TEST_F(SpdySessionTest, WaitingForWrongPing) {
// that could be used to call RunLoop::Quit().
// TODO(bnc): Fix once a RunLoop-compatible mock time framework is supported.
// See https://crbug.com/708584#c75.
- EXPECT_TRUE(session_->check_ping_status_pending());
+ EXPECT_TRUE(check_ping_status_pending());
// Finish going away.
base::RunLoop().RunUntilIdle();
@@ -2481,7 +2620,7 @@ class SessionClosingDelegate : public test::StreamDelegateDoNothing {
: StreamDelegateDoNothing(stream),
session_to_close_(session_to_close) {}
- ~SessionClosingDelegate() override {}
+ ~SessionClosingDelegate() override = default;
void OnClose(int status) override {
session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error");
@@ -2667,9 +2806,9 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
request3.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_,
LOWEST, NetLogWithSource(), callback3.callback()));
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(2u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -2680,16 +2819,16 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
EXPECT_FALSE(spdy_stream1);
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
// Pump loop for SpdySession::ProcessPendingStreamRequests() to
// create the 2nd stream.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
test::StreamDelegateDoNothing delegate2(stream2);
@@ -2703,16 +2842,16 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
EXPECT_FALSE(stream2);
EXPECT_EQ(3u, delegate2.stream_id());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
// Pump loop for SpdySession::ProcessPendingStreamRequests() to
// create the 3rd stream.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
test::StreamDelegateDoNothing delegate3(stream3);
@@ -2726,9 +2865,9 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
EXPECT_FALSE(stream3);
EXPECT_EQ(5u, delegate3.stream_id());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -2777,9 +2916,9 @@ TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) {
request3.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
LOWEST, NetLogWithSource(), callback3.callback()));
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(kInitialMaxConcurrentStreams, session_->num_created_streams());
- EXPECT_EQ(2u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
+ EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));
// Cancel the first stream; this will allow the second stream to be created.
EXPECT_TRUE(spdy_stream1);
@@ -2787,9 +2926,9 @@ TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) {
EXPECT_FALSE(spdy_stream1);
EXPECT_THAT(callback2.WaitForResult(), IsOk());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(kInitialMaxConcurrentStreams, session_->num_created_streams());
- EXPECT_EQ(1u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
+ EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));
// Cancel the second stream; this will allow the third stream to be created.
base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
@@ -2797,17 +2936,17 @@ TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) {
EXPECT_FALSE(spdy_stream2);
EXPECT_THAT(callback3.WaitForResult(), IsOk());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(kInitialMaxConcurrentStreams, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
// Cancel the third stream.
base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
spdy_stream3->Cancel();
EXPECT_FALSE(spdy_stream3);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session_->num_created_streams());
- EXPECT_EQ(0u, session_->pending_create_stream_queue_size(LOWEST));
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(kInitialMaxConcurrentStreams - 1, num_created_streams());
+ EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
}
// Test that SpdySession::DoReadLoop reads data from the socket
@@ -3280,9 +3419,9 @@ TEST_F(SpdySessionTest, ProtocolNegotiation) {
CreateNetworkSession();
session_ = CreateFakeSpdySession(spdy_session_pool_, key_);
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_send_window_size_);
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_send_window_size());
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
}
// Tests the case of a non-SPDY request closing an idle SPDY session when no
@@ -3320,10 +3459,11 @@ TEST_F(SpdySessionTest, CloseOneIdleConnection) {
host_port2, false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
auto connection2 = std::make_unique<ClientSocketHandle>();
- EXPECT_EQ(ERR_IO_PENDING,
- connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
- callback2.callback(), pool, NetLogWithSource()));
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+ callback2.callback(), pool, NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// The socket pool should close the connection asynchronously and establish a
@@ -3399,10 +3539,11 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
host_port3, false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
auto connection3 = std::make_unique<ClientSocketHandle>();
- EXPECT_EQ(ERR_IO_PENDING,
- connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
- callback3.callback(), pool, NetLogWithSource()));
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+ callback3.callback(), pool, NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// The socket pool should close the connection asynchronously and establish a
@@ -3478,10 +3619,11 @@ TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
host_port2, false, OnHostResolutionCallback(),
TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
auto connection2 = std::make_unique<ClientSocketHandle>();
- EXPECT_EQ(ERR_IO_PENDING,
- connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
- ClientSocketPool::RespectLimits::ENABLED,
- callback2.callback(), pool, NetLogWithSource()));
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+ callback2.callback(), pool, NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// Running the message loop should cause the socket pool to ask the SPDY
@@ -3545,7 +3687,7 @@ class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
: StreamDelegateDoNothing(stream),
session_(session) {}
- ~StreamCreatingDelegate() override {}
+ ~StreamCreatingDelegate() override = default;
void OnClose(int status) override {
GURL url(kDefaultUrl);
@@ -3609,8 +3751,8 @@ TEST_F(SpdySessionTest, CreateStreamOnStreamReset) {
EXPECT_FALSE(spdy_stream);
EXPECT_TRUE(delegate.StreamIsClosed());
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -3656,7 +3798,7 @@ TEST_F(SpdySessionTest, UpdateStreamsSendWindowSize) {
// Process the SETTINGS frame.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(session_->stream_initial_send_window_size(), window_size);
+ EXPECT_EQ(stream_initial_send_window_size(), window_size);
EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
// Release the first one, this will allow the second to be created.
@@ -3703,29 +3845,29 @@ TEST_F(SpdySessionTest, AdjustRecvWindowSize) {
CreateNetworkSession();
CreateSpdySession();
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
- session_->IncreaseRecvWindowSize(delta_window_size);
+ IncreaseRecvWindowSize(delta_window_size);
EXPECT_EQ(initial_window_size + delta_window_size,
- session_->session_recv_window_size_);
- EXPECT_EQ(delta_window_size, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(delta_window_size, session_unacked_recv_window_bytes());
// Should trigger sending a WINDOW_UPDATE frame.
- session_->IncreaseRecvWindowSize(initial_window_size);
+ IncreaseRecvWindowSize(initial_window_size);
EXPECT_EQ(initial_window_size + delta_window_size + initial_window_size,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
base::RunLoop().RunUntilIdle();
// DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
- session_->in_io_loop_ = true;
- session_->DecreaseRecvWindowSize(initial_window_size + delta_window_size +
- initial_window_size);
- session_->in_io_loop_ = false;
- EXPECT_EQ(0, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ set_in_io_loop(true);
+ DecreaseRecvWindowSize(initial_window_size + delta_window_size +
+ initial_window_size);
+ set_in_io_loop(false);
+ EXPECT_EQ(0, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
EXPECT_TRUE(session_);
data.Resume();
@@ -3751,14 +3893,14 @@ TEST_F(SpdySessionTest, AdjustSendWindowSize) {
const int32_t initial_window_size = kDefaultInitialWindowSize;
const int32_t delta_window_size = 100;
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
- session_->IncreaseSendWindowSize(delta_window_size);
+ IncreaseSendWindowSize(delta_window_size);
EXPECT_EQ(initial_window_size + delta_window_size,
- session_->session_send_window_size_);
+ session_send_window_size());
- session_->DecreaseSendWindowSize(delta_window_size);
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
+ DecreaseSendWindowSize(delta_window_size);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
}
// Incoming data for an inactive stream should not cause the session
@@ -3780,13 +3922,13 @@ TEST_F(SpdySessionTest, SessionFlowControlInactiveStream) {
CreateNetworkSession();
CreateSpdySession();
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());
EXPECT_TRUE(session_);
data.Resume();
@@ -3814,14 +3956,14 @@ TEST_F(SpdySessionTest, SessionFlowControlPadding) {
CreateNetworkSession();
CreateSpdySession();
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_);
+ EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
EXPECT_EQ(kUploadDataSize + padding_length,
- session_->session_unacked_recv_window_bytes_);
+ session_unacked_recv_window_bytes());
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -3935,20 +4077,19 @@ TEST_F(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
CreateSpdySession();
// Setting session level receiving window size to smaller than initial is not
// possible via SpdySessionPoolPeer.
- session_->session_recv_window_size_ = session_max_recv_window_size;
+ set_session_recv_window_size(session_max_recv_window_size);
// First data frame is immediately consumed and does not trigger
// WINDOW_UPDATE.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(first_data_frame_size,
- session_->session_unacked_recv_window_bytes_);
- EXPECT_EQ(session_max_recv_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(SpdySession::STATE_AVAILABLE, session_->availability_state_);
+ EXPECT_EQ(first_data_frame_size, session_unacked_recv_window_bytes());
+ EXPECT_EQ(session_max_recv_window_size, session_recv_window_size());
+ EXPECT_TRUE(session_->IsAvailable());
// Second data frame overflows receiving window, causes session to close.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SpdySession::STATE_DRAINING, session_->availability_state_);
+ EXPECT_TRUE(session_->IsDraining());
}
// Regression test for a bug that was caused by including unsent WINDOW_UPDATE
@@ -4046,7 +4187,7 @@ class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
SpdyStringPiece data)
: StreamDelegateSendImmediate(stream, data) {}
- ~DropReceivedDataDelegate() override {}
+ ~DropReceivedDataDelegate() override = default;
// Drop any received data.
void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {}
@@ -4102,21 +4243,21 @@ TEST_F(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
const int32_t initial_window_size = kDefaultInitialWindowSize;
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
stream->Close();
EXPECT_FALSE(stream);
EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -4167,25 +4308,24 @@ TEST_F(SpdySessionTest, SessionFlowControlNoSendLeaks) {
stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
const int32_t initial_window_size = kDefaultInitialWindowSize;
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
// Write request.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
// Read response, but do not run the message loop, so that the body is not
// written to the socket.
data.Resume();
- EXPECT_EQ(initial_window_size - kMsgDataSize,
- session_->session_send_window_size_);
+ EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
// Closing the stream should increase the session's send window.
stream->Close();
EXPECT_FALSE(stream);
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
EXPECT_THAT(delegate.WaitForClose(), IsOk());
@@ -4250,53 +4390,49 @@ TEST_F(SpdySessionTest, SessionFlowControlEndToEnd) {
stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
const int32_t initial_window_size = kDefaultInitialWindowSize;
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Send request and message.
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size - kMsgDataSize,
- session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Read echo.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size - kMsgDataSize,
- session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size - kMsgDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
+ EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
// Read window update.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size - kMsgDataSize,
- session_->session_recv_window_size_);
- EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
+ EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
+ EXPECT_EQ(0, session_unacked_recv_window_bytes());
EXPECT_EQ(msg_data, delegate.TakeReceivedData());
// Draining the delegate's read queue should increase the session's
// receive window.
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
stream->Close();
EXPECT_FALSE(stream);
EXPECT_THAT(delegate.WaitForClose(), IsOk());
- EXPECT_EQ(initial_window_size, session_->session_send_window_size_);
- EXPECT_EQ(initial_window_size, session_->session_recv_window_size_);
- EXPECT_EQ(kMsgDataSize, session_->session_unacked_recv_window_bytes_);
+ EXPECT_EQ(initial_window_size, session_send_window_size());
+ EXPECT_EQ(initial_window_size, session_recv_window_size());
+ EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());
data.Resume();
base::RunLoop().RunUntilIdle();
@@ -4656,7 +4792,7 @@ class StreamClosingDelegate : public test::StreamDelegateWithBody {
SpdyStringPiece data)
: StreamDelegateWithBody(stream, data) {}
- ~StreamClosingDelegate() override {}
+ ~StreamClosingDelegate() override = default;
void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
stream_to_close_ = stream_to_close;
@@ -4947,7 +5083,7 @@ TEST_F(SpdySessionTest, GoAwayOnSessionFlowControlError) {
base::RunLoop().RunUntilIdle();
// Put session on the edge of overflowing it's recv window.
- session_->session_recv_window_size_ = 1;
+ set_session_recv_window_size(1);
// Read response headers & body. Body overflows the session window, and a
// goaway is written.
@@ -4965,8 +5101,8 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = 2;
SpdySerializedFrame settings_frame(
spdy_util_.ConstructSpdySettings(new_settings));
- SpdySerializedFrame pushed(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame pushed(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
MockRead reads[] = {
CreateMockRead(settings_frame, 0),
MockRead(ASYNC, ERR_IO_PENDING, 3),
@@ -5004,10 +5140,10 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
test::StreamDelegateDoNothing delegate1(spdy_stream1);
spdy_stream1->SetDelegate(&delegate1);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5016,18 +5152,18 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
EXPECT_EQ(0u, delegate1.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
// Run until pushed stream is created.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Second stream should not be stalled, although we have 2 active streams, but
// one of them is push stream and should not be taken into account when we
@@ -5036,10 +5172,10 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
test_url_, LOWEST, NetLogWithSource());
EXPECT_TRUE(spdy_stream2);
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Read EOF.
data.Resume();
@@ -5048,8 +5184,8 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
}
TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
- SpdySerializedFrame push_a(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push_a(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdySerializedFrame push_b(spdy_util_.ConstructSpdyPush(
nullptr, 0, 4, 1, "https://www.example.org/b.dat"));
MockRead reads[] = {
@@ -5078,7 +5214,7 @@ TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
CreateNetworkSession();
CreateSpdySession();
- session_->set_max_concurrent_pushed_streams(1);
+ set_max_concurrent_pushed_streams(1);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
@@ -5088,10 +5224,10 @@ TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
test::StreamDelegateDoNothing delegate1(spdy_stream1);
spdy_stream1->SetDelegate(&delegate1);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5100,26 +5236,26 @@ TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
EXPECT_EQ(0u, delegate1.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
// Run until pushed stream is created.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Reset incoming pushed stream.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Read EOF.
data.Resume();
@@ -5184,10 +5320,10 @@ TEST_F(SpdySessionTest, TrustedSpdyProxy) {
test::StreamDelegateDoNothing delegate(spdy_stream);
spdy_stream->SetDelegate(&delegate);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5196,26 +5332,26 @@ TEST_F(SpdySessionTest, TrustedSpdyProxy) {
EXPECT_EQ(0u, delegate.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
// Run until pushed stream is created.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Reset incoming pushed stream.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Read EOF.
data.Resume();
@@ -5263,10 +5399,10 @@ TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) {
test::StreamDelegateDoNothing delegate(spdy_stream);
spdy_stream->SetDelegate(&delegate);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5275,10 +5411,10 @@ TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) {
EXPECT_EQ(0u, delegate.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
// Read EOF.
data.Resume();
@@ -5287,14 +5423,14 @@ TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) {
}
TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
- SpdySerializedFrame push_a(spdy_util_.ConstructSpdyPush(
- nullptr, 0, 2, 1, "https://www.example.org/a.dat"));
+ SpdySerializedFrame push_a(
+ spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
SpdyHeaderBlock push_headers;
push_headers[":method"] = "GET";
spdy_util_.AddUrlToHeaderBlock("https://www.example.org/b.dat",
&push_headers);
SpdySerializedFrame push_b(
- spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 4, 1));
+ spdy_util_.ConstructSpdyPushPromise(1, 4, std::move(push_headers)));
SpdySerializedFrame headers_b(
spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0));
MockRead reads[] = {
@@ -5324,7 +5460,7 @@ TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
CreateNetworkSession();
CreateSpdySession();
- session_->set_max_concurrent_pushed_streams(1);
+ set_max_concurrent_pushed_streams(1);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
@@ -5334,10 +5470,10 @@ TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
test::StreamDelegateDoNothing delegate1(spdy_stream1);
spdy_stream1->SetDelegate(&delegate1);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5346,35 +5482,35 @@ TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
EXPECT_EQ(0u, delegate1.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
// Run until pushed stream is created.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Accept promised stream. It should not count towards pushed stream limit.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(3u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(2u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(3u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(2u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Reset last pushed stream upon headers reception as it is going to be 2nd,
// while we accept only one.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(1u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(1u, num_active_pushed_streams());
// Read EOF.
data.Resume();
@@ -5383,12 +5519,11 @@ TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
}
TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
- const char kPushedUrl[] = "https://www.example.org/a.dat";
SpdyHeaderBlock push_headers;
push_headers[":method"] = "GET";
spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_headers);
SpdySerializedFrame push_promise(
- spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1));
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
SpdySerializedFrame headers_frame(
spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
MockRead reads[] = {
@@ -5424,10 +5559,10 @@ TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
test::StreamDelegateDoNothing delegate1(spdy_stream1);
spdy_stream1->SetDelegate(&delegate1);
- EXPECT_EQ(0u, session_->num_active_streams());
- EXPECT_EQ(1u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
@@ -5436,22 +5571,38 @@ TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
EXPECT_EQ(0u, delegate1.stream_id());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, delegate1.stream_id());
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
// Run until pushed stream is created.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(1u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+
+ // Claim pushed stream from Http2PushPromiseIndex.
+ const GURL pushed_url(kPushedUrl);
+ HttpRequestInfo push_request;
+ push_request.url = pushed_url;
+ push_request.method = "GET";
+ base::WeakPtr<SpdySession> session_with_pushed_stream;
+ SpdyStreamId pushed_stream_id;
+ spdy_session_pool_->push_promise_index()->ClaimPushedStream(
+ key_, pushed_url, push_request, &session_with_pushed_stream,
+ &pushed_stream_id);
+ EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
+ EXPECT_EQ(2u, pushed_stream_id);
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
SpdyStream* pushed_stream;
- int rv = session_->GetPushStream(GURL(kPushedUrl), IDLE, &pushed_stream,
- NetLogWithSource());
+ int rv = session_->GetPushedStream(pushed_url, pushed_stream_id, IDLE,
+ &pushed_stream, NetLogWithSource());
ASSERT_THAT(rv, IsOk());
ASSERT_TRUE(pushed_stream);
test::StreamDelegateCloseOnHeaders delegate2(pushed_stream->GetWeakPtr());
@@ -5461,10 +5612,11 @@ TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
// that all our counters are in consistent state.
data.Resume();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, session_->num_active_streams());
- EXPECT_EQ(0u, session_->num_created_streams());
- EXPECT_EQ(0u, session_->num_pushed_streams());
- EXPECT_EQ(0u, session_->num_active_pushed_streams());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
// Read EOF.
data.Resume();
@@ -5473,6 +5625,128 @@ TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
EXPECT_TRUE(data.AllReadDataConsumed());
}
+TEST_F(SpdySessionTest, GetPushedStream) {
+ SpdyHeaderBlock push_headers;
+ push_headers[":method"] = "GET";
+ spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_headers);
+ SpdySerializedFrame push_promise(
+ spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
+ SpdySerializedFrame headers_frame(
+ spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_promise, 2),
+ MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(headers_frame, 5),
+ MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8)};
+
+ SpdySerializedFrame req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
+ SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ SpdySerializedFrame rst(
+ spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_CANCEL));
+ MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
+ CreateMockWrite(rst, 6)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+ CreateSpdySession();
+
+ base::WeakPtr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
+ test_url_, LOWEST, NetLogWithSource());
+ ASSERT_TRUE(spdy_stream1);
+ EXPECT_EQ(0u, spdy_stream1->stream_id());
+ test::StreamDelegateDoNothing delegate1(spdy_stream1);
+ spdy_stream1->SetDelegate(&delegate1);
+
+ EXPECT_EQ(0u, num_active_streams());
+ EXPECT_EQ(1u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+
+ SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
+ spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+
+ // Activate first request.
+ EXPECT_EQ(0u, delegate1.stream_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, delegate1.stream_id());
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+
+ // No streams are pushed yet, therefore GetPushedStream() should return an
+ // error.
+ const GURL pushed_url(kPushedUrl);
+ SpdyStream* pushed_stream;
+ int rv = session_->GetPushedStream(pushed_url, 2 /* pushed_stream_id */, IDLE,
+ &pushed_stream, NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE));
+
+ // Read PUSH_PROMISE.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(1u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+ EXPECT_EQ(1u, num_unclaimed_pushed_streams());
+
+ // Claim pushed stream from Http2PushPromiseIndex so that GetPushedStream()
+ // can be called.
+ HttpRequestInfo push_request;
+ push_request.url = pushed_url;
+ push_request.method = "GET";
+ base::WeakPtr<SpdySession> session_with_pushed_stream;
+ SpdyStreamId pushed_stream_id;
+ spdy_session_pool_->push_promise_index()->ClaimPushedStream(
+ key_, pushed_url, push_request, &session_with_pushed_stream,
+ &pushed_stream_id);
+ EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
+ EXPECT_EQ(2u, pushed_stream_id);
+
+ // Verify that pushed stream is claimed.
+ EXPECT_EQ(0u, num_unclaimed_pushed_streams());
+
+ // GetPushedStream() should return an error if there does not exist a pushed
+ // stream with ID |pushed_stream_id|.
+ rv = session_->GetPushedStream(pushed_url, 4 /* pushed_stream_id */, IDLE,
+ &pushed_stream, NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE));
+
+ // GetPushedStream() should return OK and return the pushed stream in
+ // |pushed_stream| outparam if |pushed_stream_id| matches.
+ rv = session_->GetPushedStream(pushed_url, 2 /* pushed_stream_id */, IDLE,
+ &pushed_stream, NetLogWithSource());
+ EXPECT_THAT(rv, IsOk());
+ ASSERT_TRUE(pushed_stream);
+ test::StreamDelegateCloseOnHeaders delegate2(pushed_stream->GetWeakPtr());
+ pushed_stream->SetDelegate(&delegate2);
+
+ // Upon reading pushed headers, delegate closes the stream.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, num_active_streams());
+ EXPECT_EQ(0u, num_created_streams());
+ EXPECT_EQ(0u, num_pushed_streams());
+ EXPECT_EQ(0u, num_active_pushed_streams());
+
+ // Read EOF.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(delegate1.StreamIsClosed());
+ EXPECT_TRUE(delegate2.StreamIsClosed());
+
+ EXPECT_TRUE(data.AllWriteDataConsumed());
+ EXPECT_TRUE(data.AllReadDataConsumed());
+}
+
TEST_F(SpdySessionTest, RejectInvalidUnknownFrames) {
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -5488,17 +5762,17 @@ TEST_F(SpdySessionTest, RejectInvalidUnknownFrames) {
CreateNetworkSession();
CreateSpdySession();
- session_->stream_hi_water_mark_ = 5;
+ set_stream_hi_water_mark(5);
// Low client (odd) ids are fine.
- EXPECT_TRUE(session_->OnUnknownFrame(3, 0));
+ EXPECT_TRUE(OnUnknownFrame(3, 0));
// Client id exceeding watermark.
- EXPECT_FALSE(session_->OnUnknownFrame(9, 0));
+ EXPECT_FALSE(OnUnknownFrame(9, 0));
- session_->last_accepted_push_stream_id_ = 6;
+ set_last_accepted_push_stream_id(6);
// Low server (even) ids are fine.
- EXPECT_TRUE(session_->OnUnknownFrame(2, 0));
+ EXPECT_TRUE(OnUnknownFrame(2, 0));
// Server id exceeding last accepted id.
- EXPECT_FALSE(session_->OnUnknownFrame(8, 0));
+ EXPECT_FALSE(OnUnknownFrame(8, 0));
}
enum ReadIfReadySupport {
diff --git a/chromium/net/spdy/chromium/spdy_stream.cc b/chromium/net/spdy/chromium/spdy_stream.cc
index 685bc8385e3..41e08ed9154 100644
--- a/chromium/net/spdy/chromium/spdy_stream.cc
+++ b/chromium/net/spdy/chromium/spdy_stream.cc
@@ -65,7 +65,7 @@ class SpdyStream::HeadersBufferProducer : public SpdyBufferProducer {
DCHECK(stream_.get());
}
- ~HeadersBufferProducer() override {}
+ ~HeadersBufferProducer() override = default;
std::unique_ptr<SpdyBuffer> ProduceBuffer() override {
if (!stream_.get()) {
@@ -455,6 +455,12 @@ void SpdyStream::OnHeadersReceived(const SpdyHeaderBlock& response_headers,
}
}
+bool SpdyStream::ShouldRetryRSTPushStream() {
+ // Retry if the stream is a pushed stream, has been claimed, but did not yet
+ // receive response headers
+ return (response_headers_.empty() && type_ == SPDY_PUSH_STREAM && delegate_);
+}
+
void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers) {
CHECK(!request_headers_valid_);
CHECK_EQ(io_state_, STATE_IDLE);
diff --git a/chromium/net/spdy/chromium/spdy_stream.h b/chromium/net/spdy/chromium/spdy_stream.h
index 7ba0ff6d667..06e6b1e8396 100644
--- a/chromium/net/spdy/chromium/spdy_stream.h
+++ b/chromium/net/spdy/chromium/spdy_stream.h
@@ -370,9 +370,12 @@ class NET_EXPORT_PRIVATE SpdyStream {
int64_t raw_received_bytes() const { return raw_received_bytes_; }
int64_t raw_sent_bytes() const { return raw_sent_bytes_; }
int recv_bytes() const { return recv_bytes_; }
+ bool ShouldRetryRSTPushStream();
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
+ const SpdyHeaderBlock& request_headers() { return request_headers_; }
+
// Get the URL from the appropriate stream headers, or the empty
// GURL() if it is unknown.
const GURL& GetUrlFromHeaders() const { return url_from_header_block_; }
diff --git a/chromium/net/spdy/chromium/spdy_stream_test_util.cc b/chromium/net/spdy/chromium/spdy_stream_test_util.cc
index 00b9ab9cd0c..b891cd2ac22 100644
--- a/chromium/net/spdy/chromium/spdy_stream_test_util.cc
+++ b/chromium/net/spdy/chromium/spdy_stream_test_util.cc
@@ -21,7 +21,7 @@ ClosingDelegate::ClosingDelegate(
DCHECK(stream_);
}
-ClosingDelegate::~ClosingDelegate() {}
+ClosingDelegate::~ClosingDelegate() = default;
void ClosingDelegate::OnHeadersSent() {}
@@ -51,8 +51,7 @@ StreamDelegateBase::StreamDelegateBase(
send_headers_completed_(false) {
}
-StreamDelegateBase::~StreamDelegateBase() {
-}
+StreamDelegateBase::~StreamDelegateBase() = default;
void StreamDelegateBase::OnHeadersSent() {
stream_id_ = stream_->stream_id();
@@ -114,16 +113,14 @@ StreamDelegateDoNothing::StreamDelegateDoNothing(
const base::WeakPtr<SpdyStream>& stream)
: StreamDelegateBase(stream) {}
-StreamDelegateDoNothing::~StreamDelegateDoNothing() {
-}
+StreamDelegateDoNothing::~StreamDelegateDoNothing() = default;
StreamDelegateSendImmediate::StreamDelegateSendImmediate(
const base::WeakPtr<SpdyStream>& stream,
SpdyStringPiece data)
: StreamDelegateBase(stream), data_(data) {}
-StreamDelegateSendImmediate::~StreamDelegateSendImmediate() {
-}
+StreamDelegateSendImmediate::~StreamDelegateSendImmediate() = default;
void StreamDelegateSendImmediate::OnHeadersReceived(
const SpdyHeaderBlock& response_headers) {
@@ -139,8 +136,7 @@ StreamDelegateWithBody::StreamDelegateWithBody(
SpdyStringPiece data)
: StreamDelegateBase(stream), buf_(new StringIOBuffer(data.as_string())) {}
-StreamDelegateWithBody::~StreamDelegateWithBody() {
-}
+StreamDelegateWithBody::~StreamDelegateWithBody() = default;
void StreamDelegateWithBody::OnHeadersSent() {
StreamDelegateBase::OnHeadersSent();
@@ -152,8 +148,7 @@ StreamDelegateCloseOnHeaders::StreamDelegateCloseOnHeaders(
: StreamDelegateBase(stream) {
}
-StreamDelegateCloseOnHeaders::~StreamDelegateCloseOnHeaders() {
-}
+StreamDelegateCloseOnHeaders::~StreamDelegateCloseOnHeaders() = default;
void StreamDelegateCloseOnHeaders::OnHeadersReceived(
const SpdyHeaderBlock& response_headers) {
diff --git a/chromium/net/spdy/chromium/spdy_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_stream_unittest.cc
index 911a1836e83..12e40c0266c 100644
--- a/chromium/net/spdy/chromium/spdy_stream_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_stream_unittest.cc
@@ -17,14 +17,17 @@
#include "base/run_loop.h"
#include "net/base/completion_callback.h"
#include "net/base/request_priority.h"
+#include "net/http/http_request_info.h"
#include "net/log/net_log_event_type.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/buffered_spdy_framer.h"
+#include "net/spdy/chromium/http2_push_promise_index.h"
#include "net/spdy/chromium/spdy_http_utils.h"
#include "net/spdy/chromium/spdy_session.h"
+#include "net/spdy/chromium/spdy_session_pool.h"
#include "net/spdy/chromium/spdy_stream_test_util.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/spdy/core/spdy_protocol.h"
@@ -69,7 +72,7 @@ class SpdyStreamTest : public ::testing::Test {
offset_(0),
ssl_(SYNCHRONOUS, OK) {}
- ~SpdyStreamTest() override {}
+ ~SpdyStreamTest() override = default;
base::WeakPtr<SpdySession> CreateDefaultSpdySession() {
SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
@@ -136,6 +139,15 @@ class SpdyStreamTest : public ::testing::Test {
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
}
+ static size_t num_pushed_streams(base::WeakPtr<SpdySession> session) {
+ return session->num_pushed_streams_;
+ }
+
+ static SpdySessionPool* spdy_session_pool(
+ base::WeakPtr<SpdySession> session) {
+ return session->pool_;
+ }
+
const GURL url_;
SpdyTestUtil spdy_util_;
SpdySessionDependencies session_deps_;
@@ -208,7 +220,7 @@ class StreamDelegateWithTrailers : public test::StreamDelegateWithBody {
SpdyStringPiece data)
: StreamDelegateWithBody(stream, data) {}
- ~StreamDelegateWithTrailers() override {}
+ ~StreamDelegateWithTrailers() override = default;
void OnTrailers(const SpdyHeaderBlock& trailers) override {
trailers_ = trailers.Clone();
@@ -343,9 +355,23 @@ TEST_F(SpdyStreamTest, PushedStream) {
data.RunUntilPaused();
+ const SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED);
+ const GURL pushed_url(kPushUrl);
+ HttpRequestInfo push_request;
+ push_request.url = pushed_url;
+ push_request.method = "GET";
+ base::WeakPtr<SpdySession> session_with_pushed_stream;
+ SpdyStreamId pushed_stream_id;
+ spdy_session_pool(session)->push_promise_index()->ClaimPushedStream(
+ key, pushed_url, push_request, &session_with_pushed_stream,
+ &pushed_stream_id);
+ EXPECT_EQ(session.get(), session_with_pushed_stream.get());
+ EXPECT_EQ(2u, pushed_stream_id);
+
SpdyStream* push_stream;
- EXPECT_THAT(session->GetPushStream(GURL(kPushUrl), IDLE, &push_stream,
- NetLogWithSource()),
+ EXPECT_THAT(session->GetPushedStream(pushed_url, pushed_stream_id, IDLE,
+ &push_stream, NetLogWithSource()),
IsOk());
ASSERT_TRUE(push_stream);
EXPECT_EQ(kPushUrl, push_stream->GetUrlFromHeaders().spec());
@@ -656,11 +682,7 @@ TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
data.RunUntilPaused();
- SpdyStream* push_stream;
- EXPECT_THAT(session->GetPushStream(GURL(kPushUrl), IDLE, &push_stream,
- NetLogWithSource()),
- IsOk());
- EXPECT_FALSE(push_stream);
+ EXPECT_EQ(0u, num_pushed_streams(session));
data.Resume();
@@ -732,8 +754,8 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
AddRead(reply);
- SpdySerializedFrame push_promise(spdy_util_.ConstructInitialSpdyPushFrame(
- spdy_util_.ConstructGetHeaderBlock(kPushUrl), 2, 1));
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
AddRead(push_promise);
SpdySerializedFrame priority(
@@ -848,8 +870,8 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
AddRead(reply);
- SpdySerializedFrame push_promise(spdy_util_.ConstructInitialSpdyPushFrame(
- spdy_util_.ConstructGetHeaderBlock(kPushUrl), 2, 1));
+ SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, spdy_util_.ConstructGetHeaderBlock(kPushUrl)));
AddRead(push_promise);
SpdySerializedFrame priority(
diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.cc b/chromium/net/spdy/chromium/spdy_test_util_common.cc
index 3a0dc7a706e..daa832c40bb 100644
--- a/chromium/net/spdy/chromium/spdy_test_util_common.cc
+++ b/chromium/net/spdy/chromium/spdy_test_util_common.cc
@@ -22,6 +22,7 @@
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/next_proto.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/chromium/buffered_spdy_framer.h"
@@ -31,6 +32,7 @@
#include "net/spdy/core/spdy_alt_svc_wire_format.h"
#include "net/spdy/core/spdy_framer.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -156,7 +158,7 @@ namespace {
class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
public:
PriorityGetter() : priority_(0) {}
- ~PriorityGetter() override {}
+ ~PriorityGetter() override = default;
SpdyPriority priority() const {
return priority_;
@@ -238,9 +240,9 @@ base::WeakPtr<SpdyStream> CreateStreamSynchronously(
(rv == OK) ? stream_request.ReleaseStream() : base::WeakPtr<SpdyStream>();
}
-StreamReleaserCallback::StreamReleaserCallback() {}
+StreamReleaserCallback::StreamReleaserCallback() = default;
-StreamReleaserCallback::~StreamReleaserCallback() {}
+StreamReleaserCallback::~StreamReleaserCallback() = default;
CompletionCallback StreamReleaserCallback::MakeCallback(
SpdyStreamRequest* request) {
@@ -324,7 +326,8 @@ SpdySessionDependencies::SpdySessionDependencies(
time_func(&base::TimeTicks::Now),
enable_http2_alternative_service(false),
net_log(nullptr),
- http_09_on_non_default_ports_enabled(false) {
+ http_09_on_non_default_ports_enabled(false),
+ disable_idle_sockets_close_on_memory_pressure(false) {
// Note: The CancelledTransaction test does cleanup by running all
// tasks in the message loop (RunAllPending). Unfortunately, that
// doesn't clean up tasks on the host resolver thread; and
@@ -335,7 +338,7 @@ SpdySessionDependencies::SpdySessionDependencies(
http2_settings[SETTINGS_INITIAL_WINDOW_SIZE] = kDefaultInitialWindowSize;
}
-SpdySessionDependencies::~SpdySessionDependencies() {}
+SpdySessionDependencies::~SpdySessionDependencies() = default;
// static
std::unique_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession(
@@ -378,6 +381,8 @@ HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
session_deps->enable_http2_alternative_service;
params.http_09_on_non_default_ports_enabled =
session_deps->http_09_on_non_default_ports_enabled;
+ params.disable_idle_sockets_close_on_memory_pressure =
+ session_deps->disable_idle_sockets_close_on_memory_pressure;
return params;
}
@@ -405,7 +410,7 @@ HttpNetworkSession::Context SpdySessionDependencies::CreateSessionContext(
class AllowAnyCertCTPolicyEnforcer : public CTPolicyEnforcer {
public:
- AllowAnyCertCTPolicyEnforcer() {}
+ AllowAnyCertCTPolicyEnforcer() = default;
~AllowAnyCertCTPolicyEnforcer() override = default;
ct::CTPolicyCompliance CheckCompliance(
@@ -488,7 +493,7 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper(
transport_params, nullptr, nullptr, key.host_port_pair(), ssl_config,
key.privacy_mode(), 0, /* expect_spdy = */ false);
int rv = connection->Init(
- key.host_port_pair().ToString(), ssl_params, MEDIUM,
+ key.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
http_session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
net_log);
@@ -529,7 +534,7 @@ class FakeSpdySessionClientSocket : public MockClientSocket {
explicit FakeSpdySessionClientSocket(int read_result)
: MockClientSocket(NetLogWithSource()), read_result_(read_result) {}
- ~FakeSpdySessionClientSocket() override {}
+ ~FakeSpdySessionClientSocket() override = default;
int Read(IOBuffer* buf,
int buf_len,
@@ -539,7 +544,8 @@ class FakeSpdySessionClientSocket : public MockClientSocket {
int Write(IOBuffer* buf,
int buf_len,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
return ERR_IO_PENDING;
}
@@ -627,7 +633,7 @@ SpdyTestUtil::SpdyTestUtil()
response_spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
default_url_(GURL(kDefaultUrl)) {}
-SpdyTestUtil::~SpdyTestUtil() {}
+SpdyTestUtil::~SpdyTestUtil() = default;
void SpdyTestUtil::AddUrlToHeaderBlock(SpdyStringPiece url,
SpdyHeaderBlock* headers) const {
@@ -805,10 +811,8 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyPush(
SpdyHeaderBlock push_promise_header_block;
push_promise_header_block[kHttp2MethodHeader] = "GET";
AddUrlToHeaderBlock(url, &push_promise_header_block);
- SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
- std::move(push_promise_header_block));
- SpdySerializedFrame push_promise_frame(
- response_spdy_framer_.SerializeFrame(push_promise));
+ SpdySerializedFrame push_promise_frame(ConstructSpdyPushPromise(
+ associated_stream_id, stream_id, std::move(push_promise_header_block)));
SpdyHeaderBlock headers_header_block;
headers_header_block[kHttp2StatusHeader] = "200";
@@ -832,10 +836,8 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyPush(
SpdyHeaderBlock push_promise_header_block;
push_promise_header_block[kHttp2MethodHeader] = "GET";
AddUrlToHeaderBlock(url, &push_promise_header_block);
- SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
- std::move(push_promise_header_block));
- SpdySerializedFrame push_promise_frame(
- response_spdy_framer_.SerializeFrame(push_promise));
+ SpdySerializedFrame push_promise_frame(ConstructSpdyPushPromise(
+ associated_stream_id, stream_id, std::move(push_promise_header_block)));
SpdyHeaderBlock headers_header_block;
headers_header_block["hello"] = "bye";
@@ -849,10 +851,10 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyPush(
return CombineFrames({&push_promise_frame, &headers_frame});
}
-SpdySerializedFrame SpdyTestUtil::ConstructInitialSpdyPushFrame(
- SpdyHeaderBlock headers,
- int stream_id,
- int associated_stream_id) {
+SpdySerializedFrame SpdyTestUtil::ConstructSpdyPushPromise(
+ SpdyStreamId associated_stream_id,
+ SpdyStreamId stream_id,
+ SpdyHeaderBlock headers) {
SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
std::move(headers));
return SpdySerializedFrame(
diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.h b/chromium/net/spdy/chromium/spdy_test_util_common.h
index 316a8b920d4..5aa3cd6a43b 100644
--- a/chromium/net/spdy/chromium/spdy_test_util_common.h
+++ b/chromium/net/spdy/chromium/spdy_test_util_common.h
@@ -220,6 +220,7 @@ struct SpdySessionDependencies {
bool enable_http2_alternative_service;
NetLog* net_log;
bool http_09_on_non_default_ports_enabled;
+ bool disable_idle_sockets_close_on_memory_pressure;
};
class SpdyURLRequestContext : public URLRequestContext {
@@ -372,10 +373,10 @@ class SpdyTestUtil {
RequestPriority priority,
const HostPortPair& host_port_pair);
- // Constructs a SPDY PUSH_PROMISE frame.
+ // Constructs a PUSH_PROMISE frame and a HEADERS frame on the pushed stream.
// |extra_headers| are the extra header-value pairs, which typically
// will vary the most between calls.
- // Returns a SpdySerializedFrame.
+ // Returns a SpdySerializedFrame object with the two frames concatenated.
SpdySerializedFrame ConstructSpdyPush(const char* const extra_headers[],
int extra_header_count,
int stream_id,
@@ -389,9 +390,11 @@ class SpdyTestUtil {
const char* status,
const char* location);
- SpdySerializedFrame ConstructInitialSpdyPushFrame(SpdyHeaderBlock headers,
- int stream_id,
- int associated_stream_id);
+ // Constructs a PUSH_PROMISE frame.
+ SpdySerializedFrame ConstructSpdyPushPromise(
+ SpdyStreamId associated_stream_id,
+ SpdyStreamId stream_id,
+ SpdyHeaderBlock headers);
SpdySerializedFrame ConstructSpdyPushHeaders(
int stream_id,
diff --git a/chromium/net/spdy/chromium/spdy_write_queue.cc b/chromium/net/spdy/chromium/spdy_write_queue.cc
index 246c4d921a1..2d874e44ae1 100644
--- a/chromium/net/spdy/chromium/spdy_write_queue.cc
+++ b/chromium/net/spdy/chromium/spdy_write_queue.cc
@@ -17,7 +17,7 @@
namespace net {
-SpdyWriteQueue::PendingWrite::PendingWrite() {}
+SpdyWriteQueue::PendingWrite::PendingWrite() = default;
SpdyWriteQueue::PendingWrite::PendingWrite(
SpdyFrameType frame_type,
@@ -28,7 +28,7 @@ SpdyWriteQueue::PendingWrite::PendingWrite(
stream(stream),
has_stream(stream.get() != nullptr) {}
-SpdyWriteQueue::PendingWrite::~PendingWrite() {}
+SpdyWriteQueue::PendingWrite::~PendingWrite() = default;
SpdyWriteQueue::PendingWrite::PendingWrite(PendingWrite&& other) = default;
SpdyWriteQueue::PendingWrite& SpdyWriteQueue::PendingWrite::operator=(
diff --git a/chromium/net/spdy/core/fuzzing/hpack_fuzz_util.cc b/chromium/net/spdy/core/fuzzing/hpack_fuzz_util.cc
index 3d7ec4edbcb..356040139f4 100644
--- a/chromium/net/spdy/core/fuzzing/hpack_fuzz_util.cc
+++ b/chromium/net/spdy/core/fuzzing/hpack_fuzz_util.cc
@@ -35,14 +35,14 @@ const size_t kValueLengthMax = 75;
using base::RandBytesAsString;
using std::map;
-HpackFuzzUtil::GeneratorContext::GeneratorContext() {}
-HpackFuzzUtil::GeneratorContext::~GeneratorContext() {}
+HpackFuzzUtil::GeneratorContext::GeneratorContext() = default;
+HpackFuzzUtil::GeneratorContext::~GeneratorContext() = default;
HpackFuzzUtil::Input::Input() : offset(0) {}
-HpackFuzzUtil::Input::~Input() {}
+HpackFuzzUtil::Input::~Input() = default;
-HpackFuzzUtil::FuzzerContext::FuzzerContext() {}
-HpackFuzzUtil::FuzzerContext::~FuzzerContext() {}
+HpackFuzzUtil::FuzzerContext::FuzzerContext() = default;
+HpackFuzzUtil::FuzzerContext::~FuzzerContext() = default;
// static
void HpackFuzzUtil::InitializeGeneratorContext(GeneratorContext* context) {
diff --git a/chromium/net/spdy/core/hpack/hpack_decoder_adapter.cc b/chromium/net/spdy/core/hpack/hpack_decoder_adapter.cc
index c3197005f30..4a11a32b514 100644
--- a/chromium/net/spdy/core/hpack/hpack_decoder_adapter.cc
+++ b/chromium/net/spdy/core/hpack/hpack_decoder_adapter.cc
@@ -21,7 +21,7 @@ HpackDecoderAdapter::HpackDecoderAdapter()
max_decode_buffer_size_bytes_(kMaxDecodeBufferSizeBytes),
header_block_started_(false) {}
-HpackDecoderAdapter::~HpackDecoderAdapter() {}
+HpackDecoderAdapter::~HpackDecoderAdapter() = default;
void HpackDecoderAdapter::ApplyHeaderTableSizeSetting(size_t size_setting) {
DVLOG(2) << "HpackDecoderAdapter::ApplyHeaderTableSizeSetting";
@@ -111,7 +111,7 @@ size_t HpackDecoderAdapter::EstimateMemoryUsage() const {
}
HpackDecoderAdapter::ListenerAdapter::ListenerAdapter() : handler_(nullptr) {}
-HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() {}
+HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() = default;
void HpackDecoderAdapter::ListenerAdapter::set_handler(
SpdyHeadersHandlerInterface* handler) {
diff --git a/chromium/net/spdy/core/hpack/hpack_decoder_adapter_test.cc b/chromium/net/spdy/core/hpack/hpack_decoder_adapter_test.cc
index 4e36442197b..eebd473e77e 100644
--- a/chromium/net/spdy/core/hpack/hpack_decoder_adapter_test.cc
+++ b/chromium/net/spdy/core/hpack/hpack_decoder_adapter_test.cc
@@ -144,11 +144,11 @@ class HpackDecoderAdapterTest
if (randomly_split_input_buffer_) {
do {
// Decode some fragment of the remaining bytes.
- size_t bytes = str.length();
+ size_t bytes = str.size();
if (!str.empty()) {
- bytes = random_.Uniform(str.length()) + 1;
+ bytes = random_.Uniform(str.size()) + 1;
}
- EXPECT_LE(bytes, str.length());
+ EXPECT_LE(bytes, str.size());
if (!HandleControlFrameHeadersData(str.substr(0, bytes))) {
decode_has_failed_ = true;
return false;
diff --git a/chromium/net/spdy/core/hpack/hpack_encoder.cc b/chromium/net/spdy/core/hpack/hpack_encoder.cc
index 1ae47c67791..824b0a3e3eb 100644
--- a/chromium/net/spdy/core/hpack/hpack_encoder.cc
+++ b/chromium/net/spdy/core/hpack/hpack_encoder.cc
@@ -83,7 +83,7 @@ HpackEncoder::HpackEncoder(const HpackHuffmanTable& table)
enable_compression_(true),
should_emit_table_size_(false) {}
-HpackEncoder::~HpackEncoder() {}
+HpackEncoder::~HpackEncoder() = default;
void HpackEncoder::EncodeHeaderSet(const Representations& representations,
SpdyString* output) {
diff --git a/chromium/net/spdy/core/hpack/hpack_encoder_test.cc b/chromium/net/spdy/core/hpack/hpack_encoder_test.cc
index fb10c8ff7c2..477bc37c817 100644
--- a/chromium/net/spdy/core/hpack/hpack_encoder_test.cc
+++ b/chromium/net/spdy/core/hpack/hpack_encoder_test.cc
@@ -445,7 +445,7 @@ TEST_P(HpackEncoderTest, PseudoHeadersFirst) {
}
TEST_P(HpackEncoderTest, CookieToCrumbs) {
- test::HpackEncoderPeer peer(NULL);
+ test::HpackEncoderPeer peer(nullptr);
std::vector<SpdyStringPiece> out;
// Leading and trailing whitespace is consumed. A space after ';' is consumed.
@@ -479,7 +479,7 @@ TEST_P(HpackEncoderTest, CookieToCrumbs) {
}
TEST_P(HpackEncoderTest, DecomposeRepresentation) {
- test::HpackEncoderPeer peer(NULL);
+ test::HpackEncoderPeer peer(nullptr);
std::vector<SpdyStringPiece> out;
peer.DecomposeRepresentation("", &out);
diff --git a/chromium/net/spdy/core/hpack/hpack_entry.cc b/chromium/net/spdy/core/hpack/hpack_entry.cc
index 86d120bb5b2..a948877cd6d 100644
--- a/chromium/net/spdy/core/hpack/hpack_entry.cc
+++ b/chromium/net/spdy/core/hpack/hpack_entry.cc
@@ -63,7 +63,7 @@ HpackEntry& HpackEntry::operator=(const HpackEntry& other) {
return *this;
}
-HpackEntry::~HpackEntry() {}
+HpackEntry::~HpackEntry() = default;
// static
size_t HpackEntry::Size(SpdyStringPiece name, SpdyStringPiece value) {
diff --git a/chromium/net/spdy/core/hpack/hpack_header_table.cc b/chromium/net/spdy/core/hpack/hpack_header_table.cc
index dc29b5cccff..ba7b787f6de 100644
--- a/chromium/net/spdy/core/hpack/hpack_header_table.cc
+++ b/chromium/net/spdy/core/hpack/hpack_header_table.cc
@@ -39,11 +39,11 @@ HpackHeaderTable::HpackHeaderTable()
max_size_(kDefaultHeaderTableSizeSetting),
total_insertions_(static_entries_.size()) {}
-HpackHeaderTable::~HpackHeaderTable() {}
+HpackHeaderTable::~HpackHeaderTable() = default;
const HpackEntry* HpackHeaderTable::GetByIndex(size_t index) {
if (index == 0) {
- return NULL;
+ return nullptr;
}
index -= 1;
if (index < static_entries_.size()) {
@@ -57,7 +57,7 @@ const HpackEntry* HpackHeaderTable::GetByIndex(size_t index) {
}
return result;
}
- return NULL;
+ return nullptr;
}
const HpackEntry* HpackHeaderTable::GetByName(SpdyStringPiece name) {
@@ -77,7 +77,7 @@ const HpackEntry* HpackHeaderTable::GetByName(SpdyStringPiece name) {
return result;
}
}
- return NULL;
+ return nullptr;
}
const HpackEntry* HpackHeaderTable::GetByNameAndValue(SpdyStringPiece name,
@@ -99,7 +99,7 @@ const HpackEntry* HpackHeaderTable::GetByNameAndValue(SpdyStringPiece name,
return result;
}
}
- return NULL;
+ return nullptr;
}
size_t HpackHeaderTable::IndexOf(const HpackEntry* entry) const {
@@ -192,7 +192,7 @@ const HpackEntry* HpackHeaderTable::TryAddEntry(SpdyStringPiece name,
// Entire table has been emptied, but there's still insufficient room.
DCHECK(dynamic_entries_.empty());
DCHECK_EQ(0u, size_);
- return NULL;
+ return nullptr;
}
dynamic_entries_.push_front(HpackEntry(name, value,
false, // is_static
diff --git a/chromium/net/spdy/core/hpack/hpack_header_table_test.cc b/chromium/net/spdy/core/hpack/hpack_header_table_test.cc
index 141d58b43cb..4be29b4d6b2 100644
--- a/chromium/net/spdy/core/hpack/hpack_header_table_test.cc
+++ b/chromium/net/spdy/core/hpack/hpack_header_table_test.cc
@@ -109,7 +109,7 @@ class HpackHeaderTableTest : public ::testing::Test {
EXPECT_EQ(0, distance(begin, end));
const HpackEntry* entry = table_.TryAddEntry(it->name(), it->value());
- EXPECT_NE(entry, static_cast<HpackEntry*>(NULL));
+ EXPECT_NE(entry, static_cast<HpackEntry*>(nullptr));
}
for (size_t i = 0; i != entries.size(); ++i) {
@@ -225,7 +225,7 @@ TEST_F(HpackHeaderTableTest, EntryIndexing) {
EXPECT_EQ(entry7, table_.GetByName("key-2"));
EXPECT_EQ(entry2->name(),
table_.GetByName(first_static_entry->name())->name());
- EXPECT_EQ(NULL, table_.GetByName("not-present"));
+ EXPECT_EQ(nullptr, table_.GetByName("not-present"));
// Querying by name & value returns the lowest-index matching entry among
// static entries, and the highest-index one among dynamic entries.
@@ -238,8 +238,8 @@ TEST_F(HpackHeaderTableTest, EntryIndexing) {
first_static_entry->value()));
EXPECT_EQ(entry2,
table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
- EXPECT_EQ(NULL, table_.GetByNameAndValue("key-1", "Not Present"));
- EXPECT_EQ(NULL, table_.GetByNameAndValue("not-present", "Value One"));
+ EXPECT_EQ(nullptr, table_.GetByNameAndValue("key-1", "Not Present"));
+ EXPECT_EQ(nullptr, table_.GetByNameAndValue("not-present", "Value One"));
// Evict |entry1|. Queries for its name & value now return the static entry.
// |entry2| remains queryable.
@@ -252,7 +252,7 @@ TEST_F(HpackHeaderTableTest, EntryIndexing) {
// Evict |entry2|. Queries by its name & value are not found.
peer_.Evict(1);
- EXPECT_EQ(NULL,
+ EXPECT_EQ(nullptr,
table_.GetByNameAndValue(first_static_entry->name(), "Value Four"));
}
@@ -394,7 +394,7 @@ TEST_F(HpackHeaderTableTest, TryAddTooLargeEntry) {
const HpackEntry* new_entry =
table_.TryAddEntry(long_entry.name(), long_entry.value());
- EXPECT_EQ(new_entry, static_cast<HpackEntry*>(NULL));
+ EXPECT_EQ(new_entry, static_cast<HpackEntry*>(nullptr));
EXPECT_EQ(0u, peer_.dynamic_entries().size());
}
diff --git a/chromium/net/spdy/core/hpack/hpack_huffman_table.cc b/chromium/net/spdy/core/hpack/hpack_huffman_table.cc
index dbfa8e5051c..842acf2d100 100644
--- a/chromium/net/spdy/core/hpack/hpack_huffman_table.cc
+++ b/chromium/net/spdy/core/hpack/hpack_huffman_table.cc
@@ -32,7 +32,7 @@ bool SymbolIdCompare(const HpackHuffmanSymbol& a, const HpackHuffmanSymbol& b) {
HpackHuffmanTable::HpackHuffmanTable() : pad_bits_(0), failed_symbol_id_(0) {}
-HpackHuffmanTable::~HpackHuffmanTable() {}
+HpackHuffmanTable::~HpackHuffmanTable() = default;
bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols,
size_t symbol_count) {
diff --git a/chromium/net/spdy/core/hpack/hpack_output_stream.cc b/chromium/net/spdy/core/hpack/hpack_output_stream.cc
index 6f01f64f104..49b2d60fa13 100644
--- a/chromium/net/spdy/core/hpack/hpack_output_stream.cc
+++ b/chromium/net/spdy/core/hpack/hpack_output_stream.cc
@@ -13,7 +13,7 @@ namespace net {
HpackOutputStream::HpackOutputStream() : bit_offset_(0) {}
-HpackOutputStream::~HpackOutputStream() {}
+HpackOutputStream::~HpackOutputStream() = default;
void HpackOutputStream::AppendBits(uint8_t bits, size_t bit_size) {
DCHECK_GT(bit_size, 0u);
diff --git a/chromium/net/spdy/core/hpack/hpack_static_table.cc b/chromium/net/spdy/core/hpack/hpack_static_table.cc
index 2eb17206098..0b3c0dc38a4 100644
--- a/chromium/net/spdy/core/hpack/hpack_static_table.cc
+++ b/chromium/net/spdy/core/hpack/hpack_static_table.cc
@@ -12,9 +12,9 @@
namespace net {
-HpackStaticTable::HpackStaticTable() {}
+HpackStaticTable::HpackStaticTable() = default;
-HpackStaticTable::~HpackStaticTable() {}
+HpackStaticTable::~HpackStaticTable() = default;
void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table,
size_t static_entry_count) {
diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
index ad714052466..0655db68fe4 100644
--- a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
+++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
@@ -160,12 +160,15 @@ const char* Http2DecoderAdapter::SpdyFramerErrorToString(
return "UNKNOWN_ERROR";
}
-Http2DecoderAdapter::Http2DecoderAdapter() {
+Http2DecoderAdapter::Http2DecoderAdapter() : Http2DecoderAdapter(false) {}
+
+Http2DecoderAdapter::Http2DecoderAdapter(bool h2_on_stream_pad_length)
+ : h2_on_stream_pad_length_(h2_on_stream_pad_length) {
DVLOG(1) << "Http2DecoderAdapter ctor";
ResetInternal();
}
-Http2DecoderAdapter::~Http2DecoderAdapter() {}
+Http2DecoderAdapter::~Http2DecoderAdapter() = default;
void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) {
visitor_ = visitor;
@@ -436,10 +439,13 @@ void Http2DecoderAdapter::OnContinuationEnd() {
void Http2DecoderAdapter::OnPadLength(size_t trailing_length) {
DVLOG(1) << "OnPadLength: " << trailing_length;
opt_pad_length_ = trailing_length;
+ DCHECK_LT(trailing_length, 256u);
if (frame_header_.type == Http2FrameType::DATA) {
- visitor()->OnStreamPadding(stream_id(), 1);
- } else if (frame_header_.type == Http2FrameType::HEADERS) {
- CHECK_LT(trailing_length, 256u);
+ if (h2_on_stream_pad_length_) {
+ visitor()->OnStreamPadLength(stream_id(), trailing_length);
+ } else {
+ visitor()->OnStreamPadding(stream_id(), 1);
+ }
}
}
diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.h b/chromium/net/spdy/core/http2_frame_decoder_adapter.h
index c3e08b3be4a..94be5d4c353 100644
--- a/chromium/net/spdy/core/http2_frame_decoder_adapter.h
+++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.h
@@ -77,6 +77,7 @@ class SPDY_EXPORT_PRIVATE Http2DecoderAdapter
static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error);
Http2DecoderAdapter();
+ explicit Http2DecoderAdapter(bool h2_on_stream_pad_length);
~Http2DecoderAdapter() override;
// Set callbacks to be called from the framer. A visitor must be set, or
@@ -314,6 +315,9 @@ class SPDY_EXPORT_PRIVATE Http2DecoderAdapter
bool handling_extension_payload_ = false;
bool process_single_input_frame_ = false;
+
+ // Flag value latched at construction.
+ const bool h2_on_stream_pad_length_ : 1;
};
// Http2DecoderAdapter will use the given visitor implementing this
@@ -364,7 +368,13 @@ class SPDY_EXPORT_PRIVATE SpdyFramerVisitorInterface {
// |stream_id| The stream that was receiving data.
virtual void OnStreamEnd(SpdyStreamId stream_id) = 0;
- // Called when padding is received (padding length field or padding octets).
+ // Called when padding length field is received on a DATA frame.
+ // |stream_id| The stream receiving data.
+ // |value| The value of the padding length field.
+ virtual void OnStreamPadLength(SpdyStreamId stream_id, size_t value) {}
+
+ // Called when padding is received (the trailing octets, not pad_len field) on
+ // a DATA frame.
// |stream_id| The stream receiving data.
// |len| The number of padding octets.
virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;
diff --git a/chromium/net/spdy/core/mock_spdy_framer_visitor.cc b/chromium/net/spdy/core/mock_spdy_framer_visitor.cc
index 437dc57ba17..f9f3f407ebe 100644
--- a/chromium/net/spdy/core/mock_spdy_framer_visitor.cc
+++ b/chromium/net/spdy/core/mock_spdy_framer_visitor.cc
@@ -12,7 +12,7 @@ MockSpdyFramerVisitor::MockSpdyFramerVisitor() {
DelegateHeaderHandling();
}
-MockSpdyFramerVisitor::~MockSpdyFramerVisitor() {}
+MockSpdyFramerVisitor::~MockSpdyFramerVisitor() = default;
} // namespace test
diff --git a/chromium/net/spdy/core/mock_spdy_framer_visitor.h b/chromium/net/spdy/core/mock_spdy_framer_visitor.h
index 8bff920ec92..696d508b9ff 100644
--- a/chromium/net/spdy/core/mock_spdy_framer_visitor.h
+++ b/chromium/net/spdy/core/mock_spdy_framer_visitor.h
@@ -32,6 +32,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD3(OnStreamFrameData,
void(SpdyStreamId stream_id, const char* data, size_t len));
MOCK_METHOD1(OnStreamEnd, void(SpdyStreamId stream_id));
+ MOCK_METHOD2(OnStreamPadLength, void(SpdyStreamId stream_id, size_t value));
MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len));
MOCK_METHOD1(OnHeaderFrameStart,
SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
diff --git a/chromium/net/spdy/core/spdy_alt_svc_wire_format.cc b/chromium/net/spdy/core/spdy_alt_svc_wire_format.cc
index a0a378300a5..df8b7d88c89 100644
--- a/chromium/net/spdy/core/spdy_alt_svc_wire_format.cc
+++ b/chromium/net/spdy/core/spdy_alt_svc_wire_format.cc
@@ -35,7 +35,7 @@ bool ParsePositiveIntegerImpl(SpdyStringPiece::const_iterator c,
} // namespace
-SpdyAltSvcWireFormat::AlternativeService::AlternativeService() {}
+SpdyAltSvcWireFormat::AlternativeService::AlternativeService() = default;
SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
const SpdyString& protocol_id,
@@ -49,7 +49,7 @@ SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
max_age(max_age),
version(version) {}
-SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() {}
+SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() = default;
SpdyAltSvcWireFormat::AlternativeService::AlternativeService(
const AlternativeService& other) = default;
diff --git a/chromium/net/spdy/core/spdy_deframer_visitor.cc b/chromium/net/spdy/core/spdy_deframer_visitor.cc
index 20489d73b2e..e7d1a46daaf 100644
--- a/chromium/net/spdy/core/spdy_deframer_visitor.cc
+++ b/chromium/net/spdy/core/spdy_deframer_visitor.cc
@@ -126,7 +126,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer,
: listener_(std::move(listener)) {
CHECK(listener_);
}
- ~SpdyTestDeframerImpl() override {}
+ ~SpdyTestDeframerImpl() override = default;
bool AtFrameEnd() override;
@@ -172,6 +172,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer,
const char* data,
size_t len) override;
void OnStreamEnd(SpdyStreamId stream_id) override;
+ void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
@@ -676,8 +677,23 @@ void SpdyTestDeframerImpl::OnStreamFrameData(SpdyStreamId stream_id,
data_->append(data, len);
}
-// Called when padding is skipped over, including the padding length field at
-// the start of the frame payload, and the actual padding at the end. len will
+// Called when receiving the padding length field at the start of the DATA frame
+// payload. value will be in the range 0 to 255.
+void SpdyTestDeframerImpl::OnStreamPadLength(SpdyStreamId stream_id,
+ size_t value) {
+ DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
+ << " value: " << value;
+ CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
+ frame_type_ == PUSH_PROMISE)
+ << " frame_type_=" << Http2FrameTypeToString(frame_type_);
+ CHECK_EQ(stream_id_, stream_id);
+ CHECK_GE(255u, value);
+ // Count the padding length byte against total padding.
+ padding_len_ += 1;
+ CHECK_EQ(1u, padding_len_);
+}
+
+// Called when padding is skipped over at the end of the DATA frame. len will
// be in the range 1 to 255.
void SpdyTestDeframerImpl::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
DVLOG(1) << "OnStreamPadding stream_id: " << stream_id << " len: " << len;
@@ -765,7 +781,7 @@ class LoggingSpdyDeframerDelegate : public SpdyDeframerVisitorInterface {
wrapped_ = SpdyMakeUnique<SpdyDeframerVisitorInterface>();
}
}
- ~LoggingSpdyDeframerDelegate() override {}
+ ~LoggingSpdyDeframerDelegate() override = default;
void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override {
DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc";
@@ -857,7 +873,7 @@ SpdyDeframerVisitorInterface::LogBeforeVisiting(
std::move(wrapped_listener));
}
-CollectedFrame::CollectedFrame() {}
+CollectedFrame::CollectedFrame() = default;
CollectedFrame::CollectedFrame(CollectedFrame&& other)
: frame_ir(std::move(other.frame_ir)),
@@ -865,7 +881,7 @@ CollectedFrame::CollectedFrame(CollectedFrame&& other)
settings(std::move(other.settings)),
error_reported(other.error_reported) {}
-CollectedFrame::~CollectedFrame() {}
+CollectedFrame::~CollectedFrame() = default;
CollectedFrame& CollectedFrame::operator=(CollectedFrame&& other) {
frame_ir = std::move(other.frame_ir);
diff --git a/chromium/net/spdy/core/spdy_frame_builder.cc b/chromium/net/spdy/core/spdy_frame_builder.cc
index 23eff899b8a..90a28a997f1 100644
--- a/chromium/net/spdy/core/spdy_frame_builder.cc
+++ b/chromium/net/spdy/core/spdy_frame_builder.cc
@@ -26,7 +26,7 @@ SpdyFrameBuilder::SpdyFrameBuilder(size_t size, ZeroCopyOutputBuffer* output)
length_(0),
offset_(0) {}
-SpdyFrameBuilder::~SpdyFrameBuilder() {}
+SpdyFrameBuilder::~SpdyFrameBuilder() = default;
char* SpdyFrameBuilder::GetWritableBuffer(size_t length) {
if (!CanWrite(length)) {
@@ -120,7 +120,7 @@ bool SpdyFrameBuilder::BeginNewFrameInternal(uint8_t raw_frame_type,
return success;
}
-bool SpdyFrameBuilder::WriteStringPiece32(const SpdyStringPiece& value) {
+bool SpdyFrameBuilder::WriteStringPiece32(const SpdyStringPiece value) {
if (!WriteUInt32(value.size())) {
return false;
}
diff --git a/chromium/net/spdy/core/spdy_frame_builder.h b/chromium/net/spdy/core/spdy_frame_builder.h
index b75e73b0db7..f7474570e9e 100644
--- a/chromium/net/spdy/core/spdy_frame_builder.h
+++ b/chromium/net/spdy/core/spdy_frame_builder.h
@@ -99,7 +99,7 @@ class SPDY_EXPORT_PRIVATE SpdyFrameBuilder {
return (WriteBytes(&upper, sizeof(upper)) &&
WriteBytes(&lower, sizeof(lower)));
}
- bool WriteStringPiece32(const SpdyStringPiece& value);
+ bool WriteStringPiece32(const SpdyStringPiece value);
bool WriteBytes(const void* data, uint32_t data_len);
private:
diff --git a/chromium/net/spdy/core/spdy_framer.cc b/chromium/net/spdy/core/spdy_framer.cc
index 4e90c0558e6..eaefdde4918 100644
--- a/chromium/net/spdy/core/spdy_framer.cc
+++ b/chromium/net/spdy/core/spdy_framer.cc
@@ -4,8 +4,6 @@
#include "net/spdy/core/spdy_framer.h"
-#include <string.h>
-
#include <algorithm>
#include <cctype>
#include <ios>
@@ -191,8 +189,8 @@ bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
size_t bytes_remaining = 0;
bytes_remaining = hpack_encoding.size() -
std::min(hpack_encoding.size(),
- SpdyFramer::kMaxControlFrameSendSize -
- builder->length() - padding_payload_len);
+ kHttp2MaxControlFrameSendSize - builder->length() -
+ padding_payload_len);
bool ret = builder->WriteBytes(&hpack_encoding[0],
hpack_encoding.size() - bytes_remaining);
if (padding_payload_len > 0) {
@@ -203,8 +201,8 @@ bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
// Tack on CONTINUATION frames for the overflow.
while (bytes_remaining > 0 && ret) {
size_t bytes_to_write =
- std::min(bytes_remaining, SpdyFramer::kMaxControlFrameSendSize -
- kContinuationFrameMinimumSize);
+ std::min(bytes_remaining,
+ kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize);
// Write CONTINUATION frame prefix.
if (bytes_remaining == bytes_to_write) {
flags |= end_flag;
@@ -278,19 +276,13 @@ void SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
} // namespace
-// Even though the length field is 24 bits, we keep this 16 kB
-// limit on control frame size for legacy reasons and to
-// mitigate DOS attacks.
-const size_t SpdyFramer::kMaxControlFrameSendSize =
- kHttp2DefaultFramePayloadLimit - 1;
-
SpdyFramer::SpdyFramer(CompressionOption option)
: debug_visitor_(nullptr), compression_option_(option) {
- static_assert(kMaxControlFrameSendSize <= kHttp2DefaultFrameSizeLimit,
+ static_assert(kHttp2MaxControlFrameSendSize <= kHttp2DefaultFrameSizeLimit,
"Our send limit should be at most our receive limit.");
}
-SpdyFramer::~SpdyFramer() {}
+SpdyFramer::~SpdyFramer() = default;
void SpdyFramer::set_debug_visitor(
SpdyFramerDebugVisitorInterface* debug_visitor) {
@@ -300,7 +292,7 @@ void SpdyFramer::set_debug_visitor(
SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer)
: framer_(framer), is_first_frame_(true), has_next_frame_(true) {}
-SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() {}
+SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() = default;
size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) {
const SpdyFrameIR& frame_ir = GetIR();
@@ -313,7 +305,8 @@ size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) {
const size_t size_without_block =
is_first_frame_ ? GetFrameSizeSansBlock() : kContinuationFrameMinimumSize;
auto encoding = SpdyMakeUnique<SpdyString>();
- encoder_->Next(kMaxControlFrameSendSize - size_without_block, encoding.get());
+ encoder_->Next(kHttp2MaxControlFrameSendSize - size_without_block,
+ encoding.get());
has_next_frame_ = encoder_->HasNext();
if (framer_->debug_visitor_ != nullptr) {
@@ -352,7 +345,7 @@ SpdyFramer::SpdyHeaderFrameIterator::SpdyHeaderFrameIterator(
SetEncoder(headers_ir_.get());
}
-SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() {}
+SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() = default;
const SpdyFrameIR& SpdyFramer::SpdyHeaderFrameIterator::GetIR() const {
return *(headers_ir_.get());
@@ -376,7 +369,8 @@ SpdyFramer::SpdyPushPromiseFrameIterator::SpdyPushPromiseFrameIterator(
SetEncoder(push_promise_ir_.get());
}
-SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() {}
+SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() =
+ default;
const SpdyFrameIR& SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const {
return *(push_promise_ir_.get());
@@ -398,7 +392,7 @@ SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator(
std::unique_ptr<const SpdyFrameIR> frame_ir)
: framer_(framer), frame_ir_(std::move(frame_ir)) {}
-SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() {}
+SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() = default;
size_t SpdyFramer::SpdyControlFrameIterator::NextFrame(
ZeroCopyOutputBuffer* output) {
@@ -591,7 +585,7 @@ void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), hpack_encoding);
*size = *size + hpack_encoding->size();
- if (*size > kMaxControlFrameSendSize) {
+ if (*size > kHttp2MaxControlFrameSendSize) {
*size = *size + GetNumberRequiredContinuationFrames(*size) *
kContinuationFrameMinimumSize;
*flags = *flags & ~HEADERS_FLAG_END_HEADERS;
@@ -610,7 +604,7 @@ void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
// WritePayloadWithContinuation() will serialize CONTINUATION frames as
// necessary.
*length_field =
- std::min(*length_field, kMaxControlFrameSendSize - kFrameHeaderSize);
+ std::min(*length_field, kHttp2MaxControlFrameSendSize - kFrameHeaderSize);
}
SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
@@ -685,7 +679,7 @@ void SpdyFramer::SerializePushPromiseBuilderHelper(
GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(),
hpack_encoding);
*size = *size + hpack_encoding->size();
- if (*size > kMaxControlFrameSendSize) {
+ if (*size > kHttp2MaxControlFrameSendSize) {
*size = *size + GetNumberRequiredContinuationFrames(*size) *
kContinuationFrameMinimumSize;
*flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
@@ -701,7 +695,8 @@ SpdySerializedFrame SpdyFramer::SerializePushPromise(
&size);
SpdyFrameBuilder builder(size);
- size_t length = std::min(size, kMaxControlFrameSendSize) - kFrameHeaderSize;
+ size_t length =
+ std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
push_promise.stream_id(), length);
int padding_payload_len = 0;
@@ -790,7 +785,7 @@ class FrameSerializationVisitor : public SpdyFrameVisitor {
public:
explicit FrameSerializationVisitor(SpdyFramer* framer)
: framer_(framer), frame_() {}
- ~FrameSerializationVisitor() override {}
+ ~FrameSerializationVisitor() override = default;
SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); }
@@ -1119,7 +1114,8 @@ bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise,
bool ok = true;
SpdyFrameBuilder builder(size, output);
- size_t length = std::min(size, kMaxControlFrameSendSize) - kFrameHeaderSize;
+ size_t length =
+ std::min(size, kHttp2MaxControlFrameSendSize) - kFrameHeaderSize;
ok = builder.BeginNewFrame(SpdyFrameType::PUSH_PROMISE, flags,
push_promise.stream_id(), length);
@@ -1214,7 +1210,7 @@ class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor {
explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer,
ZeroCopyOutputBuffer* output)
: framer_(framer), output_(output), result_(false) {}
- ~FrameSerializationVisitorWithOutput() override {}
+ ~FrameSerializationVisitorWithOutput() override = default;
size_t Result() { return result_; }
@@ -1271,15 +1267,6 @@ size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame,
return visitor.Result() ? free_bytes_before - output->BytesFree() : 0;
}
-size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
- DCHECK_GT(size, SpdyFramer::kMaxControlFrameSendSize);
- size_t overflow = size - SpdyFramer::kMaxControlFrameSendSize;
- int payload_size =
- SpdyFramer::kMaxControlFrameSendSize - kContinuationFrameMinimumSize;
- // This is ceiling(overflow/payload_size) using integer arithmetics.
- return (overflow - 1) / payload_size + 1;
-}
-
HpackEncoder* SpdyFramer::GetHpackEncoder() {
if (hpack_encoder_.get() == nullptr) {
hpack_encoder_ = SpdyMakeUnique<HpackEncoder>(ObtainHpackHuffmanTable());
diff --git a/chromium/net/spdy/core/spdy_framer.h b/chromium/net/spdy/core/spdy_framer.h
index 38143205c18..3b999abaef7 100644
--- a/chromium/net/spdy/core/spdy_framer.h
+++ b/chromium/net/spdy/core/spdy_framer.h
@@ -72,12 +72,6 @@ class SPDY_EXPORT_PRIVATE SpdyFramer {
// Gets the serialized flags for the given |frame|.
static uint8_t GetSerializedFlags(const SpdyFrameIR& frame);
- // The maximum size of the control frames that we send, including the size of
- // the header. This limit is arbitrary. We can enforce it here or at the
- // application layer. We chose the framing layer, but this can be changed (or
- // removed) if necessary later down the line.
- static const size_t kMaxControlFrameSendSize;
-
// Serialize a data frame.
static SpdySerializedFrame SerializeData(const SpdyDataIR& data_ir);
// Serializes the data frame header and optionally padding length fields,
@@ -369,8 +363,6 @@ class SPDY_EXPORT_PRIVATE SpdyFramer {
};
private:
- static size_t GetNumberRequiredContinuationFrames(size_t size);
-
void SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
uint8_t* flags,
size_t* size,
diff --git a/chromium/net/spdy/core/spdy_framer_test.cc b/chromium/net/spdy/core/spdy_framer_test.cc
index 2b4030f074b..c5fad9ee027 100644
--- a/chromium/net/spdy/core/spdy_framer_test.cc
+++ b/chromium/net/spdy/core/spdy_framer_test.cc
@@ -5,7 +5,6 @@
#include "net/spdy/core/spdy_framer.h"
#include <stdlib.h>
-#include <string.h>
#include <algorithm>
#include <limits>
@@ -17,6 +16,7 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "net/quic/platform/api/quic_flags.h"
+#include "net/spdy/chromium/spdy_flags.h"
#include "net/spdy/core/array_output_buffer.h"
#include "net/spdy/core/hpack/hpack_constants.h"
#include "net/spdy/core/mock_spdy_framer_visitor.h"
@@ -26,6 +26,7 @@
#include "net/spdy/core/spdy_protocol.h"
#include "net/spdy/core/spdy_test_utils.h"
#include "net/spdy/platform/api/spdy_ptr_util.h"
+#include "net/spdy/platform/api/spdy_string.h"
#include "net/spdy/platform/api/spdy_string_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -39,7 +40,7 @@ namespace test {
namespace {
-const int64_t kSize = 64 * 1024;
+const int64_t kSize = 1024 * 1024;
char output_buffer[kSize] = "";
// frame_list_char is used to hold frames to be compared with output_buffer.
@@ -217,11 +218,6 @@ MATCHER_P(IsFrameUnionOf, frame_list, "") {
class SpdyFramerPeer {
public:
- static size_t GetNumberRequiredContinuationFrames(SpdyFramer* framer,
- size_t size) {
- return framer->GetNumberRequiredContinuationFrames(size);
- }
-
// TODO(dahollings): Remove these methods when deprecating non-incremental
// header serialization path.
static std::unique_ptr<SpdyHeadersIR> CloneSpdyHeadersIR(
@@ -375,6 +371,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
explicit TestSpdyVisitor(SpdyFramer::CompressionOption option)
: framer_(option),
+ deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length),
error_count_(0),
headers_frame_count_(0),
push_promise_frame_count_(0),
@@ -438,6 +435,13 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
++end_of_stream_count_;
}
+ void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override {
+ VLOG(1) << "OnStreamPadding(" << stream_id << ", " << value << ")\n";
+ EXPECT_EQ(header_stream_id_, stream_id);
+ // Count the padding length field byte against total data bytes.
+ data_bytes_ += 1;
+ }
+
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n";
EXPECT_EQ(header_stream_id_, stream_id);
@@ -732,7 +736,8 @@ class SpdyFramerTest : public ::testing::TestWithParam<Output> {
public:
SpdyFramerTest()
: output_(output_buffer, kSize),
- framer_(SpdyFramer::ENABLE_COMPRESSION) {}
+ framer_(SpdyFramer::ENABLE_COMPRESSION),
+ deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length) {}
protected:
void SetUp() override {
@@ -954,7 +959,11 @@ TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) {
{
testing::InSequence seq;
EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false));
- EXPECT_CALL(visitor, OnStreamPadding(1, 1));
+ if (FLAGS_chromium_http2_flag_h2_on_stream_pad_length) {
+ EXPECT_CALL(visitor, OnStreamPadLength(1, 4));
+ } else {
+ EXPECT_CALL(visitor, OnStreamPadding(1, 1));
+ }
EXPECT_CALL(visitor, OnError(_)).Times(0);
// Note that OnStreamFrameData(1, _, 1)) is never called
// since there is no data, only padding
@@ -2404,14 +2413,10 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
// Regression test for https://crbug.com/464748.
TEST_P(SpdyFramerTest, GetNumberRequiredContinuationFrames) {
- EXPECT_EQ(1u, SpdyFramerPeer::GetNumberRequiredContinuationFrames(
- &framer_, 16383 + 16374));
- EXPECT_EQ(2u, SpdyFramerPeer::GetNumberRequiredContinuationFrames(
- &framer_, 16383 + 16374 + 1));
- EXPECT_EQ(2u, SpdyFramerPeer::GetNumberRequiredContinuationFrames(
- &framer_, 16383 + 2 * 16374));
- EXPECT_EQ(3u, SpdyFramerPeer::GetNumberRequiredContinuationFrames(
- &framer_, 16383 + 2 * 16374 + 1));
+ EXPECT_EQ(1u, GetNumberRequiredContinuationFrames(16383 + 16374));
+ EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 16374 + 1));
+ EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374));
+ EXPECT_EQ(3u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374 + 1));
}
TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
@@ -2560,7 +2565,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
/* promised_stream_id = */ 57);
push_promise.set_padding_len(1);
- SpdyString big_value(SpdyFramer::kMaxControlFrameSendSize, 'x');
+ SpdyString big_value(kHttp2MaxControlFrameSendSize, 'x');
push_promise.SetHeader("xxx", big_value);
SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
&framer, push_promise, use_output_ ? &output_ : nullptr));
@@ -2582,7 +2587,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
// Length of everything listed above except big_value.
int len_non_data_payload = 31;
- EXPECT_EQ(SpdyFramer::kMaxControlFrameSendSize + len_non_data_payload,
+ EXPECT_EQ(kHttp2MaxControlFrameSendSize + len_non_data_payload,
frame.size());
// Partially compare the PUSH_PROMISE frame against the template.
@@ -2593,7 +2598,7 @@ TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
kPartialPushPromiseFrameData, arraysize(kPartialPushPromiseFrameData));
// Compare the CONTINUATION frame against the template.
- frame_data += SpdyFramer::kMaxControlFrameSendSize;
+ frame_data += kHttp2MaxControlFrameSendSize;
CompareCharArraysWithHexError(
kDescription, frame_data, arraysize(kContinuationFrameData),
kContinuationFrameData, arraysize(kContinuationFrameData));
@@ -2749,12 +2754,12 @@ TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) {
// Exact payload length will change with HPACK, but this should be long
// enough to cause an overflow.
- const size_t kBigValueSize = SpdyFramer::kMaxControlFrameSendSize;
+ const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
SpdyString big_value(kBigValueSize, 'x');
headers.SetHeader("aa", big_value);
SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
&framer, headers, use_output_ ? &output_ : nullptr));
- EXPECT_GT(control_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(
@@ -2774,7 +2779,7 @@ TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
// Exact payload length will change with HPACK, but this should be long
// enough to cause an overflow.
- const size_t kBigValueSize = SpdyFramer::kMaxControlFrameSendSize;
+ const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
SpdyString big_valuex(kBigValueSize, 'x');
headers->SetHeader("aa", big_valuex);
SpdyString big_valuez(kBigValueSize, 'z');
@@ -2785,7 +2790,7 @@ TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
EXPECT_TRUE(frame_it.HasNextFrame());
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame headers_frame(output_.Begin(), output_.Size(), false);
- EXPECT_EQ(headers_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_EQ(headers_frame.size(), kHttp2MaxControlFrameSendSize);
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(
@@ -2801,7 +2806,7 @@ TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
EXPECT_TRUE(frame_it.HasNextFrame());
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
- EXPECT_EQ(first_cont_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(first_cont_frame.data()),
@@ -2816,7 +2821,7 @@ TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
EXPECT_TRUE(frame_it.HasNextFrame());
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
- EXPECT_LT(second_cont_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(second_cont_frame.data()),
@@ -2839,7 +2844,7 @@ TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
// Exact payload length will change with HPACK, but this should be long
// enough to cause an overflow.
- const size_t kBigValueSize = SpdyFramer::kMaxControlFrameSendSize;
+ const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
SpdyString big_valuex(kBigValueSize, 'x');
push_promise->SetHeader("aa", big_valuex);
SpdyString big_valuez(kBigValueSize, 'z');
@@ -2852,7 +2857,7 @@ TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame push_promise_frame(output_.Begin(), output_.Size(),
false);
- EXPECT_EQ(push_promise_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_EQ(push_promise_frame.size(), kHttp2MaxControlFrameSendSize);
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(
@@ -2869,7 +2874,7 @@ TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame first_cont_frame(output_.Begin(), output_.Size(), false);
- EXPECT_EQ(first_cont_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(first_cont_frame.data()),
first_cont_frame.size());
@@ -2883,7 +2888,7 @@ TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
output_.Reset();
EXPECT_GT(frame_it.NextFrame(&output_), 0u);
SpdySerializedFrame second_cont_frame(output_.Begin(), output_.Size(), false);
- EXPECT_LT(second_cont_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(second_cont_frame.data()),
@@ -2968,12 +2973,12 @@ TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) {
// Exact payload length will change with HPACK, but this should be long
// enough to cause an overflow.
- const size_t kBigValueSize = SpdyFramer::kMaxControlFrameSendSize;
+ const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
SpdyString big_value(kBigValueSize, 'x');
push_promise.SetHeader("aa", big_value);
SpdySerializedFrame control_frame(SpdyFramerPeer::SerializePushPromise(
&framer, push_promise, use_output_ ? &output_ : nullptr));
- EXPECT_GT(control_frame.size(), SpdyFramer::kMaxControlFrameSendSize);
+ EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(
@@ -3265,7 +3270,11 @@ TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
bytes_consumed += kDataFrameMinimumSize;
// Send the padding length field.
- EXPECT_CALL(visitor, OnStreamPadding(1, 1));
+ if (FLAGS_chromium_http2_flag_h2_on_stream_pad_length) {
+ EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1));
+ } else {
+ EXPECT_CALL(visitor, OnStreamPadding(1, 1));
+ }
CHECK_EQ(1u, deframer_.ProcessInput(frame.data() + bytes_consumed, 1));
CHECK_EQ(deframer_.state(), Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
CHECK_EQ(deframer_.spdy_framer_error(), Http2DecoderAdapter::SPDY_NO_ERROR);
@@ -4873,6 +4882,90 @@ TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) {
}
}
+namespace {
+void CheckFrameAndIRSize(SpdyFrameIR* ir,
+ SpdyFramer* framer,
+ ArrayOutputBuffer* output_buffer) {
+ output_buffer->Reset();
+ SpdyFrameType type = ir->frame_type();
+ size_t ir_size = ir->size();
+ framer->SerializeFrame(*ir, output_buffer);
+ if (type == SpdyFrameType::HEADERS || type == SpdyFrameType::PUSH_PROMISE) {
+ // For HEADERS and PUSH_PROMISE, the size is an estimate.
+ EXPECT_GE(ir_size, output_buffer->Size() * 9 / 10);
+ EXPECT_LT(ir_size, output_buffer->Size() * 11 / 10);
+ } else {
+ EXPECT_EQ(ir_size, output_buffer->Size());
+ }
+}
+} // namespace
+
+TEST_P(SpdyFramerTest, SpdyFrameIRSize) {
+ SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
+
+ const char bytes[] = "this is a very short data frame";
+ SpdyDataIR data_ir(1, SpdyStringPiece(bytes, arraysize(bytes)));
+ CheckFrameAndIRSize(&data_ir, &framer, &output_);
+
+ SpdyRstStreamIR rst_ir(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
+ CheckFrameAndIRSize(&rst_ir, &framer, &output_);
+
+ SpdySettingsIR settings_ir;
+ settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
+ settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
+ settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
+ CheckFrameAndIRSize(&settings_ir, &framer, &output_);
+
+ SpdyPingIR ping_ir(42);
+ CheckFrameAndIRSize(&ping_ir, &framer, &output_);
+
+ SpdyGoAwayIR goaway_ir(97, ERROR_CODE_NO_ERROR, "Goaway description");
+ CheckFrameAndIRSize(&goaway_ir, &framer, &output_);
+
+ SpdyHeadersIR headers_ir(1);
+ headers_ir.SetHeader("alpha", "beta");
+ headers_ir.SetHeader("gamma", "charlie");
+ headers_ir.SetHeader("cookie", "key1=value1; key2=value2");
+ CheckFrameAndIRSize(&headers_ir, &framer, &output_);
+
+ SpdyHeadersIR headers_ir_with_continuation(1);
+ headers_ir_with_continuation.SetHeader("alpha", SpdyString(100000, 'x'));
+ headers_ir_with_continuation.SetHeader("beta", SpdyString(100000, 'x'));
+ headers_ir_with_continuation.SetHeader("cookie", "key1=value1; key2=value2");
+ CheckFrameAndIRSize(&headers_ir_with_continuation, &framer, &output_);
+
+ SpdyWindowUpdateIR window_update_ir(4, 1024);
+ CheckFrameAndIRSize(&window_update_ir, &framer, &output_);
+
+ SpdyPushPromiseIR push_promise_ir(3, 8);
+ push_promise_ir.SetHeader("alpha", SpdyString(100000, 'x'));
+ push_promise_ir.SetHeader("beta", SpdyString(100000, 'x'));
+ push_promise_ir.SetHeader("cookie", "key1=value1; key2=value2");
+ CheckFrameAndIRSize(&push_promise_ir, &framer, &output_);
+
+ SpdyAltSvcWireFormat::AlternativeService altsvc1(
+ "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
+ SpdyAltSvcWireFormat::AlternativeService altsvc2(
+ "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
+ SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
+ altsvc_vector.push_back(altsvc1);
+ altsvc_vector.push_back(altsvc2);
+ SpdyAltSvcIR altsvc_ir(0);
+ altsvc_ir.set_origin("o_r|g!n");
+ altsvc_ir.add_altsvc(altsvc1);
+ altsvc_ir.add_altsvc(altsvc2);
+ CheckFrameAndIRSize(&altsvc_ir, &framer, &output_);
+
+ SpdyPriorityIR priority_ir(3, 1, 256, false);
+ CheckFrameAndIRSize(&priority_ir, &framer, &output_);
+
+ const char kDescription[] = "Unknown frame";
+ const uint8_t kType = 0xaf;
+ const uint8_t kFlags = 0x11;
+ SpdyUnknownIR unknown_ir(2, kType, kFlags, kDescription);
+ CheckFrameAndIRSize(&unknown_ir, &framer, &output_);
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/core/spdy_header_block.cc b/chromium/net/spdy/core/spdy_header_block.cc
index 9fda908dfb7..fb2c4cb0c9b 100644
--- a/chromium/net/spdy/core/spdy_header_block.cc
+++ b/chromium/net/spdy/core/spdy_header_block.cc
@@ -106,22 +106,30 @@ class SpdyHeaderBlock::Storage {
SpdyHeaderBlock::HeaderValue::HeaderValue(Storage* storage,
SpdyStringPiece key,
SpdyStringPiece initial_value)
- : storage_(storage), fragments_({initial_value}), pair_({key, {}}) {}
+ : storage_(storage),
+ fragments_({initial_value}),
+ pair_({key, {}}),
+ size_(initial_value.size()),
+ separator_size_(SeparatorForKey(key).size()) {}
SpdyHeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other)
: storage_(other.storage_),
fragments_(std::move(other.fragments_)),
- pair_(std::move(other.pair_)) {}
+ pair_(std::move(other.pair_)),
+ size_(other.size_),
+ separator_size_(other.separator_size_) {}
SpdyHeaderBlock::HeaderValue& SpdyHeaderBlock::HeaderValue::operator=(
HeaderValue&& other) {
storage_ = other.storage_;
fragments_ = std::move(other.fragments_);
pair_ = std::move(other.pair_);
+ size_ = other.size_;
+ separator_size_ = other.separator_size_;
return *this;
}
-SpdyHeaderBlock::HeaderValue::~HeaderValue() {}
+SpdyHeaderBlock::HeaderValue::~HeaderValue() = default;
SpdyStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() const {
if (fragments_.empty()) {
@@ -135,6 +143,7 @@ SpdyStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() const {
}
void SpdyHeaderBlock::HeaderValue::Append(SpdyStringPiece fragment) {
+ size_ += (fragment.size() + separator_size_);
fragments_.push_back(fragment);
}
@@ -146,19 +155,21 @@ SpdyHeaderBlock::HeaderValue::as_pair() const {
SpdyHeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {}
-SpdyHeaderBlock::iterator::iterator(const iterator& other) : it_(other.it_) {}
+SpdyHeaderBlock::iterator::iterator(const iterator& other) = default;
-SpdyHeaderBlock::iterator::~iterator() {}
+SpdyHeaderBlock::iterator::~iterator() = default;
SpdyHeaderBlock::ValueProxy::ValueProxy(
SpdyHeaderBlock::MapType* block,
SpdyHeaderBlock::Storage* storage,
SpdyHeaderBlock::MapType::iterator lookup_result,
- const SpdyStringPiece key)
+ const SpdyStringPiece key,
+ size_t* spdy_header_block_value_size)
: block_(block),
storage_(storage),
lookup_result_(lookup_result),
key_(key),
+ spdy_header_block_value_size_(spdy_header_block_value_size),
valid_(true) {}
SpdyHeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
@@ -166,6 +177,7 @@ SpdyHeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
storage_(other.storage_),
lookup_result_(other.lookup_result_),
key_(other.key_),
+ spdy_header_block_value_size_(other.spdy_header_block_value_size_),
valid_(true) {
other.valid_ = false;
}
@@ -178,6 +190,7 @@ SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=(
key_ = other.key_;
valid_ = true;
other.valid_ = false;
+ spdy_header_block_value_size_ = other.spdy_header_block_value_size_;
return *this;
}
@@ -193,6 +206,7 @@ SpdyHeaderBlock::ValueProxy::~ValueProxy() {
SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=(
const SpdyStringPiece value) {
+ *spdy_header_block_value_size_ += value.size();
if (lookup_result_ == block_->end()) {
DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")";
lookup_result_ =
@@ -202,6 +216,7 @@ SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=(
.first;
} else {
DVLOG(1) << "Updating key: " << key_ << " with value: " << value;
+ *spdy_header_block_value_size_ -= lookup_result_->second.SizeEstimate();
lookup_result_->second =
HeaderValue(storage_, key_, storage_->Write(value));
}
@@ -220,11 +235,13 @@ SpdyHeaderBlock::SpdyHeaderBlock() : block_(kInitialMapBuckets) {}
SpdyHeaderBlock::SpdyHeaderBlock(SpdyHeaderBlock&& other) = default;
-SpdyHeaderBlock::~SpdyHeaderBlock() {}
+SpdyHeaderBlock::~SpdyHeaderBlock() = default;
SpdyHeaderBlock& SpdyHeaderBlock::operator=(SpdyHeaderBlock&& other) {
block_.swap(other.block_);
storage_.swap(other.storage_);
+ key_size_ = other.key_size_;
+ value_size_ = other.value_size_;
return *this;
}
@@ -257,13 +274,26 @@ SpdyString SpdyHeaderBlock::DebugString() const {
return output;
}
+void SpdyHeaderBlock::erase(SpdyStringPiece key) {
+ auto iter = block_.find(key);
+ if (iter != block_.end()) {
+ key_size_ -= key.size();
+ value_size_ -= iter->second.SizeEstimate();
+ block_.erase(iter);
+ }
+}
+
void SpdyHeaderBlock::clear() {
+ key_size_ = 0;
+ value_size_ = 0;
block_.clear();
storage_.reset();
}
void SpdyHeaderBlock::insert(const SpdyHeaderBlock::value_type& value) {
// TODO(birenroy): Write new value in place of old value, if it fits.
+ value_size_ += value.second.size();
+
auto iter = block_.find(value.first);
if (iter == block_.end()) {
DVLOG(1) << "Inserting: (" << value.first << ", " << value.second << ")";
@@ -271,6 +301,7 @@ void SpdyHeaderBlock::insert(const SpdyHeaderBlock::value_type& value) {
} else {
DVLOG(1) << "Updating key: " << iter->first
<< " with value: " << value.second;
+ value_size_ -= iter->second.SizeEstimate();
auto* storage = GetStorage();
iter->second =
HeaderValue(storage, iter->first, storage->Write(value.second));
@@ -285,25 +316,29 @@ SpdyHeaderBlock::ValueProxy SpdyHeaderBlock::operator[](
if (iter == block_.end()) {
// We write the key first, to assure that the ValueProxy has a
// reference to a valid SpdyStringPiece in its operator=.
- out_key = GetStorage()->Write(key);
+ out_key = WriteKey(key);
DVLOG(2) << "Key written as: " << std::hex
<< static_cast<const void*>(key.data()) << ", " << std::dec
<< key.size();
} else {
out_key = iter->first;
}
- return ValueProxy(&block_, GetStorage(), iter, out_key);
+ return ValueProxy(&block_, GetStorage(), iter, out_key, &value_size_);
}
void SpdyHeaderBlock::AppendValueOrAddHeader(const SpdyStringPiece key,
const SpdyStringPiece value) {
+ value_size_ += value.size();
+
auto iter = block_.find(key);
if (iter == block_.end()) {
DVLOG(1) << "Inserting: (" << key << ", " << value << ")";
+
AppendHeader(key, value);
return;
}
DVLOG(1) << "Updating key: " << iter->first << "; appending value: " << value;
+ value_size_ += SeparatorForKey(key).size();
iter->second.Append(GetStorage()->Write(value));
}
@@ -315,8 +350,8 @@ size_t SpdyHeaderBlock::EstimateMemoryUsage() const {
void SpdyHeaderBlock::AppendHeader(const SpdyStringPiece key,
const SpdyStringPiece value) {
+ auto backed_key = WriteKey(key);
auto* storage = GetStorage();
- auto backed_key = storage->Write(key);
block_.emplace(std::make_pair(
backed_key, HeaderValue(storage, backed_key, storage->Write(value))));
}
@@ -344,6 +379,11 @@ std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
return std::move(dict);
}
+SpdyStringPiece SpdyHeaderBlock::WriteKey(const SpdyStringPiece key) {
+ key_size_ += key.size();
+ return GetStorage()->Write(key);
+}
+
size_t SpdyHeaderBlock::bytes_allocated() const {
if (storage_ == nullptr) {
return 0;
diff --git a/chromium/net/spdy/core/spdy_header_block.h b/chromium/net/spdy/core/spdy_header_block.h
index c82383e20f6..248ec73f0be 100644
--- a/chromium/net/spdy/core/spdy_header_block.h
+++ b/chromium/net/spdy/core/spdy_header_block.h
@@ -72,6 +72,10 @@ class SPDY_EXPORT_PRIVATE SpdyHeaderBlock {
SpdyStringPiece value() const { return as_pair().second; }
const std::pair<SpdyStringPiece, SpdyStringPiece>& as_pair() const;
+ // Size estimate including separators. Used when keys are erased from
+ // SpdyHeaderBlock.
+ size_t SizeEstimate() const { return size_; }
+
private:
// May allocate a large contiguous region of memory to hold the concatenated
// fragments and separators.
@@ -81,6 +85,8 @@ class SPDY_EXPORT_PRIVATE SpdyHeaderBlock {
mutable std::vector<SpdyStringPiece> fragments_;
// The first element is the key; the second is the consolidated value.
mutable std::pair<SpdyStringPiece, SpdyStringPiece> pair_;
+ size_t size_ = 0;
+ size_t separator_size_ = 0;
};
typedef linked_hash_map<SpdyStringPiece, HeaderValue, base::StringPieceHash>
@@ -163,7 +169,7 @@ class SPDY_EXPORT_PRIVATE SpdyHeaderBlock {
const_iterator find(SpdyStringPiece key) const {
return const_iterator(block_.find(key));
}
- void erase(SpdyStringPiece key) { block_.erase(key); }
+ void erase(SpdyStringPiece key);
// Clears both our MapType member and the memory used to hold headers.
void clear();
@@ -211,29 +217,37 @@ class SPDY_EXPORT_PRIVATE SpdyHeaderBlock {
ValueProxy(SpdyHeaderBlock::MapType* block,
SpdyHeaderBlock::Storage* storage,
SpdyHeaderBlock::MapType::iterator lookup_result,
- const SpdyStringPiece key);
+ const SpdyStringPiece key,
+ size_t* spdy_header_block_value_size);
SpdyHeaderBlock::MapType* block_;
SpdyHeaderBlock::Storage* storage_;
SpdyHeaderBlock::MapType::iterator lookup_result_;
SpdyStringPiece key_;
+ size_t* spdy_header_block_value_size_;
bool valid_;
};
// Returns the estimate of dynamically allocated memory in bytes.
size_t EstimateMemoryUsage() const;
+ size_t TotalBytesUsed() const { return key_size_ + value_size_; }
+
private:
friend class test::SpdyHeaderBlockPeer;
void AppendHeader(const SpdyStringPiece key, const SpdyStringPiece value);
Storage* GetStorage();
+ SpdyStringPiece WriteKey(const SpdyStringPiece key);
size_t bytes_allocated() const;
// SpdyStringPieces held by |block_| point to memory owned by |*storage_|.
// |storage_| might be nullptr as long as |block_| is empty.
MapType block_;
std::unique_ptr<Storage> storage_;
+
+ size_t key_size_ = 0;
+ size_t value_size_ = 0;
};
// Writes |fragments| to |dst|, joined by |separator|. |dst| must be large
diff --git a/chromium/net/spdy/core/spdy_header_block_test.cc b/chromium/net/spdy/core/spdy_header_block_test.cc
index 98881620f6c..da0eb7d6d6a 100644
--- a/chromium/net/spdy/core/spdy_header_block_test.cc
+++ b/chromium/net/spdy/core/spdy_header_block_test.cc
@@ -206,5 +206,49 @@ TEST(JoinTest, JoinMultiple) {
EXPECT_EQ("one, two, three", SpdyStringPiece(buf, written));
}
+namespace {
+size_t SpdyHeaderBlockSize(const SpdyHeaderBlock& block) {
+ size_t size = 0;
+ for (const auto& pair : block) {
+ size += pair.first.size() + pair.second.size();
+ }
+ return size;
+}
+} // namespace
+
+// Tests SpdyHeaderBlock SizeEstimate().
+TEST(SpdyHeaderBlockTest, TotalBytesUsed) {
+ SpdyHeaderBlock block;
+ const size_t value_size = 300;
+ block["foo"] = SpdyString(value_size, 'x');
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+ block.insert(std::make_pair("key", SpdyString(value_size, 'x')));
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+ block.AppendValueOrAddHeader("abc", SpdyString(value_size, 'x'));
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+
+ // Replace value for existing key.
+ block["foo"] = SpdyString(value_size, 'x');
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+ block.insert(std::make_pair("key", SpdyString(value_size, 'x')));
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+ // Add value for existing key.
+ block.AppendValueOrAddHeader("abc", SpdyString(value_size, 'x'));
+ EXPECT_EQ(block.TotalBytesUsed(), SpdyHeaderBlockSize(block));
+
+ // Copies/clones SpdyHeaderBlock.
+ size_t block_size = block.TotalBytesUsed();
+ SpdyHeaderBlock block_copy = std::move(block);
+ EXPECT_EQ(block_size, block_copy.TotalBytesUsed());
+
+ // Erases key.
+ block_copy.erase("foo");
+ EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy));
+ block_copy.erase("key");
+ EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy));
+ block_copy.erase("abc");
+ EXPECT_EQ(block_copy.TotalBytesUsed(), SpdyHeaderBlockSize(block_copy));
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/core/spdy_no_op_visitor.cc b/chromium/net/spdy/core/spdy_no_op_visitor.cc
index b82e547adfc..a196069c20e 100644
--- a/chromium/net/spdy/core/spdy_no_op_visitor.cc
+++ b/chromium/net/spdy/core/spdy_no_op_visitor.cc
@@ -13,7 +13,7 @@ SpdyNoOpVisitor::SpdyNoOpVisitor() {
static_assert(std::is_abstract<SpdyNoOpVisitor>::value == false,
"Need to update SpdyNoOpVisitor.");
}
-SpdyNoOpVisitor::~SpdyNoOpVisitor() {}
+SpdyNoOpVisitor::~SpdyNoOpVisitor() = default;
SpdyHeadersHandlerInterface* SpdyNoOpVisitor::OnHeaderFrameStart(
SpdyStreamId stream_id) {
diff --git a/chromium/net/spdy/core/spdy_pinnable_buffer_piece.cc b/chromium/net/spdy/core/spdy_pinnable_buffer_piece.cc
index a277060dbe6..588a17be30b 100644
--- a/chromium/net/spdy/core/spdy_pinnable_buffer_piece.cc
+++ b/chromium/net/spdy/core/spdy_pinnable_buffer_piece.cc
@@ -11,7 +11,7 @@ namespace net {
SpdyPinnableBufferPiece::SpdyPinnableBufferPiece()
: buffer_(nullptr), length_(0) {}
-SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() {}
+SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() = default;
void SpdyPinnableBufferPiece::Pin() {
if (!storage_ && buffer_ != nullptr && length_ != 0) {
diff --git a/chromium/net/spdy/core/spdy_protocol.cc b/chromium/net/spdy/core/spdy_protocol.cc
index e13761b5462..3b57e367869 100644
--- a/chromium/net/spdy/core/spdy_protocol.cc
+++ b/chromium/net/spdy/core/spdy_protocol.cc
@@ -206,6 +206,15 @@ const char* ErrorCodeToString(SpdyErrorCode error_code) {
return "UNKNOWN_ERROR_CODE";
}
+size_t GetNumberRequiredContinuationFrames(size_t size) {
+ DCHECK_GT(size, kHttp2MaxControlFrameSendSize);
+ size_t overflow = size - kHttp2MaxControlFrameSendSize;
+ int payload_size =
+ kHttp2MaxControlFrameSendSize - kContinuationFrameMinimumSize;
+ // This is ceiling(overflow/payload_size) using integer arithmetics.
+ return (overflow - 1) / payload_size + 1;
+}
+
const char* const kHttp2Npn = "h2";
const char* const kHttp2AuthorityHeader = ":authority";
@@ -232,7 +241,7 @@ SpdyFrameWithHeaderBlockIR::SpdyFrameWithHeaderBlockIR(
SpdyHeaderBlock header_block)
: SpdyFrameWithFinIR(stream_id), header_block_(std::move(header_block)) {}
-SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() {}
+SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() = default;
SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, SpdyStringPiece data)
: SpdyFrameWithFinIR(stream_id),
@@ -261,7 +270,7 @@ SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id)
padded_(false),
padding_payload_len_(0) {}
-SpdyDataIR::~SpdyDataIR() {}
+SpdyDataIR::~SpdyDataIR() = default;
void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitData(*this);
@@ -272,7 +281,12 @@ SpdyFrameType SpdyDataIR::frame_type() const {
}
int SpdyDataIR::flow_control_window_consumed() const {
- return padded() ? 1 + padding_payload_len() + data_len() : data_len();
+ return padded_ ? 1 + padding_payload_len_ + data_len_ : data_len_;
+}
+
+size_t SpdyDataIR::size() const {
+ return kFrameHeaderSize +
+ (padded() ? 1 + padding_payload_len() + data_len() : data_len());
}
SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
@@ -281,7 +295,7 @@ SpdyRstStreamIR::SpdyRstStreamIR(SpdyStreamId stream_id,
set_error_code(error_code);
}
-SpdyRstStreamIR::~SpdyRstStreamIR() {}
+SpdyRstStreamIR::~SpdyRstStreamIR() = default;
void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitRstStream(*this);
@@ -291,9 +305,13 @@ SpdyFrameType SpdyRstStreamIR::frame_type() const {
return SpdyFrameType::RST_STREAM;
}
+size_t SpdyRstStreamIR::size() const {
+ return kRstStreamFrameSize;
+}
+
SpdySettingsIR::SpdySettingsIR() : is_ack_(false) {}
-SpdySettingsIR::~SpdySettingsIR() {}
+SpdySettingsIR::~SpdySettingsIR() = default;
void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitSettings(*this);
@@ -303,6 +321,10 @@ SpdyFrameType SpdySettingsIR::frame_type() const {
return SpdyFrameType::SETTINGS;
}
+size_t SpdySettingsIR::size() const {
+ return kFrameHeaderSize + values_.size() * kSettingsOneSettingSize;
+}
+
void SpdyPingIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitPing(*this);
}
@@ -311,6 +333,10 @@ SpdyFrameType SpdyPingIR::frame_type() const {
return SpdyFrameType::PING;
}
+size_t SpdyPingIR::size() const {
+ return kPingFrameSize;
+}
+
SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
SpdyErrorCode error_code,
SpdyStringPiece description)
@@ -335,7 +361,7 @@ SpdyGoAwayIR::SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
set_error_code(error_code);
}
-SpdyGoAwayIR::~SpdyGoAwayIR() {}
+SpdyGoAwayIR::~SpdyGoAwayIR() = default;
void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitGoAway(*this);
@@ -345,12 +371,16 @@ SpdyFrameType SpdyGoAwayIR::frame_type() const {
return SpdyFrameType::GOAWAY;
}
+size_t SpdyGoAwayIR::size() const {
+ return kGoawayFrameMinimumSize + description_.size();
+}
+
SpdyContinuationIR::SpdyContinuationIR(SpdyStreamId stream_id)
: SpdyFrameIR(stream_id), end_headers_(false) {
encoding_ = SpdyMakeUnique<SpdyString>();
}
-SpdyContinuationIR::~SpdyContinuationIR() {}
+SpdyContinuationIR::~SpdyContinuationIR() = default;
void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitContinuation(*this);
@@ -360,6 +390,13 @@ SpdyFrameType SpdyContinuationIR::frame_type() const {
return SpdyFrameType::CONTINUATION;
}
+size_t SpdyContinuationIR::size() const {
+ // We don't need to get the size of CONTINUATION frame directly. It is
+ // calculated in HEADERS or PUSH_PROMISE frame.
+ SPDY_BUG << "Shouldn't not call size() for CONTINUATION frame.";
+ return 0;
+}
+
void SpdyHeadersIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitHeaders(*this);
}
@@ -368,6 +405,29 @@ SpdyFrameType SpdyHeadersIR::frame_type() const {
return SpdyFrameType::HEADERS;
}
+size_t SpdyHeadersIR::size() const {
+ size_t size = kHeadersFrameMinimumSize;
+
+ if (padded_) {
+ // Padding field length.
+ size += 1;
+ size += padding_payload_len_;
+ }
+
+ if (has_priority_) {
+ size += 5;
+ }
+
+ // Assume no hpack encoding is applied.
+ size += header_block().TotalBytesUsed() +
+ header_block().size() * kPerHeaderHpackOverhead;
+ if (size > kHttp2MaxControlFrameSendSize) {
+ size += GetNumberRequiredContinuationFrames(size) *
+ kContinuationFrameMinimumSize;
+ }
+ return size;
+}
+
void SpdyWindowUpdateIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitWindowUpdate(*this);
}
@@ -376,6 +436,10 @@ SpdyFrameType SpdyWindowUpdateIR::frame_type() const {
return SpdyFrameType::WINDOW_UPDATE;
}
+size_t SpdyWindowUpdateIR::size() const {
+ return kWindowUpdateFrameSize;
+}
+
void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitPushPromise(*this);
}
@@ -384,9 +448,26 @@ SpdyFrameType SpdyPushPromiseIR::frame_type() const {
return SpdyFrameType::PUSH_PROMISE;
}
+size_t SpdyPushPromiseIR::size() const {
+ size_t size = kPushPromiseFrameMinimumSize;
+
+ if (padded_) {
+ // Padding length field.
+ size += 1;
+ size += padding_payload_len_;
+ }
+
+ size += header_block().TotalBytesUsed();
+ if (size > kHttp2MaxControlFrameSendSize) {
+ size += GetNumberRequiredContinuationFrames(size) *
+ kContinuationFrameMinimumSize;
+ }
+ return size;
+}
+
SpdyAltSvcIR::SpdyAltSvcIR(SpdyStreamId stream_id) : SpdyFrameIR(stream_id) {}
-SpdyAltSvcIR::~SpdyAltSvcIR() {}
+SpdyAltSvcIR::~SpdyAltSvcIR() = default;
void SpdyAltSvcIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitAltSvc(*this);
@@ -396,6 +477,16 @@ SpdyFrameType SpdyAltSvcIR::frame_type() const {
return SpdyFrameType::ALTSVC;
}
+size_t SpdyAltSvcIR::size() const {
+ size_t size = kGetAltSvcFrameMinimumSize;
+ size += origin_.length();
+ // TODO(yasong): estimates the size without serializing the vector.
+ SpdyString str =
+ SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector_);
+ size += str.size();
+ return size;
+}
+
void SpdyPriorityIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitPriority(*this);
}
@@ -404,6 +495,10 @@ SpdyFrameType SpdyPriorityIR::frame_type() const {
return SpdyFrameType::PRIORITY;
}
+size_t SpdyPriorityIR::size() const {
+ return kPriorityFrameSize;
+}
+
void SpdyUnknownIR::Visit(SpdyFrameVisitor* visitor) const {
return visitor->VisitUnknown(*this);
}
@@ -412,6 +507,10 @@ SpdyFrameType SpdyUnknownIR::frame_type() const {
return static_cast<SpdyFrameType>(type());
}
+size_t SpdyUnknownIR::size() const {
+ return kFrameHeaderSize + payload_.size();
+}
+
int SpdyUnknownIR::flow_control_window_consumed() const {
if (frame_type() == SpdyFrameType::DATA) {
return payload_.size();
diff --git a/chromium/net/spdy/core/spdy_protocol.h b/chromium/net/spdy/core/spdy_protocol.h
index 8b806a9a030..be15a0affc8 100644
--- a/chromium/net/spdy/core/spdy_protocol.h
+++ b/chromium/net/spdy/core/spdy_protocol.h
@@ -51,6 +51,12 @@ const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;
// the maximum control frame size we accept.
const uint32_t kHttp2DefaultFramePayloadLimit = 1 << 14;
+// The maximum size of the control frames that we send, including the size of
+// the header. This limit is arbitrary. We can enforce it here or at the
+// application layer. We chose the framing layer, but this can be changed (or
+// removed) if necessary later down the line.
+const size_t kHttp2MaxControlFrameSendSize = kHttp2DefaultFramePayloadLimit - 1;
+
// Number of octets in the frame header.
const size_t kFrameHeaderSize = 9;
@@ -276,6 +282,8 @@ const size_t kPriorityFrameSize = kFrameHeaderSize + 5;
// RST_STREAM frame has error_code (4 octets) field.
const size_t kRstStreamFrameSize = kFrameHeaderSize + 4;
const size_t kSettingsFrameMinimumSize = kFrameHeaderSize;
+const size_t kSettingsOneSettingSize =
+ sizeof(uint32_t) + sizeof(SpdySettingsIds);
// PUSH_PROMISE frame has promised_stream_id (4 octet) field.
const size_t kPushPromiseFrameMinimumSize = kFrameHeaderSize + 4;
// PING frame has opaque_bytes (8 octet) field.
@@ -300,6 +308,10 @@ const int32_t kInitialStreamWindowSize = 64 * 1024 - 1;
const int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
// The NPN string for HTTP2, "h2".
extern const char* const kHttp2Npn;
+// An estimate size of the HPACK overhead for each header field. 1 bytes for
+// indexed literal, 1 bytes for key literal and length encoding, and 2 bytes for
+// value literal and length encoding.
+const size_t kPerHeaderHpackOverhead = 4;
// Names of pseudo-headers defined for HTTP/2 requests.
SPDY_EXPORT_PRIVATE extern const char* const kHttp2AuthorityHeader;
@@ -310,6 +322,8 @@ SPDY_EXPORT_PRIVATE extern const char* const kHttp2SchemeHeader;
// Name of pseudo-header defined for HTTP/2 responses.
SPDY_EXPORT_PRIVATE extern const char* const kHttp2StatusHeader;
+SPDY_EXPORT_PRIVATE size_t GetNumberRequiredContinuationFrames(size_t size);
+
// Variant type (i.e. tagged union) that is either a SPDY 3.x priority value,
// or else an HTTP/2 stream dependency tuple {parent stream ID, weight,
// exclusive bit}. Templated to allow for use by QUIC code; SPDY and HTTP/2
@@ -417,6 +431,9 @@ class SPDY_EXPORT_PRIVATE SpdyFrameIR {
virtual SpdyFrameType frame_type() const = 0;
SpdyStreamId stream_id() const { return stream_id_; }
virtual bool fin() const;
+ // Returns an estimate of the size of the serialized frame, without applying
+ // compression. May not be exact.
+ virtual size_t size() const = 0;
// Returns the number of bytes of flow control window that would be consumed
// by this frame if written to the wire.
@@ -535,6 +552,8 @@ class SPDY_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR {
int flow_control_window_consumed() const override;
+ size_t size() const override;
+
private:
// Used to store data that this SpdyDataIR should own.
std::unique_ptr<SpdyString> data_store_;
@@ -561,6 +580,8 @@ class SPDY_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SpdyErrorCode error_code_;
@@ -583,6 +604,8 @@ class SPDY_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SettingsMap values_;
bool is_ack_;
@@ -602,6 +625,8 @@ class SPDY_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SpdyPingId id_;
bool is_ack_;
@@ -648,6 +673,8 @@ class SPDY_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SpdyStreamId last_good_stream_id_;
SpdyErrorCode error_code_;
@@ -668,6 +695,8 @@ class SPDY_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
bool has_priority() const { return has_priority_; }
void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
int weight() const { return weight_; }
@@ -714,6 +743,8 @@ class SPDY_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
int32_t delta_;
@@ -738,6 +769,8 @@ class SPDY_EXPORT_PRIVATE SpdyPushPromiseIR
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
bool padded() const { return padded_; }
int padding_payload_len() const { return padding_payload_len_; }
void set_padding_len(int padding_len) {
@@ -772,6 +805,7 @@ class SPDY_EXPORT_PRIVATE SpdyContinuationIR : public SpdyFrameIR {
void take_encoding(std::unique_ptr<SpdyString> encoding) {
encoding_ = std::move(encoding);
}
+ size_t size() const override;
private:
std::unique_ptr<SpdyString> encoding_;
@@ -798,6 +832,8 @@ class SPDY_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SpdyString origin_;
SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector_;
@@ -822,6 +858,8 @@ class SPDY_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameIR {
SpdyFrameType frame_type() const override;
+ size_t size() const override;
+
private:
SpdyStreamId parent_stream_id_;
int weight_;
@@ -852,6 +890,8 @@ class SPDY_EXPORT_PRIVATE SpdyUnknownIR : public SpdyFrameIR {
int flow_control_window_consumed() const override;
+ size_t size() const override;
+
protected:
// Allows subclasses to overwrite the default length.
void set_length(int length) { length_ = length; }
diff --git a/chromium/net/spdy/core/spdy_test_utils.cc b/chromium/net/spdy/core/spdy_test_utils.cc
index 1717236f4b9..e8e29f7b7b8 100644
--- a/chromium/net/spdy/core/spdy_test_utils.cc
+++ b/chromium/net/spdy/core/spdy_test_utils.cc
@@ -149,9 +149,9 @@ void TestHeadersHandler::OnHeaderBlockEnd(
compressed_header_bytes_parsed_ = compressed_header_bytes_parsed;
}
-TestServerPushDelegate::TestServerPushDelegate() {}
+TestServerPushDelegate::TestServerPushDelegate() = default;
-TestServerPushDelegate::~TestServerPushDelegate() {}
+TestServerPushDelegate::~TestServerPushDelegate() = default;
void TestServerPushDelegate::OnPush(
std::unique_ptr<ServerPushHelper> push_helper,
diff --git a/chromium/net/ssl/client_cert_identity.cc b/chromium/net/ssl/client_cert_identity.cc
index 3b89f41f757..928aafde8ab 100644
--- a/chromium/net/ssl/client_cert_identity.cc
+++ b/chromium/net/ssl/client_cert_identity.cc
@@ -5,6 +5,7 @@
#include "net/ssl/client_cert_identity.h"
#include "base/bind.h"
+#include "net/cert/x509_util.h"
#include "net/ssl/ssl_private_key.h"
namespace net {
@@ -38,7 +39,7 @@ void ClientCertIdentity::SelfOwningAcquirePrivateKey(
}
void ClientCertIdentity::SetIntermediates(
- X509Certificate::OSCertHandles intermediates) {
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) {
// Allow UTF-8 inside PrintableStrings in client certificates. See
// crbug.com/770323.
// TODO(mattm): Perhaps X509Certificate should have a method to clone the
@@ -47,9 +48,10 @@ void ClientCertIdentity::SetIntermediates(
// X509Certificate was initially created.)
X509Certificate::UnsafeCreateOptions options;
options.printable_string_is_utf8 = true;
- cert_ = X509Certificate::CreateFromHandleUnsafeOptions(
- cert_->os_cert_handle(), intermediates, options);
- // |cert_->os_cert_handle()| was already successfully parsed, so this should
+ cert_ = X509Certificate::CreateFromBufferUnsafeOptions(
+ x509_util::DupCryptoBuffer(cert_->cert_buffer()),
+ std::move(intermediates), options);
+ // |cert_->cert_buffer()| was already successfully parsed, so this should
// never fail.
DCHECK(cert_);
}
@@ -82,10 +84,8 @@ bool ClientCertIdentitySorter::operator()(
return a->valid_start() > b->valid_start();
// Otherwise, prefer client certificates with shorter chains.
- const X509Certificate::OSCertHandles& a_intermediates =
- a->GetIntermediateCertificates();
- const X509Certificate::OSCertHandles& b_intermediates =
- b->GetIntermediateCertificates();
+ const auto& a_intermediates = a->intermediate_buffers();
+ const auto& b_intermediates = b->intermediate_buffers();
return a_intermediates.size() < b_intermediates.size();
}
diff --git a/chromium/net/ssl/client_cert_identity.h b/chromium/net/ssl/client_cert_identity.h
index 1f8e4cb79be..6848217b2d2 100644
--- a/chromium/net/ssl/client_cert_identity.h
+++ b/chromium/net/ssl/client_cert_identity.h
@@ -56,7 +56,8 @@ class NET_EXPORT ClientCertIdentity {
// this will change the value of |certificate()|, and any references that
// were retained to the previous value will not reflect the updated
// intermediates list.
- void SetIntermediates(X509Certificate::OSCertHandles intermediates);
+ void SetIntermediates(
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates);
private:
scoped_refptr<net::X509Certificate> cert_;
diff --git a/chromium/net/ssl/client_cert_store_mac.cc b/chromium/net/ssl/client_cert_store_mac.cc
index cbbc35b4b61..b2fb32d680b 100644
--- a/chromium/net/ssl/client_cert_store_mac.cc
+++ b/chromium/net/ssl/client_cert_store_mac.cc
@@ -13,6 +13,8 @@
#include <algorithm>
#include <memory>
#include <string>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -132,7 +134,13 @@ bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
if (!new_cert || !new_cert->IsIssuedByEncoded(valid_issuers))
return false;
- identity->SetIntermediates(new_cert->GetIntermediateCertificates());
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_buffers;
+ intermediate_buffers.reserve(new_cert->intermediate_buffers().size());
+ for (const auto& intermediate : new_cert->intermediate_buffers()) {
+ intermediate_buffers.push_back(
+ x509_util::DupCryptoBuffer(intermediate.get()));
+ }
+ identity->SetIntermediates(std::move(intermediate_buffers));
return true;
}
@@ -193,7 +201,7 @@ bool SupportsSSLClientAuth(SecCertificateRef cert) {
// storing the matching certificates in |selected_identities|.
// If |query_keychain| is true, Keychain Services will be queried to construct
// full certificate chains. If it is false, only the the certificates and their
-// intermediates (available via X509Certificate::GetIntermediateCertificates())
+// intermediates (available via X509Certificate::intermediate_buffers())
// will be considered.
void GetClientCertsImpl(std::unique_ptr<ClientCertIdentity> preferred_identity,
ClientCertIdentityList regular_identities,
@@ -219,9 +227,9 @@ void GetClientCertsImpl(std::unique_ptr<ClientCertIdentity> preferred_identity,
selected_identities->begin(), selected_identities->end(),
[&cert](
const std::unique_ptr<ClientCertIdentity>& other_cert_identity) {
- return X509Certificate::IsSameOSCert(
- cert->certificate()->os_cert_handle(),
- other_cert_identity->certificate()->os_cert_handle());
+ return x509_util::CryptoBufferEqual(
+ cert->certificate()->cert_buffer(),
+ other_cert_identity->certificate()->cert_buffer());
});
if (cert_iter != selected_identities->end())
continue;
@@ -236,19 +244,56 @@ void GetClientCertsImpl(std::unique_ptr<ClientCertIdentity> preferred_identity,
}
// Preferred cert should appear first in the ui, so exclude it from the
- // sorting. Compare the os_cert_handle since the X509Certificate object may
+ // sorting. Compare the cert_buffer since the X509Certificate object may
// have changed if intermediates were added.
ClientCertIdentityList::iterator sort_begin = selected_identities->begin();
ClientCertIdentityList::iterator sort_end = selected_identities->end();
if (preferred_cert_orig && sort_begin != sort_end &&
- X509Certificate::IsSameOSCert(
- sort_begin->get()->certificate()->os_cert_handle(),
- preferred_cert_orig->os_cert_handle())) {
+ x509_util::CryptoBufferEqual(
+ sort_begin->get()->certificate()->cert_buffer(),
+ preferred_cert_orig->cert_buffer())) {
++sort_begin;
}
sort(sort_begin, sort_end, ClientCertIdentitySorter());
}
+// Given a |sec_identity|, identifies its corresponding certificate, and either
+// adds it to |regular_identities| or assigns it to |preferred_identity|, if the
+// |sec_identity| matches the |preferred_sec_identity|.
+void AddIdentity(ScopedCFTypeRef<SecIdentityRef> sec_identity,
+ SecIdentityRef preferred_sec_identity,
+ ClientCertIdentityList* regular_identities,
+ std::unique_ptr<ClientCertIdentity>* preferred_identity) {
+ OSStatus err;
+ ScopedCFTypeRef<SecCertificateRef> cert_handle;
+ err = SecIdentityCopyCertificate(sec_identity.get(),
+ cert_handle.InitializeInto());
+ if (err != noErr)
+ return;
+
+ if (!SupportsSSLClientAuth(cert_handle.get()))
+ return;
+
+ // Allow UTF-8 inside PrintableStrings in client certificates. See
+ // crbug.com/770323.
+ X509Certificate::UnsafeCreateOptions options;
+ options.printable_string_is_utf8 = true;
+ scoped_refptr<X509Certificate> cert(
+ x509_util::CreateX509CertificateFromSecCertificate(cert_handle.get(), {},
+ options));
+ if (!cert)
+ return;
+
+ if (preferred_sec_identity &&
+ CFEqual(preferred_sec_identity, sec_identity.get())) {
+ *preferred_identity = std::make_unique<ClientCertIdentityMac>(
+ std::move(cert), std::move(sec_identity));
+ } else {
+ regular_identities->push_back(std::make_unique<ClientCertIdentityMac>(
+ std::move(cert), std::move(sec_identity)));
+ }
+}
+
ClientCertIdentityList GetClientCertsOnBackgroundThread(
const SSLCertRequestInfo& request) {
std::string server_domain = request.host_and_port.host();
@@ -293,36 +338,8 @@ ClientCertIdentityList GetClientCertsOnBackgroundThread(
}
if (err)
break;
-
- ScopedCFTypeRef<SecCertificateRef> cert_handle;
- err = SecIdentityCopyCertificate(sec_identity.get(),
- cert_handle.InitializeInto());
- if (err != noErr)
- continue;
-
- if (!SupportsSSLClientAuth(cert_handle.get()))
- continue;
-
- // Allow UTF-8 inside PrintableStrings in client certificates. See
- // crbug.com/770323.
- X509Certificate::UnsafeCreateOptions options;
- options.printable_string_is_utf8 = true;
- scoped_refptr<X509Certificate> cert(
- x509_util::CreateX509CertificateFromSecCertificate(
- cert_handle.get(), std::vector<SecCertificateRef>(), options));
- if (!cert)
- continue;
-
- if (preferred_sec_identity &&
- CFEqual(preferred_sec_identity, sec_identity.get())) {
- // Only one certificate should match.
- DCHECK(!preferred_identity.get());
- preferred_identity = std::make_unique<ClientCertIdentityMac>(
- std::move(cert), std::move(sec_identity));
- } else {
- regular_identities.push_back(std::make_unique<ClientCertIdentityMac>(
- std::move(cert), std::move(sec_identity)));
- }
+ AddIdentity(std::move(sec_identity), preferred_sec_identity.get(),
+ &regular_identities, &preferred_identity);
}
if (err != errSecItemNotFound) {
@@ -330,6 +347,39 @@ ClientCertIdentityList GetClientCertsOnBackgroundThread(
return ClientCertIdentityList();
}
+ // macOS provides two ways to search for identities. SecIdentitySearchCreate()
+ // is deprecated, as it relies on CSSM_KEYUSE_SIGN (part of the deprecated
+ // CDSM/CSSA implementation), but is necessary to return some certificates
+ // that would otherwise not be returned by SecItemCopyMatching(), which is the
+ // non-deprecated way. However, SecIdentitySearchCreate() will not return all
+ // items, particularly smart-card based identities, so it's necessary to call
+ // both functions.
+ static const void* kKeys[] = {
+ kSecClass, kSecMatchLimit, kSecReturnRef, kSecAttrCanSign,
+ };
+ static const void* kValues[] = {
+ kSecClassIdentity, kSecMatchLimitAll, kCFBooleanTrue, kCFBooleanTrue,
+ };
+ ScopedCFTypeRef<CFDictionaryRef> query(CFDictionaryCreate(
+ kCFAllocatorDefault, kKeys, kValues, arraysize(kValues),
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ ScopedCFTypeRef<CFArrayRef> result;
+ {
+ base::AutoLock lock(crypto::GetMacSecurityServicesLock());
+ err = SecItemCopyMatching(
+ query, reinterpret_cast<CFTypeRef*>(result.InitializeInto()));
+ }
+ if (!err) {
+ for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
+ SecIdentityRef item = reinterpret_cast<SecIdentityRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(result, i)));
+ AddIdentity(
+ ScopedCFTypeRef<SecIdentityRef>(item, base::scoped_policy::RETAIN),
+ preferred_sec_identity.get(), &regular_identities,
+ &preferred_identity);
+ }
+ }
+
ClientCertIdentityList selected_identities;
GetClientCertsImpl(std::move(preferred_identity),
std::move(regular_identities), request, true,
diff --git a/chromium/net/ssl/client_cert_store_nss.cc b/chromium/net/ssl/client_cert_store_nss.cc
index 512b38e81cb..7c773ee51d1 100644
--- a/chromium/net/ssl/client_cert_store_nss.cc
+++ b/chromium/net/ssl/client_cert_store_nss.cc
@@ -115,25 +115,22 @@ void ClientCertStoreNSS::FilterCertsOnWorkerThread(
continue;
}
- X509Certificate::OSCertHandles intermediates_raw;
- intermediates_raw.reserve(nss_intermediates.size());
std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
intermediates.reserve(nss_intermediates.size());
for (const ScopedCERTCertificate& nss_intermediate : nss_intermediates) {
bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle(
- X509Certificate::CreateOSCertHandleFromBytes(
+ X509Certificate::CreateCertBufferFromBytes(
reinterpret_cast<const char*>(nss_intermediate->derCert.data),
nss_intermediate->derCert.len));
if (!intermediate_cert_handle)
break;
- intermediates_raw.push_back(intermediate_cert_handle.get());
intermediates.push_back(std::move(intermediate_cert_handle));
}
// Retain a copy of the intermediates. Some deployments expect the client to
// supply intermediates out of the local store. See
// https://crbug.com/548631.
- (*examine_iter)->SetIntermediates(intermediates_raw);
+ (*examine_iter)->SetIntermediates(std::move(intermediates));
if (examine_iter == keep_iter)
++keep_iter;
diff --git a/chromium/net/ssl/client_cert_store_nss_unittest.cc b/chromium/net/ssl/client_cert_store_nss_unittest.cc
index 5b9b323a167..859a38c59e9 100644
--- a/chromium/net/ssl/client_cert_store_nss_unittest.cc
+++ b/chromium/net/ssl/client_cert_store_nss_unittest.cc
@@ -110,9 +110,9 @@ TEST(ClientCertStoreNSSTest, BuildsCertificateChain) {
ASSERT_EQ(1u, selected_identities.size());
scoped_refptr<X509Certificate> selected_cert =
selected_identities[0]->certificate();
- EXPECT_TRUE(X509Certificate::IsSameOSCert(client_1->os_cert_handle(),
- selected_cert->os_cert_handle()));
- ASSERT_EQ(0u, selected_cert->GetIntermediateCertificates().size());
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(client_1->cert_buffer(),
+ selected_cert->cert_buffer()));
+ ASSERT_EQ(0u, selected_cert->intermediate_buffers().size());
scoped_refptr<SSLPrivateKey> ssl_private_key;
base::RunLoop key_loop;
@@ -144,12 +144,12 @@ TEST(ClientCertStoreNSSTest, BuildsCertificateChain) {
ASSERT_EQ(1u, selected_identities.size());
scoped_refptr<X509Certificate> selected_cert =
selected_identities[0]->certificate();
- EXPECT_TRUE(X509Certificate::IsSameOSCert(client_1->os_cert_handle(),
- selected_cert->os_cert_handle()));
- ASSERT_EQ(1u, selected_cert->GetIntermediateCertificates().size());
- EXPECT_TRUE(X509Certificate::IsSameOSCert(
- client_1_ca->os_cert_handle(),
- selected_cert->GetIntermediateCertificates()[0]));
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(client_1->cert_buffer(),
+ selected_cert->cert_buffer()));
+ ASSERT_EQ(1u, selected_cert->intermediate_buffers().size());
+ EXPECT_TRUE(x509_util::CryptoBufferEqual(
+ client_1_ca->cert_buffer(),
+ selected_cert->intermediate_buffers()[0].get()));
scoped_refptr<SSLPrivateKey> ssl_private_key;
base::RunLoop key_loop;
@@ -221,7 +221,7 @@ TEST(ClientCertStoreNSSTest, SubjectPrintableStringContainingUTF8) {
scoped_refptr<X509Certificate> selected_cert =
selected_identities[0]->certificate();
EXPECT_TRUE(x509_util::IsSameCertificate(cert.get(), selected_cert.get()));
- EXPECT_EQ(0u, selected_cert->GetIntermediateCertificates().size());
+ EXPECT_EQ(0u, selected_cert->intermediate_buffers().size());
scoped_refptr<SSLPrivateKey> ssl_private_key;
base::RunLoop key_loop;
diff --git a/chromium/net/ssl/client_cert_store_unittest-inl.h b/chromium/net/ssl/client_cert_store_unittest-inl.h
index 4da72c4afbd..7cc02d3d4be 100644
--- a/chromium/net/ssl/client_cert_store_unittest-inl.h
+++ b/chromium/net/ssl/client_cert_store_unittest-inl.h
@@ -152,7 +152,7 @@ TYPED_TEST_P(ClientCertStoreTest, PrintableStringContainingUTF8) {
X509Certificate::UnsafeCreateOptions options;
options.printable_string_is_utf8 = true;
scoped_refptr<X509Certificate> cert =
- X509Certificate::CreateFromHandleUnsafeOptions(cert_handle.get(), {},
+ X509Certificate::CreateFromBufferUnsafeOptions(std::move(cert_handle), {},
options);
ASSERT_TRUE(cert);
diff --git a/chromium/net/ssl/client_cert_store_win.cc b/chromium/net/ssl/client_cert_store_win.cc
index 6622ea417f4..d9c271f3ab1 100644
--- a/chromium/net/ssl/client_cert_store_win.cc
+++ b/chromium/net/ssl/client_cert_store_win.cc
@@ -25,6 +25,7 @@
#include "net/ssl/ssl_platform_key_util.h"
#include "net/ssl/ssl_platform_key_win.h"
#include "net/ssl/ssl_private_key.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
@@ -273,16 +274,16 @@ bool ClientCertStoreWin::SelectClientCertsForTesting(
return false;
// Add available certificates to the test store.
- for (size_t i = 0; i < input_certs.size(); ++i) {
+ for (const auto& input_cert : input_certs) {
// Add the certificate to the test store.
PCCERT_CONTEXT cert = NULL;
- std::string der_cert;
- X509Certificate::GetDEREncoded(input_certs[i]->os_cert_handle(), &der_cert);
if (!CertAddEncodedCertificateToStore(
test_store, X509_ASN_ENCODING,
- reinterpret_cast<const BYTE*>(der_cert.data()),
- base::checked_cast<DWORD>(der_cert.size()), CERT_STORE_ADD_NEW,
- &cert)) {
+ reinterpret_cast<const BYTE*>(
+ CRYPTO_BUFFER_data(input_cert->cert_buffer())),
+ base::checked_cast<DWORD>(
+ CRYPTO_BUFFER_len(input_cert->cert_buffer())),
+ CERT_STORE_ADD_NEW, &cert)) {
return false;
}
// Hold the reference to the certificate (since we requested a copy).
diff --git a/chromium/net/ssl/openssl_ssl_util.cc b/chromium/net/ssl/openssl_ssl_util.cc
index ae0fb4f75e9..b2067f1fe1f 100644
--- a/chromium/net/ssl/openssl_ssl_util.cc
+++ b/chromium/net/ssl/openssl_ssl_util.cc
@@ -231,11 +231,10 @@ bool SetSSLChainAndKey(SSL* ssl,
EVP_PKEY* pkey,
const SSL_PRIVATE_KEY_METHOD* custom_key) {
std::vector<CRYPTO_BUFFER*> chain_raw;
- chain_raw.push_back(cert->os_cert_handle());
- for (X509Certificate::OSCertHandle handle :
- cert->GetIntermediateCertificates()) {
- chain_raw.push_back(handle);
- }
+ chain_raw.reserve(1 + cert->intermediate_buffers().size());
+ chain_raw.push_back(cert->cert_buffer());
+ for (const auto& handle : cert->intermediate_buffers())
+ chain_raw.push_back(handle.get());
if (!SSL_set_chain_and_key(ssl, chain_raw.data(), chain_raw.size(), pkey,
custom_key)) {
diff --git a/chromium/net/ssl/ssl_client_session_cache.cc b/chromium/net/ssl/ssl_client_session_cache.cc
index eebca7640b3..f7fcdfa6e8a 100644
--- a/chromium/net/ssl/ssl_client_session_cache.cc
+++ b/chromium/net/ssl/ssl_client_session_cache.cc
@@ -17,7 +17,7 @@
namespace net {
SSLClientSessionCache::SSLClientSessionCache(const Config& config)
- : clock_(new base::DefaultClock),
+ : clock_(base::DefaultClock::GetInstance()),
config_(config),
cache_(config.max_entries),
lookups_since_flush_(0) {
@@ -87,9 +87,8 @@ void SSLClientSessionCache::Flush() {
cache_.Clear();
}
-void SSLClientSessionCache::SetClockForTesting(
- std::unique_ptr<base::Clock> clock) {
- clock_ = std::move(clock);
+void SSLClientSessionCache::SetClockForTesting(base::Clock* clock) {
+ clock_ = clock;
}
bool SSLClientSessionCache::IsExpired(SSL_SESSION* session, time_t now) {
diff --git a/chromium/net/ssl/ssl_client_session_cache.h b/chromium/net/ssl/ssl_client_session_cache.h
index 865206ffe5e..ad64c8062db 100644
--- a/chromium/net/ssl/ssl_client_session_cache.h
+++ b/chromium/net/ssl/ssl_client_session_cache.h
@@ -64,7 +64,7 @@ class NET_EXPORT SSLClientSessionCache : public base::MemoryCoordinatorClient {
// Removes all entries from the cache.
void Flush();
- void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+ void SetClockForTesting(base::Clock* clock);
// Dumps memory allocation stats. |pmd| is the ProcessMemoryDump of the
// browser process.
@@ -101,7 +101,7 @@ class NET_EXPORT SSLClientSessionCache : public base::MemoryCoordinatorClient {
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
- std::unique_ptr<base::Clock> clock_;
+ base::Clock* clock_;
Config config_;
base::HashingMRUCache<std::string, Entry> cache_;
size_t lookups_since_flush_;
diff --git a/chromium/net/ssl/ssl_client_session_cache_unittest.cc b/chromium/net/ssl/ssl_client_session_cache_unittest.cc
index 6b6299186a2..461fb189561 100644
--- a/chromium/net/ssl/ssl_client_session_cache_unittest.cc
+++ b/chromium/net/ssl/ssl_client_session_cache_unittest.cc
@@ -313,8 +313,8 @@ TEST_F(SSLClientSessionCacheTest, Expiration) {
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
SSLClientSessionCache cache(config);
- base::SimpleTestClock* clock = MakeTestClock().release();
- cache.SetClockForTesting(base::WrapUnique(clock));
+ std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
+ cache.SetClockForTesting(clock.get());
// Add |kNumEntries - 1| entries.
for (size_t i = 0; i < kNumEntries - 1; i++) {
@@ -362,8 +362,8 @@ TEST_F(SSLClientSessionCacheTest, LookupExpirationCheck) {
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
SSLClientSessionCache cache(config);
- base::SimpleTestClock* clock = MakeTestClock().release();
- cache.SetClockForTesting(base::WrapUnique(clock));
+ std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
+ cache.SetClockForTesting(clock.get());
// Insert an entry into the session cache.
bssl::UniquePtr<SSL_SESSION> session =
@@ -410,8 +410,8 @@ TEST_F(SSLClientSessionCacheTest, TestFlushOnMemoryNotifications) {
SSLClientSessionCache::Config config;
config.expiration_check_count = kExpirationCheckCount;
SSLClientSessionCache cache(config);
- base::SimpleTestClock* clock = MakeTestClock().release();
- cache.SetClockForTesting(base::WrapUnique(clock));
+ std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
+ cache.SetClockForTesting(clock.get());
// Insert an entry into the session cache.
bssl::UniquePtr<SSL_SESSION> session1 =
diff --git a/chromium/net/ssl/ssl_config.cc b/chromium/net/ssl/ssl_config.cc
index a460ebe038f..72d63d83a28 100644
--- a/chromium/net/ssl/ssl_config.cc
+++ b/chromium/net/ssl/ssl_config.cc
@@ -12,7 +12,7 @@ const uint16_t kDefaultSSLVersionMin = SSL_PROTOCOL_VERSION_TLS1;
const uint16_t kDefaultSSLVersionMax = SSL_PROTOCOL_VERSION_TLS1_2;
-const TLS13Variant kDefaultTLS13Variant = kTLS13VariantDraft;
+const TLS13Variant kDefaultTLS13Variant = kTLS13VariantDraft22;
SSLConfig::CertAndStatus::CertAndStatus() = default;
SSLConfig::CertAndStatus::CertAndStatus(scoped_refptr<X509Certificate> cert_arg,
@@ -26,6 +26,7 @@ SSLConfig::SSLConfig()
rev_checking_required_local_anchors(false),
sha1_local_anchors_enabled(true),
common_name_fallback_local_anchors_enabled(true),
+ symantec_enforcement_disabled(false),
version_min(kDefaultSSLVersionMin),
version_max(kDefaultSSLVersionMax),
tls13_variant(kDefaultTLS13Variant),
@@ -69,6 +70,9 @@ int SSLConfig::GetCertVerifyFlags() const {
flags |= CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
if (common_name_fallback_local_anchors_enabled)
flags |= CertVerifier::VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS;
+ if (symantec_enforcement_disabled)
+ flags |= CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT;
+
return flags;
}
diff --git a/chromium/net/ssl/ssl_config.h b/chromium/net/ssl/ssl_config.h
index cf6c693f425..d1d677179d1 100644
--- a/chromium/net/ssl/ssl_config.h
+++ b/chromium/net/ssl/ssl_config.h
@@ -36,10 +36,9 @@ enum TokenBindingParam {
};
enum TLS13Variant {
- kTLS13VariantDraft,
- kTLS13VariantExperiment,
kTLS13VariantExperiment2,
- kTLS13VariantExperiment3,
+ kTLS13VariantDraft22,
+ kTLS13VariantDraft23,
};
// Default minimum protocol version.
@@ -94,6 +93,11 @@ struct NET_EXPORT SSLConfig {
// (non-public) trust anchor will be allowed to match.
bool common_name_fallback_local_anchors_enabled;
+ // symantec_enforcement_disabled is true if the policies outlined in
+ // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+ // should not be enforced.
+ bool symantec_enforcement_disabled;
+
// The minimum and maximum protocol versions that are enabled.
// (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.)
// SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it
diff --git a/chromium/net/ssl/ssl_config_unittest.cc b/chromium/net/ssl/ssl_config_unittest.cc
index 437edd5bd02..e3fca97dec2 100644
--- a/chromium/net/ssl/ssl_config_unittest.cc
+++ b/chromium/net/ssl/ssl_config_unittest.cc
@@ -15,32 +15,25 @@ void CheckCertVerifyFlags(SSLConfig* ssl_config,
bool rev_checking_enabled,
bool verify_ev_cert,
bool cert_io_enabled,
- bool rev_checking_required_local_anchors) {
+ bool rev_checking_required_local_anchors,
+ bool symantec_enforcement_disabled) {
ssl_config->rev_checking_enabled = rev_checking_enabled;
ssl_config->verify_ev_cert = verify_ev_cert;
ssl_config->cert_io_enabled = cert_io_enabled;
ssl_config->rev_checking_required_local_anchors =
rev_checking_required_local_anchors;
+ ssl_config->symantec_enforcement_disabled = symantec_enforcement_disabled;
+
int flags = ssl_config->GetCertVerifyFlags();
- if (rev_checking_enabled)
- EXPECT_TRUE(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED);
- else
- EXPECT_FALSE(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED);
- if (verify_ev_cert)
- EXPECT_TRUE(flags & CertVerifier::VERIFY_EV_CERT);
- else
- EXPECT_FALSE(flags & CertVerifier::VERIFY_EV_CERT);
- if (cert_io_enabled)
- EXPECT_TRUE(flags & CertVerifier::VERIFY_CERT_IO_ENABLED);
- else
- EXPECT_FALSE(flags & CertVerifier::VERIFY_CERT_IO_ENABLED);
- if (rev_checking_required_local_anchors) {
- EXPECT_TRUE(flags &
- CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS);
- } else {
- EXPECT_FALSE(flags &
- CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS);
- }
+ EXPECT_EQ(rev_checking_enabled,
+ !!(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED));
+ EXPECT_EQ(verify_ev_cert, !!(flags & CertVerifier::VERIFY_EV_CERT));
+ EXPECT_EQ(cert_io_enabled, !!(flags & CertVerifier::VERIFY_CERT_IO_ENABLED));
+ EXPECT_EQ(
+ rev_checking_required_local_anchors,
+ !!(flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS));
+ EXPECT_EQ(symantec_enforcement_disabled,
+ !!(flags & CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT));
}
} // namespace
@@ -51,37 +44,50 @@ TEST(SSLConfigTest, GetCertVerifyFlags) {
/*rev_checking_enabled=*/true,
/*verify_ev_cert=*/true,
/*cert_io_enabled=*/true,
- /*rev_checking_required_local_anchors=*/true);
+ /*rev_checking_required_local_anchors=*/true,
+ /*symantec_enforcement_disabled=*/true);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
/*verify_ev_cert=*/false,
/*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/false);
+ /*rev_checking_required_local_anchors=*/false,
+ /*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/true,
/*verify_ev_cert=*/false,
/*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/false);
+ /*rev_checking_required_local_anchors=*/false,
+ /*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
/*verify_ev_cert=*/true,
/*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/false);
+ /*rev_checking_required_local_anchors=*/false,
+ /*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
/*verify_ev_cert=*/false,
/*cert_io_enabled=*/true,
- /*rev_checking_required_local_anchors=*/false);
+ /*rev_checking_required_local_anchors=*/false,
+ /*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
/*verify_ev_cert=*/false,
/*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/true);
+ /*rev_checking_required_local_anchors=*/true,
+ /*symantec_enforcement_disabled=*/false);
+
+ CheckCertVerifyFlags(&ssl_config,
+ /*rev_checking_enabled=*/false,
+ /*verify_ev_cert=*/false,
+ /*cert_io_enabled=*/true,
+ /*rev_checking_required_local_anchors=*/false,
+ /*symantec_enforcement_disabled=*/true);
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_info.cc b/chromium/net/ssl/ssl_info.cc
index 28fcc140d66..f80610f22ee 100644
--- a/chromium/net/ssl/ssl_info.cc
+++ b/chromium/net/ssl/ssl_info.cc
@@ -48,6 +48,7 @@ void SSLInfo::Reset() {
ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
ct_policy_compliance_required = false;
ocsp_result = OCSPVerifyResult();
+ is_fatal_cert_error = false;
}
void SSLInfo::SetCertError(int error) {
diff --git a/chromium/net/ssl/ssl_info.h b/chromium/net/ssl/ssl_info.h
index fd39bbc9f62..2d903cf26df 100644
--- a/chromium/net/ssl/ssl_info.h
+++ b/chromium/net/ssl/ssl_info.h
@@ -139,6 +139,10 @@ class NET_EXPORT SSLInfo {
// OCSP stapling details.
OCSPVerifyResult ocsp_result;
+
+ // True if there was a certificate error which should be treated as fatal,
+ // and false otherwise.
+ bool is_fatal_cert_error;
};
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_util.cc b/chromium/net/ssl/ssl_platform_key_util.cc
index 46ba59f064f..70df11b4fd7 100644
--- a/chromium/net/ssl/ssl_platform_key_util.cc
+++ b/chromium/net/ssl/ssl_platform_key_util.cc
@@ -12,6 +12,7 @@
#include "crypto/openssl_util.h"
#include "net/cert/asn1_util.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec_key.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
@@ -54,11 +55,10 @@ bool GetClientCertInfo(const X509Certificate* certificate,
size_t* out_max_length) {
crypto::OpenSSLErrStackTracer tracker(FROM_HERE);
- std::string der_encoded;
base::StringPiece spki;
- if (!X509Certificate::GetDEREncoded(certificate->os_cert_handle(),
- &der_encoded) ||
- !asn1::ExtractSPKIFromDERCert(der_encoded, &spki)) {
+ if (!asn1::ExtractSPKIFromDERCert(
+ x509_util::CryptoBufferAsStringPiece(certificate->cert_buffer()),
+ &spki)) {
LOG(ERROR) << "Could not extract SPKI from certificate.";
return false;
}
diff --git a/chromium/net/test/cert_test_util.cc b/chromium/net/test/cert_test_util.cc
index 0295d7b8963..454071f2fc7 100644
--- a/chromium/net/test/cert_test_util.cc
+++ b/chromium/net/test/cert_test_util.cc
@@ -9,6 +9,7 @@
#include "base/threading/thread_restrictions.h"
#include "net/cert/ev_root_ca_metadata.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/test/test_data_directory.h"
namespace net {
@@ -52,12 +53,14 @@ scoped_refptr<X509Certificate> CreateCertificateChainFromFile(
if (certs.empty())
return NULL;
- X509Certificate::OSCertHandles intermediates;
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
for (size_t i = 1; i < certs.size(); ++i)
- intermediates.push_back(certs[i]->os_cert_handle());
+ intermediates.push_back(
+ x509_util::DupCryptoBuffer(certs[i]->cert_buffer()));
- scoped_refptr<X509Certificate> result(X509Certificate::CreateFromHandle(
- certs[0]->os_cert_handle(), intermediates));
+ scoped_refptr<X509Certificate> result(X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates)));
return result;
}
diff --git a/chromium/net/test/embedded_test_server/default_handlers.cc b/chromium/net/test/embedded_test_server/default_handlers.cc
index a1e984fa631..05aa1037c5d 100644
--- a/chromium/net/test/embedded_test_server/default_handlers.cc
+++ b/chromium/net/test/embedded_test_server/default_handlers.cc
@@ -30,6 +30,7 @@
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "net/base/escape.h"
+#include "net/base/host_port_pair.h"
#include "net/base/url_util.h"
#include "net/filter/filter_source_stream_test_util.h"
#include "net/test/embedded_test_server/http_request.h"
@@ -497,15 +498,16 @@ std::unique_ptr<HttpResponse> HandleAuthDigest(const HttpRequest& request) {
return std::move(http_response);
}
-// /server-redirect?URL
-// Returns a server-redirect (301) to URL.
-std::unique_ptr<HttpResponse> HandleServerRedirect(const HttpRequest& request) {
+// /server-redirect?URL (Also /server-redirect-xxx?URL)
+// Returns a server redirect to URL.
+std::unique_ptr<HttpResponse> HandleServerRedirect(HttpStatusCode redirect_code,
+ const HttpRequest& request) {
GURL request_url = request.GetURL();
std::string dest =
net::UnescapeURLComponent(request_url.query(), kUnescapeAll);
std::unique_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
- http_response->set_code(HTTP_MOVED_PERMANENTLY);
+ http_response->set_code(redirect_code);
http_response->AddCustomHeader("Location", dest);
http_response->set_content_type("text/html");
http_response->set_content(base::StringPrintf(
@@ -668,10 +670,26 @@ std::unique_ptr<HttpResponse> HandleGzipBody(const HttpRequest& request) {
return std::move(http_response);
}
+// /self.pac
+// Returns a response that is a PAC script making requests use the
+// EmbeddedTestServer itself as a proxy.
+std::unique_ptr<HttpResponse> HandleSelfPac(const HttpRequest& request) {
+ std::unique_ptr<BasicHttpResponse> http_response =
+ std::make_unique<BasicHttpResponse>();
+ http_response->set_content(base::StringPrintf(
+ "function FindProxyForURL(url, host) {\n"
+ "return 'PROXY %s';\n"
+ "}",
+ net::HostPortPair::FromURL(request.base_url).ToString().c_str()));
+ return std::move(http_response);
+}
+
} // anonymous namespace
#define PREFIXED_HANDLER(prefix, handler) \
base::Bind(&HandlePrefixedRequest, prefix, base::Bind(handler))
+#define SERVER_REDIRECT_HANDLER(prefix, handler, status_code) \
+ base::Bind(&HandlePrefixedRequest, prefix, base::Bind(handler, status_code))
void RegisterDefaultHandlers(EmbeddedTestServer* server) {
server->RegisterDefaultHandler(base::Bind(&HandleDefaultConnect));
@@ -703,8 +721,20 @@ void RegisterDefaultHandlers(EmbeddedTestServer* server) {
PREFIXED_HANDLER("/auth-basic", &HandleAuthBasic));
server->RegisterDefaultHandler(
PREFIXED_HANDLER("/auth-digest", &HandleAuthDigest));
- server->RegisterDefaultHandler(
- PREFIXED_HANDLER("/server-redirect", &HandleServerRedirect));
+
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect", &HandleServerRedirect, HTTP_MOVED_PERMANENTLY));
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect-301", &HandleServerRedirect, HTTP_MOVED_PERMANENTLY));
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect-302", &HandleServerRedirect, HTTP_FOUND));
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect-303", &HandleServerRedirect, HTTP_SEE_OTHER));
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect-307", &HandleServerRedirect, HTTP_TEMPORARY_REDIRECT));
+ server->RegisterDefaultHandler(SERVER_REDIRECT_HANDLER(
+ "/server-redirect-308", &HandleServerRedirect, HTTP_PERMANENT_REDIRECT));
+
server->RegisterDefaultHandler(base::Bind(&HandleCrossSiteRedirect, server));
server->RegisterDefaultHandler(
PREFIXED_HANDLER("/client-redirect", &HandleClientRedirect));
@@ -717,6 +747,7 @@ void RegisterDefaultHandlers(EmbeddedTestServer* server) {
PREFIXED_HANDLER("/hung-after-headers", &HandleHungAfterHeadersResponse));
server->RegisterDefaultHandler(
PREFIXED_HANDLER("/gzip-body", &HandleGzipBody));
+ server->RegisterDefaultHandler(PREFIXED_HANDLER("/self.pac", &HandleSelfPac));
// TODO(svaldez): HandleDownload
// TODO(svaldez): HandleDownloadFinish
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 de416f22aed..5caf5c59857 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc
@@ -281,6 +281,10 @@ std::string EmbeddedTestServer::GetCertificateName() const {
return "localhost_cert.pem";
case CERT_EXPIRED:
return "expired_cert.pem";
+ case CERT_COMMON_NAME_ONLY:
+ return "common_name_only.pem";
+ case CERT_SHA1_LEAF:
+ return "sha1_leaf.pem";
}
return "ok_cert.pem";
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 5d26cf4ec37..a2d33517e9d 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.h
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.h
@@ -103,6 +103,13 @@ class EmbeddedTestServer {
// Causes the testserver to use a hostname that is a domain
// instead of an IP.
CERT_COMMON_NAME_IS_DOMAIN,
+
+ // A certificate that only contains a commonName, rather than also
+ // including a subjectAltName extension.
+ CERT_COMMON_NAME_ONLY,
+
+ // A certificate that is a leaf certificate signed with SHA-1.
+ CERT_SHA1_LEAF,
};
typedef base::Callback<std::unique_ptr<HttpResponse>(
diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc
index 8b1a668540b..792eeab126f 100644
--- a/chromium/net/test/net_test_suite.cc
+++ b/chromium/net/test/net_test_suite.cc
@@ -15,6 +15,9 @@
#endif
namespace {
+base::test::ScopedTaskEnvironment::MainThreadType kDefaultMainThreadType =
+ base::test::ScopedTaskEnvironment::MainThreadType::IO;
+
NetTestSuite* g_current_net_test_suite = nullptr;
} // namespace
@@ -46,11 +49,13 @@ void NetTestSuite::Shutdown() {
TestSuite::Shutdown();
}
+// static
base::test::ScopedTaskEnvironment* NetTestSuite::GetScopedTaskEnvironment() {
DCHECK(g_current_net_test_suite);
return g_current_net_test_suite->scoped_task_environment_.get();
}
+// static
void NetTestSuite::SetScopedTaskEnvironment(
base::test::ScopedTaskEnvironment::MainThreadType type) {
g_current_net_test_suite->scoped_task_environment_ = nullptr;
@@ -58,6 +63,11 @@ void NetTestSuite::SetScopedTaskEnvironment(
std::make_unique<base::test::ScopedTaskEnvironment>(type);
}
+// static
+void NetTestSuite::ResetScopedTaskEnvironment() {
+ SetScopedTaskEnvironment(kDefaultMainThreadType);
+}
+
void NetTestSuite::InitializeTestThread() {
network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock());
@@ -74,5 +84,5 @@ void NetTestSuite::InitializeTestThreadNoNetworkChangeNotifier() {
scoped_task_environment_ =
std::make_unique<base::test::ScopedTaskEnvironment>(
- base::test::ScopedTaskEnvironment::MainThreadType::IO);
+ kDefaultMainThreadType);
}
diff --git a/chromium/net/test/net_test_suite.h b/chromium/net/test/net_test_suite.h
index 9cb4e355a81..a35a30c90e3 100644
--- a/chromium/net/test/net_test_suite.h
+++ b/chromium/net/test/net_test_suite.h
@@ -42,6 +42,10 @@ class NetTestSuite : public base::TestSuite {
static void SetScopedTaskEnvironment(
base::test::ScopedTaskEnvironment::MainThreadType type);
+ // Sets the global ScopedTaskEnvironment to a new environment of the default
+ // type used by NetTestSuite.
+ static void ResetScopedTaskEnvironment();
+
protected:
// Called from within Initialize(), but separate so that derived classes
// can initialize the NetTestSuite instance only and not
diff --git a/chromium/net/test/python_utils.cc b/chromium/net/test/python_utils.cc
index 57429626b17..e439813a8c5 100644
--- a/chromium/net/test/python_utils.cc
+++ b/chromium/net/test/python_utils.cc
@@ -23,11 +23,16 @@
#endif
const char kPythonPathEnv[] = "PYTHONPATH";
-const char kPythonVirtualEnv[] = "VIRTUAL_ENV";
+const char kVPythonClearPathEnv[] = "VPYTHON_CLEAR_PYTHONPATH";
void ClearPythonPath() {
std::unique_ptr<base::Environment> env(base::Environment::Create());
env->UnSetVar(kPythonPathEnv);
+
+ // vpython has instructions on BuildBot (not swarming or LUCI) to clear
+ // PYTHONPATH on invocation. Since we are clearing and manipulating it
+ // ourselves, we don't want vpython to throw out our hard work.
+ env->UnSetVar(kVPythonClearPathEnv);
}
void AppendToPythonPath(const base::FilePath& dir) {
@@ -83,53 +88,19 @@ bool GetPyProtoPath(base::FilePath* dir) {
return false;
}
-#if defined(OS_WIN)
-struct PythonExePath {
- PythonExePath() {
- // This is test-only code, so CHECK with a subprocess invocation is ok.
- base::CommandLine command(base::FilePath(FILE_PATH_LITERAL("cmd")));
- command.AppendArg("/c");
- command.AppendArg("python");
- command.AppendArg("-c");
- command.AppendArg("import sys; print sys.executable");
- std::string output;
- CHECK(GetAppOutput(command, &output));
- // This does only work if cmd.exe doesn't use a non-US codepage.
- path_ = base::ASCIIToUTF16(output);
- TrimWhitespace(path_, base::TRIM_ALL, &path_);
- }
- base::string16 path_;
-};
-static base::LazyInstance<PythonExePath>::Leaky g_python_path;
-#endif
-
-bool IsInPythonVirtualEnv() {
- return base::Environment::Create()->HasVar(kPythonVirtualEnv);
-}
-
bool GetPythonCommand(base::CommandLine* python_cmd) {
DCHECK(python_cmd);
+// Use vpython to pick up src.git's vpython VirtualEnv spec.
#if defined(OS_WIN)
- // Most developers have depot_tools in their path, which only has a
- // python.bat, not a python.exe. Go through cmd to find the path to
- // the python executable.
- // (Don't just return a a "cmd /c python" command line, because then tests
- // that try to kill the python process will kill the cmd process instead,
- // which can cause flakiness.)
- python_cmd->SetProgram(base::FilePath(g_python_path.Get().path_));
+ python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("vpython.bat")));
#else
- python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("python")));
+ python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("vpython")));
#endif
// Launch python in unbuffered mode, so that python output doesn't mix with
// gtest output in buildbot log files. See http://crbug.com/147368.
python_cmd->AppendArg("-u");
- if (!IsInPythonVirtualEnv()) {
- // Prevent using system-installed libraries. Use hermetic versioned copies.
- python_cmd->AppendArg("-S");
- }
-
return true;
}
diff --git a/chromium/net/test/run_all_unittests.cc b/chromium/net/test/run_all_unittests.cc
index 7ba6b98ad76..635c4099e9b 100644
--- a/chromium/net/test/run_all_unittests.cc
+++ b/chromium/net/test/run_all_unittests.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <iostream>
+
#include "base/build_time.h"
-#include "base/metrics/statistics_recorder.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
@@ -50,9 +51,6 @@ bool VerifyBuildIsTimely() {
} // namespace
int main(int argc, char** argv) {
- // Record histograms, so we can get histograms data in tests.
- base::StatisticsRecorder::Initialize();
-
if (!VerifyBuildIsTimely())
return 1;
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 3f9ba3e615f..75a4cf8dbf1 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.cc
+++ b/chromium/net/test/spawned_test_server/base_test_server.cc
@@ -269,8 +269,7 @@ const HostPortPair& BaseTestServer::host_port_pair() const {
}
const base::DictionaryValue& BaseTestServer::server_data() const {
- DCHECK(started_);
- DCHECK(server_data_.get());
+ DCHECK(server_data_);
return *server_data_;
}
@@ -445,7 +444,7 @@ bool BaseTestServer::SetAndParseServerData(const std::string& server_data,
VLOG(1) << "Server data: " << server_data;
base::JSONReader json_reader;
std::unique_ptr<base::Value> value(json_reader.ReadToValue(server_data));
- if (!value.get() || !value->IsType(base::Value::Type::DICTIONARY)) {
+ if (!value.get() || !value->is_dict()) {
LOG(ERROR) << "Could not parse server data: "
<< json_reader.GetErrorMessage();
return false;
@@ -581,6 +580,10 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const {
arguments->SetInteger("cert-serial", ssl_options_.cert_serial);
}
+ if (!ssl_options_.cert_common_name.empty()) {
+ arguments->SetString("cert-common-name", ssl_options_.cert_common_name);
+ }
+
// Check key exchange argument.
std::unique_ptr<base::ListValue> key_exchange_values(new base::ListValue());
GetKeyExchangesList(ssl_options_.key_exchanges, key_exchange_values.get());
diff --git a/chromium/net/test/spawned_test_server/base_test_server.h b/chromium/net/test/spawned_test_server/base_test_server.h
index a35d3816f59..c279b6cf21d 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.h
+++ b/chromium/net/test/spawned_test_server/base_test_server.h
@@ -217,6 +217,10 @@ class BaseTestServer {
// auto-generated leaf certificate when |server_certificate==CERT_AUTO|.
uint64_t cert_serial = 0;
+ // If not empty, |cert_common_name| will be the common name of the
+ // auto-generated leaf certificate when |server_certificate==CERT_AUTO|.
+ std::string cert_common_name;
+
// True if a CertificateRequest should be sent to the client during
// handshaking.
bool request_client_certificate = false;
@@ -381,6 +385,7 @@ class BaseTestServer {
protected:
virtual ~BaseTestServer();
Type type() const { return type_; }
+ const SSLOptions& ssl_options() const { return ssl_options_; }
bool started() const { return started_; }
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 3f0ad15fdca..8528663b90a 100644
--- a/chromium/net/test/spawned_test_server/local_test_server.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server.cc
@@ -167,15 +167,8 @@ bool LocalTestServer::SetPythonPath() const {
}
third_party_dir = third_party_dir.AppendASCII("third_party");
- // For simplejson. (simplejson, unlike all the other Python modules
- // we include, doesn't have an extra 'simplejson' directory, so we
- // need to include its parent directory, i.e. third_party_dir).
- AppendToPythonPath(third_party_dir);
-
AppendToPythonPath(third_party_dir.AppendASCII("tlslite"));
AppendToPythonPath(
- third_party_dir.AppendASCII("pyftpdlib").AppendASCII("src"));
- AppendToPythonPath(
third_party_dir.AppendASCII("pywebsocket").AppendASCII("src"));
// Locate the Python code generated by the protocol buffers compiler.
@@ -203,7 +196,7 @@ bool LocalTestServer::AddCommandLineArguments(
const std::string& key = it.key();
// Add arguments from a list.
- if (value.IsType(base::Value::Type::LIST)) {
+ if (value.is_list()) {
const base::ListValue* list = NULL;
if (!value.GetAsList(&list) || !list || list->empty())
return false;
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.cc b/chromium/net/test/spawned_test_server/remote_test_server.cc
index 6a26cde5f94..8cfe03b20d8 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.cc
+++ b/chromium/net/test/spawned_test_server/remote_test_server.cc
@@ -88,6 +88,20 @@ bool RemoteTestServer::StartInBackground() {
// pass right server type to Python test server.
arguments_dict.SetString("server-type", GetServerTypeString(type()));
+ // If the server is not on localhost and it's expected to start OCSP server
+ // then pass OCSP proxy port number, so the server can generate certificates
+ // for the OCSP server valid for the proxied port.
+ bool ocsp_server_enabled =
+ type() == TYPE_HTTPS && (ssl_options().server_certificate ==
+ SSLOptions::CERT_AUTO_AIA_INTERMEDIATE ||
+ !ssl_options().GetOCSPArgument().empty());
+ if (config_.address() != IPAddress::IPv4Localhost() && ocsp_server_enabled) {
+ ocsp_proxy_ =
+ std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
+ arguments_dict.SetKey("ocsp-proxy-port-number",
+ base::Value(ocsp_proxy_->local_port()));
+ }
+
// Generate JSON-formatted argument string.
std::string arguments_string;
base::JSONWriter::Write(arguments_dict, &arguments_string);
@@ -104,24 +118,36 @@ bool RemoteTestServer::StartInBackground() {
bool RemoteTestServer::BlockUntilStarted() {
DCHECK(start_request_);
- std::string server_data;
- bool request_result = start_request_->WaitForCompletion(&server_data);
+ std::string server_data_json;
+ bool request_result = start_request_->WaitForCompletion(&server_data_json);
start_request_.reset();
if (!request_result)
return false;
- // Parse server_data.
- if (server_data.empty() ||
- !SetAndParseServerData(server_data, &remote_port_)) {
- LOG(ERROR) << "Could not parse server_data: " << server_data;
+ // Parse server_data_json.
+ if (server_data_json.empty() ||
+ !SetAndParseServerData(server_data_json, &remote_port_)) {
+ LOG(ERROR) << "Could not parse server_data: " << server_data_json;
return false;
}
// If the server is not on localhost then start a proxy on localhost to
// forward connections to the server.
if (config_.address() != IPAddress::IPv4Localhost()) {
- test_server_proxy_ = std::make_unique<RemoteTestServerProxy>(
- IPEndPoint(config_.address(), remote_port_), io_thread_.task_runner());
+ test_server_proxy_ =
+ std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
+ test_server_proxy_->Start(IPEndPoint(config_.address(), remote_port_));
+
+ if (ocsp_proxy_) {
+ const base::Value* ocsp_port_value = server_data().FindKey("ocsp_port");
+ if (ocsp_port_value && ocsp_port_value->is_int()) {
+ ocsp_proxy_->Start(
+ IPEndPoint(config_.address(), ocsp_port_value->GetInt()));
+ } else {
+ LOG(WARNING) << "testserver.py didn't return ocsp_port.";
+ }
+ }
+
SetPort(test_server_proxy_->local_port());
} else {
SetPort(remote_port_);
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.h b/chromium/net/test/spawned_test_server/remote_test_server.h
index af75d2f3d27..8a7e430d82d 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.h
+++ b/chromium/net/test/spawned_test_server/remote_test_server.h
@@ -93,6 +93,7 @@ class RemoteTestServer : public BaseTestServer {
int remote_port_ = 0;
std::unique_ptr<RemoteTestServerProxy> test_server_proxy_;
+ std::unique_ptr<RemoteTestServerProxy> ocsp_proxy_;
DISALLOW_COPY_AND_ASSIGN(RemoteTestServer);
};
diff --git a/chromium/net/test/spawned_test_server/remote_test_server_proxy.cc b/chromium/net/test/spawned_test_server/remote_test_server_proxy.cc
index 70330cba600..86278709a79 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server_proxy.cc
+++ b/chromium/net/test/spawned_test_server/remote_test_server_proxy.cc
@@ -197,10 +197,16 @@ void ConnectionProxy::Close() {
// RemoteTestServerProxy implementation that runs on a background IO thread.
class RemoteTestServerProxy::Core {
public:
- explicit Core(const IPEndPoint& remote_address);
+ Core();
~Core();
- void Start(base::WaitableEvent* started_event);
+ // Creates local socket for accepting incoming connections and binds it to a
+ // port. local_port() comes valid after this call is complete.
+ void Initialize(base::WaitableEvent* initialized_event);
+
+ // Starts accepting incoming connections and redirecting them to
+ // remote_address. Must be called only after Initialize().
+ void Start(const IPEndPoint& remote_address);
uint16_t local_port() const { return local_port_; }
@@ -222,10 +228,12 @@ class RemoteTestServerProxy::Core {
DISALLOW_COPY_AND_ASSIGN(Core);
};
-RemoteTestServerProxy::Core::Core(const IPEndPoint& remote_address)
- : remote_address_(remote_address) {}
+RemoteTestServerProxy::Core::Core() {}
+
+void RemoteTestServerProxy::Core::Initialize(
+ base::WaitableEvent* initialized_event) {
+ CHECK(!socket_);
-void RemoteTestServerProxy::Core::Start(base::WaitableEvent* started_event) {
socket_ = std::make_unique<TCPServerSocket>(nullptr, net::NetLogSource());
int result = socket_->Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 5);
CHECK_EQ(result, OK);
@@ -236,9 +244,14 @@ void RemoteTestServerProxy::Core::Start(base::WaitableEvent* started_event) {
CHECK_EQ(result, OK);
local_port_ = address.port();
- DoAcceptLoop();
+ initialized_event->Signal();
+}
+
+void RemoteTestServerProxy::Core::Start(const IPEndPoint& remote_address) {
+ CHECK(socket_);
- started_event->Signal();
+ remote_address_ = remote_address;
+ DoAcceptLoop();
}
RemoteTestServerProxy::Core::~Core() {}
@@ -294,17 +307,16 @@ void RemoteTestServerProxy::Core::OnConnectionClosed(
}
RemoteTestServerProxy::RemoteTestServerProxy(
- const IPEndPoint& remote_address,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
- : io_task_runner_(io_task_runner),
- core_(std::make_unique<Core>(remote_address)) {
- base::WaitableEvent started_event(
+ : io_task_runner_(io_task_runner), core_(std::make_unique<Core>()) {
+ base::WaitableEvent intialized_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
io_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&Core::Start, base::Unretained(core_.get()), &started_event));
- started_event.Wait();
+ base::BindOnce(&Core::Initialize, base::Unretained(core_.get()),
+ &intialized_event));
+ intialized_event.Wait();
local_port_ = core_->local_port();
}
@@ -314,4 +326,10 @@ RemoteTestServerProxy::~RemoteTestServerProxy() {
io_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}
+void RemoteTestServerProxy::Start(const IPEndPoint& remote_address) {
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()),
+ remote_address));
+}
+
} // namespace net
diff --git a/chromium/net/test/spawned_test_server/remote_test_server_proxy.h b/chromium/net/test/spawned_test_server/remote_test_server_proxy.h
index 538fcea075e..366e254e100 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server_proxy.h
+++ b/chromium/net/test/spawned_test_server/remote_test_server_proxy.h
@@ -24,13 +24,16 @@ class IPEndPoint;
// address.
class RemoteTestServerProxy {
public:
- RemoteTestServerProxy(
- const IPEndPoint& remote_address,
+ explicit RemoteTestServerProxy(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteTestServerProxy();
uint16_t local_port() const { return local_port_; }
+ // Starts the proxy for the specified |remote_address|. Must be called before
+ // any incoming connection on local_port() are initiated.
+ void Start(const IPEndPoint& remote_address);
+
private:
class Core;
diff --git a/chromium/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc b/chromium/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
index ddb623c13e0..7b3b6b5d110 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
+++ b/chromium/net/test/spawned_test_server/remote_test_server_proxy_unittests.cc
@@ -35,10 +35,10 @@ class RemoteTestServerProxyTest : public testing::Test {
result = listen_socket_->GetLocalAddress(&address);
EXPECT_THAT(result, IsOk());
- proxy_ = std::make_unique<RemoteTestServerProxy>(address,
- io_thread_.task_runner());
+ proxy_ = std::make_unique<RemoteTestServerProxy>(io_thread_.task_runner());
proxy_address_ =
IPEndPoint(IPAddress::IPv4Localhost(), proxy_->local_port());
+ proxy_->Start(address);
}
void MakeConnection(std::unique_ptr<StreamSocket>* client_socket,
diff --git a/chromium/net/third_party/nss/ssl/cmpcert.cc b/chromium/net/third_party/nss/ssl/cmpcert.cc
index 64e482811f7..27ceeb8fd17 100644
--- a/chromium/net/third_party/nss/ssl/cmpcert.cc
+++ b/chromium/net/third_party/nss/ssl/cmpcert.cc
@@ -35,8 +35,8 @@ bool GetIssuerAndSubject(X509Certificate* cert,
der::Input tbs_certificate_tlv;
der::Input signature_algorithm_tlv;
der::BitString signature_value;
- if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert->os_cert_handle()),
- CRYPTO_BUFFER_len(cert->os_cert_handle())),
+ if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert->cert_buffer()),
+ CRYPTO_BUFFER_len(cert->cert_buffer())),
&tbs_certificate_tlv, &signature_algorithm_tlv,
&signature_value, nullptr)) {
return false;
diff --git a/chromium/net/tools/cachetool/cachetool.cc b/chromium/net/tools/cachetool/cachetool.cc
index 2c3207f854a..c93f7614479 100644
--- a/chromium/net/tools/cachetool/cachetool.cc
+++ b/chromium/net/tools/cachetool/cachetool.cc
@@ -194,7 +194,7 @@ class ProgramArgumentCommandMarshal final : public CommandMarshal {
// Implements CommandMarshal.
void ReturnBuffer(net::GrowableIOBuffer* buffer) override {
DCHECK(!has_failed());
- std::cout.write(buffer->data(), buffer->offset());
+ std::cout.write(buffer->StartOfBuffer(), buffer->offset());
}
// Implements CommandMarshal.
diff --git a/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc b/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
index 24e92313713..38f7c18fe4e 100644
--- a/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
+++ b/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
@@ -6,6 +6,7 @@
#include <iostream>
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -15,6 +16,7 @@
#include "net/cert/cert_verify_proc.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/tools/cert_verify_tool/cert_verify_tool_util.h"
namespace {
@@ -40,12 +42,11 @@ bool DumpX509CertificateChain(const base::FilePath& file_path,
std::cerr << "ERROR: X509Certificate::GetPEMEncodedChain failed.\n";
return false;
}
- return WriteToFile(file_path, base::JoinString(pem_encoded, ""));
+ return WriteToFile(file_path, base::StrCat(pem_encoded));
}
// Returns a hex-encoded sha256 of the DER-encoding of |cert_handle|.
-std::string FingerPrintOSCertHandle(
- net::X509Certificate::OSCertHandle cert_handle) {
+std::string FingerPrintCryptoBuffer(const CRYPTO_BUFFER* cert_handle) {
net::SHA256HashValue hash =
net::X509Certificate::CalculateFingerprint256(cert_handle);
return base::HexEncode(hash.data, arraysize(hash.data));
@@ -57,11 +58,10 @@ std::string SubjectFromX509Certificate(const net::X509Certificate* cert) {
}
// Returns a textual representation of the Subject of |cert_handle|.
-std::string SubjectFromOSCertHandle(
- net::X509Certificate::OSCertHandle cert_handle) {
+std::string SubjectFromCryptoBuffer(CRYPTO_BUFFER* cert_handle) {
scoped_refptr<net::X509Certificate> cert =
- net::X509Certificate::CreateFromHandle(
- cert_handle, net::X509Certificate::OSCertHandles());
+ net::X509Certificate::CreateFromBuffer(
+ net::x509_util::DupCryptoBuffer(cert_handle), {});
if (!cert)
return std::string();
return SubjectFromX509Certificate(cert.get());
@@ -97,12 +97,13 @@ void PrintCertVerifyResult(const net::CertVerifyResult& result) {
if (result.verified_cert) {
std::cout << "chain:\n "
- << FingerPrintOSCertHandle(result.verified_cert->os_cert_handle())
+ << FingerPrintCryptoBuffer(result.verified_cert->cert_buffer())
<< " " << SubjectFromX509Certificate(result.verified_cert.get())
<< "\n";
- for (auto* os_cert : result.verified_cert->GetIntermediateCertificates()) {
- std::cout << " " << FingerPrintOSCertHandle(os_cert) << " "
- << SubjectFromOSCertHandle(os_cert) << "\n";
+ for (const auto& intermediate :
+ result.verified_cert->intermediate_buffers()) {
+ std::cout << " " << FingerPrintCryptoBuffer(intermediate.get()) << " "
+ << SubjectFromCryptoBuffer(intermediate.get()) << "\n";
}
}
}
diff --git a/chromium/net/tools/ct_log_list/PRESUBMIT.py b/chromium/net/tools/ct_log_list/PRESUBMIT.py
index ff9bf5c1830..ed1da40b331 100644
--- a/chromium/net/tools/ct_log_list/PRESUBMIT.py
+++ b/chromium/net/tools/ct_log_list/PRESUBMIT.py
@@ -8,10 +8,12 @@
def _RunMakeCTLogListTests(input_api, output_api):
"""Runs make_ct_known_logs_list unittests if related files were modified."""
- files = ('net/tools/ct_log_list/make_ct_known_logs_list.py',
- 'net/tools/ct_log_list/make_ct_known_logs_list_unittest.py',
- 'net/data/ssl/certificate_transparency/log_list.json')
- if not any(f in input_api.LocalPaths() for f in files):
+ files = (input_api.os_path.normpath(x) for x in
+ ('net/tools/ct_log_list/make_ct_known_logs_list.py',
+ 'net/tools/ct_log_list/make_ct_known_logs_list_unittest.py',
+ 'net/data/ssl/certificate_transparency/log_list.json'))
+ if not any(f in (af.LocalPath() for af in input_api.change.AffectedFiles())
+ for f in files):
return []
test_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
'make_ct_known_logs_list_unittest.py')
@@ -31,4 +33,3 @@ def CheckChangeOnUpload(input_api, output_api):
def CheckChangeOnCommit(input_api, output_api):
return _RunMakeCTLogListTests(input_api, output_api)
-
diff --git a/chromium/net/tools/quic/chlo_extractor.cc b/chromium/net/tools/quic/chlo_extractor.cc
index 38cb9893f31..4d71aa7f50c 100644
--- a/chromium/net/tools/quic/chlo_extractor.cc
+++ b/chromium/net/tools/quic/chlo_extractor.cc
@@ -26,7 +26,7 @@ class ChloFramerVisitor : public QuicFramerVisitorInterface,
// QuicFramerVisitorInterface implementation
void OnError(QuicFramer* framer) override {}
- bool OnProtocolVersionMismatch(QuicTransportVersion version) override;
+ bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
void OnPacket() override {}
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}
void OnVersionNegotiationPacket(
@@ -67,8 +67,7 @@ ChloFramerVisitor::ChloFramerVisitor(QuicFramer* framer,
found_chlo_(false),
connection_id_(0) {}
-bool ChloFramerVisitor::OnProtocolVersionMismatch(
- QuicTransportVersion version) {
+bool ChloFramerVisitor::OnProtocolVersionMismatch(ParsedQuicVersion version) {
if (!framer_->IsSupportedVersion(version)) {
return false;
}
@@ -153,7 +152,7 @@ void ChloFramerVisitor::OnHandshakeMessage(
// static
bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
- const QuicTransportVersionVector& versions,
+ const ParsedQuicVersionVector& versions,
Delegate* delegate) {
QuicFramer framer(versions, QuicTime::Zero(), Perspective::IS_SERVER);
ChloFramerVisitor visitor(&framer, delegate);
diff --git a/chromium/net/tools/quic/chlo_extractor.h b/chromium/net/tools/quic/chlo_extractor.h
index 6ad12c5fed3..b56df49aa26 100644
--- a/chromium/net/tools/quic/chlo_extractor.h
+++ b/chromium/net/tools/quic/chlo_extractor.h
@@ -28,7 +28,7 @@ class ChloExtractor {
// of |delegate|. Return true if a CHLO message was found, and false
// otherwise.
static bool Extract(const QuicEncryptedPacket& packet,
- const QuicTransportVersionVector& versions,
+ const ParsedQuicVersionVector& versions,
Delegate* delegate);
ChloExtractor(const ChloExtractor&) = delete;
diff --git a/chromium/net/tools/quic/chlo_extractor_test.cc b/chromium/net/tools/quic/chlo_extractor_test.cc
index 4fdd591a3ee..169288712a9 100644
--- a/chromium/net/tools/quic/chlo_extractor_test.cc
+++ b/chromium/net/tools/quic/chlo_extractor_test.cc
@@ -46,7 +46,7 @@ class ChloExtractorTest : public QuicTest {
header_.connection_id = 42;
header_.connection_id_length = PACKET_8BYTE_CONNECTION_ID;
header_.version_flag = true;
- header_.version = AllSupportedTransportVersions().front();
+ header_.version = AllSupportedVersions().front();
header_.reset_flag = false;
header_.packet_number_length = PACKET_6BYTE_PACKET_NUMBER;
header_.packet_number = 1;
@@ -56,8 +56,8 @@ class ChloExtractorTest : public QuicTest {
QuicFrame frame(stream_frame);
QuicFrames frames;
frames.push_back(frame);
- QuicFramer framer(SupportedTransportVersions(header_.version),
- QuicTime::Zero(), Perspective::IS_CLIENT);
+ QuicFramer framer(SupportedVersions(header_.version), QuicTime::Zero(),
+ Perspective::IS_CLIENT);
std::unique_ptr<QuicPacket> packet(
BuildUnsizedDataPacket(&framer, header_, frames));
EXPECT_TRUE(packet != nullptr);
@@ -85,18 +85,18 @@ TEST_F(ChloExtractorTest, FindsValidChlo) {
.AsStringPiece()
.as_string());
// Construct a CHLO with each supported version
- for (QuicTransportVersion version : AllSupportedTransportVersions()) {
- QuicTransportVersionVector versions(SupportedTransportVersions(version));
+ for (ParsedQuicVersion version : AllSupportedVersions()) {
+ ParsedQuicVersionVector versions(SupportedVersions(version));
header_.version = version;
MakePacket(
new QuicStreamFrame(kCryptoStreamId, false, 0, client_hello_str));
EXPECT_TRUE(ChloExtractor::Extract(*packet_, versions, &delegate_))
- << QuicVersionToString(version);
- EXPECT_EQ(version, delegate_.transport_version());
+ << ParsedQuicVersionToString(version);
+ EXPECT_EQ(version.transport_version, delegate_.transport_version());
EXPECT_EQ(header_.connection_id, delegate_.connection_id());
EXPECT_EQ(client_hello.DebugString(Perspective::IS_SERVER),
delegate_.chlo())
- << QuicVersionToString(version);
+ << ParsedQuicVersionToString(version);
}
}
@@ -109,8 +109,8 @@ TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
.as_string());
MakePacket(
new QuicStreamFrame(kCryptoStreamId + 1, false, 0, client_hello_str));
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, AllSupportedTransportVersions(),
- &delegate_));
+ EXPECT_FALSE(
+ ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_));
}
TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
@@ -121,14 +121,14 @@ TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
.AsStringPiece()
.as_string());
MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 1, client_hello_str));
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, AllSupportedTransportVersions(),
- &delegate_));
+ EXPECT_FALSE(
+ ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_));
}
TEST_F(ChloExtractorTest, DoesNotFindInvalidChlo) {
MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 0, "foo"));
- EXPECT_FALSE(ChloExtractor::Extract(*packet_, AllSupportedTransportVersions(),
- &delegate_));
+ EXPECT_FALSE(
+ ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_));
}
} // namespace
diff --git a/chromium/net/tools/quic/end_to_end_test.cc b/chromium/net/tools/quic/end_to_end_test.cc
index ceeca25dd90..053e63f6bbb 100644
--- a/chromium/net/tools/quic/end_to_end_test.cc
+++ b/chromium/net/tools/quic/end_to_end_test.cc
@@ -56,6 +56,7 @@
#include "net/tools/quic/quic_server.h"
#include "net/tools/quic/quic_simple_server_stream.h"
#include "net/tools/quic/quic_spdy_client_stream.h"
+#include "net/tools/quic/test_tools/bad_packet_writer.h"
#include "net/tools/quic/test_tools/packet_dropping_test_writer.h"
#include "net/tools/quic/test_tools/packet_reordering_writer.h"
#include "net/tools/quic/test_tools/quic_client_peer.h"
@@ -80,9 +81,9 @@ const float kSessionToStreamRatio = 1.5;
// Run all tests with the cross products of all versions.
struct TestParams {
- TestParams(const QuicTransportVersionVector& client_supported_versions,
- const QuicTransportVersionVector& server_supported_versions,
- QuicTransportVersion negotiated_version,
+ TestParams(const ParsedQuicVersionVector& client_supported_versions,
+ const ParsedQuicVersionVector& server_supported_versions,
+ ParsedQuicVersion negotiated_version,
bool client_supports_stateless_rejects,
bool server_uses_stateless_rejects_if_peer_supported,
QuicTag congestion_control_tag,
@@ -100,10 +101,11 @@ struct TestParams {
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
os << "{ server_supported_versions: "
- << QuicTransportVersionVectorToString(p.server_supported_versions);
+ << ParsedQuicVersionVectorToString(p.server_supported_versions);
os << " client_supported_versions: "
- << QuicTransportVersionVectorToString(p.client_supported_versions);
- os << " negotiated_version: " << QuicVersionToString(p.negotiated_version);
+ << ParsedQuicVersionVectorToString(p.client_supported_versions);
+ os << " negotiated_version: "
+ << ParsedQuicVersionToString(p.negotiated_version);
os << " client_supports_stateless_rejects: "
<< p.client_supports_stateless_rejects;
os << " server_uses_stateless_rejects_if_peer_supported: "
@@ -116,9 +118,9 @@ struct TestParams {
return os;
}
- QuicTransportVersionVector client_supported_versions;
- QuicTransportVersionVector server_supported_versions;
- QuicTransportVersion negotiated_version;
+ ParsedQuicVersionVector client_supported_versions;
+ ParsedQuicVersionVector server_supported_versions;
+ ParsedQuicVersion negotiated_version;
bool client_supports_stateless_rejects;
bool server_uses_stateless_rejects_if_peer_supported;
QuicTag congestion_control_tag;
@@ -136,13 +138,12 @@ std::vector<TestParams> GetTestParams() {
// these tests need to ensure that clients are never attempting
// to do 0-RTT across incompatible versions. Chromium only supports
// a single version at a time anyway. :)
- QuicTransportVersionVector all_supported_versions =
- AllSupportedTransportVersions();
+ ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
// Even though this currently has one element, it may well get another
// with future versions of QUIC, so don't remove it.
- QuicTransportVersionVector version_buckets[1];
+ ParsedQuicVersionVector version_buckets[1];
- for (const QuicTransportVersion version : all_supported_versions) {
+ for (const ParsedQuicVersion version : all_supported_versions) {
// Versions: 35+
// QUIC_VERSION_35 allows endpoints to independently set stream limit.
version_buckets[0].push_back(version);
@@ -186,10 +187,10 @@ std::vector<TestParams> GetTestParams() {
continue;
}
- for (const QuicTransportVersionVector& client_versions :
+ for (const ParsedQuicVersionVector& client_versions :
version_buckets) {
CHECK(!client_versions.empty());
- if (FilterSupportedTransportVersions(client_versions).empty()) {
+ if (FilterSupportedVersions(client_versions).empty()) {
continue;
}
// Add an entry for server and client supporting all
@@ -214,9 +215,9 @@ std::vector<TestParams> GetTestParams() {
// occur. Skip the i = 0 case because it is essentially the
// same as the default case.
for (size_t i = 1; i < client_versions.size(); ++i) {
- QuicTransportVersionVector server_supported_versions;
+ ParsedQuicVersionVector server_supported_versions;
server_supported_versions.push_back(client_versions[i]);
- if (FilterSupportedTransportVersions(server_supported_versions)
+ if (FilterSupportedVersions(server_supported_versions)
.empty()) {
continue;
}
@@ -271,6 +272,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
client_writer_(nullptr),
server_writer_(nullptr),
server_started_(false),
+ negotiated_version_(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
chlo_multiplier_(0),
stream_factory_(nullptr),
support_server_push_(false) {
@@ -376,17 +378,8 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
// TODO(nimia): Consider setting the congestion control algorithm for the
// client as well according to the test parameter.
copt.push_back(GetParam().congestion_control_tag);
- if (GetParam().congestion_control_tag == kQBIC) {
- copt.push_back(kCCVX);
- }
- if (GetParam().congestion_control_tag == kQBIC) {
- copt.push_back(kCBQT);
- }
- if (GetParam().congestion_control_tag == kQBIC) {
- copt.push_back(kCPAU);
- }
if (GetParam().congestion_control_tag == kTPCC &&
- FLAGS_quic_reloadable_flag_quic_enable_pcc) {
+ GetQuicReloadableFlag(quic_enable_pcc)) {
copt.push_back(kTPCC);
}
@@ -433,8 +426,8 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
void StartServer() {
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects =
- GetParam().use_cheap_stateless_reject;
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
+ GetParam().use_cheap_stateless_reject);
auto* test_server = new QuicTestServer(
crypto_test_utils::ProofSourceForTesting(), server_config_,
@@ -450,8 +443,9 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
QuicServerPeer::GetDispatcher(server_thread_->server());
QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support =
- GetParam().server_uses_stateless_rejects_if_peer_supported;
+ SetQuicReloadableFlag(
+ enable_quic_stateless_reject_support,
+ GetParam().server_uses_stateless_rejects_if_peer_supported);
server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
QuicDispatcherPeer::GetAlarmFactory(dispatcher),
@@ -513,7 +507,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
client_->client()->client_session()->connection()->GetStats();
// TODO(ianswett): Determine why this becomes even more flaky with BBR
// enabled. b/62141144
- if (!had_packet_loss && !FLAGS_quic_reloadable_flag_quic_default_to_bbr) {
+ if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
EXPECT_EQ(0u, client_stats.packets_lost);
}
EXPECT_EQ(0u, client_stats.packets_discarded);
@@ -587,10 +581,10 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
bool server_started_;
QuicConfig client_config_;
QuicConfig server_config_;
- QuicTransportVersionVector client_supported_versions_;
- QuicTransportVersionVector server_supported_versions_;
+ ParsedQuicVersionVector client_supported_versions_;
+ ParsedQuicVersionVector server_supported_versions_;
QuicTagVector client_extra_copts_;
- QuicTransportVersion negotiated_version_;
+ ParsedQuicVersion negotiated_version_;
size_t chlo_multiplier_;
QuicTestServer::StreamFactory* stream_factory_;
bool support_server_push_;
@@ -1789,7 +1783,7 @@ TEST_P(EndToEndTest, FlowControlsSynced) {
QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller();
QuicFlowController* server_header_stream_flow_controller =
QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller();
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) {
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
// Both client and server are sending this SETTINGS frame, and the send
// window is consumed. But because of timing issue, the server may send or
// not send the frame, and the client may send/ not send / receive / not
@@ -1813,7 +1807,7 @@ TEST_P(EndToEndTest, FlowControlsSynced) {
->flow_controller());
}
- if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) {
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
// Client *may* have received the SETTINGs frame.
// TODO(fayang): Rewrite this part because it is hacky.
float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
@@ -2401,7 +2395,7 @@ class MockableQuicClientThatDropsBody : public MockableQuicClient {
QuicSocketAddress server_address,
const QuicServerId& server_id,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server)
: MockableQuicClient(server_address,
server_id,
@@ -2420,11 +2414,10 @@ class MockableQuicClientThatDropsBody : public MockableQuicClient {
class QuicTestClientThatDropsBody : public QuicTestClient {
public:
- QuicTestClientThatDropsBody(
- QuicSocketAddress server_address,
- const string& server_hostname,
- const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions)
+ QuicTestClientThatDropsBody(QuicSocketAddress server_address,
+ const string& server_hostname,
+ const QuicConfig& config,
+ const ParsedQuicVersionVector& supported_versions)
: QuicTestClient(server_address,
server_hostname,
config,
@@ -2935,8 +2928,6 @@ class WindowUpdateObserver : public QuicConnectionDebugVisitor {
};
TEST_P(EndToEndTest, WindowUpdateInAck) {
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = true;
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = true;
ASSERT_TRUE(Initialize());
EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
WindowUpdateObserver observer;
@@ -2966,13 +2957,30 @@ TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
ASSERT_TRUE(Initialize());
EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
QuicConfig* config = client_->client()->session()->config();
- if (FLAGS_quic_reloadable_flag_quic_send_reset_token_in_shlo) {
- EXPECT_TRUE(config->HasReceivedStatelessResetToken());
- EXPECT_EQ(1010101u, config->ReceivedStatelessResetToken());
- }
+ EXPECT_TRUE(config->HasReceivedStatelessResetToken());
+ EXPECT_EQ(1010101u, config->ReceivedStatelessResetToken());
client_->Disconnect();
}
+// Regression test of b/70782529.
+TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
+ ASSERT_TRUE(Initialize());
+ BadPacketWriter* bad_writer =
+ new BadPacketWriter(/*packet_causing_write_error=*/5,
+ /*error_code=*/90);
+ std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
+
+ // 1 MB body.
+ string body(1024 * 1024, 'a');
+ SpdyHeaderBlock headers;
+ headers[":method"] = "POST";
+ headers[":path"] = "/foo";
+ headers[":scheme"] = "https";
+ headers[":authority"] = server_hostname_;
+
+ client->SendCustomSynchronousRequest(headers, body);
+}
+
class EndToEndBufferedPacketsTest : public EndToEndTest {
public:
void CreateClientWithWriter() override {
diff --git a/chromium/net/tools/quic/quic_client.cc b/chromium/net/tools/quic/quic_client.cc
index ee4e5847abf..49af6ae8a59 100644
--- a/chromium/net/tools/quic/quic_client.cc
+++ b/chromium/net/tools/quic/quic_client.cc
@@ -37,7 +37,7 @@ namespace net {
QuicClient::QuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier)
: QuicClient(
@@ -52,7 +52,7 @@ QuicClient::QuicClient(QuicSocketAddress server_address,
QuicClient::QuicClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
std::unique_ptr<ProofVerifier> proof_verifier)
@@ -67,7 +67,7 @@ QuicClient::QuicClient(
QuicClient::QuicClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
EpollServer* epoll_server,
std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
diff --git a/chromium/net/tools/quic/quic_client.h b/chromium/net/tools/quic/quic_client.h
index 278d3b712b7..031cdff92ea 100644
--- a/chromium/net/tools/quic/quic_client.h
+++ b/chromium/net/tools/quic/quic_client.h
@@ -39,19 +39,19 @@ class QuicClient : public QuicSpdyClientBase {
// This will create its own QuicClientEpollNetworkHelper.
QuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier);
// This will take ownership of a passed in network primitive.
QuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
std::unique_ptr<ProofVerifier> proof_verifier);
QuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
EpollServer* epoll_server,
std::unique_ptr<QuicClientEpollNetworkHelper> network_helper,
diff --git a/chromium/net/tools/quic/quic_client_base.cc b/chromium/net/tools/quic/quic_client_base.cc
index 0ef9999d78b..310a5c01b9d 100644
--- a/chromium/net/tools/quic/quic_client_base.cc
+++ b/chromium/net/tools/quic/quic_client_base.cc
@@ -7,6 +7,7 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_server_id.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_text_utils.h"
@@ -20,7 +21,7 @@ QuicClientBase::NetworkHelper::~NetworkHelper() = default;
QuicClientBase::QuicClientBase(
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
@@ -30,7 +31,8 @@ QuicClientBase::QuicClientBase(
initialized_(false),
local_port_(0),
config_(config),
- crypto_config_(std::move(proof_verifier)),
+ crypto_config_(std::move(proof_verifier),
+ TlsClientHandshaker::CreateSslCtx()),
helper_(helper),
alarm_factory_(alarm_factory),
supported_versions_(supported_versions),
@@ -81,7 +83,7 @@ bool QuicClientBase::Connect() {
while (EncryptionBeingEstablished()) {
WaitForEvents();
}
- if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support &&
+ if (GetQuicReloadableFlag(enable_quic_stateless_reject_support) &&
connected()) {
// Resend any previously queued data.
ResendSavedData();
@@ -169,7 +171,7 @@ bool QuicClientBase::WaitForEvents() {
DCHECK(session() != nullptr);
if (!connected() &&
session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
- DCHECK(FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support);
+ DCHECK(GetQuicReloadableFlag(enable_quic_stateless_reject_support));
QUIC_DLOG(INFO) << "Detected stateless reject while waiting for events. "
<< "Attempting to reconnect.";
Connect();
diff --git a/chromium/net/tools/quic/quic_client_base.h b/chromium/net/tools/quic/quic_client_base.h
index db021899351..cb26051945c 100644
--- a/chromium/net/tools/quic/quic_client_base.h
+++ b/chromium/net/tools/quic/quic_client_base.h
@@ -59,7 +59,7 @@ class QuicClientBase {
};
QuicClientBase(const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
@@ -142,12 +142,11 @@ class QuicClientBase {
crypto_config_.tb_key_params = QuicTagVector{kTB10};
}
- const QuicTransportVersionVector& supported_versions() const {
+ const ParsedQuicVersionVector& supported_versions() const {
return supported_versions_;
}
- void SetSupportedTransportVersions(
- const QuicTransportVersionVector& versions) {
+ void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
supported_versions_ = versions;
}
@@ -207,10 +206,6 @@ class QuicClientBase {
}
void reset_writer() { writer_.reset(); }
- QuicByteCount initial_max_packet_length() {
- return initial_max_packet_length_;
- }
-
ProofVerifier* proof_verifier() const;
void set_bind_to_address(QuicIpAddress address) {
@@ -278,14 +273,6 @@ class QuicClientBase {
QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
- void set_num_sent_client_hellos(int num_sent_client_hellos) {
- num_sent_client_hellos_ = num_sent_client_hellos;
- }
-
- void set_num_stateless_rejects_received(int num_stateless_rejects_received) {
- num_stateless_rejects_received_ = num_stateless_rejects_received;
- }
-
// Subclasses may need to explicitly clear the session on destruction
// if they create it with objects that will be destroyed before this is.
// You probably want to call this if you override CreateQuicSpdyClientSession.
@@ -329,7 +316,7 @@ class QuicClientBase {
// element, with subsequent elements in descending order (versions can be
// skipped as necessary). We will always pick supported_versions_[0] as the
// initial version to use.
- QuicTransportVersionVector supported_versions_;
+ ParsedQuicVersionVector supported_versions_;
// The initial value of maximum packet size of the connection. If set to
// zero, the default is used.
diff --git a/chromium/net/tools/quic/quic_client_bin.cc b/chromium/net/tools/quic/quic_client_bin.cc
index 583620c55b4..d5c43714a0b 100644
--- a/chromium/net/tools/quic/quic_client_bin.cc
+++ b/chromium/net/tools/quic/quic_client_bin.cc
@@ -255,12 +255,12 @@ int main(int argc, char* argv[]) {
net::EpollServer epoll_server;
net::QuicServerId server_id(url.host(), url.port(),
net::PRIVACY_MODE_DISABLED);
- net::QuicTransportVersionVector versions =
- net::AllSupportedTransportVersions();
+ net::ParsedQuicVersionVector versions = net::AllSupportedVersions();
if (FLAGS_quic_version != -1) {
versions.clear();
- versions.push_back(
- static_cast<net::QuicTransportVersion>(FLAGS_quic_version));
+ versions.push_back(net::ParsedQuicVersion(
+ net::PROTOCOL_QUIC_CRYPTO,
+ static_cast<net::QuicTransportVersion>(FLAGS_quic_version)));
}
// For secure QUIC we need to verify the cert chain.
std::unique_ptr<CertVerifier> cert_verifier(CertVerifier::CreateDefault());
@@ -289,7 +289,7 @@ int main(int argc, char* argv[]) {
net::QuicErrorCode error = client.session()->error();
if (FLAGS_version_mismatch_ok && error == net::QUIC_INVALID_VERSION) {
cout << "Server talks QUIC, but none of the versions supported by "
- << "this client: " << QuicTransportVersionVectorToString(versions)
+ << "this client: " << ParsedQuicVersionVectorToString(versions)
<< endl;
// Version mismatch is not deemed a failure.
return 0;
diff --git a/chromium/net/tools/quic/quic_client_test.cc b/chromium/net/tools/quic/quic_client_test.cc
index 941996cb21b..e9b7e5d6d21 100644
--- a/chromium/net/tools/quic/quic_client_test.cc
+++ b/chromium/net/tools/quic/quic_client_test.cc
@@ -53,7 +53,7 @@ QuicClient* CreateAndInitializeQuicClient(EpollServer* eps, uint16_t port) {
QuicSocketAddress server_address(QuicSocketAddress(TestLoopback(), port));
QuicServerId server_id("hostname", server_address.port(),
PRIVACY_MODE_DISABLED);
- QuicTransportVersionVector versions = AllSupportedTransportVersions();
+ ParsedQuicVersionVector versions = AllSupportedVersions();
QuicClient* client =
new QuicClient(server_address, server_id, versions, eps,
crypto_test_utils::ProofVerifierForTesting());
diff --git a/chromium/net/tools/quic/quic_dispatcher.cc b/chromium/net/tools/quic/quic_dispatcher.cc
index 3d1188dc15f..a5214d53826 100644
--- a/chromium/net/tools/quic/quic_dispatcher.cc
+++ b/chromium/net/tools/quic/quic_dispatcher.cc
@@ -56,7 +56,7 @@ class PacketCollector : public QuicPacketCreator::DelegateInterface,
explicit PacketCollector(QuicBufferAllocator* allocator)
: send_buffer_(
allocator,
- FLAGS_quic_reloadable_flag_quic_allow_multiple_acks_for_data2) {}
+ GetQuicReloadableFlag(quic_allow_multiple_acks_for_data2)) {}
~PacketCollector() override = default;
// QuicPacketCreator::DelegateInterface methods:
@@ -140,7 +140,7 @@ class StatelessConnectionTerminator {
creator_.Flush();
DCHECK_EQ(1u, collector_.packets()->size());
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->transport_version(),
+ connection_id_, framer_->version(),
/*connection_rejected_statelessly=*/false, collector_.packets());
}
@@ -166,7 +166,7 @@ class StatelessConnectionTerminator {
creator_.Flush();
}
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->transport_version(),
+ connection_id_, framer_->version(),
/*connection_rejected_statelessly=*/true, collector_.packets());
DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id_));
}
@@ -257,7 +257,7 @@ QuicDispatcher::QuicDispatcher(
buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()),
current_packet_(nullptr),
version_manager_(version_manager),
- framer_(GetSupportedTransportVersions(),
+ framer_(GetSupportedVersions(),
/*unused*/ QuicTime::Zero(),
Perspective::IS_SERVER),
last_error_(QUIC_NO_ERROR),
@@ -355,12 +355,12 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
// Unless the packet provides a version, assume that we can continue
// processing using our preferred version.
- QuicTransportVersion version = GetSupportedTransportVersions().front();
+ ParsedQuicVersion version = GetSupportedVersions().front();
if (header.version_flag) {
- QuicTransportVersion packet_version = header.version;
- if (framer_.supported_versions() != GetSupportedTransportVersions()) {
+ ParsedQuicVersion packet_version = header.version;
+ if (framer_.supported_versions() != GetSupportedVersions()) {
// Reset framer's version if version flags change in flight.
- framer_.SetSupportedTransportVersions(GetSupportedTransportVersions());
+ framer_.SetSupportedVersions(GetSupportedVersions());
}
if (!framer_.IsSupportedVersion(packet_version)) {
if (ShouldCreateSessionForUnknownVersion(framer_.last_version_label())) {
@@ -369,8 +369,8 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
// Since the version is not supported, send a version negotiation
// packet and stop processing the current packet.
time_wait_list_manager()->SendVersionNegotiationPacket(
- connection_id, GetSupportedTransportVersions(),
- current_server_address_, current_client_address_);
+ connection_id, GetSupportedVersions(), current_server_address_,
+ current_client_address_);
return false;
}
version = packet_version;
@@ -416,14 +416,14 @@ void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
case kFateTimeWait:
// MaybeRejectStatelessly or OnExpiredPackets might have already added the
// connection to time wait, in which case it should not be added again.
- if (!FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects ||
+ if (!GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
!time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
// Add this connection_id to the time-wait state, to safely reject
// future packets.
QUIC_DLOG(INFO) << "Adding connection ID " << connection_id
<< "to time-wait list.";
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, framer_.transport_version(),
+ connection_id, framer_.version(),
/*connection_rejected_statelessly=*/false, nullptr);
}
DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
@@ -475,7 +475,7 @@ QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
if (header.packet_number == kInvalidPacketNumber) {
return kFateTimeWait;
}
- if (FLAGS_quic_restart_flag_quic_enable_accept_random_ipn) {
+ if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
QUIC_FLAG_COUNT_N(quic_restart_flag_quic_enable_accept_random_ipn, 1, 2);
// Accepting Initial Packet Numbers in 1...((2^31)-1) range... check
// maximum accordingly.
@@ -508,7 +508,7 @@ void QuicDispatcher::CleanUpSession(SessionMap::iterator it,
!connection->termination_packets()->empty());
}
time_wait_list_manager_->AddConnectionIdToTimeWait(
- it->first, connection->transport_version(), should_close_statelessly,
+ it->first, connection->version(), should_close_statelessly,
connection->termination_packets());
session_map_.erase(it);
}
@@ -622,7 +622,7 @@ bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
}
bool QuicDispatcher::OnProtocolVersionMismatch(
- QuicTransportVersion /*received_version*/) {
+ ParsedQuicVersion /*received_version*/) {
QUIC_BUG_IF(
!time_wait_list_manager_->IsConnectionIdInTimeWait(
current_connection_id_) &&
@@ -714,7 +714,7 @@ void QuicDispatcher::OnExpiredPackets(
QuicConnectionId connection_id,
BufferedPacketList early_arrived_packets) {
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, framer_.transport_version(), false, nullptr);
+ connection_id, framer_.version(), false, nullptr);
}
void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
@@ -789,7 +789,7 @@ void QuicDispatcher::ProcessChlo() {
if (!accept_new_connections_) {
// Don't any create new connection.
time_wait_list_manager()->AddConnectionIdToTimeWait(
- current_connection_id(), framer()->transport_version(),
+ current_connection_id(), framer()->version(),
/*connection_rejected_statelessly=*/false,
/*termination_packets=*/nullptr);
// This will trigger sending Public Reset packet.
@@ -874,7 +874,7 @@ class StatelessRejectorProcessDoneCallback
: public StatelessRejector::ProcessDoneCallback {
public:
StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher,
- QuicTransportVersion first_version)
+ ParsedQuicVersion first_version)
: dispatcher_(dispatcher),
current_client_address_(dispatcher->current_client_address_),
current_server_address_(dispatcher->current_server_address_),
@@ -893,21 +893,20 @@ class StatelessRejectorProcessDoneCallback
QuicSocketAddress current_client_address_;
QuicSocketAddress current_server_address_;
std::unique_ptr<QuicReceivedPacket> current_packet_;
- QuicTransportVersion first_version_;
+ ParsedQuicVersion first_version_;
};
void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
- QuicTransportVersion version) {
+ ParsedQuicVersion version) {
// TODO(rch): This logic should probably live completely inside the rejector.
if (!FLAGS_quic_allow_chlo_buffering ||
- !FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects ||
- !FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support ||
+ !GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
+ !GetQuicReloadableFlag(enable_quic_stateless_reject_support) ||
!ShouldAttemptCheapStatelessRejection()) {
// Not use cheap stateless reject.
ChloAlpnExtractor alpn_extractor;
if (FLAGS_quic_allow_chlo_buffering &&
- !ChloExtractor::Extract(*current_packet_,
- GetSupportedTransportVersions(),
+ !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
&alpn_extractor)) {
// Buffer non-CHLO packets.
ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
@@ -919,13 +918,13 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
}
std::unique_ptr<StatelessRejector> rejector(new StatelessRejector(
- version, GetSupportedTransportVersions(), crypto_config_,
- &compressed_certs_cache_, helper()->GetClock(),
+ version.transport_version, GetSupportedTransportVersions(),
+ crypto_config_, &compressed_certs_cache_, helper()->GetClock(),
helper()->GetRandomGenerator(), current_packet_->length(),
GetClientAddress(), current_server_address_));
ChloValidator validator(session_helper_.get(), current_server_address_,
rejector.get());
- if (!ChloExtractor::Extract(*current_packet_, GetSupportedTransportVersions(),
+ if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
&validator)) {
ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
return;
@@ -946,7 +945,8 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
// If we were able to make a decision about this CHLO based purely on the
// information available in OnChlo, just invoke the done callback immediately.
if (rejector->state() != StatelessRejector::UNKNOWN) {
- ProcessStatelessRejectorState(std::move(rejector), version);
+ ProcessStatelessRejectorState(std::move(rejector),
+ version.transport_version);
return;
}
@@ -968,7 +968,7 @@ void QuicDispatcher::OnStatelessRejectorProcessDone(
const QuicSocketAddress& current_client_address,
const QuicSocketAddress& current_server_address,
std::unique_ptr<QuicReceivedPacket> current_packet,
- QuicTransportVersion first_version) {
+ ParsedQuicVersion first_version) {
// Stop buffering packets on this connection
const auto num_erased =
temporarily_buffered_connections_.erase(rejector->connection_id());
@@ -994,7 +994,8 @@ void QuicDispatcher::OnStatelessRejectorProcessDone(
current_connection_id_ = rejector->connection_id();
framer_.set_version(first_version);
- ProcessStatelessRejectorState(std::move(rejector), first_version);
+ ProcessStatelessRejectorState(std::move(rejector),
+ first_version.transport_version);
}
void QuicDispatcher::ProcessStatelessRejectorState(
@@ -1051,6 +1052,10 @@ QuicDispatcher::GetSupportedTransportVersions() {
return version_manager_->GetSupportedTransportVersions();
}
+const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() {
+ return version_manager_->GetSupportedVersions();
+}
+
void QuicDispatcher::DeliverPacketsToSession(
const std::list<BufferedPacket>& packets,
QuicSession* session) {
diff --git a/chromium/net/tools/quic/quic_dispatcher.h b/chromium/net/tools/quic/quic_dispatcher.h
index ec980ee68d6..1fbc2659224 100644
--- a/chromium/net/tools/quic/quic_dispatcher.h
+++ b/chromium/net/tools/quic/quic_dispatcher.h
@@ -121,8 +121,7 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
// destined for the time wait manager.
bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
void OnError(QuicFramer* framer) override;
- bool OnProtocolVersionMismatch(
- QuicTransportVersion received_version) override;
+ bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override;
// The following methods should never get called because
// OnUnauthenticatedPublicHeader() or OnUnauthenticatedHeader() (whichever
@@ -219,6 +218,8 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
const QuicTransportVersionVector& GetSupportedTransportVersions();
+ const ParsedQuicVersionVector& GetSupportedVersions();
+
QuicConnectionId current_connection_id() { return current_connection_id_; }
const QuicSocketAddress& current_server_address() {
return current_server_address_;
@@ -307,7 +308,7 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
// fate which describes what subsequent processing should be performed on the
// packets, like ValidityChecks, and invokes ProcessUnauthenticatedHeaderFate.
void MaybeRejectStatelessly(QuicConnectionId connection_id,
- QuicTransportVersion version);
+ ParsedQuicVersion version);
// Deliver |packets| to |session| for further processing.
void DeliverPacketsToSession(
@@ -326,7 +327,7 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
const QuicSocketAddress& current_client_address,
const QuicSocketAddress& current_server_address,
std::unique_ptr<QuicReceivedPacket> current_packet,
- QuicTransportVersion first_version);
+ ParsedQuicVersion first_version);
// Examine the state of the rejector and decide what to do with the current
// packet.
diff --git a/chromium/net/tools/quic/quic_dispatcher_test.cc b/chromium/net/tools/quic/quic_dispatcher_test.cc
index 9fb6b3c7717..ae7b3770f69 100644
--- a/chromium/net/tools/quic/quic_dispatcher_test.cc
+++ b/chromium/net/tools/quic/quic_dispatcher_test.cc
@@ -15,6 +15,7 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_str_cat.h"
@@ -86,7 +87,7 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase {
QuicCompressedCertsCache* compressed_certs_cache) override {
return new QuicCryptoServerStream(
crypto_config, compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support, this,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
stream_helper());
}
@@ -176,10 +177,11 @@ class QuicDispatcherTest : public QuicTest {
explicit QuicDispatcherTest(std::unique_ptr<ProofSource> proof_source)
: helper_(&eps_, QuicAllocator::BUFFER_POOL),
alarm_factory_(&eps_),
- version_manager_(AllSupportedTransportVersions()),
+ version_manager_(AllSupportedVersions()),
crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- std::move(proof_source)),
+ std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()),
dispatcher_(new TestDispatcher(config_,
&crypto_config_,
&version_manager_,
@@ -240,7 +242,7 @@ class QuicDispatcherTest : public QuicTest {
QuicPacketNumberLength packet_number_length,
QuicPacketNumber packet_number) {
ProcessPacket(client_address, connection_id, has_version_flag,
- CurrentSupportedTransportVersions().front(), data,
+ CurrentSupportedVersions().front(), data,
connection_id_length, packet_number_length, packet_number);
}
@@ -248,12 +250,12 @@ class QuicDispatcherTest : public QuicTest {
void ProcessPacket(QuicSocketAddress client_address,
QuicConnectionId connection_id,
bool has_version_flag,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
const string& data,
QuicConnectionIdLength connection_id_length,
QuicPacketNumberLength packet_number_length,
QuicPacketNumber packet_number) {
- QuicTransportVersionVector versions(SupportedTransportVersions(version));
+ ParsedQuicVersionVector versions(SupportedVersions(version));
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
connection_id, has_version_flag, false, packet_number, data,
connection_id_length, packet_number_length, &versions));
@@ -387,8 +389,9 @@ TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
CreateQuicSession(1, client_address, QuicStringPiece("hq")))
.Times(0);
QuicTransportVersion version =
- static_cast<QuicTransportVersion>(QuicVersionMin() - 1);
- ProcessPacket(client_address, 1, true, version, SerializeCHLO(),
+ static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
+ ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
+ ProcessPacket(client_address, 1, true, parsed_version, SerializeCHLO(),
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
}
@@ -526,7 +529,7 @@ TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
CreateTimeWaitListManager();
- FLAGS_quic_restart_flag_quic_enable_accept_random_ipn = false;
+ SetQuicRestartFlag(quic_enable_accept_random_ipn, false);
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QuicConnectionId connection_id = 1;
@@ -544,7 +547,7 @@ TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
connection_id = 2;
- FLAGS_quic_restart_flag_quic_enable_accept_random_ipn = true;
+ SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
kMaxRandomInitialPacketNumber +
@@ -554,9 +557,6 @@ TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
static_assert(arraysize(kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
- FLAGS_quic_reloadable_flag_quic_enable_version_38 = true;
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = true;
- FLAGS_quic_reloadable_flag_quic_enable_version_41 = true;
SetQuicFlag(&FLAGS_quic_enable_version_42, true);
SetQuicFlag(&FLAGS_quic_enable_version_43, true);
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
@@ -566,10 +566,11 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
.Times(0);
- ProcessPacket(client_address, connection_id, true,
- static_cast<QuicTransportVersion>(QuicVersionMin() - 1),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ ParsedQuicVersion version(
+ PROTOCOL_QUIC_CRYPTO,
+ static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1));
+ ProcessPacket(client_address, connection_id, true, version, SerializeCHLO(),
+ PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
++connection_id;
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
@@ -611,7 +612,8 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
.Times(0);
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_43,
+ ProcessPacket(client_address, connection_id, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
PACKET_6BYTE_PACKET_NUMBER, 1);
@@ -631,7 +633,8 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
base::Unretained(this), connection_id))));
EXPECT_CALL(*dispatcher_,
ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_43,
+ ProcessPacket(client_address, connection_id, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
PACKET_6BYTE_PACKET_NUMBER, 1);
@@ -641,7 +644,8 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
.Times(0);
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_42,
+ ProcessPacket(client_address, connection_id, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
PACKET_6BYTE_PACKET_NUMBER, 1);
@@ -661,67 +665,8 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
base::Unretained(this), connection_id))));
EXPECT_CALL(*dispatcher_,
ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_42,
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 41.
- FLAGS_quic_reloadable_flag_quic_enable_version_41 = false;
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_41,
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 41.
- FLAGS_quic_reloadable_flag_quic_enable_version_41 = true;
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(testing::WithArgs<2>(
- Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
- base::Unretained(this), connection_id))));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_41,
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
-
- // Turn off version 39.
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = false;
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .Times(0);
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_39,
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
-
- // Turn on version 39.
- FLAGS_quic_reloadable_flag_quic_enable_version_39 = true;
- ++connection_id;
- EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
- QuicStringPiece("hq")))
- .WillOnce(testing::Return(CreateSession(
- dispatcher_.get(), config_, connection_id, client_address,
- &mock_helper_, &mock_alarm_factory_, &crypto_config_,
- QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, _, _))
- .WillOnce(testing::WithArgs<2>(
- Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
- base::Unretained(this), connection_id))));
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(connection_id));
- ProcessPacket(client_address, connection_id, true, QUIC_VERSION_39,
+ ProcessPacket(client_address, connection_id, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
PACKET_6BYTE_PACKET_NUMBER, 1);
}
@@ -736,7 +681,7 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
: QuicCryptoServerStream(
&crypto_config,
compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support),
session,
helper),
handshake_confirmed_(false) {}
@@ -812,8 +757,8 @@ class QuicDispatcherStatelessRejectTest
// crypto_stream1_.
void SetUp() override {
QuicDispatcherTest::SetUp();
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support =
- GetParam().enable_stateless_rejects_via_flag;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support,
+ GetParam().enable_stateless_rejects_via_flag);
}
// Returns true or false, depending on whether the server will emit
@@ -905,7 +850,7 @@ TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
}
TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = true;
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
CreateTimeWaitListManager();
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
@@ -957,7 +902,7 @@ TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
}
TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = true;
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
CreateTimeWaitListManager();
const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
@@ -1281,10 +1226,10 @@ class BufferedPacketStoreTest
: QuicDispatcherTest(),
client_addr_(QuicIpAddress::Loopback4(), 1234),
signed_config_(new QuicSignedServerConfig) {
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects =
- GetParam().support_cheap_stateless_reject;
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support =
- GetParam().enable_stateless_rejects_via_flag;
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
+ GetParam().support_cheap_stateless_reject);
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support,
+ GetParam().enable_stateless_rejects_via_flag);
}
void SetUp() override {
@@ -1692,8 +1637,8 @@ class AsyncGetProofTest : public QuicDispatcherTest {
client_addr_(QuicIpAddress::Loopback4(), 1234),
crypto_config_peer_(&crypto_config_),
signed_config_(new QuicSignedServerConfig) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support = true;
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects = true;
+ SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
+ SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
}
void SetUp() override {
@@ -2188,12 +2133,16 @@ TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
// because of QUIC_INVALID_STREAM_DATA.
// Send a CHLO with v39. Dispatcher framer's version is set to v39.
- ProcessPacket(client_addr_, 1, true, QUIC_VERSION_39, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
+ ProcessPacket(client_addr_, 1, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
+ SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
+ PACKET_6BYTE_PACKET_NUMBER, 1);
// Send another CHLO with v37. Dispatcher framer's version is set to v37.
- ProcessPacket(client_addr_, 2, true, QUIC_VERSION_37, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
+ ProcessPacket(client_addr_, 2, true,
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37),
+ SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
+ PACKET_6BYTE_PACKET_NUMBER, 1);
ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
// Complete the ProofSource::GetProof call for v39. This would cause the
diff --git a/chromium/net/tools/quic/quic_http_response_cache.cc b/chromium/net/tools/quic/quic_http_response_cache.cc
index 90c221a80ff..c960fc4f02f 100644
--- a/chromium/net/tools/quic/quic_http_response_cache.cc
+++ b/chromium/net/tools/quic/quic_http_response_cache.cc
@@ -330,7 +330,11 @@ void QuicHttpResponseCache::AddResponseImpl(QuicStringPiece host,
string QuicHttpResponseCache::GetKey(QuicStringPiece host,
QuicStringPiece path) const {
- return host.as_string() + path.as_string();
+ string host_string = host.as_string();
+ size_t port = host_string.find(':');
+ if (port != string::npos)
+ host_string = string(host_string.c_str(), port);
+ return host_string + path.as_string();
}
void QuicHttpResponseCache::MaybeAddServerPushResources(
diff --git a/chromium/net/tools/quic/quic_http_response_cache.h b/chromium/net/tools/quic/quic_http_response_cache.h
index fe9360489ec..ea840feaa6e 100644
--- a/chromium/net/tools/quic/quic_http_response_cache.h
+++ b/chromium/net/tools/quic/quic_http_response_cache.h
@@ -95,10 +95,8 @@ class QuicHttpResponseCache {
const std::string& file_name() { return file_name_string_; }
QuicStringPiece host() { return host_; }
- void set_host(QuicStringPiece host) { host_ = host; }
QuicStringPiece path() { return path_; }
- void set_path(QuicStringPiece path) { path_ = path; }
const SpdyHeaderBlock& spdy_headers() { return spdy_headers_; }
diff --git a/chromium/net/tools/quic/quic_packet_printer_bin.cc b/chromium/net/tools/quic/quic_packet_printer_bin.cc
index 06a251cf178..365e5ec84a0 100644
--- a/chromium/net/tools/quic/quic_packet_printer_bin.cc
+++ b/chromium/net/tools/quic/quic_packet_printer_bin.cc
@@ -67,11 +67,10 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface {
std::cerr << "OnError: " << QuicErrorCodeToString(framer->error())
<< " detail: " << framer->detailed_error() << "\n";
}
- bool OnProtocolVersionMismatch(
- QuicTransportVersion received_version) override {
+ bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
framer_->set_version(received_version);
std::cerr << "OnProtocolVersionMismatch: "
- << QuicVersionToString(received_version) << "\n";
+ << ParsedQuicVersionToString(received_version) << "\n";
return true;
}
void OnPacket() override { std::cerr << "OnPacket\n"; }
@@ -177,14 +176,14 @@ int main(int argc, char* argv[]) {
return 1;
}
string hex = net::QuicTextUtils::HexDecode(argv[2]);
- net::QuicTransportVersionVector versions =
- net::AllSupportedTransportVersions();
+ net::ParsedQuicVersionVector versions = net::AllSupportedVersions();
// Fake a time since we're not actually generating acks.
net::QuicTime start(net::QuicTime::Zero());
net::QuicFramer framer(versions, start, perspective);
if (!FLAGS_quic_version.empty()) {
- for (net::QuicTransportVersion version : versions) {
- if (net::QuicVersionToString(version) == FLAGS_quic_version) {
+ for (net::ParsedQuicVersion version : versions) {
+ if (net::QuicVersionToString(version.transport_version) ==
+ FLAGS_quic_version) {
framer.set_version(version);
}
}
diff --git a/chromium/net/tools/quic/quic_server.cc b/chromium/net/tools/quic/quic_server.cc
index bfaefc0afd0..42fb237379c 100644
--- a/chromium/net/tools/quic/quic_server.cc
+++ b/chromium/net/tools/quic/quic_server.cc
@@ -18,6 +18,7 @@
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/quic_data_reader.h"
#include "net/quic/core/quic_packets.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_clock.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
@@ -56,14 +57,14 @@ QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
: QuicServer(std::move(proof_source),
QuicConfig(),
QuicCryptoServerConfig::ConfigOptions(),
- AllSupportedTransportVersions(),
+ AllSupportedVersions(),
response_cache) {}
QuicServer::QuicServer(
std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache)
: port_(0),
fd_(-1),
@@ -73,7 +74,8 @@ QuicServer::QuicServer(
config_(config),
crypto_config_(kSourceAddressTokenSecret,
QuicRandom::GetInstance(),
- std::move(proof_source)),
+ std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()),
crypto_config_options_(crypto_config_options),
version_manager_(supported_versions),
packet_reader_(new QuicPacketReader()),
diff --git a/chromium/net/tools/quic/quic_server.h b/chromium/net/tools/quic/quic_server.h
index 9e404973156..e284941dc4d 100644
--- a/chromium/net/tools/quic/quic_server.h
+++ b/chromium/net/tools/quic/quic_server.h
@@ -40,7 +40,7 @@ class QuicServer : public EpollCallbackInterface {
QuicServer(std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& server_config_options,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache);
~QuicServer() override;
diff --git a/chromium/net/tools/quic/quic_server_bin.cc b/chromium/net/tools/quic/quic_server_bin.cc
index 7c3c2bdcf81..3d18dedd43b 100644
--- a/chromium/net/tools/quic/quic_server_bin.cc
+++ b/chromium/net/tools/quic/quic_server_bin.cc
@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) {
CreateProofSource(line->GetSwitchValuePath("certificate_file"),
line->GetSwitchValuePath("key_file")),
config, net::QuicCryptoServerConfig::ConfigOptions(),
- net::AllSupportedTransportVersions(), &response_cache);
+ net::AllSupportedVersions(), &response_cache);
int rc = server.CreateUDPSocketAndListen(
net::QuicSocketAddress(net::QuicIpAddress::Any6(), FLAGS_port));
diff --git a/chromium/net/tools/quic/quic_server_test.cc b/chromium/net/tools/quic/quic_server_test.cc
index 1c3451b7743..df80fa7d7b4 100644
--- a/chromium/net/tools/quic/quic_server_test.cc
+++ b/chromium/net/tools/quic/quic_server_test.cc
@@ -6,6 +6,8 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_socket_address.h"
@@ -130,9 +132,9 @@ TEST_F(QuicServerEpollInTest, ProcessBufferedCHLOsOnEpollin) {
ASSERT_LT(0, fd);
char buf[1024];
- memset(buf, 0, arraysize(buf));
+ memset(buf, 0, QUIC_ARRAYSIZE(buf));
sockaddr_storage storage = server_address_.generic_address();
- int rc = sendto(fd, buf, arraysize(buf), 0,
+ int rc = sendto(fd, buf, QUIC_ARRAYSIZE(buf), 0,
reinterpret_cast<sockaddr*>(&storage), sizeof(storage));
if (rc < 0) {
QUIC_DLOG(INFO) << errno << " " << strerror(errno);
@@ -148,8 +150,9 @@ class QuicServerDispatchPacketTest : public QuicTest {
QuicServerDispatchPacketTest()
: crypto_config_("blah",
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting()),
- version_manager_(AllSupportedTransportVersions()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
+ version_manager_(AllSupportedVersions()),
dispatcher_(
config_,
&crypto_config_,
@@ -196,7 +199,7 @@ TEST_F(QuicServerDispatchPacketTest, DispatchPacket) {
};
// clang-format on
QuicReceivedPacket encrypted_valid_packet(
- reinterpret_cast<char*>(valid_packet), arraysize(valid_packet),
+ reinterpret_cast<char*>(valid_packet), QUIC_ARRAYSIZE(valid_packet),
QuicTime::Zero(), false);
EXPECT_CALL(dispatcher_, ProcessPacket(_, _, _)).Times(1);
diff --git a/chromium/net/tools/quic/quic_simple_client.cc b/chromium/net/tools/quic/quic_simple_client.cc
index b394ae13458..1273c1bed19 100644
--- a/chromium/net/tools/quic/quic_simple_client.cc
+++ b/chromium/net/tools/quic/quic_simple_client.cc
@@ -36,7 +36,7 @@ namespace net {
QuicSimpleClient::QuicSimpleClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
std::unique_ptr<ProofVerifier> proof_verifier)
: QuicSpdyClientBase(
server_id,
diff --git a/chromium/net/tools/quic/quic_simple_client.h b/chromium/net/tools/quic/quic_simple_client.h
index 5f79e0497d2..8f17f68a1d9 100644
--- a/chromium/net/tools/quic/quic_simple_client.h
+++ b/chromium/net/tools/quic/quic_simple_client.h
@@ -40,7 +40,7 @@ class QuicSimpleClient : public QuicSpdyClientBase {
// Create a quic client, which will have events managed by the message loop.
QuicSimpleClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
std::unique_ptr<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 c4c91aac2be..af5e63e2616 100644
--- a/chromium/net/tools/quic/quic_simple_client_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_client_bin.cc
@@ -254,12 +254,12 @@ int main(int argc, char* argv[]) {
// Build the client, and try to connect.
net::QuicServerId server_id(url.host(), url.EffectiveIntPort(),
net::PRIVACY_MODE_DISABLED);
- net::QuicTransportVersionVector versions =
- net::AllSupportedTransportVersions();
+ net::ParsedQuicVersionVector versions = net::AllSupportedVersions();
if (FLAGS_quic_version != -1) {
versions.clear();
- versions.push_back(
- static_cast<net::QuicTransportVersion>(FLAGS_quic_version));
+ versions.push_back(net::ParsedQuicVersion(
+ net::PROTOCOL_QUIC_CRYPTO,
+ static_cast<net::QuicTransportVersion>(FLAGS_quic_version)));
}
// For secure QUIC we need to verify the cert chain.
std::unique_ptr<CertVerifier> cert_verifier(CertVerifier::CreateDefault());
@@ -288,7 +288,7 @@ int main(int argc, char* argv[]) {
net::QuicErrorCode error = client.session()->error();
if (FLAGS_version_mismatch_ok && error == net::QUIC_INVALID_VERSION) {
cout << "Server talks QUIC, but none of the versions supported by "
- << "this client: " << QuicTransportVersionVectorToString(versions)
+ << "this client: " << ParsedQuicVersionVectorToString(versions)
<< endl;
// Version mismatch is not deemed a failure.
return 0;
diff --git a/chromium/net/tools/quic/quic_simple_client_test.cc b/chromium/net/tools/quic/quic_simple_client_test.cc
index 2c6baef3145..16ff1bfa337 100644
--- a/chromium/net/tools/quic/quic_simple_client_test.cc
+++ b/chromium/net/tools/quic/quic_simple_client_test.cc
@@ -16,7 +16,7 @@ TEST(QuicSimpleClientTest, Initialize) {
QuicSocketAddress server_address(QuicIpAddress::Loopback4(), 80);
QuicServerId server_id("hostname", server_address.port(),
PRIVACY_MODE_DISABLED);
- QuicTransportVersionVector versions = AllSupportedTransportVersions();
+ ParsedQuicVersionVector versions = AllSupportedVersions();
QuicSimpleClient client(server_address, server_id, versions,
crypto_test_utils::ProofVerifierForTesting());
EXPECT_TRUE(client.Initialize());
diff --git a/chromium/net/tools/quic/quic_simple_dispatcher.cc b/chromium/net/tools/quic/quic_simple_dispatcher.cc
index 832415cc1dd..1f64cb5d6f4 100644
--- a/chromium/net/tools/quic/quic_simple_dispatcher.cc
+++ b/chromium/net/tools/quic/quic_simple_dispatcher.cc
@@ -51,11 +51,10 @@ QuicServerSessionBase* QuicSimpleDispatcher::CreateQuicSession(
const QuicSocketAddress& client_address,
QuicStringPiece /*alpn*/) {
// The QuicServerSessionBase takes ownership of |connection| below.
- QuicConnection* connection =
- new QuicConnection(connection_id, client_address, helper(),
- alarm_factory(), CreatePerConnectionWriter(),
- /* owns_writer= */ true, Perspective::IS_SERVER,
- GetSupportedTransportVersions());
+ QuicConnection* connection = new QuicConnection(
+ connection_id, client_address, helper(), alarm_factory(),
+ CreatePerConnectionWriter(),
+ /* owns_writer= */ true, Perspective::IS_SERVER, GetSupportedVersions());
QuicServerSessionBase* session = new QuicSimpleServerSession(
config(), connection, this, session_helper(), crypto_config(),
diff --git a/chromium/net/tools/quic/quic_simple_server.cc b/chromium/net/tools/quic/quic_simple_server.cc
index 4ecbf753610..6526e6ce6bb 100644
--- a/chromium/net/tools/quic/quic_simple_server.cc
+++ b/chromium/net/tools/quic/quic_simple_server.cc
@@ -17,6 +17,7 @@
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/quic_data_reader.h"
#include "net/quic/core/quic_packets.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/socket/udp_server_socket.h"
#include "net/tools/quic/quic_simple_dispatcher.h"
#include "net/tools/quic/quic_simple_per_connection_packet_writer.h"
@@ -40,7 +41,7 @@ QuicSimpleServer::QuicSimpleServer(
std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache)
: version_manager_(supported_versions),
helper_(
@@ -52,7 +53,8 @@ QuicSimpleServer::QuicSimpleServer(
crypto_config_options_(crypto_config_options),
crypto_config_(kSourceAddressTokenSecret,
QuicRandom::GetInstance(),
- std::move(proof_source)),
+ std::move(proof_source),
+ TlsServerHandshaker::CreateSslCtx()),
read_pending_(false),
synchronous_read_count_(0),
read_buffer_(new IOBufferWithSize(kReadBufferSize)),
@@ -146,6 +148,9 @@ void QuicSimpleServer::Shutdown() {
// notify clients that they're closing.
dispatcher_->Shutdown();
+ if (!socket_) {
+ return;
+ }
socket_->Close();
socket_.reset();
}
diff --git a/chromium/net/tools/quic/quic_simple_server.h b/chromium/net/tools/quic/quic_simple_server.h
index 938a7132788..b72d967e8da 100644
--- a/chromium/net/tools/quic/quic_simple_server.h
+++ b/chromium/net/tools/quic/quic_simple_server.h
@@ -39,7 +39,7 @@ class QuicSimpleServer {
std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache);
virtual ~QuicSimpleServer();
diff --git a/chromium/net/tools/quic/quic_simple_server_bin.cc b/chromium/net/tools/quic/quic_simple_server_bin.cc
index c435d766de8..e7c44d2553c 100644
--- a/chromium/net/tools/quic/quic_simple_server_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_server_bin.cc
@@ -90,7 +90,7 @@ int main(int argc, char* argv[]) {
CreateProofSource(line->GetSwitchValuePath("certificate_file"),
line->GetSwitchValuePath("key_file")),
config, net::QuicCryptoServerConfig::ConfigOptions(),
- net::AllSupportedTransportVersions(), &response_cache);
+ net::AllSupportedVersions(), &response_cache);
int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port));
if (rc < 0) {
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 fa7ece10834..15b24ca664f 100644
--- a/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
+++ b/chromium/net/tools/quic/quic_simple_server_packet_writer.cc
@@ -7,7 +7,7 @@
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_functions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/socket/udp_server_socket.h"
@@ -87,7 +87,7 @@ WriteResult QuicSimpleServerPacketWriter::WritePacket(
WriteStatus status = WRITE_STATUS_OK;
if (rv < 0) {
if (rv != ERR_IO_PENDING) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv);
+ base::UmaHistogramSparse("Net.QuicSession.WriteError", -rv);
status = WRITE_STATUS_ERROR;
} else {
status = WRITE_STATUS_BLOCKED;
diff --git a/chromium/net/tools/quic/quic_simple_server_session.cc b/chromium/net/tools/quic/quic_simple_server_session.cc
index 4d10c403231..42d195d32ae 100644
--- a/chromium/net/tools/quic/quic_simple_server_session.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/core/quic_connection.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
@@ -44,7 +43,7 @@ QuicSimpleServerSession::CreateQuicCryptoServerStream(
QuicCompressedCertsCache* compressed_certs_cache) {
return new QuicCryptoServerStream(
crypto_config, compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support, this,
+ GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
stream_helper());
}
diff --git a/chromium/net/tools/quic/quic_simple_server_session_test.cc b/chromium/net/tools/quic/quic_simple_server_session_test.cc
index 712fff9eeeb..d1189a52468 100644
--- a/chromium/net/tools/quic/quic_simple_server_session_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session_test.cc
@@ -14,6 +14,7 @@
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/quic_crypto_server_stream.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_containers.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_socket_address.h"
@@ -64,15 +65,6 @@ class QuicSimpleServerSessionPeer {
QuicSimpleServerSession* s) {
return s->CreateOutgoingDynamicStream();
}
-
- static QuicDeque<PromisedStreamInfo>* promised_streams(
- QuicSimpleServerSession* s) {
- return &(s->promised_streams_);
- }
-
- static QuicStreamId hightest_promised_stream_id(QuicSimpleServerSession* s) {
- return s->highest_promised_stream_id_;
- }
};
namespace {
@@ -89,7 +81,8 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream {
: QuicCryptoServerStream(
crypto_config,
compressed_certs_cache,
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support,
+ GetQuicReloadableFlag(
+ enable_quic_stateless_reject_support), // NOLINT
session,
helper) {}
~MockQuicCryptoServerStream() override = default;
@@ -118,7 +111,7 @@ class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
MockQuicConnectionHelper* helper,
MockAlarmFactory* alarm_factory,
Perspective perspective,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: MockQuicConnection(helper,
alarm_factory,
perspective,
@@ -179,12 +172,13 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession {
};
class QuicSimpleServerSessionTest
- : public QuicTestWithParam<QuicTransportVersion> {
+ : public QuicTestWithParam<ParsedQuicVersion> {
protected:
QuicSimpleServerSessionTest()
: crypto_config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
@@ -198,7 +192,7 @@ class QuicSimpleServerSessionTest
connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
&helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(GetParam()));
session_.reset(new MockQuicSimpleServerSession(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &response_cache_));
@@ -236,7 +230,7 @@ class QuicSimpleServerSessionTest
INSTANTIATE_TEST_CASE_P(Tests,
QuicSimpleServerSessionTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
// Open a stream, then reset it.
@@ -453,7 +447,7 @@ class QuicSimpleServerSessionServerPushTest
connection_ = new StrictMock<MockQuicConnectionWithSendStreamData>(
&helper_, &alarm_factory_, Perspective::IS_SERVER,
- SupportedTransportVersions(GetParam()));
+ SupportedVersions(GetParam()));
session_.reset(new MockQuicSimpleServerSession(
config_, connection_, &owner_, &stream_helper_, &crypto_config_,
&compressed_certs_cache_, &response_cache_));
@@ -521,7 +515,7 @@ class QuicSimpleServerSessionServerPushTest
INSTANTIATE_TEST_CASE_P(Tests,
QuicSimpleServerSessionServerPushTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSimpleServerSessionServerPushTest, TestPromisePushResources) {
// Tests that given more than kMaxOpenStreamForTest resources, all their
diff --git a/chromium/net/tools/quic/quic_simple_server_stream_test.cc b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
index 7a1040d1eb2..1d119ac452f 100644
--- a/chromium/net/tools/quic/quic_simple_server_stream_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
@@ -10,6 +10,8 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_test.h"
@@ -164,19 +166,19 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession {
DISALLOW_COPY_AND_ASSIGN(MockQuicSimpleServerSession);
};
-class QuicSimpleServerStreamTest
- : public QuicTestWithParam<QuicTransportVersion> {
+class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
public:
QuicSimpleServerStreamTest()
- : connection_(new StrictMock<MockQuicConnection>(
- &helper_,
- &alarm_factory_,
- Perspective::IS_SERVER,
- SupportedTransportVersions(GetParam()))),
+ : connection_(
+ new StrictMock<MockQuicConnection>(&helper_,
+ &alarm_factory_,
+ Perspective::IS_SERVER,
+ SupportedVersions(GetParam()))),
crypto_config_(new QuicCryptoServerConfig(
QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting())),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx())),
compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
session_(connection_,
@@ -232,12 +234,12 @@ class QuicSimpleServerStreamTest
INSTANTIATE_TEST_CASE_P(Tests,
QuicSimpleServerStreamTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSimpleServerStreamTest, TestFraming) {
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
stream_->OnStreamFrame(
QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
@@ -250,7 +252,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFraming) {
TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
stream_->OnStreamFrame(
@@ -264,7 +266,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFramingOnePacket) {
TEST_P(QuicSimpleServerStreamTest, SendQuicRstStreamNoErrorInStopReading) {
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
EXPECT_FALSE(stream_->fin_received());
EXPECT_FALSE(stream_->rst_received());
@@ -282,7 +284,7 @@ TEST_P(QuicSimpleServerStreamTest, TestFramingExtraData) {
// We'll automatically write out an error (headers + body)
EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
- .WillOnce(Invoke(MockQuicSession::ConsumeAllData));
+ .WillOnce(Invoke(MockQuicSession::ConsumeData));
EXPECT_CALL(session_, SendRstStream(_, QUIC_STREAM_NO_ERROR, _)).Times(0);
stream_->OnStreamHeaderList(false, kFakeFrameLen, header_list_);
@@ -526,7 +528,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidMultipleContentLength) {
EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
@@ -544,7 +546,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidLeadingNullContentLength) {
EXPECT_CALL(session_, WriteHeadersMock(_, _, _, _, _));
EXPECT_CALL(session_, WritevData(_, _, _, _, _))
.Times(AnyNumber())
- .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
+ .WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
stream_->OnStreamHeaderList(true, kFakeFrameLen, header_list_);
EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream_));
@@ -604,7 +606,7 @@ TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
0x54, 0x54, 0x50, 0x2f, // TTP/
0x31, 0x2e, 0x31, // 1.1
};
- QuicStringPiece data(arr, arraysize(arr));
+ QuicStringPiece data(arr, QUIC_ARRAYSIZE(arr));
QuicStreamFrame frame(stream_->id(), true, 0, data);
// Verify that we don't crash when we get a invalid headers in stream frame.
stream_->OnStreamFrame(frame);
diff --git a/chromium/net/tools/quic/quic_simple_server_test.cc b/chromium/net/tools/quic/quic_simple_server_test.cc
index 3b5000cac81..66bbd33774b 100644
--- a/chromium/net/tools/quic/quic_simple_server_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_test.cc
@@ -7,6 +7,7 @@
#include "net/quic/core/crypto/quic_random.h"
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_quic_dispatcher.h"
@@ -25,8 +26,9 @@ class QuicChromeServerDispatchPacketTest : public QuicTest {
QuicChromeServerDispatchPacketTest()
: crypto_config_("blah",
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting()),
- version_manager_(AllSupportedTransportVersions()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
+ version_manager_(AllSupportedVersions()),
dispatcher_(
config_,
&crypto_config_,
diff --git a/chromium/net/tools/quic/quic_spdy_client_base.cc b/chromium/net/tools/quic/quic_spdy_client_base.cc
index d285648b0da..6cad4ee3c35 100644
--- a/chromium/net/tools/quic/quic_spdy_client_base.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_base.cc
@@ -32,7 +32,7 @@ QuicSpdyClientBase::QuicDataToResend::~QuicDataToResend() = default;
QuicSpdyClientBase::QuicSpdyClientBase(
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
@@ -170,7 +170,7 @@ int QuicSpdyClientBase::GetNumReceivedServerConfigUpdatesFromSession() {
void QuicSpdyClientBase::MaybeAddDataToResend(const SpdyHeaderBlock& headers,
QuicStringPiece body,
bool fin) {
- if (!FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support) {
+ if (!GetQuicReloadableFlag(enable_quic_stateless_reject_support)) {
return;
}
diff --git a/chromium/net/tools/quic/quic_spdy_client_base.h b/chromium/net/tools/quic/quic_spdy_client_base.h
index a79a5ef9ebb..468e712c1de 100644
--- a/chromium/net/tools/quic/quic_spdy_client_base.h
+++ b/chromium/net/tools/quic/quic_spdy_client_base.h
@@ -69,7 +69,7 @@ class QuicSpdyClientBase : public QuicClientBase,
};
QuicSpdyClientBase(const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicConfig& config,
QuicConnectionHelperInterface* helper,
QuicAlarmFactory* alarm_factory,
diff --git a/chromium/net/tools/quic/quic_spdy_client_session_test.cc b/chromium/net/tools/quic/quic_spdy_client_session_test.cc
index b2da7ceb7db..a41ebe13778 100644
--- a/chromium/net/tools/quic/quic_spdy_client_session_test.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_session_test.cc
@@ -8,6 +8,7 @@
#include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_socket_address.h"
@@ -63,11 +64,11 @@ class TestQuicSpdyClientSession : public QuicSpdyClientSession {
}
};
-class QuicSpdyClientSessionTest
- : public QuicTestWithParam<QuicTransportVersion> {
+class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
protected:
QuicSpdyClientSessionTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ : crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()),
promised_stream_id_(kInvalidStreamId),
associated_stream_id_(kInvalidStreamId) {
Initialize();
@@ -82,9 +83,9 @@ class QuicSpdyClientSessionTest
void Initialize() {
session_.reset();
- connection_ = new PacketSavingConnection(
- &helper_, &alarm_factory_, Perspective::IS_CLIENT,
- SupportedTransportVersions(GetParam()));
+ connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
+ Perspective::IS_CLIENT,
+ SupportedVersions(GetParam()));
session_.reset(new TestQuicSpdyClientSession(
DefaultQuicConfig(), connection_,
QuicServerId(kServerHostname, kPort, PRIVACY_MODE_DISABLED),
@@ -131,7 +132,7 @@ class QuicSpdyClientSessionTest
INSTANTIATE_TEST_CASE_P(Tests,
QuicSpdyClientSessionTest,
- ::testing::ValuesIn(AllSupportedTransportVersions()));
+ ::testing::ValuesIn(AllSupportedVersions()));
TEST_P(QuicSpdyClientSessionTest, CryptoConnect) {
CompleteCryptoHandshake();
@@ -342,7 +343,7 @@ TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
// Verify that a decryptable packet with bad frames does close the connection.
QuicConnectionId connection_id = session_->connection()->connection_id();
- QuicTransportVersionVector versions = {GetParam()};
+ ParsedQuicVersionVector versions = {GetParam()};
std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
PACKET_6BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
index 361f87e0954..c8d035eb1ad 100644
--- a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_test.h"
@@ -38,7 +39,8 @@ class MockQuicSpdyClientSession : public QuicSpdyClientSession {
QuicServerId("example.com", 443, PRIVACY_MODE_DISABLED),
&crypto_config_,
push_promise_index),
- crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {}
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
+ TlsClientHandshaker::CreateSslCtx()) {}
~MockQuicSpdyClientSession() override = default;
MOCK_METHOD1(CloseStream, void(QuicStreamId stream_id));
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.cc b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
index 9f54816de89..31279b34c39 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
@@ -93,7 +93,7 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() {
void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
if (connection_rejected_statelessly) {
@@ -127,7 +127,7 @@ bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
return QuicContainsKey(connection_id_map_, connection_id);
}
-QuicTransportVersion QuicTimeWaitListManager::GetQuicVersionFromConnectionId(
+ParsedQuicVersion QuicTimeWaitListManager::GetQuicVersionFromConnectionId(
QuicConnectionId connection_id) {
ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
DCHECK(it != connection_id_map_.end());
@@ -180,7 +180,7 @@ void QuicTimeWaitListManager::ProcessPacket(
void QuicTimeWaitListManager::SendVersionNegotiationPacket(
QuicConnectionId connection_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address) {
SendOrQueuePacket(
@@ -308,7 +308,7 @@ void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
int num_packets_,
- QuicTransportVersion version_,
+ ParsedQuicVersion version_,
QuicTime time_added_,
bool connection_rejected_statelessly)
: num_packets(num_packets_),
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.h b/chromium/net/tools/quic/quic_time_wait_list_manager.h
index ed0b545b77a..0bd53b87c90 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.h
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.h
@@ -68,7 +68,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// and termination packets are expected.
virtual void AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets);
@@ -100,8 +100,8 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
void TrimTimeWaitListIfNeeded();
// Given a ConnectionId that exists in the time wait list, returns the
- // QuicTransportVersion associated with it.
- QuicTransportVersion GetQuicVersionFromConnectionId(
+ // ParsedQuicVersion associated with it.
+ ParsedQuicVersion GetQuicVersionFromConnectionId(
QuicConnectionId connection_id);
// The number of connections on the time-wait list.
@@ -111,7 +111,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// for |supported_versions| to |client_address| from |server_address|.
virtual void SendVersionNegotiationPacket(
QuicConnectionId connection_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address);
@@ -162,7 +162,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// connection_id.
struct ConnectionIdData {
ConnectionIdData(int num_packets_,
- QuicTransportVersion version_,
+ ParsedQuicVersion version_,
QuicTime time_added_,
bool connection_rejected_statelessly);
@@ -172,7 +172,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
~ConnectionIdData();
int num_packets;
- QuicTransportVersion version;
+ ParsedQuicVersion version;
QuicTime time_added;
// These packets may contain CONNECTION_CLOSE frames, or SREJ messages.
std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc b/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
index a1576767763..a4e6ffc394c 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -102,7 +102,7 @@ class QuicTimeWaitListManagerTest : public QuicTest {
void AddConnectionId(
QuicConnectionId connection_id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
time_wait_list_manager_.AddConnectionIdToTimeWait(
@@ -147,7 +147,7 @@ class ValidatePublicResetPacketPredicate
const std::tr1::tuple<const char*, int> packet_buffer,
testing::MatchResultListener* /* listener */) const override {
FramerVisitorCapturingPublicReset visitor;
- QuicFramer framer(AllSupportedTransportVersions(), QuicTime::Zero(),
+ QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
Perspective::IS_CLIENT);
framer.set_visitor(&visitor);
QuicEncryptedPacket encrypted(std::tr1::get<0>(packet_buffer),
@@ -190,15 +190,14 @@ TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id_, AllSupportedTransportVersions()));
+ QuicFramer::BuildVersionNegotiationPacket(connection_id_,
+ AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), server_address_.host(),
client_address_, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, AllSupportedTransportVersions(), server_address_,
- client_address_);
+ connection_id_, AllSupportedVersions(), server_address_, client_address_);
EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
}
@@ -395,13 +394,13 @@ TEST_F(QuicTimeWaitListManagerTest, GetQuicVersionFromMap) {
AddConnectionId(kConnectionId3, QuicVersionMax(),
/*connection_rejected_statelessly=*/false, nullptr);
- EXPECT_EQ(QuicVersionMin(),
+ EXPECT_EQ(QuicTransportVersionMin(),
QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
&time_wait_list_manager_, kConnectionId1));
- EXPECT_EQ(QuicVersionMax(),
+ EXPECT_EQ(QuicTransportVersionMax(),
QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
&time_wait_list_manager_, kConnectionId2));
- EXPECT_EQ(QuicVersionMax(),
+ EXPECT_EQ(QuicTransportVersionMax(),
QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
&time_wait_list_manager_, kConnectionId3));
}
diff --git a/chromium/net/tools/quic/stateless_rejector.cc b/chromium/net/tools/quic/stateless_rejector.cc
index 668065c35e4..625898a49ca 100644
--- a/chromium/net/tools/quic/stateless_rejector.cc
+++ b/chromium/net/tools/quic/stateless_rejector.cc
@@ -68,8 +68,8 @@ void StatelessRejector::OnChlo(QuicTransportVersion version,
DCHECK_NE(connection_id, server_designated_connection_id);
DCHECK_EQ(state_, UNKNOWN);
- if (!FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support ||
- !FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects ||
+ if (!GetQuicReloadableFlag(enable_quic_stateless_reject_support) ||
+ !GetQuicReloadableFlag(quic_use_cheap_stateless_rejects) ||
!QuicCryptoServerStream::DoesPeerSupportStatelessRejects(message)) {
state_ = UNSUPPORTED;
return;
diff --git a/chromium/net/tools/quic/stateless_rejector_test.cc b/chromium/net/tools/quic/stateless_rejector_test.cc
index 67a630bc139..c1e17394dfd 100644
--- a/chromium/net/tools/quic/stateless_rejector_test.cc
+++ b/chromium/net/tools/quic/stateless_rejector_test.cc
@@ -10,6 +10,7 @@
#include "net/quic/core/crypto/crypto_handshake_message.h"
#include "net/quic/core/crypto/proof_source.h"
#include "net/quic/core/quic_utils.h"
+#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
@@ -80,7 +81,8 @@ class StatelessRejectorTest : public QuicTestWithParam<TestParams> {
: proof_source_(crypto_test_utils::ProofSourceForTesting()),
config_(QuicCryptoServerConfig::TESTING,
QuicRandom::GetInstance(),
- crypto_test_utils::ProofSourceForTesting()),
+ crypto_test_utils::ProofSourceForTesting(),
+ TlsServerHandshaker::CreateSslCtx()),
config_peer_(&config_),
compressed_certs_cache_(
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
@@ -94,10 +96,12 @@ class StatelessRejectorTest : public QuicTestWithParam<TestParams> {
kDefaultMaxPacketSize,
QuicSocketAddress(QuicIpAddress::Loopback4(), 12345),
QuicSocketAddress(QuicIpAddress::Loopback4(), 443))) {
- FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support =
- GetParam().flags == ENABLED || GetParam().flags == CHEAP_DISABLED;
- FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects =
- GetParam().flags == ENABLED || GetParam().flags == STATELESS_DISABLED;
+ SetQuicReloadableFlag(
+ enable_quic_stateless_reject_support,
+ GetParam().flags == ENABLED || GetParam().flags == CHEAP_DISABLED);
+ SetQuicReloadableFlag(
+ quic_use_cheap_stateless_rejects,
+ GetParam().flags == ENABLED || GetParam().flags == STATELESS_DISABLED);
// Add a new primary config.
std::unique_ptr<CryptoHandshakeMessage> msg(config_.AddDefaultConfig(
diff --git a/chromium/net/tools/quic/test_tools/bad_packet_writer.cc b/chromium/net/tools/quic/test_tools/bad_packet_writer.cc
new file mode 100644
index 00000000000..91d5fe50bca
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/bad_packet_writer.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/tools/quic/test_tools/bad_packet_writer.h"
+
+namespace net {
+namespace test {
+
+BadPacketWriter::BadPacketWriter(size_t packet_causing_write_error,
+ int error_code)
+ : packet_causing_write_error_(packet_causing_write_error),
+ error_code_(error_code) {}
+
+BadPacketWriter::~BadPacketWriter() {}
+
+WriteResult BadPacketWriter::WritePacket(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options) {
+ if (error_code_ == 0 || packet_causing_write_error_ > 0) {
+ if (packet_causing_write_error_ > 0) {
+ --packet_causing_write_error_;
+ }
+ return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
+ peer_address, options);
+ }
+ // It's time to cause write error.
+ int error_code = error_code_;
+ error_code_ = 0;
+ return WriteResult(WRITE_STATUS_ERROR, error_code);
+}
+
+} // namespace test
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/bad_packet_writer.h b/chromium/net/tools/quic/test_tools/bad_packet_writer.h
new file mode 100644
index 00000000000..e8d6d4ead06
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/bad_packet_writer.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
+
+#include "net/tools/quic/quic_packet_writer_wrapper.h"
+
+namespace net {
+
+namespace test {
+// This packet writer allows causing packet write error with specified error
+// code when writing a particular packet.
+class BadPacketWriter : public QuicPacketWriterWrapper {
+ public:
+ BadPacketWriter(size_t packet_causing_write_error, int error_code);
+
+ ~BadPacketWriter() override;
+
+ WriteResult WritePacket(const char* buffer,
+ size_t buf_len,
+ const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address,
+ PerPacketOptions* options) override;
+
+ private:
+ size_t packet_causing_write_error_;
+ int error_code_;
+};
+
+} // namespace test
+
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_BAD_PACKET_WRITER_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
index a7e72efd6fb..547ed7cb8ee 100644
--- a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -21,14 +21,14 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
MOCK_METHOD4(AddConnectionIdToTimeWait,
void(QuicConnectionId connection_id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>*
termination_packets));
void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
- QuicTransportVersion version,
+ ParsedQuicVersion version,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
QuicTimeWaitListManager::AddConnectionIdToTimeWait(
@@ -43,7 +43,7 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
MOCK_METHOD4(SendVersionNegotiationPacket,
void(QuicConnectionId connection_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address));
};
diff --git a/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc b/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc
index 99c965f5d79..992b9eb07f5 100644
--- a/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc
+++ b/chromium/net/tools/quic/test_tools/packet_reordering_writer.cc
@@ -18,10 +18,12 @@ WriteResult PacketReorderingWriter::WritePacket(
const QuicSocketAddress& peer_address,
PerPacketOptions* options) {
if (!delay_next_) {
+ VLOG(2) << "Writing a non-delayed packet";
WriteResult wr = QuicPacketWriterWrapper::WritePacket(
buffer, buf_len, self_address, peer_address, options);
--num_packets_to_wait_;
if (num_packets_to_wait_ == 0) {
+ VLOG(2) << "Writing a delayed packet";
// It's time to write the delayed packet.
QuicPacketWriterWrapper::WritePacket(
delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.cc b/chromium/net/tools/quic/test_tools/quic_test_client.cc
index 83ed2993f49..73d3be66736 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.cc
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.cc
@@ -165,7 +165,7 @@ class MockableQuicClientEpollNetworkHelper
MockableQuicClient::MockableQuicClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server)
: MockableQuicClient(server_address,
server_id,
@@ -177,7 +177,7 @@ MockableQuicClient::MockableQuicClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server)
: MockableQuicClient(server_address,
server_id,
@@ -190,7 +190,7 @@ MockableQuicClient::MockableQuicClient(
QuicSocketAddress server_address,
const QuicServerId& server_id,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier)
: QuicClient(
@@ -251,7 +251,7 @@ void MockableQuicClient::set_track_last_incoming_packet(bool track) {
QuicTestClient::QuicTestClient(
QuicSocketAddress server_address,
const string& server_hostname,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: QuicTestClient(server_address,
server_hostname,
QuicConfig(),
@@ -261,7 +261,7 @@ QuicTestClient::QuicTestClient(
QuicSocketAddress server_address,
const string& server_hostname,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions)
+ const ParsedQuicVersionVector& supported_versions)
: client_(new MockableQuicClient(server_address,
QuicServerId(server_hostname,
server_address.port(),
@@ -276,7 +276,7 @@ QuicTestClient::QuicTestClient(
QuicSocketAddress server_address,
const string& server_hostname,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
std::unique_ptr<ProofVerifier> proof_verifier)
: client_(new MockableQuicClient(server_address,
QuicServerId(server_hostname,
@@ -376,7 +376,7 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
stream->WriteOrBufferBody(body.as_string(), fin, ack_listener);
ret = body.length();
}
- if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support) {
+ if (GetQuicReloadableFlag(enable_quic_stateless_reject_support)) {
std::unique_ptr<SpdyHeaderBlock> new_headers;
if (headers) {
new_headers.reset(new SpdyHeaderBlock(headers->Clone()));
@@ -728,8 +728,15 @@ void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
client_->UseConnectionId(connection_id);
}
-void QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
- client_->MigrateSocket(new_host);
+bool QuicTestClient::MigrateSocket(const QuicIpAddress& new_host) {
+ return client_->MigrateSocket(new_host);
+}
+
+bool QuicTestClient::MigrateSocketWithSpecifiedPort(
+ const QuicIpAddress& new_host,
+ int port) {
+ client_->set_local_port(port);
+ return client_->MigrateSocket(new_host);
}
QuicIpAddress QuicTestClient::bind_to_address() const {
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.h b/chromium/net/tools/quic/test_tools/quic_test_client.h
index 4c76a763dd3..3302b52719f 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.h
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.h
@@ -34,19 +34,19 @@ class MockableQuicClient : public QuicClient {
public:
MockableQuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server);
MockableQuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server);
MockableQuicClient(QuicSocketAddress server_address,
const QuicServerId& server_id,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
EpollServer* epoll_server,
std::unique_ptr<ProofVerifier> proof_verifier);
@@ -79,15 +79,15 @@ class QuicTestClient : public QuicSpdyStream::Visitor,
public:
QuicTestClient(QuicSocketAddress server_address,
const std::string& server_hostname,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
QuicTestClient(QuicSocketAddress server_address,
const std::string& server_hostname,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions);
+ const ParsedQuicVersionVector& supported_versions);
QuicTestClient(QuicSocketAddress server_address,
const std::string& server_hostname,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
std::unique_ptr<ProofVerifier> proof_verifier);
~QuicTestClient() override;
@@ -183,7 +183,12 @@ class QuicTestClient : public QuicSpdyStream::Visitor,
WaitUntil(timeout_ms, [this]() { return response_size() != 0; });
}
- void MigrateSocket(const QuicIpAddress& new_host);
+ // Migrate local address to <|new_host|, a random port>.
+ // Return whether the migration succeeded.
+ bool MigrateSocket(const QuicIpAddress& new_host);
+ // Migrate local address to <|new_host|, |port|>.
+ // Return whether the migration succeeded.
+ bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port);
QuicIpAddress bind_to_address() const;
void set_bind_to_address(QuicIpAddress address);
const QuicSocketAddress& address() const;
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.cc b/chromium/net/tools/quic/test_tools/quic_test_server.cc
index 39d09265a2e..172000f596c 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_server.cc
+++ b/chromium/net/tools/quic/test_tools/quic_test_server.cc
@@ -97,7 +97,7 @@ class QuicTestDispatcher : public QuicSimpleDispatcher {
QuicConnection* connection = new QuicConnection(
id, client, helper(), alarm_factory(), CreatePerConnectionWriter(),
/* owns_writer= */ true, Perspective::IS_SERVER,
- GetSupportedTransportVersions());
+ GetSupportedVersions());
QuicServerSessionBase* session = nullptr;
if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
@@ -150,7 +150,7 @@ QuicTestServer::QuicTestServer(std::unique_ptr<ProofSource> proof_source,
QuicTestServer::QuicTestServer(
std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache)
: QuicServer(std::move(proof_source),
config,
diff --git a/chromium/net/tools/quic/test_tools/quic_test_server.h b/chromium/net/tools/quic/test_tools/quic_test_server.h
index cf223118a1c..13ffc4ca6a0 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_server.h
+++ b/chromium/net/tools/quic/test_tools/quic_test_server.h
@@ -62,7 +62,7 @@ class QuicTestServer : public QuicServer {
QuicHttpResponseCache* response_cache);
QuicTestServer(std::unique_ptr<ProofSource> proof_source,
const QuicConfig& config,
- const QuicTransportVersionVector& supported_versions,
+ const ParsedQuicVersionVector& supported_versions,
QuicHttpResponseCache* response_cache);
// Create a custom dispatcher which creates custom sessions.
diff --git a/chromium/net/tools/testserver/minica.py b/chromium/net/tools/testserver/minica.py
index 62991ffba2e..ff35b9cd833 100644
--- a/chromium/net/tools/testserver/minica.py
+++ b/chromium/net/tools/testserver/minica.py
@@ -93,37 +93,14 @@ class RSA(object):
return asn1.ToDER(asn1.SEQUENCE([self.m, self.e]))
-def Name(cn = None, c = None, o = None):
- names = asn1.SEQUENCE([])
-
- if cn is not None:
- names.children.append(
- asn1.SET([
- asn1.SEQUENCE([
- COMMON_NAME, cn,
- ])
- ])
- )
-
- if c is not None:
- names.children.append(
- asn1.SET([
- asn1.SEQUENCE([
- COUNTRY, c,
- ])
- ])
- )
-
- if o is not None:
- names.children.append(
- asn1.SET([
- asn1.SEQUENCE([
- ORGANIZATION, o,
- ])
+def Name(cn):
+ return asn1.SEQUENCE([
+ asn1.SET([
+ asn1.SEQUENCE([
+ COMMON_NAME, cn,
])
- )
-
- return names
+ ])
+ ])
# The private key and root certificate name are hard coded here:
@@ -225,10 +202,6 @@ def MakeCertificate(
'''MakeCertificate returns a DER encoded certificate, signed by privkey.'''
extensions = asn1.SEQUENCE([])
- # Default subject name fields
- c = "XX"
- o = "Testing Org"
-
if is_ca:
# Root certificate.
c = None
@@ -306,7 +279,7 @@ def MakeCertificate(
asn1.UTCTime("100101060000Z"), # NotBefore
asn1.UTCTime("321201060000Z"), # NotAfter
]),
- Name(cn = subject_cn, c = c, o = o), # Subject
+ Name(cn = subject_cn), # Subject
asn1.SEQUENCE([ # SubjectPublicKeyInfo
asn1.SEQUENCE([ # Algorithm
PUBLIC_KEY_RSA,
diff --git a/chromium/net/tools/testserver/testserver.py b/chromium/net/tools/testserver/testserver.py
index 10d207dfd13..4ec483109e6 100755
--- a/chromium/net/tools/testserver/testserver.py
+++ b/chromium/net/tools/testserver/testserver.py
@@ -39,21 +39,9 @@ import zlib
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(BASE_DIR)))
-# Temporary hack to deal with tlslite 0.3.8 -> 0.4.6 upgrade.
-#
-# TODO(davidben): Remove this when it has cycled through all the bots and
-# developer checkouts or when http://crbug.com/356276 is resolved.
-try:
- os.remove(os.path.join(ROOT_DIR, 'third_party', 'tlslite',
- 'tlslite', 'utils', 'hmac.pyc'))
-except Exception:
- pass
-
-# Append at the end of sys.path, it's fine to use the system library.
-sys.path.append(os.path.join(ROOT_DIR, 'third_party', 'pyftpdlib', 'src'))
-
# Insert at the beginning of the path, we want to use our copies of the library
-# unconditionally.
+# unconditionally (since they contain modifications from anything that might be
+# obtained from e.g. PyPi).
sys.path.insert(0, os.path.join(ROOT_DIR, 'third_party', 'pywebsocket', 'src'))
sys.path.insert(0, os.path.join(ROOT_DIR, 'third_party', 'tlslite'))
@@ -1922,11 +1910,16 @@ class ServerRunner(testserver_base.TestServerRunner):
print ('AIA server started on %s:%d...' %
(host, self.__ocsp_server.server_port))
+ ocsp_server_port = self.__ocsp_server.server_port
+ if self.options.ocsp_proxy_port_number != 0:
+ ocsp_server_port = self.options.ocsp_proxy_port_number
+ server_data['ocsp_port'] = self.__ocsp_server.server_port
+
(pem_cert_and_key, intermediate_cert_der) = \
minica.GenerateCertKeyAndIntermediate(
- subject = "127.0.0.1",
- ca_issuers_url = ("http://%s:%d/ca_issuers" %
- (host, self.__ocsp_server.server_port)),
+ subject = self.options.cert_common_name,
+ ca_issuers_url =
+ ("http://%s:%d/ca_issuers" % (host, ocsp_server_port)),
serial = self.options.cert_serial)
self.__ocsp_server.ocsp_response = None
@@ -1995,10 +1988,14 @@ class ServerRunner(testserver_base.TestServerRunner):
raise testserver_base.OptionError('unknown OCSP produced: ' +
self.options.ocsp_produced)
+ ocsp_server_port = self.__ocsp_server.server_port
+ if self.options.ocsp_proxy_port_number != 0:
+ ocsp_server_port = self.options.ocsp_proxy_port_number
+ server_data['ocsp_port'] = self.__ocsp_server.server_port
+
(pem_cert_and_key, ocsp_der) = minica.GenerateCertKeyAndOCSP(
- subject = "127.0.0.1",
- ocsp_url = ("http://%s:%d/ocsp" %
- (host, self.__ocsp_server.server_port)),
+ subject = self.options.cert_common_name,
+ ocsp_url = ("http://%s:%d/ocsp" % (host, ocsp_server_port)),
ocsp_states = ocsp_states,
ocsp_dates = ocsp_dates,
ocsp_produced = ocsp_produced,
@@ -2198,6 +2195,10 @@ class ServerRunner(testserver_base.TestServerRunner):
default=0, type=int,
help='If non-zero then the generated '
'certificate will have this serial number')
+ self.option_parser.add_option('--cert-common-name', dest='cert_common_name',
+ default="127.0.0.1",
+ help='The generated certificate will have '
+ 'this common name')
self.option_parser.add_option('--tls-intolerant', dest='tls_intolerant',
default='0', type='int',
help='If nonzero, certain TLS connections '
@@ -2297,6 +2298,10 @@ class ServerRunner(testserver_base.TestServerRunner):
help='If set, the OCSP server will return '
'a tryLater status rather than the actual '
'OCSP response.')
+ self.option_parser.add_option('--ocsp-proxy-port-number', default=0,
+ type='int', dest='ocsp_proxy_port_number',
+ help='Port allocated for OCSP proxy '
+ 'when connection is proxied.')
self.option_parser.add_option('--alert-after-handshake',
dest='alert_after_handshake',
default=False, action='store_true',
diff --git a/chromium/net/traffic_annotation/network_traffic_annotation.h b/chromium/net/traffic_annotation/network_traffic_annotation.h
index 333e839df5d..15f1aeaa84e 100644
--- a/chromium/net/traffic_annotation/network_traffic_annotation.h
+++ b/chromium/net/traffic_annotation/network_traffic_annotation.h
@@ -276,6 +276,12 @@ struct MutablePartialNetworkTrafficAnnotationTag {
net::DefineNetworkTrafficAnnotation( \
"missing", "Function called without traffic annotation.")
+// TODO(crbug.com/656607): Remove this temporary tag which is only used during
+// refactoring.
+#define NO_TRAFFIC_ANNOTATION_BUG_656607 \
+ net::DefineNetworkTrafficAnnotation("undefined-656607", \
+ "Temporary tag for crbug.com/656607.")
+
#undef COMPUTE_STRING_HASH
#endif // NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
diff --git a/chromium/net/url_request/network_error_logging_delegate.h b/chromium/net/url_request/network_error_logging_delegate.h
index ec2238ca54e..26330d860d4 100644
--- a/chromium/net/url_request/network_error_logging_delegate.h
+++ b/chromium/net/url_request/network_error_logging_delegate.h
@@ -38,6 +38,8 @@ class NET_EXPORT NetworkErrorLoggingDelegate {
int status_code;
base::TimeDelta elapsed_time;
Error type;
+
+ bool is_reporting_upload;
};
static const char kHeaderName[];
@@ -65,6 +67,11 @@ class NET_EXPORT NetworkErrorLoggingDelegate {
//
// |details| is the details of the network error.
virtual void OnNetworkError(const ErrorDetails& details) = 0;
+
+ // Removes all stored data associated with any origins matching
+ // |origin_filter| (or all origins if null).
+ virtual void RemoveBrowsingData(
+ const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0;
};
} // namespace net
diff --git a/chromium/net/url_request/url_request.cc b/chromium/net/url_request/url_request.cc
index 91763538afe..8cef4d5f0d1 100644
--- a/chromium/net/url_request/url_request.cc
+++ b/chromium/net/url_request/url_request.cc
@@ -31,6 +31,7 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
+#include "net/reporting/reporting_service.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/redirect_util.h"
@@ -191,7 +192,8 @@ URLRequest::~URLRequest() {
// on UserData associated with |this| and poke at it during teardown.
job_.reset();
- context_->RemoveURLRequest(this);
+ DCHECK_EQ(1u, context_->url_requests()->count(this));
+ context_->url_requests()->erase(this);
int net_error = OK;
// Log error only on failure, not cancellation, as even successful requests
@@ -574,11 +576,12 @@ URLRequest::URLRequest(const GURL& url,
received_response_content_length_(0),
creation_time_(base::TimeTicks::Now()),
raw_header_size_(0),
+ is_pac_request_(false),
traffic_annotation_(traffic_annotation) {
// Sanity check out environment.
DCHECK(base::ThreadTaskRunnerHandle::IsSet());
- context->InsertURLRequest(this);
+ context->url_requests()->insert(this);
net_log_.BeginEvent(
NetLogEventType::REQUEST_ALIVE,
base::Bind(&NetLogURLRequestConstructorCallback, &url, priority_));
@@ -1183,13 +1186,21 @@ void URLRequest::MaybeGenerateNetworkErrorLoggingReport() {
details.server_ip = endpoint.address();
// TODO(juliatuttle): Plumb this.
details.protocol = kProtoUnknown;
- details.status_code = GetResponseCode();
- if (details.status_code == -1)
+ if (response_headers()) {
+ // HttpResponseHeaders::response_code() returns 0 if response code couldn't
+ // be parsed, which is also how NEL represents the same.
+ details.status_code = response_headers()->response_code();
+ } else {
details.status_code = 0;
+ }
details.elapsed_time =
base::TimeTicks::Now() - load_timing_info_.request_start;
details.type = status().ToNetError();
+ details.is_reporting_upload =
+ context()->reporting_service() &&
+ context()->reporting_service()->RequestIsUpload(*this);
+
delegate->OnNetworkError(details);
}
#endif // BUILDFLAG(ENABLE_REPORTING)
diff --git a/chromium/net/url_request/url_request.h b/chromium/net/url_request/url_request.h
index 0635448f00a..60fbf78c788 100644
--- a/chromium/net/url_request/url_request.h
+++ b/chromium/net/url_request/url_request.h
@@ -662,6 +662,15 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// encryption, 0 for cached responses.
int raw_header_size() const { return raw_header_size_; }
+ // True if this request was issued by the proxy service subsystem in order to
+ // probe/fetch a Proxy Auto Config script.
+ // TODO(mmenke): See if there's a way to not need this.
+ bool is_pac_request() const { return is_pac_request_; }
+ // Sets whether this is a request for a PAC script. Defaults to false.
+ void set_is_pac_request(bool is_pac_request) {
+ is_pac_request_ = is_pac_request;
+ }
+
// Returns the error status of the request.
// Do not use! Going to be protected!
const URLRequestStatus& status() const { return status_; }
@@ -890,6 +899,9 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// The raw header size of the response.
int raw_header_size_;
+ // True if this is a request for a PAC script.
+ bool is_pac_request_;
+
const NetworkTrafficAnnotationTag traffic_annotation_;
// See Set{Request|Response}HeadersCallback() above for details.
diff --git a/chromium/net/url_request/url_request_context.cc b/chromium/net/url_request/url_request_context.cc
index b19870fdd75..17736d522f7 100644
--- a/chromium/net/url_request/url_request_context.cc
+++ b/chromium/net/url_request/url_request_context.cc
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/debug/alias.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -49,10 +50,10 @@ URLRequestContext::URLRequestContext()
reporting_service_(nullptr),
network_error_logging_delegate_(nullptr),
#endif // BUILDFLAG(ENABLE_REPORTING)
+ url_requests_(std::make_unique<std::set<const URLRequest*>>()),
enable_brotli_(false),
check_cleartext_permitted_(false),
- name_("unknown"),
- largest_outstanding_requests_count_seen_(0) {
+ name_("unknown") {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "URLRequestContext", base::ThreadTaskRunnerHandle::Get());
}
@@ -134,33 +135,14 @@ void URLRequestContext::set_cookie_store(CookieStore* cookie_store) {
cookie_store_ = cookie_store;
}
-void URLRequestContext::InsertURLRequest(const URLRequest* request) const {
- url_requests_.insert(request);
- if (url_requests_.size() > largest_outstanding_requests_count_seen_) {
- largest_outstanding_requests_count_seen_ = url_requests_.size();
- UMA_HISTOGRAM_COUNTS_1M("Net.URLRequestContext.OutstandingRequests",
- largest_outstanding_requests_count_seen_);
- UMA_HISTOGRAM_SPARSE_SLOWLY(
- "Net.URLRequestContext.OutstandingRequests.Type",
- request->traffic_annotation().unique_id_hash_code);
- }
-}
-
-void URLRequestContext::RemoveURLRequest(const URLRequest* request) const {
- DCHECK_EQ(1u, url_requests_.count(request));
- url_requests_.erase(request);
-}
-
void URLRequestContext::AssertNoURLRequests() const {
- int num_requests = url_requests_.size();
+ int num_requests = url_requests_->size();
if (num_requests != 0) {
// We're leaking URLRequests :( Dump the URL of the first one and record how
// many we leaked so we have an idea of how bad it is.
- char url_buf[128];
- const URLRequest* request = *url_requests_.begin();
- base::strlcpy(url_buf, request->url().spec().c_str(), arraysize(url_buf));
+ const URLRequest* request = *url_requests_->begin();
int load_flags = request->load_flags();
- base::debug::Alias(url_buf);
+ DEBUG_ALIAS_FOR_GURL(url_buf, request->url());
base::debug::Alias(&num_requests);
base::debug::Alias(&load_flags);
CHECK(false) << "Leaked " << num_requests << " URLRequest(s). First URL: "
@@ -180,7 +162,7 @@ bool URLRequestContext::OnMemoryDump(
pmd->CreateAllocatorDump(dump_name);
dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
base::trace_event::MemoryAllocatorDump::kUnitsObjects,
- url_requests_.size());
+ url_requests_->size());
HttpTransactionFactory* transaction_factory = http_transaction_factory();
if (transaction_factory) {
HttpNetworkSession* network_session = transaction_factory->GetSession();
diff --git a/chromium/net/url_request/url_request_context.h b/chromium/net/url_request/url_request_context.h
index c498ad2282e..30fc9851aa9 100644
--- a/chromium/net/url_request/url_request_context.h
+++ b/chromium/net/url_request/url_request_context.h
@@ -215,14 +215,10 @@ class NET_EXPORT URLRequestContext
// Gets the URLRequest objects that hold a reference to this
// URLRequestContext.
- const std::set<const URLRequest*>& url_requests() const {
- return url_requests_;
+ std::set<const URLRequest*>* url_requests() const {
+ return url_requests_.get();
}
- void InsertURLRequest(const URLRequest* request) const;
-
- void RemoveURLRequest(const URLRequest* request) const;
-
// CHECKs that no URLRequests using this context remain. Subclasses should
// additionally call AssertNoURLRequests() within their own destructor,
// prior to implicit destruction of subclass-owned state.
@@ -328,7 +324,7 @@ class NET_EXPORT URLRequestContext
// be added to CopyFrom.
// ---------------------------------------------------------------------------
- mutable std::set<const URLRequest*> url_requests_;
+ std::unique_ptr<std::set<const URLRequest*>> url_requests_;
// Enables Brotli Content-Encoding support.
bool enable_brotli_;
@@ -341,10 +337,6 @@ class NET_EXPORT URLRequestContext
// to be unique.
std::string name_;
- // The largest number of outstanding URLRequests that have been created by
- // |this| and are not yet destroyed. This doesn't need to be in CopyFrom.
- mutable size_t largest_outstanding_requests_count_seen_;
-
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(URLRequestContext);
diff --git a/chromium/net/url_request/url_request_context_builder.cc b/chromium/net/url_request/url_request_context_builder.cc
index 0d566da4c41..6bdf43edbb7 100644
--- a/chromium/net/url_request/url_request_context_builder.cc
+++ b/chromium/net/url_request/url_request_context_builder.cc
@@ -150,6 +150,12 @@ class ContainerURLRequestContext final : public URLRequestContext {
~ContainerURLRequestContext() override {
#if BUILDFLAG(ENABLE_REPORTING)
+ // Destroy the NetworkErrorLoggingDelegate so that destroying the
+ // ReportingService (which might abort in-flight URLRequests, generating
+ // network errors) won't recursively try to queue more network error
+ // reports.
+ storage_.set_network_error_logging_delegate(nullptr);
+
// Destroy the ReportingService before the rest of the URLRequestContext, so
// it cancels any pending requests it may have.
storage_.set_reporting_service(nullptr);
diff --git a/chromium/net/url_request/url_request_ftp_job.cc b/chromium/net/url_request/url_request_ftp_job.cc
index 803758125da..1d7ff64d0fc 100644
--- a/chromium/net/url_request/url_request_ftp_job.cc
+++ b/chromium/net/url_request/url_request_ftp_job.cc
@@ -45,7 +45,7 @@ URLRequestFtpJob::URLRequestFtpJob(
: URLRequestJob(request, network_delegate),
priority_(DEFAULT_PRIORITY),
proxy_service_(request_->context()->proxy_service()),
- pac_request_(NULL),
+ proxy_resolve_request_(NULL),
http_response_info_(NULL),
read_in_progress_(false),
ftp_transaction_factory_(ftp_transaction_factory),
@@ -104,7 +104,7 @@ void URLRequestFtpJob::SetPriority(RequestPriority priority) {
}
void URLRequestFtpJob::Start() {
- DCHECK(!pac_request_);
+ DCHECK(!proxy_resolve_request_);
DCHECK(!ftp_transaction_);
DCHECK(!http_transaction_);
@@ -117,7 +117,7 @@ void URLRequestFtpJob::Start() {
request_->url(), "GET", &proxy_info_,
base::Bind(&URLRequestFtpJob::OnResolveProxyComplete,
base::Unretained(this)),
- &pac_request_, NULL, request_->net_log());
+ &proxy_resolve_request_, NULL, request_->net_log());
if (rv == ERR_IO_PENDING)
return;
@@ -126,9 +126,9 @@ void URLRequestFtpJob::Start() {
}
void URLRequestFtpJob::Kill() {
- if (pac_request_) {
- proxy_service_->CancelPacRequest(pac_request_);
- pac_request_ = nullptr;
+ if (proxy_resolve_request_) {
+ proxy_service_->CancelRequest(proxy_resolve_request_);
+ proxy_resolve_request_ = nullptr;
}
if (ftp_transaction_)
ftp_transaction_.reset();
@@ -139,7 +139,7 @@ void URLRequestFtpJob::Kill() {
}
void URLRequestFtpJob::OnResolveProxyComplete(int result) {
- pac_request_ = NULL;
+ proxy_resolve_request_ = NULL;
if (result != OK) {
OnStartCompletedAsync(result);
@@ -172,9 +172,8 @@ void URLRequestFtpJob::StartFtpTransaction() {
if (ftp_transaction_) {
rv = ftp_transaction_->Start(
&ftp_request_info_,
- base::Bind(&URLRequestFtpJob::OnStartCompleted,
- base::Unretained(this)),
- request_->net_log());
+ base::Bind(&URLRequestFtpJob::OnStartCompleted, base::Unretained(this)),
+ request_->net_log(), request_->traffic_annotation());
if (rv == ERR_IO_PENDING)
return;
} else {
@@ -278,8 +277,8 @@ void URLRequestFtpJob::RestartTransactionWithAuth() {
}
LoadState URLRequestFtpJob::GetLoadState() const {
- if (pac_request_)
- return proxy_service_->GetLoadState(pac_request_);
+ if (proxy_resolve_request_)
+ return proxy_service_->GetLoadState(proxy_resolve_request_);
if (proxy_info_.is_direct()) {
return ftp_transaction_ ?
ftp_transaction_->GetLoadState() : LOAD_STATE_IDLE;
diff --git a/chromium/net/url_request/url_request_ftp_job.h b/chromium/net/url_request/url_request_ftp_job.h
index b8d06db7bc2..0edb4d661d9 100644
--- a/chromium/net/url_request/url_request_ftp_job.h
+++ b/chromium/net/url_request/url_request_ftp_job.h
@@ -81,7 +81,7 @@ class NET_EXPORT_PRIVATE URLRequestFtpJob : public URLRequestJob {
ProxyService* proxy_service_;
ProxyInfo proxy_info_;
- ProxyService::PacRequest* pac_request_;
+ ProxyService::Request* proxy_resolve_request_;
FtpRequestInfo ftp_request_info_;
std::unique_ptr<FtpTransaction> ftp_transaction_;
diff --git a/chromium/net/url_request/url_request_http_job.cc b/chromium/net/url_request/url_request_http_job.cc
index da7a1986598..d6eb1043b34 100644
--- a/chromium/net/url_request/url_request_http_job.cc
+++ b/chromium/net/url_request/url_request_http_job.cc
@@ -100,7 +100,7 @@ void LogTrustAnchor(const net::HashValueVector& spki_hashes) {
if (id != 0)
break;
}
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.Certificate.TrustAnchor.Request", id);
+ base::UmaHistogramSparse("Net.Certificate.TrustAnchor.Request", id);
}
// Records per-request histograms relating to Certificate Transparency
@@ -593,7 +593,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
bool advertise_brotli = false;
if (request()->context()->enable_brotli()) {
if (request()->url().SchemeIsCryptographic() ||
- IsLocalhost(request()->url().HostNoBracketsPiece())) {
+ IsLocalhost(request()->url())) {
advertise_brotli = true;
}
}
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 9d9aaaf1c3b..10b36de23a6 100644
--- a/chromium/net/url_request/url_request_http_job_unittest.cc
+++ b/chromium/net/url_request/url_request_http_job_unittest.cc
@@ -1575,6 +1575,7 @@ class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
// Fake implementation of HttpStreamBase methods.
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override {
diff --git a/chromium/net/url_request/url_request_quic_perftest.cc b/chromium/net/url_request/url_request_quic_perftest.cc
index a81ae35a556..614ef64461d 100644
--- a/chromium/net/url_request/url_request_quic_perftest.cc
+++ b/chromium/net/url_request/url_request_quic_perftest.cc
@@ -112,6 +112,7 @@ class URLRequestQuicPerfTest : public ::testing::Test {
new HttpNetworkSession::Params);
params->enable_quic = true;
params->enable_user_alternate_protocol_ports = true;
+ params->quic_allow_remote_alt_svc = true;
context_->set_host_resolver(host_resolver_.get());
context_->set_http_network_session_params(std::move(params));
context_->set_cert_verifier(&cert_verifier_);
@@ -146,15 +147,15 @@ class URLRequestQuicPerfTest : public ::testing::Test {
kHelloAltSvcResponse);
quic_server_.reset(new QuicSimpleServer(
test::crypto_test_utils::ProofSourceForTesting(), config,
- net::QuicCryptoServerConfig::ConfigOptions(),
- AllSupportedTransportVersions(), &response_cache_));
+ net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(),
+ &response_cache_));
int rv = quic_server_->Listen(
net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kAltSvcPort));
ASSERT_GE(rv, 0) << "Quic server fails to start";
CertVerifyResult verify_result;
verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test.example.com.crt");
+ GetTestCertsDirectory(), "quic-chain.pem");
cert_verifier_.AddResultForCert(verify_result.verified_cert.get(),
verify_result, OK);
}
diff --git a/chromium/net/url_request/url_request_quic_unittest.cc b/chromium/net/url_request/url_request_quic_unittest.cc
index 6820bd9a4c1..615aad96fb8 100644
--- a/chromium/net/url_request/url_request_quic_unittest.cc
+++ b/chromium/net/url_request/url_request_quic_unittest.cc
@@ -35,9 +35,7 @@ namespace net {
namespace {
-// This must match the certificate used (quic_test.example.com.crt and
-// quic_test.example.com.key.pkcs8).
-const int kTestServerPort = 6121;
+// This must match the certificate used (quic-chain.pem and quic-leaf-cert.key).
const char kTestServerHost[] = "test.example.com";
// Used as a simple response from the server.
const char kHelloPath[] = "/hello.txt";
@@ -53,12 +51,7 @@ class URLRequestQuicTest : public ::testing::Test {
new HttpNetworkSession::Params);
CertVerifyResult verify_result;
verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test.example.com.crt");
- cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
- "test.example.com", verify_result,
- OK);
- verify_result.verified_cert = ImportCertFromFile(
- GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
+ GetTestCertsDirectory(), "quic-chain.pem");
cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
"test.example.com", verify_result,
OK);
@@ -99,7 +92,7 @@ class URLRequestQuicTest : public ::testing::Test {
void ExtractNetLog(NetLogEventType type,
TestNetLogEntry::List* entry_list) const {
- net::TestNetLogEntry::List entries;
+ TestNetLogEntry::List entries;
net_log_.GetEntries(&entries);
for (const auto& entry : entries) {
@@ -114,6 +107,33 @@ class URLRequestQuicTest : public ::testing::Test {
->GetRstErrorCount(error_code);
}
+ static const NetLogSource FindPushUrlSource(
+ const TestNetLogEntry::List& entries,
+ const std::string& push_url) {
+ std::string entry_push_url;
+ for (const auto& entry : entries) {
+ if (entry.phase == NetLogEventPhase::BEGIN &&
+ entry.source.type ==
+ NetLogSourceType::SERVER_PUSH_LOOKUP_TRANSACTION &&
+ entry.GetStringValue("push_url", &entry_push_url) &&
+ entry_push_url == push_url) {
+ return entry.source;
+ }
+ }
+ return NetLogSource();
+ }
+
+ static const TestNetLogEntry* FindEndBySource(
+ const TestNetLogEntry::List& entries,
+ const NetLogSource& source) {
+ for (const auto& entry : entries) {
+ if (entry.phase == NetLogEventPhase::END &&
+ entry.source.type == source.type && entry.source.id == source.id)
+ return &entry;
+ }
+ return nullptr;
+ }
+
private:
void StartQuicServer() {
// Set up in-memory cache.
@@ -126,15 +146,15 @@ class URLRequestQuicTest : public ::testing::Test {
new net::ProofSourceChromium());
base::FilePath directory = GetTestCertsDirectory();
CHECK(proof_source->Initialize(
- directory.Append(FILE_PATH_LITERAL("quic_test.example.com.crt")),
- directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.pkcs8")),
- directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.sct"))));
+ directory.Append(FILE_PATH_LITERAL("quic-chain.pem")),
+ directory.Append(FILE_PATH_LITERAL("quic-leaf-cert.key")),
+ base::FilePath()));
server_.reset(new QuicSimpleServer(
test::crypto_test_utils::ProofSourceForTesting(), config,
- net::QuicCryptoServerConfig::ConfigOptions(),
- AllSupportedTransportVersions(), &response_cache_));
- int rv = server_->Listen(
- net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kTestServerPort));
+ net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(),
+ &response_cache_));
+ int rv =
+ server_->Listen(net::IPEndPoint(net::IPAddress::IPv4AllZeros(), 0));
EXPECT_GE(rv, 0) << "Quic server fails to start";
std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
@@ -248,7 +268,7 @@ TEST_F(URLRequestQuicTest, TestGetRequest) {
EXPECT_EQ(kHelloBodyValue, delegate.data_received());
}
-TEST_F(URLRequestQuicTest, CancelPushIfCached) {
+TEST_F(URLRequestQuicTest, CancelPushIfCached_SomeCached) {
base::RunLoop run_loop;
Init();
@@ -292,7 +312,7 @@ TEST_F(URLRequestQuicTest, CancelPushIfCached) {
net::TestNetLogEntry::List entries;
ExtractNetLog(NetLogEventType::SERVER_PUSH_LOOKUP_TRANSACTION, &entries);
- EXPECT_EQ(4u, entries.size());
+ ASSERT_EQ(4u, entries.size());
std::string value;
int net_error;
@@ -301,22 +321,30 @@ TEST_F(URLRequestQuicTest, CancelPushIfCached) {
std::string push_url_2 =
base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
- EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_1);
- EXPECT_TRUE(entries[1].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_2);
+ const NetLogSource source_1 = FindPushUrlSource(entries, push_url_1);
+ EXPECT_TRUE(source_1.IsValid());
+
+ // No net error code for this lookup transaction, the push is found.
+ const TestNetLogEntry* end_entry_1 = FindEndBySource(entries, source_1);
+ EXPECT_FALSE(end_entry_1->params);
+ EXPECT_FALSE(end_entry_1->GetIntegerValue("net_error", &net_error));
+
+ const NetLogSource source_2 = FindPushUrlSource(entries, push_url_2);
+ EXPECT_TRUE(source_2.IsValid());
+ EXPECT_NE(source_1.id, source_2.id);
+
// Net error code -400 is found for this lookup transaction, the push is not
// found in the cache.
- EXPECT_TRUE(entries[2].GetIntegerValue("net_error", &net_error));
+ const TestNetLogEntry* end_entry_2 = FindEndBySource(entries, source_2);
+ EXPECT_TRUE(end_entry_2->params);
+ EXPECT_TRUE(end_entry_2->GetIntegerValue("net_error", &net_error));
EXPECT_EQ(net_error, -400);
- // No net error code for this lookup transaction, the push is found.
- EXPECT_FALSE(entries[3].GetIntegerValue("net_error", &net_error));
// Verify the reset error count received on the server side.
EXPECT_LE(1u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED));
}
-TEST_F(URLRequestQuicTest, CancelPushIfCached2) {
+TEST_F(URLRequestQuicTest, CancelPushIfCached_AllCached) {
base::RunLoop run_loop;
Init();
@@ -357,7 +385,7 @@ TEST_F(URLRequestQuicTest, CancelPushIfCached2) {
EXPECT_TRUE(request_1->status().is_success());
// Send a request to /index2.html which pushes /kitten-1.jpg and /favicon.ico.
- // Should cancel push for /kitten-1.jpg.
+ // Should cancel push for both pushed resources, since they're already cached.
CheckLoadTimingDelegate delegate(true);
std::string url =
base::StringPrintf("https://%s%s", kTestServerHost, "/index2.html");
@@ -387,17 +415,22 @@ TEST_F(URLRequestQuicTest, CancelPushIfCached2) {
std::string push_url_2 =
base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
- EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_1);
-
- EXPECT_TRUE(entries[1].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_2);
+ const NetLogSource source_1 = FindPushUrlSource(entries, push_url_1);
+ EXPECT_TRUE(source_1.IsValid());
// No net error code for this lookup transaction, the push is found.
- EXPECT_FALSE(entries[2].GetIntegerValue("net_error", &net_error));
+ const TestNetLogEntry* end_entry_1 = FindEndBySource(entries, source_1);
+ EXPECT_FALSE(end_entry_1->params);
+ EXPECT_FALSE(end_entry_1->GetIntegerValue("net_error", &net_error));
+
+ const NetLogSource source_2 = FindPushUrlSource(entries, push_url_2);
+ EXPECT_TRUE(source_1.IsValid());
+ EXPECT_NE(source_1.id, source_2.id);
// No net error code for this lookup transaction, the push is found.
- EXPECT_FALSE(entries[3].GetIntegerValue("net_error", &net_error));
+ const TestNetLogEntry* end_entry_2 = FindEndBySource(entries, source_2);
+ EXPECT_FALSE(end_entry_2->params);
+ EXPECT_FALSE(end_entry_2->GetIntegerValue("net_error", &net_error));
// Verify the reset error count received on the server side.
EXPECT_LE(2u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED));
@@ -437,14 +470,19 @@ TEST_F(URLRequestQuicTest, DoNotCancelPushIfNotFoundInCache) {
std::string push_url_2 =
base::StringPrintf("https://%s%s", kTestServerHost, "/favicon.ico");
- EXPECT_TRUE(entries[0].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_1);
- EXPECT_TRUE(entries[1].GetIntegerValue("net_error", &net_error));
+ const NetLogSource source_1 = FindPushUrlSource(entries, push_url_1);
+ EXPECT_TRUE(source_1.IsValid());
+ const TestNetLogEntry* end_entry_1 = FindEndBySource(entries, source_1);
+ EXPECT_TRUE(end_entry_1->params);
+ EXPECT_TRUE(end_entry_1->GetIntegerValue("net_error", &net_error));
EXPECT_EQ(net_error, -400);
- EXPECT_TRUE(entries[2].GetStringValue("push_url", &value));
- EXPECT_EQ(value, push_url_2);
- EXPECT_TRUE(entries[3].GetIntegerValue("net_error", &net_error));
+ const NetLogSource source_2 = FindPushUrlSource(entries, push_url_2);
+ EXPECT_TRUE(source_2.IsValid());
+ EXPECT_NE(source_1.id, source_2.id);
+ const TestNetLogEntry* end_entry_2 = FindEndBySource(entries, source_2);
+ EXPECT_TRUE(end_entry_2->params);
+ EXPECT_TRUE(end_entry_2->GetIntegerValue("net_error", &net_error));
EXPECT_EQ(net_error, -400);
// Verify the reset error count received on the server side.
diff --git a/chromium/net/url_request/url_request_test_util.cc b/chromium/net/url_request/url_request_test_util.cc
index 9a34c24e539..59bcad5ddb0 100644
--- a/chromium/net/url_request/url_request_test_util.cc
+++ b/chromium/net/url_request/url_request_test_util.cc
@@ -16,7 +16,7 @@
#include "net/base/host_port_pair.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
-#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cert/do_nothing_ct_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_network_session.h"
#include "net/http/http_response_headers.h"
@@ -82,7 +82,7 @@ void TestURLRequestContext::Init() {
}
if (!cert_transparency_verifier()) {
context_storage_.set_cert_transparency_verifier(
- std::make_unique<MultiLogCTVerifier>());
+ std::make_unique<DoNothingCTVerifier>());
}
if (!ct_policy_enforcer()) {
context_storage_.set_ct_policy_enforcer(
diff --git a/chromium/net/url_request/url_request_throttler_manager.cc b/chromium/net/url_request/url_request_throttler_manager.cc
index 23ffab916d4..f879137e5d1 100644
--- a/chromium/net/url_request/url_request_throttler_manager.cc
+++ b/chromium/net/url_request/url_request_throttler_manager.cc
@@ -79,9 +79,9 @@ scoped_refptr<URLRequestThrottlerEntryInterface>
// We only disable back-off throttling on an entry that we have
// just constructed. This is to allow unit tests to explicitly override
// the entry for localhost URLs.
- std::string host = url.host();
- if (IsLocalhost(host)) {
- if (!logged_for_localhost_disabled_ && IsLocalhost(host)) {
+ if (IsLocalhost(url)) {
+ if (!logged_for_localhost_disabled_ && IsLocalhost(url)) {
+ std::string host = url.host();
logged_for_localhost_disabled_ = true;
net_log_.AddEvent(NetLogEventType::THROTTLING_DISABLED_FOR_HOST,
NetLog::StringCallback("host", &host));
diff --git a/chromium/net/url_request/url_request_unittest.cc b/chromium/net/url_request/url_request_unittest.cc
index 1aa782f31c5..01afe00bd41 100644
--- a/chromium/net/url_request/url_request_unittest.cc
+++ b/chromium/net/url_request/url_request_unittest.cc
@@ -6472,7 +6472,7 @@ TEST_F(URLRequestTestHTTP, ProcessPKPAndSendReport) {
std::unique_ptr<base::Value> value(
base::JSONReader::Read(mock_report_sender.latest_report()));
ASSERT_TRUE(value);
- ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY));
+ ASSERT_TRUE(value->is_dict());
base::DictionaryValue* report_dict;
ASSERT_TRUE(value->GetAsDictionary(&report_dict));
std::string report_hostname;
@@ -6537,7 +6537,7 @@ TEST_F(URLRequestTestHTTP, ProcessPKPReportOnly) {
std::unique_ptr<base::Value> value(
base::JSONReader::Read(mock_report_sender.latest_report()));
ASSERT_TRUE(value);
- ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY));
+ ASSERT_TRUE(value->is_dict());
base::DictionaryValue* report_dict;
ASSERT_TRUE(value->GetAsDictionary(&report_dict));
std::string report_hostname;
@@ -7037,12 +7037,17 @@ class TestReportingService : public ReportingService {
headers_.push_back({url, header_value});
}
- void RemoveBrowsingData(
- int data_type_mask,
- base::Callback<bool(const GURL&)> origin_filter) override {
+ void RemoveBrowsingData(int data_type_mask,
+ const base::RepeatingCallback<bool(const GURL&)>&
+ origin_filter) override {
NOTIMPLEMENTED();
}
+ bool RequestIsUpload(const URLRequest& request) override {
+ NOTIMPLEMENTED();
+ return true;
+ }
+
private:
std::vector<Header> headers_;
};
@@ -7060,7 +7065,8 @@ std::unique_ptr<test_server::HttpResponse> SendReportToHeader(
} // namespace
TEST_F(URLRequestTestHTTP, DontProcessReportToHeaderNoService) {
- http_test_server()->RegisterRequestHandler(base::Bind(&SendReportToHeader));
+ http_test_server()->RegisterRequestHandler(
+ base::BindRepeating(&SendReportToHeader));
ASSERT_TRUE(http_test_server()->Start());
GURL request_url = http_test_server()->GetURL("/");
@@ -7077,7 +7083,8 @@ TEST_F(URLRequestTestHTTP, DontProcessReportToHeaderNoService) {
}
TEST_F(URLRequestTestHTTP, DontProcessReportToHeaderHTTP) {
- http_test_server()->RegisterRequestHandler(base::Bind(&SendReportToHeader));
+ http_test_server()->RegisterRequestHandler(
+ base::BindRepeating(&SendReportToHeader));
ASSERT_TRUE(http_test_server()->Start());
GURL request_url = http_test_server()->GetURL("/");
@@ -7099,7 +7106,8 @@ TEST_F(URLRequestTestHTTP, DontProcessReportToHeaderHTTP) {
TEST_F(URLRequestTestHTTP, ProcessReportToHeaderHTTPS) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.RegisterRequestHandler(base::Bind(&SendReportToHeader));
+ https_test_server.RegisterRequestHandler(
+ base::BindRepeating(&SendReportToHeader));
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/");
@@ -7124,7 +7132,8 @@ TEST_F(URLRequestTestHTTP, ProcessReportToHeaderHTTPS) {
TEST_F(URLRequestTestHTTP, DontProcessReportToHeaderInvalidHttps) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
- https_test_server.RegisterRequestHandler(base::Bind(&SendReportToHeader));
+ https_test_server.RegisterRequestHandler(
+ base::BindRepeating(&SendReportToHeader));
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/");
@@ -7184,6 +7193,11 @@ class TestNetworkErrorLoggingDelegate : public NetworkErrorLoggingDelegate {
errors_.push_back(details);
}
+ void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>&
+ origin_filter) override {
+ NOTREACHED();
+ }
+
private:
std::vector<Header> headers_;
std::vector<ErrorDetails> errors_;
@@ -7199,10 +7213,16 @@ std::unique_ptr<test_server::HttpResponse> SendNelHeader(
return std::move(http_response);
}
+std::unique_ptr<test_server::HttpResponse> SendEmptyResponse(
+ const test_server::HttpRequest& request) {
+ return base::MakeUnique<test_server::RawHttpResponse>("", "");
+}
+
} // namespace
TEST_F(URLRequestTestHTTP, DontProcessNelHeaderNoDelegate) {
- http_test_server()->RegisterRequestHandler(base::Bind(&SendNelHeader));
+ http_test_server()->RegisterRequestHandler(
+ base::BindRepeating(&SendNelHeader));
ASSERT_TRUE(http_test_server()->Start());
GURL request_url = http_test_server()->GetURL("/");
@@ -7219,7 +7239,8 @@ TEST_F(URLRequestTestHTTP, DontProcessNelHeaderNoDelegate) {
}
TEST_F(URLRequestTestHTTP, DontProcessNelHeaderHttp) {
- http_test_server()->RegisterRequestHandler(base::Bind(&SendNelHeader));
+ http_test_server()->RegisterRequestHandler(
+ base::BindRepeating(&SendNelHeader));
ASSERT_TRUE(http_test_server()->Start());
GURL request_url = http_test_server()->GetURL("/");
@@ -7241,7 +7262,7 @@ TEST_F(URLRequestTestHTTP, DontProcessNelHeaderHttp) {
TEST_F(URLRequestTestHTTP, ProcessNelHeaderHttps) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
- https_test_server.RegisterRequestHandler(base::Bind(&SendNelHeader));
+ https_test_server.RegisterRequestHandler(base::BindRepeating(&SendNelHeader));
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/");
@@ -7266,7 +7287,7 @@ TEST_F(URLRequestTestHTTP, ProcessNelHeaderHttps) {
TEST_F(URLRequestTestHTTP, DontProcessNelHeaderInvalidHttps) {
EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
- https_test_server.RegisterRequestHandler(base::Bind(&SendNelHeader));
+ https_test_server.RegisterRequestHandler(base::BindRepeating(&SendNelHeader));
ASSERT_TRUE(https_test_server.Start());
GURL request_url = https_test_server.GetURL("/");
@@ -7335,7 +7356,7 @@ TEST_F(URLRequestTestHTTP, DISABLED_DontForwardErrorToNelHttp) {
URLRequestFilter::GetInstance()->ClearHandlers();
}
-TEST_F(URLRequestTestHTTP, ForwardErrorToNelHttps) {
+TEST_F(URLRequestTestHTTP, ForwardErrorToNelHttps_Mock) {
URLRequestFailedJob::AddUrlHandler();
GURL request_url =
@@ -7362,6 +7383,34 @@ TEST_F(URLRequestTestHTTP, ForwardErrorToNelHttps) {
URLRequestFilter::GetInstance()->ClearHandlers();
}
+// Also test with a real server, to exercise interactions with
+// URLRequestHttpJob.
+TEST_F(URLRequestTestHTTP, ForwardErrorToNelHttps_Real) {
+ EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_test_server.RegisterRequestHandler(
+ base::BindRepeating(&SendEmptyResponse));
+ ASSERT_TRUE(https_test_server.Start());
+ GURL request_url = https_test_server.GetURL("/");
+
+ TestNetworkDelegate network_delegate;
+ TestNetworkErrorLoggingDelegate nel_delegate;
+ TestURLRequestContext context(true);
+ context.set_network_delegate(&network_delegate);
+ context.set_network_error_logging_delegate(&nel_delegate);
+ context.Init();
+
+ TestDelegate d;
+ std::unique_ptr<URLRequest> request(context.CreateRequest(
+ request_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ request->Start();
+ base::RunLoop().Run();
+
+ ASSERT_EQ(1u, nel_delegate.errors().size());
+ EXPECT_EQ(request_url, nel_delegate.errors()[0].uri);
+ EXPECT_EQ(0, nel_delegate.errors()[0].status_code);
+ EXPECT_EQ(ERR_EMPTY_RESPONSE, nel_delegate.errors()[0].type);
+}
+
#endif // BUILDFLAG(ENABLE_REPORTING)
TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
@@ -10489,9 +10538,8 @@ static CertStatus ExpectedCertStatusForFailedOnlineEVRevocationCheck() {
}
static bool SystemSupportsOCSP() {
-#if defined(OS_ANDROID) || defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
// TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
- // TODO(crbug.com/776575): OCSP tests currently fail on Fuchsia.
return false;
#else
return true;
@@ -11189,14 +11237,13 @@ TEST_F(HTTPSAIATest, AIAFetching) {
EXPECT_EQ(OK, d.request_status());
EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
ASSERT_TRUE(r->ssl_info().cert);
- EXPECT_EQ(2u, r->ssl_info().cert->GetIntermediateCertificates().size());
+ EXPECT_EQ(2u, r->ssl_info().cert->intermediate_buffers().size());
} else {
EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID,
cert_status & CERT_STATUS_ALL_ERRORS);
}
ASSERT_TRUE(r->ssl_info().unverified_cert);
- EXPECT_EQ(
- 0u, r->ssl_info().unverified_cert->GetIntermediateCertificates().size());
+ EXPECT_EQ(0u, r->ssl_info().unverified_cert->intermediate_buffers().size());
}
class HTTPSHardFailTest : public HTTPSOCSPTest {
@@ -11378,7 +11425,8 @@ TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) {
SpawnedTestServer::SSLOptions::CERT_AUTO);
ssl_options.ocsp_status =
SpawnedTestServer::SSLOptions::OCSP_INVALID_RESPONSE;
- ScopedSetCRLSet set_crlset(CRLSet::ForTesting(false, &kOCSPTestCertSPKI, ""));
+ ScopedSetCRLSet set_crlset(
+ CRLSet::ForTesting(false, &kOCSPTestCertSPKI, "", "", {}));
CertStatus cert_status;
DoConnection(ssl_options, &cert_status);
@@ -11484,7 +11532,7 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
ssl_options.cert_serial = 10;
ScopedSetCRLSet set_crlset(
- CRLSet::ForTesting(false, &kOCSPTestCertSPKI, "\x0a"));
+ CRLSet::ForTesting(false, &kOCSPTestCertSPKI, "\x0a", "", {}));
CertStatus cert_status = 0;
DoConnection(ssl_options, &cert_status);
@@ -11496,6 +11544,55 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
EXPECT_FALSE(
static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}
+
+TEST_F(HTTPSCRLSetTest, CRLSetRevokedBySubject) {
+#if defined(OS_ANDROID)
+ LOG(WARNING) << "Skipping test because system doesn't support CRLSets";
+ return;
+#endif
+
+ SpawnedTestServer::SSLOptions ssl_options(
+ SpawnedTestServer::SSLOptions::CERT_AUTO);
+ ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
+ static const char kCommonName[] = "Test CN";
+ ssl_options.cert_common_name = kCommonName;
+
+ {
+ ScopedSetCRLSet set_crlset(
+ CRLSet::ForTesting(false, nullptr, "", kCommonName, {}));
+
+ CertStatus cert_status = 0;
+ DoConnection(ssl_options, &cert_status);
+
+ // If the certificate is recorded as revoked in the CRLSet, that should be
+ // reflected without online revocation checking.
+ EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
+ EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
+ EXPECT_FALSE(
+ static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
+ }
+
+ const uint8_t kTestServerSPKISHA256[32] = {
+ 0xb3, 0x91, 0xac, 0x73, 0x32, 0x54, 0x7f, 0x7b, 0x8a, 0x62, 0x77,
+ 0x73, 0x1d, 0x45, 0x7b, 0x23, 0x46, 0x69, 0xef, 0x6f, 0x05, 0x3d,
+ 0x07, 0x22, 0x15, 0x18, 0xd6, 0x10, 0x8b, 0xa1, 0x49, 0x33,
+ };
+ const std::string spki_hash(
+ reinterpret_cast<const char*>(kTestServerSPKISHA256),
+ sizeof(kTestServerSPKISHA256));
+
+ {
+ ScopedSetCRLSet set_crlset(
+ CRLSet::ForTesting(false, nullptr, "", kCommonName, {spki_hash}));
+
+ CertStatus cert_status = 0;
+ DoConnection(ssl_options, &cert_status);
+
+ // When the correct SPKI hash is specified, the connection should succeed
+ // even though the subject is listed in the CRLSet.
+ EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
+ }
+}
#endif // !defined(OS_IOS)
#if !BUILDFLAG(DISABLE_FTP_SUPPORT) && !defined(OS_ANDROID) && \
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.cc b/chromium/net/websockets/websocket_basic_handshake_stream.cc
index 66f5ab5f4a7..47113a243e5 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.cc
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.cc
@@ -17,8 +17,8 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -35,6 +35,7 @@
#include "net/http/http_stream_parser.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/websocket_transport_client_socket_pool.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/websockets/websocket_basic_stream.h"
#include "net/websockets/websocket_deflate_parameters.h"
#include "net/websockets/websocket_deflate_predictor.h"
@@ -311,11 +312,12 @@ WebSocketBasicHandshakeStream::~WebSocketBasicHandshakeStream() = default;
int WebSocketBasicHandshakeStream::InitializeStream(
const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) {
url_ = request_info->url;
- state_.Initialize(request_info, priority, net_log, callback);
+ state_.Initialize(request_info, can_send_early, priority, net_log, callback);
return OK;
}
@@ -363,8 +365,10 @@ int WebSocketBasicHandshakeStream::SendRequest(
request->headers.CopyFrom(enriched_headers);
connect_delegate_->OnStartOpeningHandshake(std::move(request));
- return parser()->SendRequest(
- state_.GenerateRequestLine(), enriched_headers, response, callback);
+ // TODO(crbug.com/656607): Add propoer annotation.
+ return parser()->SendRequest(state_.GenerateRequestLine(), enriched_headers,
+ NO_TRAFFIC_ANNOTATION_BUG_656607, response,
+ callback);
}
int WebSocketBasicHandshakeStream::ReadResponseHeaders(
@@ -527,7 +531,7 @@ int WebSocketBasicHandshakeStream::ValidateResponse(int rv) {
if (rv >= 0) {
const HttpResponseHeaders* headers = http_response_info_->headers.get();
const int response_code = headers->response_code();
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ResponseCode", response_code);
+ base::UmaHistogramSparse("Net.WebSocket.ResponseCode", response_code);
switch (response_code) {
case HTTP_SWITCHING_PROTOCOLS:
OnFinishOpeningHandshake();
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.h b/chromium/net/websockets/websocket_basic_handshake_stream.h
index 06bc3338090..10be3500776 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.h
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.h
@@ -44,6 +44,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
// HttpStreamBase methods
int InitializeStream(const HttpRequestInfo* request_info,
+ bool can_send_early,
RequestPriority priority,
const NetLogWithSource& net_log,
const CompletionCallback& callback) override;
diff --git a/chromium/net/websockets/websocket_basic_stream_test.cc b/chromium/net/websockets/websocket_basic_stream_test.cc
index 7061e4b581d..da8d228d513 100644
--- a/chromium/net/websockets/websocket_basic_stream_test.cc
+++ b/chromium/net/websockets/websocket_basic_stream_test.cc
@@ -19,6 +19,7 @@
#include "base/macros.h"
#include "net/base/test_completion_callback.h"
#include "net/log/test_net_log.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -134,7 +135,7 @@ class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
std::unique_ptr<ClientSocketHandle> transport_socket(
new ClientSocketHandle);
scoped_refptr<MockTransportSocketParams> params;
- transport_socket->Init("a", params, MEDIUM,
+ transport_socket->Init("a", params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, net_log_.bound());
return transport_socket;
diff --git a/chromium/net/websockets/websocket_end_to_end_test.cc b/chromium/net/websockets/websocket_end_to_end_test.cc
index 40909d22cfe..d869f837c68 100644
--- a/chromium/net/websockets/websocket_end_to_end_test.cc
+++ b/chromium/net/websockets/websocket_end_to_end_test.cc
@@ -227,23 +227,10 @@ class TestProxyDelegateWithProxyInfo : public ProxyDelegate {
resolved_proxy_info_.proxy_info = *result;
}
- void OnTunnelConnectCompleted(const HostPortPair& endpoint,
- const HostPortPair& proxy_server,
- int net_error) override {}
void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
- void OnBeforeTunnelRequest(const HostPortPair& proxy_server,
- HttpRequestHeaders* extra_headers) override {}
- void OnTunnelHeadersReceived(
- const HostPortPair& origin,
- const HostPortPair& proxy_server,
- const HttpResponseHeaders& response_headers) override {}
bool IsTrustedSpdyProxy(const net::ProxyServer& proxy_server) override {
return true;
}
- void GetAlternativeProxy(
- const GURL& url,
- const ProxyServer& resolved_proxy_server,
- ProxyServer* alternative_proxy_server) const override {}
void OnAlternativeProxyBroken(
const ProxyServer& alternative_proxy_server) override {}
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc b/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
index 515d48ca1f1..17e2d2625ac 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -17,6 +17,7 @@
#include "net/http/http_response_info.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
#include "net/websockets/websocket_basic_handshake_stream.h"
@@ -49,7 +50,7 @@ class MockClientSocketHandleFactory {
socket_factory_maker_.SetExpectations(expect_written, return_to_read);
std::unique_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
socket_handle->Init("a", scoped_refptr<MockTransportSocketParams>(), MEDIUM,
- ClientSocketPool::RespectLimits::ENABLED,
+ SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
CompletionCallback(), &pool_, NetLogWithSource());
return socket_handle;
}
@@ -122,7 +123,7 @@ class WebSocketHandshakeStreamCreateHelperTest : public ::testing::Test {
request_info.method = "GET";
request_info.load_flags = LOAD_DISABLE_CACHE;
int rv =
- handshake->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ handshake->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
NetLogWithSource(), CompletionCallback());
EXPECT_THAT(rv, IsOk());
diff --git a/chromium/net/websockets/websocket_stream.cc b/chromium/net/websockets/websocket_stream.cc
index bfc155c741b..e88a65a173e 100644
--- a/chromium/net/websockets/websocket_stream.cc
+++ b/chromium/net/websockets/websocket_stream.cc
@@ -7,8 +7,8 @@
#include <utility>
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/load_flags.h"
@@ -313,13 +313,12 @@ void Delegate::OnResponseStarted(URLRequest* request, int net_error) {
DCHECK_NE(ERR_IO_PENDING, net_error);
// All error codes, including OK and ABORTED, as with
// Net.ErrorCodesForMainFrame3
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes", -net_error);
- if (net::IsLocalhost(request->url().HostNoBrackets())) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes_Localhost",
- -net_error);
+ base::UmaHistogramSparse("Net.WebSocket.ErrorCodes", -net_error);
+ if (net::IsLocalhost(request->url())) {
+ base::UmaHistogramSparse("Net.WebSocket.ErrorCodes_Localhost", -net_error);
} else {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ErrorCodes_NotLocalhost",
- -net_error);
+ base::UmaHistogramSparse("Net.WebSocket.ErrorCodes_NotLocalhost",
+ -net_error);
}
if (net_error != OK) {