summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc15
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.h7
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view_test.cc16
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h14
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc26
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.h9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc66
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.h19
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.h6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters_test.cc16
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frames_test.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.cc387
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.h118
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule_test.cc103
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/end_to_end_test.cc306
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder_test.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames.h15
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames_test.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_header_list_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc46
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream_test.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc137
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.h14
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base_test.cc60
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc207
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.h68
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc290
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc487
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h109
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc337
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils_test.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc107
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.h25
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/packet_number_indexed_queue_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_arena_scoped_ptr_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_bandwidth_test.cc24
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store.cc37
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store_test.cc100
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.h25
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.cc1016
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.h174
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_context_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_test.cc1343
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_constants.h14
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.h5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.h14
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.h9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc144
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h30
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream_test.cc105
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.cc67
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher_test.cc134
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_clock_test.cc64
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_connection_helper.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_flags_list.h134
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc38
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer_test.cc13
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.h16
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector_test.cc98
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_deque.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_set.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena.h5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.h8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator_test.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.cc162
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.h108
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager_test.cc429
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc21
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager_test.cc18
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc530
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.h119
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager_test.cc1655
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_server_id_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.cc31
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.h10
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_session_test.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream.cc14
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_test.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_test.cc45
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_trace_visitor_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.h20
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket_posix.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map_test.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.cc11
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils_test.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_versions_test.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc23
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker_test.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc29
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc54
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.h8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker_test.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager_test.cc28
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_bin.cc20
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.cc204
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h51
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.cc526
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.h120
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.cc41
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.h18
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_client_session.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc48
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.cc53
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.h5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_bin.cc19
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.cc469
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.h54
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_containers.h22
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_ip_address.cc16
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_logging.h6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_mock_log.h19
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_stream_buffer_allocator.h15
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h15
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_udp_socket_platform_api.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/icmp_reachable_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_controller_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/internet_checksum.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_test.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/tcp_packet.cc9
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_session.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_test.cc32
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor_test.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_server_session.cc6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.h8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_stream.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.cc146
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h18
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.cc1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.cc33
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h6
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/index.html63
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/map.html65
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc39
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.h17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.cc5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_backend.h7
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.cc10
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h62
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_session_notifier_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.cc8
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.h3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_base.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_test.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.h4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/crypto_message_printer_bin.cc (renamed from chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_message_printer_bin.cc)0
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/qpack_offline_decoder_bin.cc (renamed from chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc)0
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client_interop_test_bin.cc7
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend_test.cc35
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc4
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.cc12
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.h5
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_backend.h48
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session.h7
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session_test.cc3
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.cc157
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.h36
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc157
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_tcp_like_trace_converter.h1
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_client.cc90
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_server.cc17
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc51
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.h41
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.cc168
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.h79
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.cc2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.h2
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/tools/web_transport_test_visitors.h5
257 files changed, 5015 insertions, 9002 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc
index 71b8f128421..617890762f4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc
@@ -16,6 +16,7 @@
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/print_elements.h"
namespace quic {
@@ -221,7 +222,7 @@ Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
case Bbr2Mode::PROBE_RTT:
return probe_rtt_.GetCwndLimits();
default:
- QUIC_NOTREACHED();
+ QUICHE_NOTREACHED();
return Unlimited<QuicByteCount>();
}
}
@@ -504,11 +505,6 @@ void Bbr2Sender::OnExitQuiescence(QuicTime now) {
}
}
-bool Bbr2Sender::ShouldSendProbingPacket() const {
- // TODO(wub): Implement ShouldSendProbingPacket properly.
- return BBR2_MODE_DISPATCH(IsProbingForBandwidth());
-}
-
std::string Bbr2Sender::GetDebugState() const {
std::ostringstream stream;
stream << ExportDebugState();
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.h b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.h
index b9c0a410a76..7f47a4ed3c9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.h
@@ -42,8 +42,6 @@ class QUIC_EXPORT_PRIVATE Bbr2Sender final : public SendAlgorithmInterface {
return false;
}
- bool ShouldSendProbingPacket() const override;
-
void SetFromConfig(const QuicConfig& config,
Perspective perspective) override;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
index 6a0e5815838..fdf036b981c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -127,7 +127,8 @@ class Bbr2SimulatorTest : public QuicTest {
}
void SetUp() override {
- if (GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode) == "regress") {
+ if (quiche::GetQuicheCommandLineFlag(
+ FLAGS_quic_bbr2_test_regression_mode) == "regress") {
SendAlgorithmTestResult expected;
ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
random_seed_ = expected.random_seed();
@@ -140,7 +141,7 @@ class Bbr2SimulatorTest : public QuicTest {
~Bbr2SimulatorTest() override {
const std::string regression_mode =
- GetQuicFlag(FLAGS_quic_bbr2_test_regression_mode);
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_bbr2_test_regression_mode);
const QuicTime::Delta simulated_duration =
SimulatedNow() - QuicTime::Zero();
if (regression_mode == "record") {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc
index aa121d4d626..878b5985804 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc
@@ -204,16 +204,6 @@ bool BbrSender::InRecovery() const {
return recovery_state_ != NOT_IN_RECOVERY;
}
-bool BbrSender::ShouldSendProbingPacket() const {
- if (pacing_gain_ <= 1) {
- return false;
- }
-
- // TODO(b/77975811): If the pipe is highly under-utilized, consider not
- // sending a probing transmission, because the extra bandwidth is not needed.
- return true;
-}
-
void BbrSender::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.h b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.h
index 9fe11999595..5f711fd493c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.h
@@ -100,7 +100,6 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
// Start implementation of SendAlgorithmInterface.
bool InSlowStart() const override;
bool InRecovery() const override;
- bool ShouldSendProbingPacket() const override;
void SetFromConfig(const QuicConfig& config,
Perspective perspective) override;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender_test.cc
index 199d322d30c..bbdbee6fc6f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender_test.cc
@@ -108,7 +108,8 @@ class BbrSenderTest : public QuicTest {
}
void SetUp() override {
- if (GetQuicFlag(FLAGS_quic_bbr_test_regression_mode) == "regress") {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_quic_bbr_test_regression_mode) ==
+ "regress") {
SendAlgorithmTestResult expected;
ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
random_seed_ = expected.random_seed();
@@ -121,7 +122,7 @@ class BbrSenderTest : public QuicTest {
~BbrSenderTest() {
const std::string regression_mode =
- GetQuicFlag(FLAGS_quic_bbr_test_regression_mode);
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_bbr_test_regression_mode);
const QuicTime::Delta simulated_duration = clock_->Now() - QuicTime::Zero();
if (regression_mode == "record") {
RecordSendAlgorithmTestResult(random_seed_,
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc
index 74b5c851426..d679cd63631 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc
@@ -39,14 +39,14 @@ void RttStats::ExpireSmoothedMetrics() {
}
// Updates the RTT based on a new sample.
-void RttStats::UpdateRtt(QuicTime::Delta send_delta, QuicTime::Delta ack_delay,
+bool RttStats::UpdateRtt(QuicTime::Delta send_delta, QuicTime::Delta ack_delay,
QuicTime now) {
if (send_delta.IsInfinite() || send_delta <= QuicTime::Delta::Zero()) {
QUIC_LOG_FIRST_N(WARNING, 3)
<< "Ignoring measured send_delta, because it's is "
<< "either infinite, zero, or negative. send_delta = "
<< send_delta.ToMicroseconds();
- return;
+ return false;
}
last_update_time_ = now;
@@ -92,6 +92,7 @@ void RttStats::UpdateRtt(QuicTime::Delta send_delta, QuicTime::Delta ack_delay,
QUIC_DVLOG(1) << " smoothed_rtt(us):" << smoothed_rtt_.ToMicroseconds()
<< " mean_deviation(us):" << mean_deviation_.ToMicroseconds();
}
+ return true;
}
void RttStats::OnConnectionMigration() {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.h b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.h
index c9dcab05c72..04a0148433a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.h
@@ -47,7 +47,8 @@ class QUIC_EXPORT_PRIVATE RttStats {
// Updates the RTT from an incoming ack which is received |send_delta| after
// the packet is sent and the peer reports the ack being delayed |ack_delay|.
- void UpdateRtt(QuicTime::Delta send_delta, QuicTime::Delta ack_delay,
+ // Returns true if RTT was updated, and false if the sample was ignored.
+ bool UpdateRtt(QuicTime::Delta send_delta, QuicTime::Delta ack_delay,
QuicTime now);
// Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc
index d1a70808afe..11bf11a3cf8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats_test.cc
@@ -6,13 +6,9 @@
#include <cmath>
-#include "quiche/quic/platform/api/quic_logging.h"
-#include "quiche/quic/platform/api/quic_mock_log.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
-#include "quiche/quic/test_tools/rtt_stats_peer.h"
-using testing::_;
using testing::Message;
namespace quic {
@@ -141,9 +137,6 @@ TEST_F(RttStatsTest, ExpireSmoothedMetrics) {
}
TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
- // Make sure we ignore bad RTTs.
- CREATE_QUIC_MOCK_LOG(log);
-
QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(10);
rtt_stats_.UpdateRtt(initial_rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
@@ -153,16 +146,12 @@ TEST_F(RttStatsTest, UpdateRttWithBadSendDeltas) {
bad_send_deltas.push_back(QuicTime::Delta::Zero());
bad_send_deltas.push_back(QuicTime::Delta::Infinite());
bad_send_deltas.push_back(QuicTime::Delta::FromMicroseconds(-1000));
- log.StartCapturingLogs();
for (QuicTime::Delta bad_send_delta : bad_send_deltas) {
SCOPED_TRACE(Message() << "bad_send_delta = "
<< bad_send_delta.ToMicroseconds());
- if (QUIC_LOG_WARNING_IS_ON()) {
- EXPECT_QUIC_LOG_CALL_CONTAINS(log, WARNING, "Ignoring");
- }
- rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
- QuicTime::Zero());
+ EXPECT_FALSE(rtt_stats_.UpdateRtt(bad_send_delta, QuicTime::Delta::Zero(),
+ QuicTime::Zero()));
EXPECT_EQ(initial_rtt, rtt_stats_.min_rtt());
EXPECT_EQ(initial_rtt, rtt_stats_.smoothed_rtt());
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h
index 75c69a29ee3..db14a1e3637 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -39,13 +39,11 @@ class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
: bandwidth(bandwidth),
rtt(rtt),
allow_cwnd_to_decrease(allow_cwnd_to_decrease) {}
- explicit NetworkParams(int burst_token) : burst_token(burst_token) {}
bool operator==(const NetworkParams& other) const {
return bandwidth == other.bandwidth && rtt == other.rtt &&
max_initial_congestion_window ==
other.max_initial_congestion_window &&
- burst_token == other.burst_token &&
allow_cwnd_to_decrease == other.allow_cwnd_to_decrease &&
is_rtt_trusted == other.is_rtt_trusted;
}
@@ -53,7 +51,6 @@ class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
QuicBandwidth bandwidth = QuicBandwidth::Zero();
QuicTime::Delta rtt = QuicTime::Delta::Zero();
int max_initial_congestion_window = 0;
- int burst_token = 0;
bool allow_cwnd_to_decrease = false;
bool is_rtt_trusted = false;
};
@@ -132,12 +129,6 @@ class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
// Whether the send algorithm is currently in recovery.
virtual bool InRecovery() const = 0;
- // True when the congestion control is probing for more bandwidth and needs
- // enough data to not be app-limited to do so.
- // TODO(ianswett): In the future, this API may want to indicate the size of
- // the probing packet.
- virtual bool ShouldSendProbingPacket() const = 0;
-
// Returns the size of the slow start congestion window in bytes,
// aka ssthresh. Only defined for Cubic and Reno, other algorithms return 0.
virtual QuicByteCount GetSlowStartThreshold() const = 0;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
index 966a000b97c..af0a5a9ffc2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -233,8 +233,6 @@ bool TcpCubicSenderBytes::InRecovery() const {
largest_acked_packet_number_ <= largest_sent_at_last_cutback_;
}
-bool TcpCubicSenderBytes::ShouldSendProbingPacket() const { return false; }
-
void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
largest_sent_at_last_cutback_.Clear();
if (!packets_retransmitted) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index a30f78dc78e..2531e5a3f6f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -69,7 +69,6 @@ class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
CongestionControlType GetCongestionControlType() const override;
bool InSlowStart() const override;
bool InRecovery() const override;
- bool ShouldSendProbingPacket() const override;
std::string GetDebugState() const override;
void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc
index 1c4d3a2ca37..c3b187ce766 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc
@@ -79,8 +79,12 @@ PublicKeyType PublicKeyTypeFromKey(EVP_PKEY* public_key) {
}
}
+} // namespace
+
PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
uint16_t signature_algorithm) {
+ // This should be kept in sync with the list in
+ // SupportedSignatureAlgorithmsForQuic().
switch (signature_algorithm) {
case SSL_SIGN_RSA_PSS_RSAE_SHA256:
return PublicKeyType::kRsa;
@@ -95,6 +99,17 @@ PublicKeyType PublicKeyTypeFromSignatureAlgorithm(
}
}
+QUIC_EXPORT_PRIVATE QuicSignatureAlgorithmVector
+SupportedSignatureAlgorithmsForQuic() {
+ // This should be kept in sync with the list in
+ // PublicKeyTypeFromSignatureAlgorithm().
+ return QuicSignatureAlgorithmVector{
+ SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP256R1_SHA256,
+ SSL_SIGN_ECDSA_SECP384R1_SHA384, SSL_SIGN_RSA_PSS_RSAE_SHA256};
+}
+
+namespace {
+
std::string AttributeNameToString(const CBS& oid_cbs) {
absl::string_view oid = CbsToStringPiece(oid_cbs);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.h
index a0ca3c33ecf..5c2aafc1af3 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.h
@@ -43,6 +43,13 @@ enum class PublicKeyType {
kUnknown,
};
QUIC_EXPORT_PRIVATE std::string PublicKeyTypeToString(PublicKeyType type);
+QUIC_EXPORT_PRIVATE PublicKeyType
+PublicKeyTypeFromSignatureAlgorithm(uint16_t signature_algorithm);
+
+// Returns the list of the signature algorithms that can be processed by
+// CertificateView::VerifySignature() and CertificatePrivateKey::Sign().
+QUIC_EXPORT_PRIVATE QuicSignatureAlgorithmVector
+SupportedSignatureAlgorithmsForQuic();
// CertificateView represents a parsed version of a single X.509 certificate. As
// the word "view" implies, it does not take ownership of the underlying strings
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view_test.cc
index b9ca08abc09..d142ae45215 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view_test.cc
@@ -4,9 +4,11 @@
#include "quiche/quic/core/crypto/certificate_view.h"
+#include <limits>
#include <memory>
#include <sstream>
+#include "absl/algorithm/container.h"
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "openssl/base.h"
@@ -209,6 +211,20 @@ TEST(CertificateViewTest, NameAttribute) {
X509NameAttributeToString(StringPieceToCbs(invalid_oid)));
}
+TEST(CertificateViewTest, SupportedSignatureAlgorithmsForQuicIsUpToDate) {
+ QuicSignatureAlgorithmVector supported =
+ SupportedSignatureAlgorithmsForQuic();
+ for (int i = 0; i < std::numeric_limits<uint16_t>::max(); i++) {
+ uint16_t sigalg = static_cast<uint16_t>(i);
+ PublicKeyType key_type = PublicKeyTypeFromSignatureAlgorithm(sigalg);
+ if (absl::c_find(supported, sigalg) == supported.end()) {
+ EXPECT_EQ(key_type, PublicKeyType::kUnknown);
+ } else {
+ EXPECT_NE(key_type, PublicKeyType::kUnknown);
+ }
+ }
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h
index 7dbbb6d36b0..352242f3381 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h
@@ -300,6 +300,8 @@ const QuicTag kNPCO = TAG('N', 'P', 'C', 'O'); // No pacing offload.
// Enable bandwidth resumption experiment.
const QuicTag kBWRE = TAG('B', 'W', 'R', 'E'); // Bandwidth resumption.
const QuicTag kBWMX = TAG('B', 'W', 'M', 'X'); // Max bandwidth resumption.
+const QuicTag kBWID = TAG('B', 'W', 'I', 'D'); // Send bandwidth when idle.
+const QuicTag kBWR1 = TAG('B', 'W', 'I', '1'); // Resume bandwidth experiment 1
const QuicTag kBWRS = TAG('B', 'W', 'R', 'S'); // Server bandwidth resumption.
const QuicTag kBWS2 = TAG('B', 'W', 'S', '2'); // Server bw resumption v2.
const QuicTag kBWS3 = TAG('B', 'W', 'S', '3'); // QUIC Initial CWND - Control.
@@ -425,7 +427,17 @@ const QuicTag kIGNP = TAG('I', 'G', 'N', 'P'); // Do not use PING only packet
const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on
// wire PING (ROWP) on the
// server side.
-const QuicTag kGSR0 = TAG('G', 'S', 'R', '0'); // Selective Resumption
+const QuicTag kROWF = TAG('R', 'O', 'W', 'F'); // Send first 1-RTT packet on
+ // ROWP timeout.
+const QuicTag kROWR = TAG('R', 'O', 'W', 'R'); // Send random bytes on ROWP
+ // timeout.
+// Selective Resumption variants.
+const QuicTag kGSR0 = TAG('G', 'S', 'R', '0');
+const QuicTag kGSR1 = TAG('G', 'S', 'R', '1');
+const QuicTag kGSR2 = TAG('G', 'S', 'R', '2');
+const QuicTag kGSR3 = TAG('G', 'S', 'R', '3');
+
+const QuicTag kNRES = TAG('N', 'R', 'E', 'S'); // No resumption
const QuicTag kINVC = TAG('I', 'N', 'V', 'C'); // Send connection close for
// INVALID_VERSION
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc
index 334c4d8d054..9b33b0b1098 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc
@@ -55,7 +55,7 @@ namespace {
// Secret, Label, and Length are passed in as |secret|, |label|, and
// |out_len|, respectively. The resulting expanded secret is returned.
std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
- const std::vector<uint8_t>& secret,
+ absl::Span<const uint8_t> secret,
const std::string& label, size_t out_len) {
bssl::ScopedCBB quic_hkdf_label;
CBB inner_label;
@@ -115,7 +115,7 @@ void CryptoUtils::InitializeCrypterSecrets(
}
void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
+ absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version,
QuicCrypter* crypter) {
std::vector<uint8_t> key =
@@ -130,7 +130,7 @@ void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
}
std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
- const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const EVP_MD* prf, absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version, size_t out_len) {
return HkdfExpandLabel(prf, pp_secret, getLabelForVersion(version, "hp"),
out_len);
@@ -787,4 +787,24 @@ bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
return true;
}
+// static
+absl::optional<std::string> CryptoUtils::GenerateProofPayloadToBeSigned(
+ absl::string_view chlo_hash, absl::string_view server_config) {
+ size_t payload_size = sizeof(kProofSignatureLabel) + sizeof(uint32_t) +
+ chlo_hash.size() + server_config.size();
+ std::string payload;
+ payload.resize(payload_size);
+ QuicDataWriter payload_writer(payload_size, payload.data(),
+ quiche::Endianness::HOST_BYTE_ORDER);
+ bool success = payload_writer.WriteBytes(kProofSignatureLabel,
+ sizeof(kProofSignatureLabel)) &&
+ payload_writer.WriteUInt32(chlo_hash.size()) &&
+ payload_writer.WriteStringPiece(chlo_hash) &&
+ payload_writer.WriteStringPiece(server_config);
+ if (!success) {
+ return absl::nullopt;
+ }
+ return payload;
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.h
index 4b803f8ece9..87bf30915b8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.h
@@ -91,13 +91,13 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
// protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be
// called before using |crypter|.
static void SetKeyAndIV(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
+ absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version,
QuicCrypter* crypter);
// Derives the header protection key from the packet protection secret.
static std::vector<uint8_t> GenerateHeaderProtectionKey(
- const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
+ const EVP_MD* prf, absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version, size_t out_len);
// Given a secret for key phase n, return the secret for phase n+1.
@@ -248,6 +248,11 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
static bool GetSSLCapabilities(const SSL* ssl,
bssl::UniquePtr<uint8_t>* capabilities,
size_t* capabilities_len);
+
+ // Computes the contents of a binary message that is signed inside QUIC Crypto
+ // protocol using the certificate key.
+ static absl::optional<std::string> GenerateProofPayloadToBeSigned(
+ absl::string_view chlo_hash, absl::string_view server_config);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h
index ffa5fec21bf..ab2a4872525 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h
@@ -173,7 +173,7 @@ class QUIC_EXPORT_PRIVATE ProofSource {
//
// If returns a non-empty list, ComputeTlsSignature will only be called with a
// algorithm in the list.
- virtual absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
+ virtual QuicSignatureAlgorithmVector SupportedTlsSignatureAlgorithms()
const = 0;
class QUIC_EXPORT_PRIVATE DecryptCallback {
@@ -219,7 +219,7 @@ class QUIC_EXPORT_PRIVATE ProofSource {
// |in|. If decryption fails, the callback is invoked with an empty
// vector.
virtual void Decrypt(absl::string_view in,
- std::unique_ptr<DecryptCallback> callback) = 0;
+ std::shared_ptr<DecryptCallback> callback) = 0;
};
// Returns the TicketCrypter used for encrypting and decrypting TLS
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc
index 5f26855d7c4..a86c78bf81f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc
@@ -8,23 +8,34 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#include "openssl/ssl.h"
#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/crypto_protocol.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
#include "quiche/quic/core/quic_data_writer.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/common/quiche_endian.h"
namespace quic {
+ProofSourceX509::ProofSourceX509(
+ quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+ CertificatePrivateKey default_key) {
+ if (!AddCertificateChain(default_chain, std::move(default_key))) {
+ return;
+ }
+ default_certificate_ = &certificates_.front();
+}
+
std::unique_ptr<ProofSourceX509> ProofSourceX509::Create(
quiche::QuicheReferenceCountedPointer<Chain> default_chain,
CertificatePrivateKey default_key) {
- std::unique_ptr<ProofSourceX509> result(new ProofSourceX509());
- if (!result->AddCertificateChain(default_chain, std::move(default_key))) {
+ std::unique_ptr<ProofSourceX509> result(
+ new ProofSourceX509(default_chain, std::move(default_key)));
+ if (!result->valid()) {
return nullptr;
}
- result->default_certificate_ = &result->certificates_.front();
return result;
}
@@ -36,25 +47,24 @@ void ProofSourceX509::GetProof(
std::unique_ptr<ProofSource::Callback> callback) {
QuicCryptoProof proof;
- size_t payload_size = sizeof(kProofSignatureLabel) + sizeof(uint32_t) +
- chlo_hash.size() + server_config.size();
- auto payload = std::make_unique<char[]>(payload_size);
- QuicDataWriter payload_writer(payload_size, payload.get(),
- quiche::Endianness::HOST_BYTE_ORDER);
- bool success = payload_writer.WriteBytes(kProofSignatureLabel,
- sizeof(kProofSignatureLabel)) &&
- payload_writer.WriteUInt32(chlo_hash.size()) &&
- payload_writer.WriteStringPiece(chlo_hash) &&
- payload_writer.WriteStringPiece(server_config);
- if (!success) {
+ if (!valid()) {
+ QUIC_BUG(ProofSourceX509::GetProof called in invalid state)
+ << "ProofSourceX509::GetProof called while the object is not valid";
+ callback->Run(/*ok=*/false, nullptr, proof, nullptr);
+ return;
+ }
+
+ absl::optional<std::string> payload =
+ CryptoUtils::GenerateProofPayloadToBeSigned(chlo_hash, server_config);
+ if (!payload.has_value()) {
callback->Run(/*ok=*/false, nullptr, proof, nullptr);
return;
}
Certificate* certificate = GetCertificate(hostname, &proof.cert_matched_sni);
proof.signature =
- certificate->key.Sign(absl::string_view(payload.get(), payload_size),
- SSL_SIGN_RSA_PSS_RSAE_SHA256);
+ certificate->key.Sign(*payload, SSL_SIGN_RSA_PSS_RSAE_SHA256);
+ MaybeAddSctsForHostname(hostname, proof.leaf_cert_scts);
callback->Run(/*ok=*/!proof.signature.empty(), certificate->chain, proof,
nullptr);
}
@@ -64,6 +74,13 @@ ProofSourceX509::GetCertChain(const QuicSocketAddress& /*server_address*/,
const QuicSocketAddress& /*client_address*/,
const std::string& hostname,
bool* cert_matched_sni) {
+ if (!valid()) {
+ QUIC_BUG(ProofSourceX509::GetCertChain called in invalid state)
+ << "ProofSourceX509::GetCertChain called while the object is not "
+ "valid";
+ return nullptr;
+ }
+
return GetCertificate(hostname, cert_matched_sni)->chain;
}
@@ -72,17 +89,23 @@ void ProofSourceX509::ComputeTlsSignature(
const QuicSocketAddress& /*client_address*/, const std::string& hostname,
uint16_t signature_algorithm, absl::string_view in,
std::unique_ptr<ProofSource::SignatureCallback> callback) {
+ if (!valid()) {
+ QUIC_BUG(ProofSourceX509::ComputeTlsSignature called in invalid state)
+ << "ProofSourceX509::ComputeTlsSignature called while the object is "
+ "not valid";
+ callback->Run(/*ok=*/false, "", nullptr);
+ return;
+ }
+
bool cert_matched_sni;
std::string signature = GetCertificate(hostname, &cert_matched_sni)
->key.Sign(in, signature_algorithm);
callback->Run(/*ok=*/!signature.empty(), signature, nullptr);
}
-absl::InlinedVector<uint16_t, 8>
-ProofSourceX509::SupportedTlsSignatureAlgorithms() const {
- // Let ComputeTlsSignature() report an error if a bad signature algorithm is
- // requested.
- return {};
+QuicSignatureAlgorithmVector ProofSourceX509::SupportedTlsSignatureAlgorithms()
+ const {
+ return SupportedSignatureAlgorithmsForQuic();
}
ProofSource::TicketCrypter* ProofSourceX509::GetTicketCrypter() {
@@ -124,6 +147,7 @@ bool ProofSourceX509::AddCertificateChain(
ProofSourceX509::Certificate* ProofSourceX509::GetCertificate(
const std::string& hostname, bool* cert_matched_sni) const {
+ QUICHE_DCHECK(valid());
auto it = certificate_map_.find(hostname);
if (it != certificate_map_.end()) {
*cert_matched_sni = true;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.h
index d5a3c6f1e4c..fa62bbf90d3 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.h
@@ -13,7 +13,7 @@
#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/proof_source.h"
-#include "quiche/quic/platform/api/quic_containers.h"
+#include "quiche/quic/core/crypto/quic_crypto_proof.h"
namespace quic {
@@ -43,8 +43,7 @@ class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
const QuicSocketAddress& client_address, const std::string& hostname,
uint16_t signature_algorithm, absl::string_view in,
std::unique_ptr<SignatureCallback> callback) override;
- absl::InlinedVector<uint16_t, 8> SupportedTlsSignatureAlgorithms()
- const override;
+ QuicSignatureAlgorithmVector SupportedTlsSignatureAlgorithms() const override;
TicketCrypter* GetTicketCrypter() override;
// Adds a certificate chain to the verifier. Returns false if the chain is
@@ -54,9 +53,17 @@ class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
quiche::QuicheReferenceCountedPointer<Chain> chain,
CertificatePrivateKey key);
- private:
- ProofSourceX509() = default;
+ protected:
+ ProofSourceX509(quiche::QuicheReferenceCountedPointer<Chain> default_chain,
+ CertificatePrivateKey default_key);
+ bool valid() const { return default_certificate_ != nullptr; }
+
+ // Gives an opportunity for the subclass proof source to provide SCTs for a
+ // given hostname.
+ virtual void MaybeAddSctsForHostname(absl::string_view /*hostname*/,
+ std::string& /*leaf_cert_scts*/) {}
+ private:
struct QUIC_EXPORT_PRIVATE Certificate {
quiche::QuicheReferenceCountedPointer<Chain> chain;
CertificatePrivateKey key;
@@ -68,7 +75,7 @@ class QUIC_EXPORT_PRIVATE ProofSourceX509 : public ProofSource {
bool* cert_matched_sni) const;
std::forward_list<Certificate> certificates_;
- Certificate* default_certificate_;
+ Certificate* default_certificate_ = nullptr;
absl::node_hash_map<std::string, Certificate*> certificate_map_;
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc
index 11ccc2f23bf..7a651bf81f9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc
@@ -706,7 +706,7 @@ void QuicCryptoServerConfig::ProcessClientHello(
params,
quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const {
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb) const {
QUICHE_DCHECK(done_cb);
auto context = std::make_unique<ProcessClientHelloContext>(
validate_chlo_result, reject_only, connection_id, server_address,
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.h
index c3febdc63b8..f114546fe68 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.h
@@ -335,7 +335,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
signed_config,
QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const;
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb) const;
// BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing
// the current primary config, an up to date source-address token, and cert
@@ -587,7 +587,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig>
signed_config,
QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb)
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb)
: validate_chlo_result_(validate_chlo_result),
reject_only_(reject_only),
connection_id_(connection_id),
@@ -674,7 +674,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig {
signed_config_;
const QuicByteCount total_framing_overhead_;
const QuicByteCount chlo_packet_size_;
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb_;
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb_;
};
// Callback class for bridging between ProcessClientHello and
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc
index 61e4c23b03d..1b54b14645f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc
@@ -158,12 +158,9 @@ int TlsConnection::SetReadSecretCallback(SSL* ssl,
const SSL_CIPHER* cipher,
const uint8_t* secret,
size_t secret_length) {
- // TODO(nharper): replace this vector with a span (which unfortunately doesn't
- // yet exist in quic/platform/api).
- std::vector<uint8_t> secret_vec(secret, secret + secret_length);
TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
if (!delegate->SetReadSecret(QuicEncryptionLevel(level), cipher,
- secret_vec)) {
+ absl::MakeSpan(secret, secret_length))) {
return 0;
}
return 1;
@@ -175,11 +172,9 @@ int TlsConnection::SetWriteSecretCallback(SSL* ssl,
const SSL_CIPHER* cipher,
const uint8_t* secret,
size_t secret_length) {
- // TODO(nharper): replace this vector with a span (which unfortunately doesn't
- // yet exist in quic/platform/api).
- std::vector<uint8_t> secret_vec(secret, secret + secret_length);
TlsConnection::Delegate* delegate = ConnectionFromSsl(ssl)->delegate_;
- delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher, secret_vec);
+ delegate->SetWriteSecret(QuicEncryptionLevel(level), cipher,
+ absl::MakeSpan(secret, secret_length));
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.h
index a4887e8c32b..5c4e8b8884a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.h
@@ -47,7 +47,7 @@ class QUIC_EXPORT_PRIVATE TlsConnection {
// traffic secrets and application traffic secrets. The provided write
// secret must be used with the provided cipher suite |cipher|.
virtual void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) = 0;
+ absl::Span<const uint8_t> write_secret) = 0;
// SetReadSecret is similar to SetWriteSecret, except that it is used for
// decrypting messages. SetReadSecret at a particular level is always called
@@ -55,7 +55,7 @@ class QUIC_EXPORT_PRIVATE TlsConnection {
// where the EncryptionLevel for SetWriteSecret is
// ENCRYPTION_FORWARD_SECURE.
virtual bool SetReadSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) = 0;
+ absl::Span<const uint8_t> read_secret) = 0;
// WriteMessage is called when there is |data| from the TLS stack ready for
// the QUIC stack to write in a crypto frame. The data must be transmitted
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc
index ca2adc8509f..635d159a653 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc
@@ -660,8 +660,7 @@ bool TransportParameters::AreValid(std::string* error_details) const {
TransportParameters::~TransportParameters() = default;
-bool SerializeTransportParameters(ParsedQuicVersion /*version*/,
- const TransportParameters& in,
+bool SerializeTransportParameters(const TransportParameters& in,
std::vector<uint8_t>* out) {
std::string error_details;
if (!in.AreValid(&error_details)) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.h b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.h
index 5be5ab4f89d..e1f349b6da9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.h
@@ -17,7 +17,6 @@
#include "quiche/quic/core/quic_tag.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
namespace quic {
@@ -274,8 +273,7 @@ struct QUIC_EXPORT_PRIVATE TransportParameters {
// TLS extension. The serialized bytes are written to |*out|. Returns if the
// parameters are valid and serialization succeeded.
QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
- ParsedQuicVersion version, const TransportParameters& in,
- std::vector<uint8_t>* out);
+ const TransportParameters& in, std::vector<uint8_t>* out);
// Parses bytes from the quic_transport_parameters TLS extension and writes the
// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters_test.cc
index fe9a2ceae9a..76613f0e1f8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters_test.cc
@@ -323,7 +323,7 @@ TEST_P(TransportParametersTest, RoundTripClient) {
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+ ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
TransportParameters new_params;
std::string error_details;
@@ -369,7 +369,7 @@ TEST_P(TransportParametersTest, RoundTripServer) {
orig_params.google_connection_options = CreateFakeGoogleConnectionOptions();
std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+ ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
TransportParameters new_params;
std::string error_details;
@@ -484,12 +484,10 @@ TEST_P(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
orig_params.max_udp_payload_size.set_value(kMaxPacketSizeForTest);
std::vector<uint8_t> out;
- bool ok = true;
EXPECT_QUIC_BUG(
- ok = SerializeTransportParameters(version_, orig_params, &out),
+ EXPECT_FALSE(SerializeTransportParameters(orig_params, &out)),
"Not serializing invalid transport parameters: Client cannot send "
"stateless reset token");
- EXPECT_FALSE(ok);
}
TEST_P(TransportParametersTest, ParseClientParams) {
@@ -970,7 +968,7 @@ TEST_P(TransportParametersTest, VeryLongCustomParameter) {
orig_params.custom_parameters[kCustomParameter1] = custom_value;
std::vector<uint8_t> serialized;
- ASSERT_TRUE(SerializeTransportParameters(version_, orig_params, &serialized));
+ ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
TransportParameters new_params;
std::string error_details;
@@ -1013,15 +1011,13 @@ TEST_P(TransportParametersTest, SerializationOrderIsRandom) {
orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
std::vector<uint8_t> first_serialized;
- ASSERT_TRUE(
- SerializeTransportParameters(version_, orig_params, &first_serialized));
+ ASSERT_TRUE(SerializeTransportParameters(orig_params, &first_serialized));
// Test that a subsequent serialization is different from the first.
// Run in a loop to avoid a failure in the unlikely event that randomization
// produces the same result multiple times.
for (int i = 0; i < 1000; i++) {
std::vector<uint8_t> serialized;
- ASSERT_TRUE(
- SerializeTransportParameters(version_, orig_params, &serialized));
+ ASSERT_TRUE(SerializeTransportParameters(orig_params, &serialized));
if (serialized != first_serialized) {
return;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.h b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.h
index 7142a823165..4a20e665a54 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.h
@@ -10,7 +10,6 @@
#include "quiche/quic/core/quic_interval.h"
#include "quiche/quic/core/quic_interval_set.h"
#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_flags.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc
index a3e8ebe3c4d..594de278e0c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc
@@ -11,13 +11,6 @@ namespace quic {
QuicBlockedFrame::QuicBlockedFrame() : QuicInlinedFrame(BLOCKED_FRAME) {}
QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
- QuicStreamId stream_id)
- : QuicInlinedFrame(BLOCKED_FRAME),
- control_frame_id(control_frame_id),
- stream_id(stream_id),
- offset(0) {}
-
-QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
QuicStreamId stream_id,
QuicStreamOffset offset)
: QuicInlinedFrame(BLOCKED_FRAME),
@@ -28,7 +21,8 @@ QuicBlockedFrame::QuicBlockedFrame(QuicControlFrameId control_frame_id,
std::ostream& operator<<(std::ostream& os,
const QuicBlockedFrame& blocked_frame) {
os << "{ control_frame_id: " << blocked_frame.control_frame_id
- << ", stream_id: " << blocked_frame.stream_id << " }\n";
+ << ", stream_id: " << blocked_frame.stream_id
+ << ", offset: " << blocked_frame.offset << " }\n";
return os;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.h b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.h
index c3f45f36d21..982e1e8ca8c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.h
@@ -20,7 +20,6 @@ namespace quic {
struct QUIC_EXPORT_PRIVATE QuicBlockedFrame
: public QuicInlinedFrame<QuicBlockedFrame> {
QuicBlockedFrame();
- QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id);
QuicBlockedFrame(QuicControlFrameId control_frame_id, QuicStreamId stream_id,
QuicStreamOffset offset);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.h b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.h
index bc76da14670..19fb5793610 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.h
@@ -25,6 +25,8 @@ struct QUIC_EXPORT_PRIVATE QuicCryptoFrame {
friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const QuicCryptoFrame& s);
+ // TODO(haoyuewang) Consider replace the EncryptionLevel here with
+ // PacketNumberSpace.
// When writing a crypto frame to a packet, the packet must be encrypted at
// |level|. When a crypto frame is read, the encryption level of the packet it
// was received in is put in |level|.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.h b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.h
index 8b0fbfcec88..358b20e1265 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.h
@@ -34,7 +34,6 @@
#include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
#include "quiche/quic/core/frames/quic_window_update_frame.h"
#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#ifndef QUIC_FRAME_DEBUG
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frames_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frames_test.cc
index 56269142368..671e7724014 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frames_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_frames_test.cc
@@ -252,9 +252,10 @@ TEST_F(QuicFramesTest, BlockedFrameToString) {
SetControlFrameId(4, &frame);
EXPECT_EQ(4u, GetControlFrameId(frame));
frame.blocked_frame.stream_id = 1;
+ frame.blocked_frame.offset = 2;
std::ostringstream stream;
stream << frame.blocked_frame;
- EXPECT_EQ("{ control_frame_id: 4, stream_id: 1 }\n", stream.str());
+ EXPECT_EQ("{ control_frame_id: 4, stream_id: 1, offset: 2 }\n", stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.h b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.h
index e376ef6826d..91f73646f63 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.h
@@ -8,7 +8,6 @@
#include "absl/container/inlined_vector.h"
#include "absl/types/span.h"
#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.cc
index f17c76914b8..3fba85e05af 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.cc
@@ -20,18 +20,10 @@ namespace quic {
std::string CapsuleTypeToString(CapsuleType capsule_type) {
switch (capsule_type) {
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- return "REGISTER_DATAGRAM_CONTEXT";
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- return "CLOSE_DATAGRAM_CONTEXT";
case CapsuleType::LEGACY_DATAGRAM:
return "LEGACY_DATAGRAM";
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- return "DATAGRAM_WITH_CONTEXT";
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
return "DATAGRAM_WITHOUT_CONTEXT";
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- return "REGISTER_DATAGRAM_NO_CONTEXT";
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
return "CLOSE_WEBTRANSPORT_SESSION";
}
@@ -43,45 +35,6 @@ std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
return os;
}
-std::string DatagramFormatTypeToString(
- DatagramFormatType datagram_format_type) {
- switch (datagram_format_type) {
- case DatagramFormatType::UDP_PAYLOAD:
- return "UDP_PAYLOAD";
- case DatagramFormatType::WEBTRANSPORT:
- return "WEBTRANSPORT";
- }
- return absl::StrCat("Unknown(", static_cast<uint64_t>(datagram_format_type),
- ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const DatagramFormatType& datagram_format_type) {
- os << DatagramFormatTypeToString(datagram_format_type);
- return os;
-}
-
-std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
- switch (context_close_code) {
- case ContextCloseCode::CLOSE_NO_ERROR:
- return "NO_ERROR";
- case ContextCloseCode::UNKNOWN_FORMAT:
- return "UNKNOWN_FORMAT";
- case ContextCloseCode::DENIED:
- return "DENIED";
- case ContextCloseCode::RESOURCE_LIMIT:
- return "RESOURCE_LIMIT";
- }
- return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
- ")");
-}
-
-std::ostream& operator<<(std::ostream& os,
- const ContextCloseCode& context_close_code) {
- os << ContextCloseCodeToString(context_close_code);
- return os;
-}
-
Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
switch (capsule_type) {
case CapsuleType::LEGACY_DATAGRAM:
@@ -91,13 +44,6 @@ Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
"All capsule structs must have these properties");
legacy_datagram_capsule_ = LegacyDatagramCapsule();
break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- static_assert(
- std::is_standard_layout<DatagramWithContextCapsule>::value &&
- std::is_trivially_destructible<DatagramWithContextCapsule>::value,
- "All capsule structs must have these properties");
- datagram_with_context_capsule_ = DatagramWithContextCapsule();
- break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
static_assert(
std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
@@ -106,31 +52,6 @@ Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
"All capsule structs must have these properties");
datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- static_assert(
- std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
- std::is_trivially_destructible<
- RegisterDatagramContextCapsule>::value,
- "All capsule structs must have these properties");
- register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- static_assert(
- std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
- std::is_trivially_destructible<
- RegisterDatagramNoContextCapsule>::value,
- "All capsule structs must have these properties");
- register_datagram_no_context_capsule_ =
- RegisterDatagramNoContextCapsule();
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- static_assert(
- std::is_standard_layout<CloseDatagramContextCapsule>::value &&
- std::is_trivially_destructible<
- CloseDatagramContextCapsule>::value,
- "All capsule structs must have these properties");
- close_datagram_context_capsule_ = CloseDatagramContextCapsule();
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
static_assert(
std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
@@ -147,26 +68,14 @@ Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
// static
Capsule Capsule::LegacyDatagram(
- absl::optional<QuicDatagramContextId> context_id,
absl::string_view http_datagram_payload) {
Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
- capsule.legacy_datagram_capsule().context_id = context_id;
capsule.legacy_datagram_capsule().http_datagram_payload =
http_datagram_payload;
return capsule;
}
// static
-Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
- absl::string_view http_datagram_payload) {
- Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
- capsule.datagram_with_context_capsule().context_id = context_id;
- capsule.datagram_with_context_capsule().http_datagram_payload =
- http_datagram_payload;
- return capsule;
-}
-
-// static
Capsule Capsule::DatagramWithoutContext(
absl::string_view http_datagram_payload) {
Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
@@ -176,39 +85,6 @@ Capsule Capsule::DatagramWithoutContext(
}
// static
-Capsule Capsule::RegisterDatagramContext(
- QuicDatagramContextId context_id, DatagramFormatType format_type,
- absl::string_view format_additional_data) {
- Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
- capsule.register_datagram_context_capsule().context_id = context_id;
- capsule.register_datagram_context_capsule().format_type = format_type;
- capsule.register_datagram_context_capsule().format_additional_data =
- format_additional_data;
- return capsule;
-}
-
-// static
-Capsule Capsule::RegisterDatagramNoContext(
- DatagramFormatType format_type, absl::string_view format_additional_data) {
- Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
- capsule.register_datagram_no_context_capsule().format_type = format_type;
- capsule.register_datagram_no_context_capsule().format_additional_data =
- format_additional_data;
- return capsule;
-}
-
-// static
-Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
- ContextCloseCode close_code,
- absl::string_view close_details) {
- Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
- capsule.close_datagram_context_capsule().context_id = context_id;
- capsule.close_datagram_context_capsule().close_code = close_code;
- capsule.close_datagram_context_capsule().close_details = close_details;
- return capsule;
-}
-
-// static
Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
absl::string_view error_message) {
Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
@@ -231,24 +107,10 @@ Capsule& Capsule::operator=(const Capsule& other) {
case CapsuleType::LEGACY_DATAGRAM:
legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
- break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
datagram_without_context_capsule_ =
other.datagram_without_context_capsule_;
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- register_datagram_context_capsule_ =
- other.register_datagram_context_capsule_;
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- register_datagram_no_context_capsule_ =
- other.register_datagram_no_context_capsule_;
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
close_web_transport_session_capsule_ =
other.close_web_transport_session_capsule_;
@@ -270,39 +132,11 @@ bool Capsule::operator==(const Capsule& other) const {
}
switch (capsule_type_) {
case CapsuleType::LEGACY_DATAGRAM:
- return legacy_datagram_capsule_.context_id ==
- other.legacy_datagram_capsule_.context_id &&
- legacy_datagram_capsule_.http_datagram_payload ==
- other.legacy_datagram_capsule_.http_datagram_payload;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- return datagram_with_context_capsule_.context_id ==
- other.datagram_with_context_capsule_.context_id &&
- datagram_with_context_capsule_.http_datagram_payload ==
- other.datagram_with_context_capsule_.http_datagram_payload;
+ return legacy_datagram_capsule_.http_datagram_payload ==
+ other.legacy_datagram_capsule_.http_datagram_payload;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
return datagram_without_context_capsule_.http_datagram_payload ==
other.datagram_without_context_capsule_.http_datagram_payload;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- return register_datagram_context_capsule_.context_id ==
- other.register_datagram_context_capsule_.context_id &&
- register_datagram_context_capsule_.format_type ==
- other.register_datagram_context_capsule_.format_type &&
- register_datagram_context_capsule_.format_additional_data ==
- other.register_datagram_context_capsule_
- .format_additional_data;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- return register_datagram_no_context_capsule_.format_type ==
- other.register_datagram_no_context_capsule_.format_type &&
- register_datagram_no_context_capsule_.format_additional_data ==
- other.register_datagram_no_context_capsule_
- .format_additional_data;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- return close_datagram_context_capsule_.context_id ==
- other.close_datagram_context_capsule_.context_id &&
- close_datagram_context_capsule_.close_code ==
- other.close_datagram_context_capsule_.close_code &&
- close_datagram_context_capsule_.close_details ==
- other.close_datagram_context_capsule_.close_details;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
return close_web_transport_session_capsule_.error_code ==
other.close_web_transport_session_capsule_.error_code &&
@@ -317,21 +151,11 @@ std::string Capsule::ToString() const {
std::string rv = CapsuleTypeToString(capsule_type_);
switch (capsule_type_) {
case CapsuleType::LEGACY_DATAGRAM:
- if (legacy_datagram_capsule_.context_id.has_value()) {
- absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
- ")");
- }
absl::StrAppend(&rv, "[",
absl::BytesToHexString(
legacy_datagram_capsule_.http_datagram_payload),
"]");
break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
- absl::BytesToHexString(
- datagram_with_context_capsule_.http_datagram_payload),
- "]");
- break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
absl::StrAppend(
&rv, "[",
@@ -339,36 +163,6 @@ std::string Capsule::ToString() const {
datagram_without_context_capsule_.http_datagram_payload),
"]");
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- absl::StrAppend(
- &rv, "(context_id=", register_datagram_context_capsule_.context_id,
- ",format_type=",
- DatagramFormatTypeToString(
- register_datagram_context_capsule_.format_type),
- "){",
- absl::BytesToHexString(
- register_datagram_context_capsule_.format_additional_data),
- "}");
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- absl::StrAppend(
- &rv, "(format_type=",
- DatagramFormatTypeToString(
- register_datagram_no_context_capsule_.format_type),
- "){",
- absl::BytesToHexString(
- register_datagram_no_context_capsule_.format_additional_data),
- "}");
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- absl::StrAppend(
- &rv, "(context_id=", close_datagram_context_capsule_.context_id,
- ",close_code=",
- ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
- ",close_details=\"",
- absl::BytesToHexString(close_datagram_context_capsule_.close_details),
- "\")");
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
absl::StrAppend(
&rv, "(error_code=", close_web_transport_session_capsule_.error_code,
@@ -401,46 +195,11 @@ quiche::QuicheBuffer SerializeCapsule(
case CapsuleType::LEGACY_DATAGRAM:
capsule_data_length =
capsule.legacy_datagram_capsule().http_datagram_payload.length();
- if (capsule.legacy_datagram_capsule().context_id.has_value()) {
- capsule_data_length += QuicDataWriter::GetVarInt62Len(
- capsule.legacy_datagram_capsule().context_id.value());
- }
- break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- capsule_data_length =
- QuicDataWriter::GetVarInt62Len(
- capsule.datagram_with_context_capsule().context_id) +
- capsule.datagram_with_context_capsule()
- .http_datagram_payload.length();
break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
capsule_data_length = capsule.datagram_without_context_capsule()
.http_datagram_payload.length();
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- capsule_data_length =
- QuicDataWriter::GetVarInt62Len(
- capsule.register_datagram_context_capsule().context_id) +
- QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
- capsule.register_datagram_context_capsule().format_type)) +
- capsule.register_datagram_context_capsule()
- .format_additional_data.length();
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- capsule_data_length =
- QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
- capsule.register_datagram_no_context_capsule().format_type)) +
- capsule.register_datagram_no_context_capsule()
- .format_additional_data.length();
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- capsule_data_length =
- QuicDataWriter::GetVarInt62Len(
- capsule.close_datagram_context_capsule().context_id) +
- QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
- capsule.close_datagram_context_capsule().close_code)) +
- capsule.close_datagram_context_capsule().close_details.length();
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
capsule_data_length =
sizeof(WebTransportSessionError) +
@@ -466,14 +225,6 @@ quiche::QuicheBuffer SerializeCapsule(
}
switch (capsule.capsule_type()) {
case CapsuleType::LEGACY_DATAGRAM:
- if (capsule.legacy_datagram_capsule().context_id.has_value()) {
- if (!writer.WriteVarInt62(
- capsule.legacy_datagram_capsule().context_id.value())) {
- QUIC_BUG(datagram capsule context ID write fail)
- << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
- return {};
- }
- }
if (!writer.WriteStringPiece(
capsule.legacy_datagram_capsule().http_datagram_payload)) {
QUIC_BUG(datagram capsule payload write fail)
@@ -481,20 +232,6 @@ quiche::QuicheBuffer SerializeCapsule(
return {};
}
break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- if (!writer.WriteVarInt62(
- capsule.datagram_with_context_capsule().context_id)) {
- QUIC_BUG(datagram capsule context ID write fail)
- << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
- return {};
- }
- if (!writer.WriteStringPiece(
- capsule.datagram_with_context_capsule().http_datagram_payload)) {
- QUIC_BUG(datagram capsule payload write fail)
- << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
- return {};
- }
- break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
.http_datagram_payload)) {
@@ -503,64 +240,6 @@ quiche::QuicheBuffer SerializeCapsule(
return {};
}
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- if (!writer.WriteVarInt62(
- capsule.register_datagram_context_capsule().context_id)) {
- QUIC_BUG(register context capsule context ID write fail)
- << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
- return {};
- }
- if (!writer.WriteVarInt62(static_cast<uint64_t>(
- capsule.register_datagram_context_capsule().format_type))) {
- QUIC_BUG(register context capsule format type write fail)
- << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
- return {};
- }
- if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
- .format_additional_data)) {
- QUIC_BUG(register context capsule additional data write fail)
- << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
- "data";
- return {};
- }
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- if (!writer.WriteVarInt62(static_cast<uint64_t>(
- capsule.register_datagram_no_context_capsule().format_type))) {
- QUIC_BUG(register no context capsule format type write fail)
- << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE format "
- "type";
- return {};
- }
- if (!writer.WriteStringPiece(
- capsule.register_datagram_no_context_capsule()
- .format_additional_data)) {
- QUIC_BUG(register no context capsule additional data write fail)
- << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE "
- "additional data";
- return {};
- }
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- if (!writer.WriteVarInt62(
- capsule.close_datagram_context_capsule().context_id)) {
- QUIC_BUG(close context capsule context ID write fail)
- << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
- return {};
- }
- if (!writer.WriteVarInt62(static_cast<uint64_t>(
- capsule.close_datagram_context_capsule().close_code))) {
- QUIC_BUG(close context capsule close code write fail)
- << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
- return {};
- }
- if (!writer.WriteStringPiece(
- capsule.close_datagram_context_capsule().close_details)) {
- QUIC_BUG(close context capsule close details write fail)
- << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
- return {};
- }
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
if (!writer.WriteUInt32(
capsule.close_web_transport_session_capsule().error_code)) {
@@ -638,75 +317,13 @@ size_t CapsuleParser::AttemptParseCapsule() {
Capsule capsule(static_cast<CapsuleType>(capsule_type64));
switch (capsule.capsule_type()) {
case CapsuleType::LEGACY_DATAGRAM:
- if (datagram_context_id_present_) {
- uint64_t context_id;
- if (!capsule_data_reader.ReadVarInt62(&context_id)) {
- ReportParseFailure(
- "Unable to parse capsule LEGACY_DATAGRAM context ID");
- return 0;
- }
- capsule.legacy_datagram_capsule().context_id = context_id;
- }
capsule.legacy_datagram_capsule().http_datagram_payload =
capsule_data_reader.ReadRemainingPayload();
break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT:
- uint64_t context_id;
- if (!capsule_data_reader.ReadVarInt62(&context_id)) {
- ReportParseFailure(
- "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
- return 0;
- }
- capsule.datagram_with_context_capsule().context_id = context_id;
- capsule.datagram_with_context_capsule().http_datagram_payload =
- capsule_data_reader.ReadRemainingPayload();
- break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
capsule.datagram_without_context_capsule().http_datagram_payload =
capsule_data_reader.ReadRemainingPayload();
break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
- if (!capsule_data_reader.ReadVarInt62(
- &capsule.register_datagram_context_capsule().context_id)) {
- ReportParseFailure(
- "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
- return 0;
- }
- if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
- &capsule.register_datagram_context_capsule().format_type))) {
- ReportParseFailure(
- "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
- return 0;
- }
- capsule.register_datagram_context_capsule().format_additional_data =
- capsule_data_reader.ReadRemainingPayload();
- break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
- if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
- &capsule.register_datagram_no_context_capsule().format_type))) {
- ReportParseFailure(
- "Unable to parse capsule REGISTER_DATAGRAM_NO_CONTEXT format type");
- return 0;
- }
- capsule.register_datagram_no_context_capsule().format_additional_data =
- capsule_data_reader.ReadRemainingPayload();
- break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
- if (!capsule_data_reader.ReadVarInt62(
- &capsule.close_datagram_context_capsule().context_id)) {
- ReportParseFailure(
- "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
- return 0;
- }
- if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
- &capsule.close_datagram_context_capsule().close_code))) {
- ReportParseFailure(
- "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
- return 0;
- }
- capsule.close_datagram_context_capsule().close_details =
- capsule_data_reader.ReadRemainingPayload();
- break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
if (!capsule_data_reader.ReadUInt32(
&capsule.close_web_transport_session_capsule().error_code)) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.h
index 5a93bd38304..7b4cc46d16b 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule.h
@@ -20,12 +20,9 @@ namespace quic {
enum class CapsuleType : uint64_t {
// Casing in this enum matches the IETF specification.
- LEGACY_DATAGRAM = 0xff37a0, // draft-ietf-masque-h3-datagram-04
- REGISTER_DATAGRAM_CONTEXT = 0xff37a1,
- REGISTER_DATAGRAM_NO_CONTEXT = 0xff37a2,
- CLOSE_DATAGRAM_CONTEXT = 0xff37a3,
- DATAGRAM_WITH_CONTEXT = 0xff37a4,
- DATAGRAM_WITHOUT_CONTEXT = 0xff37a5,
+ LEGACY_DATAGRAM = 0xff37a0, // draft-ietf-masque-h3-datagram-04.
+ DATAGRAM_WITHOUT_CONTEXT =
+ 0xff37a5, // draft-ietf-masque-h3-datagram-05 to -08.
CLOSE_WEBTRANSPORT_SESSION = 0x2843,
};
@@ -33,55 +30,12 @@ QUIC_EXPORT_PRIVATE std::string CapsuleTypeToString(CapsuleType capsule_type);
QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const CapsuleType& capsule_type);
-enum class DatagramFormatType : uint64_t {
- // Casing in this enum matches the IETF specification.
- UDP_PAYLOAD = 0xff6f00,
- WEBTRANSPORT = 0xff7c00,
-};
-
-QUIC_EXPORT_PRIVATE std::string DatagramFormatTypeToString(
- DatagramFormatType datagram_format_type);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const DatagramFormatType& datagram_format_type);
-
-enum class ContextCloseCode : uint64_t {
- // Casing in this enum matches the IETF specification.
- CLOSE_NO_ERROR = 0xff78a0, // NO_ERROR already exists in winerror.h.
- UNKNOWN_FORMAT = 0xff78a1,
- DENIED = 0xff78a2,
- RESOURCE_LIMIT = 0xff78a3,
-};
-
-QUIC_EXPORT_PRIVATE std::string ContextCloseCodeToString(
- ContextCloseCode context_close_code);
-QUIC_EXPORT_PRIVATE std::ostream& operator<<(
- std::ostream& os, const ContextCloseCode& context_close_code);
-
struct QUIC_EXPORT_PRIVATE LegacyDatagramCapsule {
- absl::optional<QuicDatagramContextId> context_id;
- absl::string_view http_datagram_payload;
-};
-struct QUIC_EXPORT_PRIVATE DatagramWithContextCapsule {
- QuicDatagramContextId context_id;
absl::string_view http_datagram_payload;
};
struct QUIC_EXPORT_PRIVATE DatagramWithoutContextCapsule {
absl::string_view http_datagram_payload;
};
-struct QUIC_EXPORT_PRIVATE RegisterDatagramContextCapsule {
- QuicDatagramContextId context_id;
- DatagramFormatType format_type;
- absl::string_view format_additional_data;
-};
-struct QUIC_EXPORT_PRIVATE RegisterDatagramNoContextCapsule {
- DatagramFormatType format_type;
- absl::string_view format_additional_data;
-};
-struct QUIC_EXPORT_PRIVATE CloseDatagramContextCapsule {
- QuicDatagramContextId context_id;
- ContextCloseCode close_code;
- absl::string_view close_details;
-};
struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
WebTransportSessionError error_code;
absl::string_view error_message;
@@ -95,23 +49,9 @@ struct QUIC_EXPORT_PRIVATE CloseWebTransportSessionCapsule {
class QUIC_EXPORT_PRIVATE Capsule {
public:
static Capsule LegacyDatagram(
- absl::optional<QuicDatagramContextId> context_id = absl::nullopt,
- absl::string_view http_datagram_payload = absl::string_view());
- static Capsule DatagramWithContext(
- QuicDatagramContextId context_id,
absl::string_view http_datagram_payload = absl::string_view());
static Capsule DatagramWithoutContext(
absl::string_view http_datagram_payload = absl::string_view());
- static Capsule RegisterDatagramContext(
- QuicDatagramContextId context_id, DatagramFormatType format_type,
- absl::string_view format_additional_data = absl::string_view());
- static Capsule RegisterDatagramNoContext(
- DatagramFormatType format_type,
- absl::string_view format_additional_data = absl::string_view());
- static Capsule CloseDatagramContext(
- QuicDatagramContextId context_id,
- ContextCloseCode close_code = ContextCloseCode::CLOSE_NO_ERROR,
- absl::string_view close_details = absl::string_view());
static Capsule CloseWebTransportSession(
WebTransportSessionError error_code = 0,
absl::string_view error_message = "");
@@ -138,14 +78,6 @@ class QUIC_EXPORT_PRIVATE Capsule {
QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::LEGACY_DATAGRAM);
return legacy_datagram_capsule_;
}
- DatagramWithContextCapsule& datagram_with_context_capsule() {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
- return datagram_with_context_capsule_;
- }
- const DatagramWithContextCapsule& datagram_with_context_capsule() const {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITH_CONTEXT);
- return datagram_with_context_capsule_;
- }
DatagramWithoutContextCapsule& datagram_without_context_capsule() {
QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
return datagram_without_context_capsule_;
@@ -155,32 +87,6 @@ class QUIC_EXPORT_PRIVATE Capsule {
QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
return datagram_without_context_capsule_;
}
- RegisterDatagramContextCapsule& register_datagram_context_capsule() {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
- return register_datagram_context_capsule_;
- }
- const RegisterDatagramContextCapsule& register_datagram_context_capsule()
- const {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_CONTEXT);
- return register_datagram_context_capsule_;
- }
- RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule() {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
- return register_datagram_no_context_capsule_;
- }
- const RegisterDatagramNoContextCapsule& register_datagram_no_context_capsule()
- const {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
- return register_datagram_no_context_capsule_;
- }
- CloseDatagramContextCapsule& close_datagram_context_capsule() {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
- return close_datagram_context_capsule_;
- }
- const CloseDatagramContextCapsule& close_datagram_context_capsule() const {
- QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_DATAGRAM_CONTEXT);
- return close_datagram_context_capsule_;
- }
CloseWebTransportSessionCapsule& close_web_transport_session_capsule() {
QUICHE_DCHECK_EQ(capsule_type_, CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
return close_web_transport_session_capsule_;
@@ -192,22 +98,14 @@ class QUIC_EXPORT_PRIVATE Capsule {
}
absl::string_view& unknown_capsule_data() {
QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
- capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
- capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
- capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
- capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
<< capsule_type_;
return unknown_capsule_data_;
}
const absl::string_view& unknown_capsule_data() const {
QUICHE_DCHECK(capsule_type_ != CapsuleType::LEGACY_DATAGRAM &&
- capsule_type_ != CapsuleType::DATAGRAM_WITH_CONTEXT &&
capsule_type_ != CapsuleType::DATAGRAM_WITHOUT_CONTEXT &&
- capsule_type_ != CapsuleType::REGISTER_DATAGRAM_CONTEXT &&
- capsule_type_ != CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT &&
- capsule_type_ != CapsuleType::CLOSE_DATAGRAM_CONTEXT &&
capsule_type_ != CapsuleType::CLOSE_WEBTRANSPORT_SESSION)
<< capsule_type_;
return unknown_capsule_data_;
@@ -217,11 +115,7 @@ class QUIC_EXPORT_PRIVATE Capsule {
CapsuleType capsule_type_;
union {
LegacyDatagramCapsule legacy_datagram_capsule_;
- DatagramWithContextCapsule datagram_with_context_capsule_;
DatagramWithoutContextCapsule datagram_without_context_capsule_;
- RegisterDatagramContextCapsule register_datagram_context_capsule_;
- RegisterDatagramNoContextCapsule register_datagram_no_context_capsule_;
- CloseDatagramContextCapsule close_datagram_context_capsule_;
CloseWebTransportSessionCapsule close_web_transport_session_capsule_;
absl::string_view unknown_capsule_data_;
};
@@ -252,10 +146,6 @@ class QUIC_EXPORT_PRIVATE CapsuleParser {
// |visitor| must be non-null, and must outlive CapsuleParser.
explicit CapsuleParser(Visitor* visitor);
- void set_datagram_context_id_present(bool datagram_context_id_present) {
- datagram_context_id_present_ = datagram_context_id_present;
- }
-
// Ingests a capsule fragment (any fragment of bytes from the capsule data
// stream) and parses and complete capsules it encounters. Returns false if a
// parsing error occurred.
@@ -272,8 +162,6 @@ class QUIC_EXPORT_PRIVATE CapsuleParser {
size_t AttemptParseCapsule();
void ReportParseFailure(const std::string& error_message);
- // Whether HTTP Datagram Context IDs are present.
- bool datagram_context_id_present_ = false;
// Whether a parsing error has occurred.
bool parsing_error_occurred_ = false;
// Visitor which will receive callbacks, unowned.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule_test.cc
index 895f275ad6f..1791bb6a504 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/capsule_test.cc
@@ -31,11 +31,6 @@ class CapsuleParserPeer {
namespace {
-constexpr DatagramFormatType kFakeFormatType =
- static_cast<DatagramFormatType>(0x123456);
-constexpr ContextCloseCode kFakeCloseCode =
- static_cast<ContextCloseCode>(0x654321);
-
class MockCapsuleParserVisitor : public CapsuleParser::Visitor {
public:
MockCapsuleParserVisitor() {
@@ -79,27 +74,7 @@ TEST_F(CapsuleTest, LegacyDatagramCapsule) {
"a1a2a3a4a5a6a7a8" // HTTP Datagram payload
);
std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- Capsule expected_capsule =
- Capsule::LegacyDatagram(/*context_id=*/absl::nullopt, datagram_payload);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, LegacyDatagramCapsuleWithContext) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a0" // LEGACY_DATAGRAM capsule type
- "09" // capsule length
- "04" // context ID
- "a1a2a3a4a5a6a7a8" // HTTP Datagram payload
- );
- capsule_parser_.set_datagram_context_id_present(true);
- std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- Capsule expected_capsule =
- Capsule::LegacyDatagram(/*context_id=*/4, datagram_payload);
+ Capsule expected_capsule = Capsule::LegacyDatagram(datagram_payload);
{
EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
@@ -124,82 +99,6 @@ TEST_F(CapsuleTest, DatagramWithoutContextCapsule) {
TestSerialization(expected_capsule, capsule_fragment);
}
-TEST_F(CapsuleTest, DatagramWithContextCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a4" // DATAGRAM_WITH_CONTEXT capsule type
- "09" // capsule length
- "04" // context ID
- "a1a2a3a4a5a6a7a8" // HTTP Datagram payload
- );
- std::string datagram_payload = absl::HexStringToBytes("a1a2a3a4a5a6a7a8");
- Capsule expected_capsule =
- Capsule::DatagramWithContext(/*context_id=*/4, datagram_payload);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, RegisterContextCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a1" // REGISTER_DATAGRAM_CONTEXT capsule type
- "0d" // capsule length
- "04" // context ID
- "80123456" // 0x123456 datagram format type
- "f1f2f3f4f5f6f7f8" // format additional data
- );
- std::string format_additional_data =
- absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
- Capsule expected_capsule = Capsule::RegisterDatagramContext(
- /*context_id=*/4, kFakeFormatType, format_additional_data);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, RegisterNoContextCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a2" // REGISTER_DATAGRAM_NO_CONTEXT capsule type
- "0c" // capsule length
- "80123456" // 0x123456 datagram format type
- "f1f2f3f4f5f6f7f8" // format additional data
- );
- std::string format_additional_data =
- absl::HexStringToBytes("f1f2f3f4f5f6f7f8");
- Capsule expected_capsule = Capsule::RegisterDatagramNoContext(
- kFakeFormatType, format_additional_data);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
-TEST_F(CapsuleTest, CloseContextCapsule) {
- std::string capsule_fragment = absl::HexStringToBytes(
- "80ff37a3" // CLOSE_DATAGRAM_CONTEXT capsule type
- "27" // capsule length
- "04" // context ID
- "80654321" // 0x654321 close code
- );
- std::string close_details = "All your contexts are belong to us";
- capsule_fragment += close_details;
- Capsule expected_capsule = Capsule::CloseDatagramContext(
- /*context_id=*/4, kFakeCloseCode, close_details);
- {
- EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
- ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
- }
- ValidateParserIsEmpty();
- TestSerialization(expected_capsule, capsule_fragment);
-}
-
TEST_F(CapsuleTest, CloseWebTransportStreamCapsule) {
std::string capsule_fragment = absl::HexStringToBytes(
"6843" // CLOSE_WEBTRANSPORT_STREAM capsule type
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/end_to_end_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/end_to_end_test.cc
index e2891a9c1ee..d602f388392 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/end_to_end_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/end_to_end_test.cc
@@ -17,10 +17,12 @@
#include "absl/time/time.h"
#include "quiche/quic/core/crypto/null_encrypter.h"
#include "quiche/quic/core/crypto/quic_client_session_cache.h"
+#include "quiche/quic/core/frames/quic_blocked_frame.h"
#include "quiche/quic/core/http/http_constants.h"
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
#include "quiche/quic/core/http/web_transport_http3.h"
#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/core/quic_data_writer.h"
#include "quiche/quic/core/quic_epoll_connection_helper.h"
#include "quiche/quic/core/quic_error_codes.h"
@@ -91,27 +93,39 @@ const char kFooResponseBody[] = "Artichoke hearts make me happy.";
const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
const char kTestUserAgentId[] = "quic/core/http/end_to_end_test.cc";
const float kSessionToStreamRatio = 1.5;
+const int kLongConnectionIdLength = 16;
// Run all tests with the cross products of all versions.
struct TestParams {
- TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag)
- : version(version), congestion_control_tag(congestion_control_tag) {}
+ TestParams(const ParsedQuicVersion& version, QuicTag congestion_control_tag,
+ int override_server_connection_id_length)
+ : version(version),
+ congestion_control_tag(congestion_control_tag),
+ override_server_connection_id_length(
+ override_server_connection_id_length) {}
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
os << "{ version: " << ParsedQuicVersionToString(p.version);
os << " congestion_control_tag: "
- << QuicTagToString(p.congestion_control_tag) << " }";
+ << QuicTagToString(p.congestion_control_tag)
+ << " connection ID length: " << p.override_server_connection_id_length
+ << " }";
return os;
}
ParsedQuicVersion version;
QuicTag congestion_control_tag;
+ int override_server_connection_id_length;
};
// Used by ::testing::PrintToStringParamName().
std::string PrintToString(const TestParams& p) {
- std::string rv = absl::StrCat(ParsedQuicVersionToString(p.version), "_",
- QuicTagToString(p.congestion_control_tag));
+ std::string rv = absl::StrCat(
+ ParsedQuicVersionToString(p.version), "_",
+ QuicTagToString(p.congestion_control_tag), "_",
+ std::to_string((p.override_server_connection_id_length == -1)
+ ? static_cast<int>(kQuicDefaultConnectionIdLength)
+ : p.override_server_connection_id_length));
std::replace(rv.begin(), rv.end(), ',', '_');
std::replace(rv.begin(), rv.end(), ' ', '_');
return rv;
@@ -120,15 +134,27 @@ std::string PrintToString(const TestParams& p) {
// Constructs various test permutations.
std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
- for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kB2ON}) {
- if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
- congestion_control_tag == kB2ON) {
- continue;
- }
- for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
- params.push_back(TestParams(version, congestion_control_tag));
- } // End of outer version loop.
- } // End of congestion_control_tag loop.
+ std::vector<int> connection_id_lengths{-1, kLongConnectionIdLength};
+ for (auto connection_id_length : connection_id_lengths) {
+ for (const QuicTag congestion_control_tag : {kTBBR, kQBIC, kB2ON}) {
+ if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
+ congestion_control_tag == kB2ON) {
+ continue;
+ }
+ for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
+ // TODO(b/232269029): Q050 should be able to handle 0-RTT when the
+ // initial connection ID is > 8 bytes, but it cannot. This is an
+ // invasive fix that has no impact as long as gQUIC clients always use
+ // 8B server connection IDs. If this bug is fixed, we can change
+ // 'UsesTls' to 'AllowsVariableLengthConnectionIds()' below to test
+ // qQUIC as well.
+ if (connection_id_length == -1 || version.UsesTls()) {
+ params.push_back(TestParams(version, congestion_control_tag,
+ connection_id_length));
+ }
+ } // End of outer version loop.
+ } // End of congestion_control_tag loop.
+ } // End of connection_id_length loop.
return params;
}
@@ -182,6 +208,8 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
server_supported_versions_(CurrentSupportedVersions()),
chlo_multiplier_(0),
stream_factory_(nullptr),
+ override_server_connection_id_length_(
+ GetParam().override_server_connection_id_length),
expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
@@ -227,7 +255,6 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
client->UseClientConnectionIdLength(override_client_connection_id_length_);
client->client()->set_connection_debug_visitor(connection_debug_visitor_);
client->client()->set_enable_web_transport(enable_web_transport_);
- client->client()->set_use_datagram_contexts(use_datagram_contexts_);
client->Connect();
return client;
}
@@ -367,9 +394,6 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
if (enable_web_transport_) {
memory_cache_backend_.set_enable_webtransport(true);
}
- if (use_datagram_contexts_) {
- memory_cache_backend_.set_use_datagram_contexts(true);
- }
QuicTagVector copt;
server_config_.SetConnectionOptionsToSend(copt);
@@ -444,12 +468,12 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
void StartServer() {
- auto* test_server = new QuicTestServer(
+ auto test_server = std::make_unique<QuicTestServer>(
crypto_test_utils::ProofSourceForTesting(), server_config_,
server_supported_versions_, &memory_cache_backend_,
expected_server_connection_id_length_);
server_thread_ =
- std::make_unique<ServerThread>(test_server, server_address_);
+ std::make_unique<ServerThread>(std::move(test_server), server_address_);
if (chlo_multiplier_ != 0) {
server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
}
@@ -800,7 +824,7 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
}
}
- ScopedEnvironmentForThreads environment_;
+ quiche::test::ScopedEnvironmentForThreads environment_;
bool initialized_;
// If true, the Initialize() function will create |client_| and starts to
// connect to the server.
@@ -824,11 +848,10 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
QuicTestServer::StreamFactory* stream_factory_;
std::string pre_shared_key_client_;
std::string pre_shared_key_server_;
- int override_server_connection_id_length_ = -1;
+ int override_server_connection_id_length_;
int override_client_connection_id_length_ = -1;
uint8_t expected_server_connection_id_length_;
bool enable_web_transport_ = false;
- bool use_datagram_contexts_ = false;
std::vector<std::string> received_webtransport_unidirectional_streams_;
};
@@ -1085,7 +1108,8 @@ TEST_P(EndToEndTest, ForcedVersionNegotiation) {
}
TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1103,7 +1127,8 @@ TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
}
TEST_P(EndToEndTest, ZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1119,7 +1144,8 @@ TEST_P(EndToEndTest, ZeroConnectionID) {
}
TEST_P(EndToEndTest, BadConnectionIdLength) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1133,23 +1159,6 @@ TEST_P(EndToEndTest, BadConnectionIdLength) {
.length());
}
-// Tests a very long (16-byte) initial destination connection ID to make
-// sure the dispatcher properly replaces it with an 8-byte one.
-TEST_P(EndToEndTest, LongBadConnectionIdLength) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
- ASSERT_TRUE(Initialize());
- return;
- }
- override_server_connection_id_length_ = 16;
- ASSERT_TRUE(Initialize());
- SendSynchronousFooRequestAndCheckResponse();
- EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
- ->client_session()
- ->connection()
- ->connection_id()
- .length());
-}
-
TEST_P(EndToEndTest, ClientConnectionId) {
if (!version_.SupportsClientConnectionIds()) {
ASSERT_TRUE(Initialize());
@@ -1184,7 +1193,8 @@ TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
}
TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1205,13 +1215,13 @@ TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
// connection ID.
TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
if (!version_.SupportsClientConnectionIds() ||
- !version_.AllowsVariableLengthConnectionIds()) {
+ !version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ != kLongConnectionIdLength) {
ASSERT_TRUE(Initialize());
return;
}
client_supported_versions_.insert(client_supported_versions_.begin(),
QuicVersionReservedForNegotiation());
- override_server_connection_id_length_ = 16;
override_client_connection_id_length_ = 18;
ASSERT_TRUE(Initialize());
ASSERT_TRUE(ServerSendsVersionNegotiation());
@@ -1229,7 +1239,8 @@ TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
}
TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1377,7 +1388,8 @@ TEST_P(EndToEndTest, MultipleRequestResponse) {
}
TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
- if (!version_.AllowsVariableLengthConnectionIds()) {
+ if (!version_.AllowsVariableLengthConnectionIds() ||
+ override_server_connection_id_length_ > -1) {
ASSERT_TRUE(Initialize());
return;
}
@@ -1496,7 +1508,8 @@ TEST_P(EndToEndTest, LargePostNoPacketLoss) {
VerifyCleanConnection(true);
}
-TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
+// Marked as slow since this adds a real-clock one second of delay.
+TEST_P(EndToEndTest, QUICHE_SLOW_TEST(LargePostNoPacketLoss1sRTT)) {
ASSERT_TRUE(Initialize());
SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
@@ -1536,7 +1549,14 @@ TEST_P(EndToEndTest, LargePostWithPacketLoss) {
EXPECT_EQ(kFooResponseBody,
client_->SendCustomSynchronousRequest(headers, body));
- VerifyCleanConnection(true);
+ if (override_server_connection_id_length_ == -1) {
+ // If the client sends a longer connection ID, we can end up with dropped
+ // packets. The packets_dropped counter increments whenever a packet arrives
+ // with a new server connection ID that is not INITIAL, RETRY, or 1-RTT.
+ // With packet losses, we could easily lose a server INITIAL and have the
+ // first observed server packet be HANDSHAKE.
+ VerifyCleanConnection(true);
+ }
}
// Regression test for b/80090281.
@@ -1618,7 +1638,13 @@ TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
client_->SendCustomSynchronousRequest(headers, body));
}
-TEST_P(EndToEndTest, AddressToken) {
+// TODO(b/214587920): make this test not rely on timeouts.
+TEST_P(EndToEndTest, QUICHE_SLOW_TEST(AddressToken)) {
+ client_config_.set_max_time_before_crypto_handshake(
+ QuicTime::Delta::FromSeconds(3));
+ client_config_.set_max_idle_time_before_crypto_handshake(
+ QuicTime::Delta::FromSeconds(1));
+
client_extra_copts_.push_back(kTRTT);
ASSERT_TRUE(Initialize());
if (!version_.HasIetfQuicFrames()) {
@@ -1667,11 +1693,7 @@ TEST_P(EndToEndTest, AddressToken) {
// QuicSentPacketManager::SetInitialRtt clamps the initial_rtt to between
// [min_initial_rtt, max_initial_rtt].
const QuicTime::Delta min_initial_rtt =
- server_connection->sent_packet_manager().use_lower_min_irtt()
- ? QuicTime::Delta::FromMicroseconds(
- kMinTrustedInitialRoundTripTimeUs)
- : QuicTime::Delta::FromMicroseconds(
- kMinUntrustedInitialRoundTripTimeUs);
+ QuicTime::Delta::FromMicroseconds(kMinTrustedInitialRoundTripTimeUs);
const QuicTime::Delta max_initial_rtt =
QuicTime::Delta::FromMicroseconds(kMaxInitialRoundTripTimeUs);
const QuicTime::Delta expected_initial_rtt =
@@ -1734,7 +1756,13 @@ TEST_P(EndToEndTest, AddressToken) {
}
// Verify that client does not reuse a source address token.
-TEST_P(EndToEndTest, AddressTokenNotReusedByClient) {
+// TODO(b/214587920): make this test not rely on timeouts.
+TEST_P(EndToEndTest, QUICHE_SLOW_TEST(AddressTokenNotReusedByClient)) {
+ client_config_.set_max_time_before_crypto_handshake(
+ QuicTime::Delta::FromSeconds(3));
+ client_config_.set_max_idle_time_before_crypto_handshake(
+ QuicTime::Delta::FromSeconds(1));
+
ASSERT_TRUE(Initialize());
if (!version_.HasIetfQuicFrames()) {
return;
@@ -1968,6 +1996,31 @@ TEST_P(EndToEndTest, LargePostSynchronousRequest) {
VerifyCleanConnection(false);
}
+TEST_P(EndToEndTest, DisableResumption) {
+ client_extra_copts_.push_back(kNRES);
+ ASSERT_TRUE(Initialize());
+ if (!version_.UsesTls()) {
+ return;
+ }
+ SendSynchronousFooRequestAndCheckResponse();
+ QuicSpdyClientSession* client_session = GetClientSession();
+ ASSERT_TRUE(client_session);
+ EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+ ssl_early_data_no_session_offered);
+ client_->Disconnect();
+
+ SendSynchronousFooRequestAndCheckResponse();
+ client_session = GetClientSession();
+ ASSERT_TRUE(client_session);
+ if (GetQuicReloadableFlag(quic_enable_disable_resumption)) {
+ EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+ ssl_early_data_session_not_resumed);
+ } else {
+ EXPECT_EQ(client_session->GetCryptoStream()->EarlyDataReason(),
+ ssl_early_data_accepted);
+ }
+}
+
// This is a regression test for b/162595387
TEST_P(EndToEndTest, PostZeroRTTRequestDuringHandshake) {
if (!version_.UsesTls()) {
@@ -4210,7 +4263,8 @@ TEST_P(EndToEndTest, BadPacketHeaderFlags) {
// Send a packet from the client with bad encrypted data. The server should not
// tear down the connection.
-TEST_P(EndToEndTest, BadEncryptedData) {
+// Marked as slow since it calls absl::SleepFor().
+TEST_P(EndToEndTest, QUICHE_SLOW_TEST(BadEncryptedData)) {
ASSERT_TRUE(Initialize());
// Start the connection.
@@ -4434,6 +4488,72 @@ class ServerStreamThatSendsHugeResponseFactory
int64_t body_bytes_;
};
+class BlockedFrameObserver : public QuicConnectionDebugVisitor {
+ public:
+ std::vector<QuicBlockedFrame> blocked_frames() const {
+ return blocked_frames_;
+ }
+
+ void OnBlockedFrame(const QuicBlockedFrame& frame) override {
+ blocked_frames_.push_back(frame);
+ }
+
+ private:
+ std::vector<QuicBlockedFrame> blocked_frames_;
+};
+
+TEST_P(EndToEndTest, BlockedFrameIncludesOffset) {
+ if (!version_.HasIetfQuicFrames()) {
+ // For Google QUIC, the BLOCKED frame offset is ignored.
+ Initialize();
+ return;
+ }
+
+ set_smaller_flow_control_receive_window();
+ ASSERT_TRUE(Initialize());
+
+ // Observe the connection for BLOCKED frames.
+ BlockedFrameObserver observer;
+ QuicConnection* client_connection = GetClientConnection();
+ ASSERT_TRUE(client_connection);
+ client_connection->set_debug_visitor(&observer);
+
+ // Set the response body larger than the flow control window so the server
+ // must receive a window update from the client before it can finish sending
+ // it (hence, causing the server to send a BLOCKED frame)
+ uint32_t response_body_size =
+ client_config_.GetInitialSessionFlowControlWindowToSend() + 10;
+ std::string response_body(response_body_size, 'a');
+ AddToCache("/blocked", 200, response_body);
+ SendSynchronousRequestAndCheckResponse("/blocked", response_body);
+ client_->Disconnect();
+
+ bool include_offset_flag =
+ GetQuicReloadableFlag(quic_include_offset_in_blocked_frames);
+ QuicStreamOffset expected_connection_offset =
+ include_offset_flag
+ ? client_config_.GetInitialSessionFlowControlWindowToSend()
+ : 0;
+ QuicStreamOffset expected_stream_offset =
+ include_offset_flag
+ ? client_config_.GetInitialStreamFlowControlWindowToSend()
+ : 0;
+
+ ASSERT_GE(observer.blocked_frames().size(), static_cast<uint64_t>(0));
+ for (const QuicBlockedFrame& frame : observer.blocked_frames()) {
+ if (frame.stream_id ==
+ QuicUtils::GetInvalidStreamId(version_.transport_version)) {
+ // connection-level BLOCKED frame
+ ASSERT_EQ(frame.offset, expected_connection_offset);
+ } else {
+ // stream-level BLOCKED frame
+ ASSERT_EQ(frame.offset, expected_stream_offset);
+ }
+ }
+
+ client_connection->set_debug_visitor(nullptr);
+}
+
TEST_P(EndToEndTest, EarlyResponseFinRecording) {
set_smaller_flow_control_receive_window();
@@ -4754,6 +4874,8 @@ TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
// Regression test for b/116200989.
TEST_P(EndToEndTest,
SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
+ SetQuicReloadableFlag(
+ quic_consider_original_connection_id_as_active_pre_handshake, true);
connect_to_server_on_initialize_ = false;
ASSERT_TRUE(Initialize());
@@ -5542,14 +5664,12 @@ TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
// Disconnect for next 0-rtt request.
client_->Disconnect();
- // Client get valid STK now. Do a 0-rtt request.
- // Buffer a CHLO till another packets sent out.
- reorder_writer_->SetDelay(1);
+ // Client has valid Session Ticket now. Do a 0-RTT request.
+ // Buffer a CHLO till the request is sent out. HTTP/3 sends two packets: a
+ // SETTINGS frame and a request.
+ reorder_writer_->SetDelay(version_.UsesHttp3() ? 2 : 1);
// Only send out a CHLO.
client_->client()->Initialize();
- client_->client()->StartConnect();
- EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
- ASSERT_TRUE(client_->client()->connected());
// Send a request before handshake finishes.
SpdyHeaderBlock headers;
@@ -5564,10 +5684,7 @@ TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
QuicConnection* client_connection = GetClientConnection();
ASSERT_TRUE(client_connection);
QuicConnectionStats client_stats = client_connection->GetStats();
- // Client sends CHLO in packet 1 and retransmitted in packet 2. Because of
- // the delay, server processes packet 2 and later drops packet 1. ACK is
- // bundled with SHLO, such that 1 can be detected loss by time threshold.
- EXPECT_LE(0u, client_stats.packets_lost);
+ EXPECT_EQ(0u, client_stats.packets_lost);
EXPECT_TRUE(client_->client()->EarlyDataAccepted());
}
@@ -5833,7 +5950,8 @@ TEST_P(EndToEndTest, CustomTransportParameters) {
}
TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
- if (!version_.HasLongHeaderLengths()) {
+ if (!version_.HasLongHeaderLengths() ||
+ override_server_connection_id_length_ > -1) {
// Decapsulating Legacy Version Encapsulation packets from these versions
// is not currently supported in QuicDispatcher.
ASSERT_TRUE(Initialize());
@@ -5850,7 +5968,8 @@ TEST_P(EndToEndTest, LegacyVersionEncapsulation) {
}
TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
- if (!version_.HasLongHeaderLengths()) {
+ if (!version_.HasLongHeaderLengths() ||
+ override_server_connection_id_length_ > -1) {
// Decapsulating Legacy Version Encapsulation packets from these versions
// is not currently supported in QuicDispatcher.
ASSERT_TRUE(Initialize());
@@ -5877,7 +5996,8 @@ TEST_P(EndToEndTest, LegacyVersionEncapsulationWithMultiPacketChlo) {
}
TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
- if (!version_.HasLongHeaderLengths()) {
+ if (!version_.HasLongHeaderLengths() ||
+ override_server_connection_id_length_ > -1) {
// Decapsulating Legacy Version Encapsulation packets from these versions
// is not currently supported in QuicDispatcher.
ASSERT_TRUE(Initialize());
@@ -5896,7 +6016,8 @@ TEST_P(EndToEndTest, LegacyVersionEncapsulationWithVersionNegotiation) {
}
TEST_P(EndToEndTest, LegacyVersionEncapsulationWithLoss) {
- if (!version_.HasLongHeaderLengths()) {
+ if (!version_.HasLongHeaderLengths() ||
+ override_server_connection_id_length_ > -1) {
// Decapsulating Legacy Version Encapsulation packets from these versions
// is not currently supported in QuicDispatcher.
ASSERT_TRUE(Initialize());
@@ -5959,7 +6080,7 @@ TEST_P(EndToEndTest, ChaosProtectionDisabled) {
// Parse the saved packet to make sure it's valid.
SimpleQuicFramer validation_framer({version_});
validation_framer.framer()->SetInitialObfuscators(
- GetClientConnection()->connection_id());
+ GetClientConnection()->GetOriginalDestinationConnectionId());
ASSERT_GT(copying_writer->packets().size(), 0u);
EXPECT_TRUE(validation_framer.ProcessPacket(*copying_writer->packets()[0]));
// TODO(dschinazi) figure out a way to use a MockRandom in this test so we
@@ -6574,38 +6695,6 @@ TEST_P(EndToEndTest, WebTransportDatagrams) {
EXPECT_GT(received, 0);
}
-TEST_P(EndToEndTest, WebTransportDatagramsWithContexts) {
- enable_web_transport_ = true;
- use_datagram_contexts_ = true;
- SetPacketLossPercentage(30);
- ASSERT_TRUE(Initialize());
-
- if (!version_.UsesHttp3()) {
- return;
- }
-
- QuicSpdyStream* connect_stream = nullptr;
- WebTransportHttp3* session = CreateWebTransportSession(
- "/echo", /*wait_for_server_response=*/true, &connect_stream);
- ASSERT_TRUE(session != nullptr);
- ASSERT_TRUE(connect_stream != nullptr);
- NiceMock<MockWebTransportSessionVisitor>& visitor =
- SetupWebTransportVisitor(session);
-
- quiche::SimpleBufferAllocator allocator;
- for (int i = 0; i < 10; i++) {
- session->SendOrQueueDatagram(MemSliceFromString("test"));
- }
-
- int received = 0;
- EXPECT_CALL(visitor, OnDatagramReceived(_)).WillRepeatedly([&received]() {
- received++;
- });
- client_->WaitUntil(5000, [&received]() { return received > 0; });
- EXPECT_GT(received, 0);
- EXPECT_TRUE(QuicSpdyStreamPeer::use_datagram_contexts(connect_stream));
-}
-
TEST_P(EndToEndTest, WebTransportSessionClose) {
enable_web_transport_ = true;
ASSERT_TRUE(Initialize());
@@ -6830,15 +6919,16 @@ TEST_P(EndToEndTest, RejectExtendedConnect) {
client_->WaitForResponse();
CheckResponseHeaders("400");
- // Vanilla CONNECT should be accepted.
+ // Vanilla CONNECT should be sent to backend.
spdy::SpdyHeaderBlock headers2;
headers2[":authority"] = "localhost";
headers2[":method"] = "CONNECT";
+ // Backend not configured/implemented to fully handle CONNECT requests, so
+ // expect it to send a 405.
client_->SendMessage(headers2, "body", /*fin=*/true);
client_->WaitForResponse();
- // No :path header, so 404.
- CheckResponseHeaders("404");
+ CheckResponseHeaders("405");
}
TEST_P(EndToEndTest, RejectInvalidRequestHeader) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc
index ea372cd393c..a22620d9f94 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc
@@ -17,15 +17,15 @@ std::string H3SettingsToString(Http3AndQpackSettingsIdentifiers identifier) {
RETURN_STRING_LITERAL(SETTINGS_QPACK_MAX_TABLE_CAPACITY);
RETURN_STRING_LITERAL(SETTINGS_MAX_FIELD_SECTION_SIZE);
RETURN_STRING_LITERAL(SETTINGS_QPACK_BLOCKED_STREAMS);
- RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT00);
RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT04);
+ RETURN_STRING_LITERAL(SETTINGS_H3_DATAGRAM_DRAFT09);
RETURN_STRING_LITERAL(SETTINGS_WEBTRANS_DRAFT00);
RETURN_STRING_LITERAL(SETTINGS_ENABLE_CONNECT_PROTOCOL);
}
return absl::StrCat("UNSUPPORTED_SETTINGS_TYPE(", identifier, ")");
}
-const absl::string_view kUserAgentHeaderName = "user-agent";
+ABSL_CONST_INIT const absl::string_view kUserAgentHeaderName = "user-agent";
#undef RETURN_STRING_LITERAL // undef for jumbo builds
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.h
index 097b2a38379..9e1a696dbbb 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_constants.h
@@ -38,10 +38,10 @@ enum Http3AndQpackSettingsIdentifiers : uint64_t {
// Same value as spdy::SETTINGS_MAX_HEADER_LIST_SIZE.
SETTINGS_MAX_FIELD_SECTION_SIZE = 0x06,
SETTINGS_QPACK_BLOCKED_STREAMS = 0x07,
- // draft-ietf-masque-h3-datagram-00.
- SETTINGS_H3_DATAGRAM_DRAFT00 = 0x276,
// draft-ietf-masque-h3-datagram-04.
SETTINGS_H3_DATAGRAM_DRAFT04 = 0xffd277,
+ // draft-ietf-masque-h3-datagram-09.
+ SETTINGS_H3_DATAGRAM_DRAFT09 = 0x33,
// draft-ietf-webtrans-http3-00
SETTINGS_WEBTRANS_DRAFT00 = 0x2b603742,
// draft-ietf-httpbis-h3-websockets
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc
index 0008d14fa03..5845a37b264 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc
@@ -528,8 +528,8 @@ bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
return visitor_->OnGoAwayFrame(frame);
}
case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
- MaxPushIdFrame frame;
- if (!reader->ReadVarInt62(&frame.push_id)) {
+ uint64_t unused;
+ if (!reader->ReadVarInt62(&unused)) {
RaiseError(QUIC_HTTP_FRAME_ERROR,
"Unable to read MAX_PUSH_ID push_id.");
return false;
@@ -539,7 +539,7 @@ bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
"Superfluous data in MAX_PUSH_ID frame.");
return false;
}
- return visitor_->OnMaxPushIdFrame(frame);
+ return visitor_->OnMaxPushIdFrame();
}
case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
PriorityUpdateFrame frame;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h
index 137755e04a7..ac6827663ad 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.h
@@ -45,7 +45,7 @@ class QUIC_EXPORT_PRIVATE HttpDecoder {
// processed. At that point it is safe to consume |header_length| bytes.
// Called when a MAX_PUSH_ID frame has been successfully parsed.
- virtual bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
+ virtual bool OnMaxPushIdFrame() = 0;
// Called when a GOAWAY frame has been successfully parsed.
virtual bool OnGoAwayFrame(const GoAwayFrame& frame) = 0;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder_test.cc
index f3854102b26..7f80d175b10 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_decoder_test.cc
@@ -45,8 +45,7 @@ class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
// Called if an error is detected.
MOCK_METHOD(void, OnError, (HttpDecoder*), (override));
- MOCK_METHOD(bool, OnMaxPushIdFrame, (const MaxPushIdFrame& frame),
- (override));
+ MOCK_METHOD(bool, OnMaxPushIdFrame, (), (override));
MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
MOCK_METHOD(bool, OnSettingsFrameStart, (QuicByteCount header_length),
(override));
@@ -90,7 +89,7 @@ class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
class HttpDecoderTest : public QuicTest {
public:
HttpDecoderTest() : decoder_(&visitor_) {
- ON_CALL(visitor_, OnMaxPushIdFrame(_)).WillByDefault(Return(true));
+ ON_CALL(visitor_, OnMaxPushIdFrame()).WillByDefault(Return(true));
ON_CALL(visitor_, OnGoAwayFrame(_)).WillByDefault(Return(true));
ON_CALL(visitor_, OnSettingsFrameStart(_)).WillByDefault(Return(true));
ON_CALL(visitor_, OnSettingsFrame(_)).WillByDefault(Return(true));
@@ -230,20 +229,19 @@ TEST_F(HttpDecoderTest, MaxPushId) {
"01"); // Push Id
// Visitor pauses processing.
- EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})))
- .WillOnce(Return(false));
+ EXPECT_CALL(visitor_, OnMaxPushIdFrame()).WillOnce(Return(false));
EXPECT_EQ(input.size(), ProcessInputWithGarbageAppended(input));
EXPECT_THAT(decoder_.error(), IsQuicNoError());
EXPECT_EQ("", decoder_.error_detail());
// Process the full frame.
- EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+ EXPECT_CALL(visitor_, OnMaxPushIdFrame());
EXPECT_EQ(input.size(), ProcessInput(input));
EXPECT_THAT(decoder_.error(), IsQuicNoError());
EXPECT_EQ("", decoder_.error_detail());
// Process the frame incrementally.
- EXPECT_CALL(visitor_, OnMaxPushIdFrame(MaxPushIdFrame({1})));
+ EXPECT_CALL(visitor_, OnMaxPushIdFrame());
ProcessInputCharByChar(input);
EXPECT_THAT(decoder_.error(), IsQuicNoError());
EXPECT_EQ("", decoder_.error_detail());
@@ -1068,9 +1066,12 @@ TEST(HttpDecoderTestNoFixture, WebTransportStreamError) {
EXPECT_CALL(visitor, OnWebTransportStreamFrameType(_, _));
decoder.ProcessInput(input.data(), input.size());
- EXPECT_CALL(visitor, OnError(_));
- EXPECT_QUIC_BUG(decoder.ProcessInput(input.data(), input.size()),
- "HttpDecoder called after an indefinite-length frame");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(visitor, OnError(_));
+ decoder.ProcessInput(input.data(), input.size());
+ },
+ "HttpDecoder called after an indefinite-length frame");
}
TEST_F(HttpDecoderTest, DecodeSettings) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames.h
index eae52ee649f..b96c5fbec8a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames.h
@@ -20,9 +20,6 @@
namespace quic {
-// TODO(b/171463363): Remove.
-using PushId = uint64_t;
-
enum class HttpFrameType {
DATA = 0x0,
HEADERS = 0x1,
@@ -101,18 +98,6 @@ struct QUIC_EXPORT_PRIVATE GoAwayFrame {
bool operator==(const GoAwayFrame& rhs) const { return id == rhs.id; }
};
-// 7.2.7. MAX_PUSH_ID
-//
-// The MAX_PUSH_ID frame (type=0xD) is used by clients to control the
-// number of server pushes that the server can initiate.
-struct QUIC_EXPORT_PRIVATE MaxPushIdFrame {
- PushId push_id;
-
- bool operator==(const MaxPushIdFrame& rhs) const {
- return push_id == rhs.push_id;
- }
-};
-
// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
//
// The PRIORITY_UPDATE frame specifies the sender-advised priority of a stream.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames_test.cc
index 1eefd7e6a55..446a6b92ca7 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/http_frames_test.cc
@@ -44,17 +44,6 @@ TEST(HttpFramesTest, GoAwayFrame) {
EXPECT_TRUE(a == b);
}
-TEST(HttpFramesTest, MaxPushIdFrame) {
- MaxPushIdFrame a{1};
- EXPECT_TRUE(a == a);
-
- MaxPushIdFrame b{2};
- EXPECT_FALSE(a == b);
-
- b.push_id = 1;
- EXPECT_TRUE(a == b);
-}
-
TEST(HttpFramesTest, PriorityUpdateFrame) {
PriorityUpdateFrame a{REQUEST_STREAM, 0, ""};
EXPECT_TRUE(a == a);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_header_list_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_header_list_test.cc
index 6007bccdfc6..573aae5ee66 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_header_list_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_header_list_test.cc
@@ -12,7 +12,7 @@
using ::testing::ElementsAre;
using ::testing::Pair;
-namespace quic {
+namespace quic::test {
class QuicHeaderListTest : public QuicTest {};
@@ -83,4 +83,4 @@ TEST_F(QuicHeaderListTest, IsCopyableAndAssignable) {
Pair("beep", "")));
}
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.h
index 1fae938bff6..ba3a27b3850 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.h
@@ -11,7 +11,6 @@
#include "quiche/quic/core/http/quic_header_list.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_stream.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/spdy/core/spdy_framer.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc
index d72eded7235..76083f33330 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream_test.cc
@@ -31,7 +31,7 @@
#include "quiche/spdy/core/recording_headers_handler.h"
#include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
#include "quiche/spdy/core/spdy_protocol.h"
-#include "quiche/spdy/core/spdy_test_utils.h"
+#include "quiche/spdy/test_tools/spdy_test_utils.h"
using spdy::ERROR_CODE_PROTOCOL_ERROR;
using spdy::RecordingHeadersHandler;
@@ -101,9 +101,9 @@ class MockVisitor : public SpdyFramerVisitorInterface {
(SpdyStreamId last_accepted_stream_id, SpdyErrorCode error_code),
(override));
MOCK_METHOD(void, OnHeaders,
- (SpdyStreamId stream_id, bool has_priority, int weight,
- SpdyStreamId parent_stream_id, bool exclusive, bool fin,
- bool end),
+ (SpdyStreamId stream_id, size_t payload_length, bool has_priority,
+ int weight, SpdyStreamId parent_stream_id, bool exclusive,
+ bool fin, bool end),
(override));
MOCK_METHOD(void, OnWindowUpdate,
(SpdyStreamId stream_id, int delta_window_size), (override));
@@ -111,7 +111,8 @@ class MockVisitor : public SpdyFramerVisitorInterface {
(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
bool end),
(override));
- MOCK_METHOD(void, OnContinuation, (SpdyStreamId stream_id, bool end),
+ MOCK_METHOD(void, OnContinuation,
+ (SpdyStreamId stream_id, size_t payload_size, bool end),
(override));
MOCK_METHOD(
void, OnAltSvc,
@@ -281,17 +282,20 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
// Parse the outgoing data and check that it matches was was written.
if (is_request) {
- EXPECT_CALL(visitor_,
- OnHeaders(stream_id, kHasPriority,
- Spdy3PriorityToHttp2Weight(priority),
- /*parent_stream_id=*/0,
- /*exclusive=*/false, fin, kFrameComplete));
+ EXPECT_CALL(
+ visitor_,
+ OnHeaders(stream_id, saved_data_.length() - spdy::kFrameHeaderSize,
+ kHasPriority, Spdy3PriorityToHttp2Weight(priority),
+ /*parent_stream_id=*/0,
+ /*exclusive=*/false, fin, kFrameComplete));
} else {
- EXPECT_CALL(visitor_,
- OnHeaders(stream_id, !kHasPriority,
- /*weight=*/0,
- /*parent_stream_id=*/0,
- /*exclusive=*/false, fin, kFrameComplete));
+ EXPECT_CALL(
+ visitor_,
+ OnHeaders(stream_id, saved_data_.length() - spdy::kFrameHeaderSize,
+ !kHasPriority,
+ /*weight=*/0,
+ /*parent_stream_id=*/0,
+ /*exclusive=*/false, fin, kFrameComplete));
}
headers_handler_ = std::make_unique<RecordingHeadersHandler>();
EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
@@ -629,7 +633,7 @@ TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
->header_encoder_table_size());
}
-// Regression bug for b/208997000.
+// Regression test for b/208997000.
TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
const uint32_t kVeryLargeTableSizeLimit = 1024 * 1024 * 1024;
SpdySettingsIR data;
@@ -638,14 +642,8 @@ TEST_P(QuicHeadersStreamTest, LimitEncoderDynamicTableSize) {
stream_frame_.data_buffer = frame.data();
stream_frame_.data_length = frame.size();
headers_stream_->OnStreamFrame(stream_frame_);
- if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
- EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
- ->header_encoder_table_size());
- } else {
- EXPECT_EQ(kVeryLargeTableSizeLimit,
- QuicSpdySessionPeer::GetSpdyFramer(&session_)
- ->header_encoder_table_size());
- }
+ EXPECT_EQ(16384u, QuicSpdySessionPeer::GetSpdyFramer(&session_)
+ ->header_encoder_table_size());
}
TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc
index 853909aa03c..c0a76af879a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc
@@ -62,21 +62,8 @@ void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
stream_delegate()->OnStreamError(decoder->error(), decoder->error_detail());
}
-bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
- if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_ignore_max_push_id);
- return ValidateFrameType(HttpFrameType::MAX_PUSH_ID);
- }
-
- if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
- }
-
- if (!ValidateFrameType(HttpFrameType::MAX_PUSH_ID)) {
- return false;
- }
-
- return spdy_session()->OnMaxPushIdFrame(frame.push_id);
+bool QuicReceiveControlStream::OnMaxPushIdFrame() {
+ return ValidateFrameType(HttpFrameType::MAX_PUSH_ID);
}
bool QuicReceiveControlStream::OnGoAwayFrame(const GoAwayFrame& frame) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.h
index 0cf34fad6fe..71d0bf2fa62 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.h
@@ -35,7 +35,7 @@ class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
// HttpDecoder::Visitor implementation.
void OnError(HttpDecoder* decoder) override;
- bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
+ bool OnMaxPushIdFrame() override;
bool OnGoAwayFrame(const GoAwayFrame& frame) override;
bool OnSettingsFrameStart(QuicByteCount header_length) override;
bool OnSettingsFrame(const SettingsFrame& frame) override;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.h
index c606ff50244..18ee01fb938 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.h
@@ -10,6 +10,7 @@
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -46,7 +47,7 @@ class QUIC_EXPORT_PRIVATE QuicSendControlStream : public QuicStream {
// The send control stream is write unidirectional, so this method should
// never be called.
- void OnDataAvailable() override { QUIC_NOTREACHED(); }
+ void OnDataAvailable() override { QUICHE_NOTREACHED(); }
private:
// Track if a settings frame is already sent.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream_test.cc
index aa7606fe8cc..f146cee9baf 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -133,11 +133,11 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) {
if ((!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
perspective() == Perspective::IS_CLIENT) &&
QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) ==
- HttpDatagramSupport::kDraft00And04) {
+ HttpDatagramSupport::kDraft04) {
expected_write_data = absl::HexStringToBytes(
"00" // stream type: control stream
"04" // frame type: SETTINGS frame
- "0e" // frame length
+ "0b" // frame length
"01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
"40ff" // 255
"06" // SETTINGS_MAX_HEADER_LIST_SIZE
@@ -146,8 +146,6 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) {
"10" // 16
"4040" // 0x40 as the reserved settings id
"14" // 20
- "4276" // SETTINGS_H3_DATAGRAM_DRAFT00
- "01" // 1
"800ffd277" // SETTINGS_H3_DATAGRAM_DRAFT04
"01" // 1
"4040" // 0x40 as the reserved frame type
@@ -183,7 +181,7 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) {
expected_write_data = absl::HexStringToBytes(
"00" // stream type: control stream
"04" // frame type: SETTINGS frame
- "11" // frame length
+ "0e" // frame length
"01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY
"40ff" // 255
"06" // SETTINGS_MAX_HEADER_LIST_SIZE
@@ -194,8 +192,6 @@ TEST_P(QuicSendControlStreamTest, WriteSettings) {
"01" // 1
"4040" // 0x40 as the reserved settings id
"14" // 20
- "4276" // SETTINGS_H3_DATAGRAM_DRAFT00
- "01" // 1
"800ffd277" // SETTINGS_H3_DATAGRAM_DRAFT04
"01" // 1
"4040" // 0x40 as the reserved frame type
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc
index 7ad1e3acb5e..d59602e103c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc
@@ -10,12 +10,14 @@
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_stream.h"
#include "quiche/quic/core/quic_tag.h"
+#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -45,15 +47,6 @@ void QuicServerSessionBase::Initialize() {
void QuicServerSessionBase::OnConfigNegotiated() {
QuicSpdySession::OnConfigNegotiated();
- const bool use_lower_min_irtt =
- connection()->sent_packet_manager().use_lower_min_irtt();
-
- if (!use_lower_min_irtt) {
- if (!config()->HasReceivedConnectionOptions()) {
- return;
- }
- }
-
const CachedNetworkParameters* cached_network_params =
crypto_stream_->PreviousCachedNetworkParams();
@@ -63,7 +56,7 @@ void QuicServerSessionBase::OnConfigNegotiated() {
if (version().UsesTls() && cached_network_params != nullptr) {
if (cached_network_params->serving_region() == serving_region_) {
QUIC_CODE_COUNT(quic_server_received_network_params_at_same_region);
- if ((!use_lower_min_irtt || config()->HasReceivedConnectionOptions()) &&
+ if (config()->HasReceivedConnectionOptions() &&
ContainsQuicTag(config()->ReceivedConnectionOptions(), kTRTT)) {
QUIC_DLOG(INFO)
<< "Server: Setting initial rtt to "
@@ -72,20 +65,33 @@ void QuicServerSessionBase::OnConfigNegotiated() {
connection()->sent_packet_manager().SetInitialRtt(
QuicTime::Delta::FromMilliseconds(
cached_network_params->min_rtt_ms()),
- /*trusted=*/use_lower_min_irtt);
+ /*trusted=*/true);
}
} else {
QUIC_CODE_COUNT(quic_server_received_network_params_at_different_region);
}
}
- if (use_lower_min_irtt) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 1, 2);
- if (!config()->HasReceivedConnectionOptions()) {
- return;
- }
+ if (!config()->HasReceivedConnectionOptions()) {
+ return;
}
+ if (GetQuicReloadableFlag(quic_enable_disable_resumption) &&
+ version().UsesTls() &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kNRES) &&
+ crypto_stream_->ResumptionAttempted()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_enable_disable_resumption);
+ const bool disabled = crypto_stream_->DisableResumption();
+ QUIC_BUG_IF(quic_failed_to_disable_resumption, !disabled)
+ << "Failed to disable resumption";
+ }
+
+ enable_sending_bandwidth_estimate_when_network_idle_ =
+ GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle) &&
+ version().HasIetfQuicFrames() &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWID);
+
// Enable bandwidth resumption if peer sent correct connection options.
const bool last_bandwidth_resumption =
ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE);
@@ -128,7 +134,31 @@ void QuicServerSessionBase::OnConnectionClosed(
}
}
+void QuicServerSessionBase::OnBandwidthUpdateTimeout() {
+ if (!enable_sending_bandwidth_estimate_when_network_idle_) {
+ return;
+ }
+ QUIC_DVLOG(1) << "Bandwidth update timed out.";
+ const SendAlgorithmInterface* send_algorithm =
+ connection()->sent_packet_manager().GetSendAlgorithm();
+ if (send_algorithm != nullptr &&
+ send_algorithm->HasGoodBandwidthEstimateForResumption()) {
+ const bool success = MaybeSendAddressToken();
+ QUIC_BUG_IF(QUIC_BUG_25522, !success) << "Failed to send address token.";
+ QUIC_RESTART_FLAG_COUNT_N(
+ quic_enable_sending_bandwidth_estimate_when_network_idle, 2, 3);
+ }
+}
+
void QuicServerSessionBase::OnCongestionWindowChange(QuicTime now) {
+ // Sending bandwidth is no longer conditioned on if session does bandwidth
+ // resumption.
+ if (GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle)) {
+ QUIC_RESTART_FLAG_COUNT_N(
+ quic_enable_sending_bandwidth_estimate_when_network_idle, 3, 3);
+ return;
+ }
if (!bandwidth_resumption_enabled_) {
return;
}
@@ -280,7 +310,7 @@ const QuicCryptoServerStreamBase* QuicServerSessionBase::GetCryptoStream()
int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
const QuicBandwidth& bandwidth) const {
return static_cast<int32_t>(std::min<int64_t>(
- bandwidth.ToBytesPerSecond(), std::numeric_limits<uint32_t>::max()));
+ bandwidth.ToBytesPerSecond(), std::numeric_limits<int32_t>::max()));
}
void QuicServerSessionBase::SendSettingsToCryptoStream() {
@@ -335,30 +365,55 @@ QuicServerSessionBase::GenerateCachedNetworkParameters() const {
sent_packet_manager.GetRttStats()->min_rtt().ToMilliseconds());
}
- // Populate bandwidth estimates if any.
- if (bandwidth_recorder != nullptr && bandwidth_recorder->HasEstimate()) {
- const int32_t bw_estimate_bytes_per_second =
- BandwidthToCachedParameterBytesPerSecond(
- bandwidth_recorder->BandwidthEstimate());
- const int32_t max_bw_estimate_bytes_per_second =
- BandwidthToCachedParameterBytesPerSecond(
- bandwidth_recorder->MaxBandwidthEstimate());
- QUIC_BUG_IF(quic_bug_12513_1, max_bw_estimate_bytes_per_second < 0)
- << max_bw_estimate_bytes_per_second;
- QUIC_BUG_IF(quic_bug_10393_1, bw_estimate_bytes_per_second < 0)
- << bw_estimate_bytes_per_second;
-
- cached_network_params.set_bandwidth_estimate_bytes_per_second(
- bw_estimate_bytes_per_second);
- cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
- max_bw_estimate_bytes_per_second);
- cached_network_params.set_max_bandwidth_timestamp_seconds(
- bandwidth_recorder->MaxBandwidthTimestamp());
-
- cached_network_params.set_previous_connection_state(
- bandwidth_recorder->EstimateRecordedDuringSlowStart()
- ? CachedNetworkParameters::SLOW_START
- : CachedNetworkParameters::CONGESTION_AVOIDANCE);
+ if (enable_sending_bandwidth_estimate_when_network_idle_) {
+ const SendAlgorithmInterface* send_algorithm =
+ sent_packet_manager.GetSendAlgorithm();
+ if (send_algorithm != nullptr &&
+ send_algorithm->HasGoodBandwidthEstimateForResumption()) {
+ cached_network_params.set_bandwidth_estimate_bytes_per_second(
+ BandwidthToCachedParameterBytesPerSecond(
+ send_algorithm->BandwidthEstimate()));
+ QUIC_CODE_COUNT(quic_send_measured_bandwidth_in_token);
+ } else {
+ const quic::CachedNetworkParameters* previous_cached_network_params =
+ crypto_stream()->PreviousCachedNetworkParams();
+ if (previous_cached_network_params != nullptr &&
+ previous_cached_network_params
+ ->bandwidth_estimate_bytes_per_second() > 0) {
+ cached_network_params.set_bandwidth_estimate_bytes_per_second(
+ previous_cached_network_params
+ ->bandwidth_estimate_bytes_per_second());
+ QUIC_CODE_COUNT(quic_send_previous_bandwidth_in_token);
+ } else {
+ QUIC_CODE_COUNT(quic_not_send_bandwidth_in_token);
+ }
+ }
+ } else {
+ // Populate bandwidth estimates if any.
+ if (bandwidth_recorder != nullptr && bandwidth_recorder->HasEstimate()) {
+ const int32_t bw_estimate_bytes_per_second =
+ BandwidthToCachedParameterBytesPerSecond(
+ bandwidth_recorder->BandwidthEstimate());
+ const int32_t max_bw_estimate_bytes_per_second =
+ BandwidthToCachedParameterBytesPerSecond(
+ bandwidth_recorder->MaxBandwidthEstimate());
+ QUIC_BUG_IF(quic_bug_12513_1, max_bw_estimate_bytes_per_second < 0)
+ << max_bw_estimate_bytes_per_second;
+ QUIC_BUG_IF(quic_bug_10393_1, bw_estimate_bytes_per_second < 0)
+ << bw_estimate_bytes_per_second;
+
+ cached_network_params.set_bandwidth_estimate_bytes_per_second(
+ bw_estimate_bytes_per_second);
+ cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
+ max_bw_estimate_bytes_per_second);
+ cached_network_params.set_max_bandwidth_timestamp_seconds(
+ bandwidth_recorder->MaxBandwidthTimestamp());
+
+ cached_network_params.set_previous_connection_state(
+ bandwidth_recorder->EstimateRecordedDuringSlowStart()
+ ? CachedNetworkParameters::SLOW_START
+ : CachedNetworkParameters::CONGESTION_AVOIDANCE);
+ }
}
if (!serving_region_.empty()) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.h
index d30b9dd359f..fcfda0e89f5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.h
@@ -48,6 +48,9 @@ class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
ConnectionCloseSource source) override;
+ // Override to send bandwidth estimate.
+ void OnBandwidthUpdateTimeout() override;
+
// Sends a server config update to the client, containing new bandwidth
// estimate.
void OnCongestionWindowChange(QuicTime now) override;
@@ -72,6 +75,10 @@ class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
QuicSSLConfig GetSSLConfig() const override;
+ bool enable_sending_bandwidth_estimate_when_network_idle() const {
+ return enable_sending_bandwidth_estimate_when_network_idle_;
+ }
+
protected:
// QuicSession methods(override them with return type of QuicSpdyStream*):
QuicCryptoServerStreamBase* GetMutableCryptoStream() override;
@@ -129,8 +136,9 @@ class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
// The most recent bandwidth estimate sent to the client.
QuicBandwidth bandwidth_estimate_sent_to_client_;
- // Text describing server location. Sent to the client as part of the bandwith
- // estimate in the source-address token. Optional, can be left empty.
+ // Text describing server location. Sent to the client as part of the
+ // bandwidth estimate in the source-address token. Optional, can be left
+ // empty.
std::string serving_region_;
// Time at which we send the last SCUP to the client.
@@ -144,6 +152,8 @@ class QUIC_EXPORT_PRIVATE QuicServerSessionBase : public QuicSpdySession {
// should go away once we fix http://b//27897982
int32_t BandwidthToCachedParameterBytesPerSecond(
const QuicBandwidth& bandwidth) const;
+
+ bool enable_sending_bandwidth_estimate_when_network_idle_ = false;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base_test.cc
index 56aa06a59b6..df099a66f3d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base_test.cc
@@ -510,6 +510,7 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
// Client has sent kBWRE connection option to trigger bandwidth resumption.
QuicTagVector copt;
copt.push_back(kBWRE);
+ copt.push_back(kBWID);
QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session_->OnConfigNegotiated();
@@ -606,35 +607,40 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
sent_packet_manager->OnPacketSent(&packet, now, NOT_RETRANSMISSION,
HAS_RETRANSMITTABLE_DATA, true);
- // Verify that the proto has exactly the values we expect.
- CachedNetworkParameters expected_network_params;
- expected_network_params.set_bandwidth_estimate_bytes_per_second(
- bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
- expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
- bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
- expected_network_params.set_max_bandwidth_timestamp_seconds(
- bandwidth_recorder.MaxBandwidthTimestamp());
- expected_network_params.set_min_rtt_ms(session_->connection()
- ->sent_packet_manager()
- .GetRttStats()
- ->min_rtt()
- .ToMilliseconds());
- expected_network_params.set_previous_connection_state(
- CachedNetworkParameters::CONGESTION_AVOIDANCE);
- expected_network_params.set_timestamp(
- session_->connection()->clock()->WallNow().ToUNIXSeconds());
- expected_network_params.set_serving_region(serving_region);
-
- if (quic_crypto_stream) {
- EXPECT_CALL(*quic_crypto_stream,
- SendServerConfigUpdate(EqualsProto(expected_network_params)))
- .Times(1);
+ if (GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle)) {
+ EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(0);
} else {
- EXPECT_CALL(*tls_server_stream,
- GetAddressToken(EqualsProto(expected_network_params)))
- .WillOnce(testing::Return("Test address token"));
+ // Verify that the proto has exactly the values we expect.
+ CachedNetworkParameters expected_network_params;
+ expected_network_params.set_bandwidth_estimate_bytes_per_second(
+ bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
+ expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
+ bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
+ expected_network_params.set_max_bandwidth_timestamp_seconds(
+ bandwidth_recorder.MaxBandwidthTimestamp());
+ expected_network_params.set_min_rtt_ms(session_->connection()
+ ->sent_packet_manager()
+ .GetRttStats()
+ ->min_rtt()
+ .ToMilliseconds());
+ expected_network_params.set_previous_connection_state(
+ CachedNetworkParameters::CONGESTION_AVOIDANCE);
+ expected_network_params.set_timestamp(
+ session_->connection()->clock()->WallNow().ToUNIXSeconds());
+ expected_network_params.set_serving_region(serving_region);
+
+ if (quic_crypto_stream) {
+ EXPECT_CALL(*quic_crypto_stream,
+ SendServerConfigUpdate(EqualsProto(expected_network_params)))
+ .Times(1);
+ } else {
+ EXPECT_CALL(*tls_server_stream,
+ GetAddressToken(EqualsProto(expected_network_params)))
+ .WillOnce(testing::Return("Test address token"));
+ }
+ EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
}
- EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
session_->OnCongestionWindowChange(now);
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h
index f75874e28e5..79e49abd4be 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.h
@@ -10,7 +10,6 @@
#include "absl/container/flat_hash_map.h"
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/quic_crypto_client_stream.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc
index 14550db5393..e54c84616b4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc
@@ -74,7 +74,7 @@ class AlpsFrameDecoder : public HttpDecoder::Visitor {
// HttpDecoder::Visitor implementation.
void OnError(HttpDecoder* /*decoder*/) override {}
- bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+ bool OnMaxPushIdFrame() override {
error_detail_ = "MAX_PUSH_ID frame forbidden";
return false;
}
@@ -318,8 +318,9 @@ class QuicSpdySession::SpdyFramerVisitor
QUIC_INVALID_HEADERS_STREAM_DATA);
}
- void OnHeaders(SpdyStreamId stream_id, bool has_priority, int weight,
- SpdyStreamId /* parent_stream_id */, bool /* exclusive */,
+ void OnHeaders(SpdyStreamId stream_id, size_t /*payload_length*/,
+ bool has_priority, int weight,
+ SpdyStreamId /*parent_stream_id*/, bool /*exclusive*/,
bool fin, bool /*end*/) override {
if (!session_->IsConnected()) {
return;
@@ -362,7 +363,8 @@ class QuicSpdySession::SpdyFramerVisitor
session_->OnPushPromise(stream_id, promised_stream_id);
}
- void OnContinuation(SpdyStreamId /*stream_id*/, bool /*end*/) override {}
+ void OnContinuation(SpdyStreamId /*stream_id*/, size_t /*payload_size*/,
+ bool /*end*/) override {}
void OnPriority(SpdyStreamId stream_id, SpdyStreamId /* parent_id */,
int weight, bool /* exclusive */) override {
@@ -516,15 +518,19 @@ void QuicSpdySession::FillSettingsFrame() {
settings_.values[SETTINGS_MAX_FIELD_SECTION_SIZE] =
max_inbound_header_list_size_;
if (version().UsesHttp3()) {
- HttpDatagramSupport local_http_datagram_support =
- LocalHttpDatagramSupport();
- if (local_http_datagram_support == HttpDatagramSupport::kDraft00 ||
- local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
- settings_.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
- }
- if (local_http_datagram_support == HttpDatagramSupport::kDraft04 ||
- local_http_datagram_support == HttpDatagramSupport::kDraft00And04) {
- settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+ switch (LocalHttpDatagramSupport()) {
+ case HttpDatagramSupport::kNone:
+ break;
+ case HttpDatagramSupport::kDraft04:
+ settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+ break;
+ case HttpDatagramSupport::kDraft09:
+ settings_.values[SETTINGS_H3_DATAGRAM_DRAFT09] = 1;
+ break;
+ case HttpDatagramSupport::kDraft04And09:
+ settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+ settings_.values[SETTINGS_H3_DATAGRAM_DRAFT09] = 1;
+ break;
}
}
if (WillNegotiateWebTransport()) {
@@ -776,21 +782,12 @@ void QuicSpdySession::SendHttp3GoAway(QuicErrorCode error_code,
stream_id = QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
transport_version());
- if (last_sent_http3_goaway_id_.has_value()) {
- if (last_sent_http3_goaway_id_.value() == stream_id) {
- // Do not send GOAWAY twice.
- return;
- }
- if (last_sent_http3_goaway_id_.value() < stream_id) {
- // A previous GOAWAY frame was sent with smaller stream ID. This is not
- // possible, because the only time a GOAWAY frame with non-maximal
- // stream ID is sent is right before closing connection.
- QUIC_BUG(quic_bug_10360_3)
- << "Not sending GOAWAY frame with " << stream_id
- << " because one with " << last_sent_http3_goaway_id_.value()
- << " already sent on connection " << connection()->connection_id();
- return;
- }
+ if (last_sent_http3_goaway_id_.has_value() &&
+ last_sent_http3_goaway_id_.value() <= stream_id) {
+ // Do not send GOAWAY frame with a higher id, because it is forbidden.
+ // Do not send one with same stream id as before, since frames on the
+ // control stream are guaranteed to be processed in order.
+ return;
}
send_control_stream_->SendGoAway(stream_id);
@@ -880,8 +877,6 @@ void QuicSpdySession::OnNewEncryptionKeyAvailable(
bool QuicSpdySession::ShouldNegotiateWebTransport() { return false; }
-bool QuicSpdySession::ShouldNegotiateDatagramContexts() { return false; }
-
bool QuicSpdySession::ShouldValidateWebTransportVersion() const { return true; }
bool QuicSpdySession::WillNegotiateWebTransport() {
@@ -1152,15 +1147,15 @@ bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
absl::StrCat("received HTTP/2 specific setting in HTTP/3 session: ",
id));
return false;
- case SETTINGS_H3_DATAGRAM_DRAFT00: {
+ case SETTINGS_H3_DATAGRAM_DRAFT04: {
HttpDatagramSupport local_http_datagram_support =
LocalHttpDatagramSupport();
- if (local_http_datagram_support != HttpDatagramSupport::kDraft00 &&
- local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+ if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
+ local_http_datagram_support != HttpDatagramSupport::kDraft04And09) {
break;
}
QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_H3_DATAGRAM_DRAFT00 received with value "
+ << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
<< value;
if (!version().UsesHttp3()) {
break;
@@ -1168,21 +1163,21 @@ bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
if (!VerifySettingIsZeroOrOne(id, value)) {
return false;
}
- if (value && http_datagram_support_ != HttpDatagramSupport::kDraft04) {
- // If both draft-00 and draft-04 are supported, use draft-04.
- http_datagram_support_ = HttpDatagramSupport::kDraft00;
+ if (value && http_datagram_support_ != HttpDatagramSupport::kDraft09) {
+ // If both draft-04 and draft-09 are supported, use draft-09.
+ http_datagram_support_ = HttpDatagramSupport::kDraft04;
}
break;
}
- case SETTINGS_H3_DATAGRAM_DRAFT04: {
+ case SETTINGS_H3_DATAGRAM_DRAFT09: {
HttpDatagramSupport local_http_datagram_support =
LocalHttpDatagramSupport();
- if (local_http_datagram_support != HttpDatagramSupport::kDraft04 &&
- local_http_datagram_support != HttpDatagramSupport::kDraft00And04) {
+ if (local_http_datagram_support != HttpDatagramSupport::kDraft09 &&
+ local_http_datagram_support != HttpDatagramSupport::kDraft04And09) {
break;
}
QUIC_DVLOG(1) << ENDPOINT
- << "SETTINGS_H3_DATAGRAM_DRAFT04 received with value "
+ << "SETTINGS_H3_DATAGRAM_DRAFT09 received with value "
<< value;
if (!version().UsesHttp3()) {
break;
@@ -1191,7 +1186,7 @@ bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
return false;
}
if (value) {
- http_datagram_support_ = HttpDatagramSupport::kDraft04;
+ http_datagram_support_ = HttpDatagramSupport::kDraft09;
}
break;
}
@@ -1225,13 +1220,8 @@ bool QuicSpdySession::OnSetting(uint64_t id, uint64_t value) {
QUIC_DVLOG(1) << ENDPOINT
<< "SETTINGS_HEADER_TABLE_SIZE received with value "
<< value;
- if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_limit_encoder_dynamic_table_size);
- spdy_framer_.UpdateHeaderEncoderTableSize(
- std::min<uint64_t>(value, kHpackEncoderDynamicTableSizeLimit));
- break;
- }
- spdy_framer_.UpdateHeaderEncoderTableSize(value);
+ spdy_framer_.UpdateHeaderEncoderTableSize(
+ std::min<uint64_t>(value, kHpackEncoderDynamicTableSizeLimit));
break;
case spdy::SETTINGS_ENABLE_PUSH:
if (perspective() == Perspective::IS_SERVER) {
@@ -1535,18 +1525,9 @@ void QuicSpdySession::BeforeConnectionCloseSent() {
}
if (last_sent_http3_goaway_id_.has_value() &&
last_sent_http3_goaway_id_.value() <= stream_id) {
- // A previous GOAWAY frame was sent with smaller stream ID. This is not
- // possible, because this is the only method sending a GOAWAY frame with
- // non-maximal stream ID, and this must only be called once, right
- // before closing connection.
- QUIC_BUG(QuicGoawayFrameAlreadySent)
- << "Not sending GOAWAY frame with " << stream_id << " because one with "
- << last_sent_http3_goaway_id_.value() << " already sent on connection "
- << connection()->connection_id();
-
- // MUST not send GOAWAY with identifier larger than previously sent.
- // Do not bother sending one with same identifier as before, since GOAWAY
- // frames on the control stream are guaranteed to be processed in order.
+ // Do not send GOAWAY frame with a higher id, because it is forbidden.
+ // Do not send one with same stream id as before, since frames on the
+ // control stream are guaranteed to be processed in order.
return;
}
@@ -1560,38 +1541,6 @@ void QuicSpdySession::OnCanCreateNewOutgoingStream(bool unidirectional) {
}
}
-bool QuicSpdySession::OnMaxPushIdFrame(PushId max_push_id) {
- QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
- QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective());
-
- if (max_push_id_.has_value()) {
- QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id
- << " from: " << max_push_id_.value();
- } else {
- QUIC_DVLOG(1) << "Setting max_push_id to: " << max_push_id
- << " from unset";
- }
- absl::optional<PushId> old_max_push_id = max_push_id_;
- max_push_id_ = max_push_id;
-
- if (!old_max_push_id.has_value() || max_push_id > old_max_push_id.value()) {
- OnCanCreateNewOutgoingStream(true);
- return true;
- }
-
- // Equal value is not considered an error.
- if (max_push_id < old_max_push_id.value()) {
- CloseConnectionWithDetails(
- QUIC_HTTP_INVALID_MAX_PUSH_ID,
- absl::StrCat("MAX_PUSH_ID received with value ", max_push_id,
- " which is smaller that previously received value ",
- old_max_push_id.value()));
- return false;
- }
-
- return true;
-}
-
bool QuicSpdySession::goaway_received() const {
return VersionUsesHttp3(transport_version())
? last_received_http3_goaway_id_.has_value()
@@ -1656,25 +1605,17 @@ void QuicSpdySession::LogHeaderCompressionRatioHistogram(
}
}
-MessageStatus QuicSpdySession::SendHttp3Datagram(
- QuicDatagramStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
+MessageStatus QuicSpdySession::SendHttp3Datagram(QuicStreamId stream_id,
+ absl::string_view payload) {
if (!SupportsH3Datagram()) {
QUIC_BUG(send http datagram too early)
<< "Refusing to send HTTP Datagram before SETTINGS received";
return MESSAGE_STATUS_INTERNAL_ERROR;
}
- uint64_t stream_id_to_write = stream_id;
- if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
- // Stream ID is sent divided by four as per the specification.
- stream_id_to_write /= kHttpDatagramStreamIdDivisor;
- }
+ // Stream ID is sent divided by four as per the specification.
+ uint64_t stream_id_to_write = stream_id / kHttpDatagramStreamIdDivisor;
size_t slice_length =
QuicDataWriter::GetVarInt62Len(stream_id_to_write) + payload.length();
- if (context_id.has_value()) {
- slice_length += QuicDataWriter::GetVarInt62Len(context_id.value());
- }
quiche::QuicheBuffer buffer(
connection()->helper()->GetStreamSendBufferAllocator(), slice_length);
QuicDataWriter writer(slice_length, buffer.data());
@@ -1683,13 +1624,6 @@ MessageStatus QuicSpdySession::SendHttp3Datagram(
<< "Failed to write HTTP/3 datagram stream ID";
return MESSAGE_STATUS_INTERNAL_ERROR;
}
- if (context_id.has_value()) {
- if (!writer.WriteVarInt62(context_id.value())) {
- QUIC_BUG(h3 datagram context ID write fail)
- << "Failed to write HTTP/3 datagram context ID";
- return MESSAGE_STATUS_INTERNAL_ERROR;
- }
- }
if (!writer.WriteBytes(payload.data(), payload.length())) {
QUIC_BUG(h3 datagram payload write fail)
<< "Failed to write HTTP/3 datagram payload";
@@ -1707,16 +1641,6 @@ void QuicSpdySession::SetMaxDatagramTimeInQueueForStreamId(
datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
}
-void QuicSpdySession::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
- QuicStreamId stream_id) {
- h3_datagram_flow_id_to_stream_id_map_[flow_id] = stream_id;
-}
-
-void QuicSpdySession::UnregisterHttp3DatagramFlowId(
- QuicDatagramStreamId flow_id) {
- h3_datagram_flow_id_to_stream_id_map_.erase(flow_id);
-}
-
void QuicSpdySession::OnMessageReceived(absl::string_view message) {
QuicSession::OnMessageReceived(message);
if (!SupportsH3Datagram()) {
@@ -1729,35 +1653,24 @@ void QuicSpdySession::OnMessageReceived(absl::string_view message) {
QUIC_DLOG(ERROR) << "Failed to parse stream ID in received HTTP/3 datagram";
return;
}
- if (http_datagram_support_ != HttpDatagramSupport::kDraft00) {
- // Stream ID is sent divided by four as per the specification.
- stream_id64 *= kHttpDatagramStreamIdDivisor;
- }
- if (perspective() == Perspective::IS_SERVER &&
- http_datagram_support_ == HttpDatagramSupport::kDraft00) {
- auto it = h3_datagram_flow_id_to_stream_id_map_.find(stream_id64);
- if (it == h3_datagram_flow_id_to_stream_id_map_.end()) {
- QUIC_DLOG(INFO) << "Received unknown HTTP/3 datagram flow ID "
- << stream_id64;
- return;
- }
- stream_id64 = it->second;
- }
- if (stream_id64 > std::numeric_limits<QuicStreamId>::max()) {
- // TODO(b/181256914) make this a connection close once we deprecate
- // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
- QUIC_DLOG(ERROR) << "Received unexpectedly high HTTP/3 datagram stream ID "
- << stream_id64;
+ // Stream ID is sent divided by four as per the specification.
+ if (stream_id64 >
+ std::numeric_limits<QuicStreamId>::max() / kHttpDatagramStreamIdDivisor) {
+ CloseConnectionWithDetails(
+ QUIC_HTTP_FRAME_ERROR,
+ absl::StrCat("Received HTTP Datagram with invalid quarter stream ID ",
+ stream_id64));
return;
}
+ stream_id64 *= kHttpDatagramStreamIdDivisor;
QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
QuicSpdyStream* stream =
static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
if (stream == nullptr) {
QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
<< stream_id;
- // TODO(b/181256914) buffer unknown HTTP/3 datagram flow IDs for a short
- // period of time in case they were reordered.
+ // TODO(b/181256914) buffer HTTP/3 datagrams with unknown stream IDs for a
+ // short period of time in case they were reordered.
return;
}
stream->OnDatagramReceived(&reader);
@@ -1909,12 +1822,12 @@ std::string HttpDatagramSupportToString(
switch (http_datagram_support) {
case HttpDatagramSupport::kNone:
return "None";
- case HttpDatagramSupport::kDraft00:
- return "Draft00";
case HttpDatagramSupport::kDraft04:
return "Draft04";
- case HttpDatagramSupport::kDraft00And04:
- return "Draft00And04";
+ case HttpDatagramSupport::kDraft09:
+ return "Draft09";
+ case HttpDatagramSupport::kDraft04And09:
+ return "Draft04And09";
}
return absl::StrCat("Unknown(", static_cast<int>(http_datagram_support), ")");
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.h
index b6038030930..f1173280d9c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.h
@@ -31,7 +31,6 @@
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/common/quiche_circular_deque.h"
#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
@@ -81,8 +80,6 @@ class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
// Incoming HTTP/3 frames on the control stream.
virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0;
virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) {}
- // TODO(b/171463363): Remove.
- virtual void OnMaxPushIdFrameReceived(const MaxPushIdFrame& /*frame*/) {}
virtual void OnPriorityUpdateFrameReceived(
const PriorityUpdateFrame& /*frame*/) {}
virtual void OnAcceptChFrameReceived(const AcceptChFrame& /*frame*/) {}
@@ -121,10 +118,10 @@ class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
// Whether draft-ietf-masque-h3-datagram is supported on this session and if so
// which draft is currently in use.
enum class HttpDatagramSupport : uint8_t {
- kNone = 0, // HTTP Datagrams are not supported for this session.
- kDraft00 = 1,
- kDraft04 = 2,
- kDraft00And04 = 3, // only used locally, we only negotiate one draft.
+ kNone, // HTTP Datagrams are not supported for this session.
+ kDraft04,
+ kDraft09,
+ kDraft04And09, // Only used locally for sending, we only negotiate one draft.
};
QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
@@ -322,14 +319,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
// those streams are not initialized yet.
void OnCanCreateNewOutgoingStream(bool unidirectional) override;
- // Sets |max_push_id_|.
- // This method must only be called if protocol is IETF QUIC and perspective is
- // server. It must only be called if a MAX_PUSH_ID frame is received.
- // Returns whether |max_push_id| is greater than or equal to current
- // |max_push_id_|.
- // TODO(b/171463363): Remove.
- bool OnMaxPushIdFrame(PushId max_push_id);
-
int32_t destruction_indicator() const { return destruction_indicator_; }
void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
@@ -389,19 +378,11 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
}
// This must not be used except by QuicSpdyStream::SendHttp3Datagram.
- MessageStatus SendHttp3Datagram(
- QuicDatagramStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload);
+ MessageStatus SendHttp3Datagram(QuicStreamId stream_id,
+ absl::string_view payload);
// This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
QuicTime::Delta max_time_in_queue);
- // This must not be used except by
- // QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders.
- void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id,
- QuicStreamId stream_id);
- // This must not be used except by QuicSpdyStream::OnClose.
- void UnregisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
// Override from QuicSession to support HTTP/3 datagrams.
void OnMessageReceived(absl::string_view message) override;
@@ -462,10 +443,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);
- // Indicates whether we will try to negotiate datagram contexts on newly
- // created WebTransport sessions over HTTP/3.
- virtual bool ShouldNegotiateDatagramContexts();
-
// Indicates whether the client should check that the
// `Sec-Webtransport-Http3-Draft` header is valid.
// TODO(vasilvv): remove this once this is enabled in Chromium.
@@ -538,6 +515,12 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
// in settings and accept remote settings for.
virtual HttpDatagramSupport LocalHttpDatagramSupport();
+ // Sends any data which should be sent at the start of a connection, including
+ // the initial SETTINGS frame. When using 0-RTT, this method is called twice:
+ // once when encryption is established, and again when 1-RTT keys are
+ // available.
+ void SendInitialData();
+
private:
friend class test::QuicSpdySessionPeer;
@@ -572,13 +555,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
absl::string_view type);
- // Sends any data which should be sent at the start of a connection, including
- // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID
- // frame if SetMaxPushId() had been called before encryption was established.
- // When using 0-RTT, this method is called twice: once when encryption is
- // established, and again when 1-RTT keys are available.
- void SendInitialData();
-
void FillSettingsFrame();
bool VerifySettingIsZeroOrOne(uint64_t id, uint64_t value);
@@ -637,20 +613,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
http2::Http2DecoderAdapter h2_deframer_;
std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
- // Used in IETF QUIC only.
- // For a server:
- // the push ID in the most recently received MAX_PUSH_ID frame,
- // or unset if no MAX_PUSH_ID frame has been received.
- // For a client:
- // unset until SetMaxPushId() is called;
- // before encryption is established, the push ID to be sent in the initial
- // MAX_PUSH_ID frame;
- // after encryption is established, the push ID in the most recently sent
- // MAX_PUSH_ID frame.
- // Once set, never goes back to unset.
- // TODO(b/171463363): Remove.
- absl::optional<PushId> max_push_id_;
-
// Not owned by the session.
Http3DebugVisitor* debug_visitor_;
@@ -677,12 +639,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession
// Whether the peer has indicated WebTransport support.
bool peer_supports_webtransport_ = false;
- // This maps from draft-ietf-masque-h3-datagram-00 flow IDs to stream IDs.
- // TODO(b/181256914) remove this when we deprecate support for that draft in
- // favor of more recent ones.
- absl::flat_hash_map<uint64_t, QuicStreamId>
- h3_datagram_flow_id_to_stream_id_map_;
-
// Whether any settings have been received, either from the peer or from a
// session ticket.
bool any_settings_received_ = false;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc
index b5e895abc6a..4cfb5b72fa5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc
@@ -195,11 +195,29 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
void OnConnectionClosed(QuicErrorCode /*error*/,
ConnectionCloseSource /*source*/) override {}
SSL* GetSsl() const override { return nullptr; }
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override {
+ return level != ENCRYPTION_ZERO_RTT;
+ }
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+ }
bool ExportKeyingMaterial(absl::string_view /*label*/,
absl::string_view /*context*/,
- size_t /*result_len*/,
- std::string* /*result*/) override {
+ size_t /*result_len*/, std::string*
+ /*result*/) override {
return false;
}
@@ -502,29 +520,6 @@ class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
return std::string(priority_buffer.get(), priority_frame_length);
}
- // TODO(b/171463363): Remove.
- std::string SerializeMaxPushIdFrame(PushId push_id) {
- const QuicByteCount payload_length =
- QuicDataWriter::GetVarInt62Len(push_id);
-
- const QuicByteCount total_length =
- QuicDataWriter::GetVarInt62Len(
- static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)) +
- QuicDataWriter::GetVarInt62Len(payload_length) +
- QuicDataWriter::GetVarInt62Len(push_id);
-
- std::string max_push_id_frame(total_length, '\0');
- QuicDataWriter writer(total_length, &*max_push_id_frame.begin());
-
- QUICHE_CHECK(writer.WriteVarInt62(
- static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID)));
- QUICHE_CHECK(writer.WriteVarInt62(payload_length));
- QUICHE_CHECK(writer.WriteVarInt62(push_id));
- QUICHE_CHECK_EQ(0u, writer.remaining());
-
- return max_push_id_frame;
- }
-
QuicStreamId StreamCountToId(QuicStreamCount stream_count,
Perspective perspective, bool bidirectional) {
// Calculate and build up stream ID rather than use
@@ -587,16 +582,8 @@ class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
headers.OnHeaderBlockStart();
headers.OnHeader(":method", "CONNECT");
headers.OnHeader(":protocol", "webtransport");
- if (session_.http_datagram_support() == HttpDatagramSupport::kDraft00) {
- headers.OnHeader("datagram-flow-id", absl::StrCat(session_id));
- } else {
- headers.OnHeader("sec-webtransport-http3-draft02", "1");
- }
+ headers.OnHeader("sec-webtransport-http3-draft02", "1");
stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
- if (session_.http_datagram_support() != HttpDatagramSupport::kDraft00) {
- stream->OnCapsule(
- Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
- }
WebTransportHttp3* web_transport =
session_.GetWebTransportSession(session_id);
ASSERT_TRUE(web_transport != nullptr);
@@ -1327,8 +1314,7 @@ TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
}
EXPECT_FALSE(session_.goaway_received());
- PushId push_id1 = 0;
- session_.OnHttp3GoAway(push_id1);
+ session_.OnHttp3GoAway(/* id = */ 0);
EXPECT_TRUE(session_.goaway_received());
EXPECT_CALL(
@@ -1337,8 +1323,7 @@ TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
"GOAWAY received with ID 1 greater than previously received ID 0",
_));
- PushId push_id2 = 1;
- session_.OnHttp3GoAway(push_id2);
+ session_.OnHttp3GoAway(/* id = */ 1);
}
// Test that server session will send a connectivity probe in response to a
@@ -1819,60 +1804,6 @@ TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
}
}
-// TODO(b/171463363): Remove.
-TEST_P(QuicSpdySessionTestServer, ReduceMaxPushId) {
- if (GetQuicReloadableFlag(quic_ignore_max_push_id)) {
- return;
- }
-
- if (!VersionUsesHttp3(transport_version())) {
- return;
- }
-
- StrictMock<MockHttp3DebugVisitor> debug_visitor;
- session_.set_debug_visitor(&debug_visitor);
-
- // Use an arbitrary stream id for incoming control stream.
- QuicStreamId stream_id =
- GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
- char type[] = {kControlStream};
- absl::string_view stream_type(type, 1);
-
- QuicStreamOffset offset = 0;
- QuicStreamFrame data1(stream_id, false, offset, stream_type);
- offset += stream_type.length();
- EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
- session_.OnStreamFrame(data1);
- EXPECT_EQ(stream_id,
- QuicSpdySessionPeer::GetReceiveControlStream(&session_)->id());
-
- SettingsFrame settings;
- std::string settings_frame = EncodeSettings(settings);
- QuicStreamFrame data2(stream_id, false, offset, settings_frame);
- offset += settings_frame.length();
-
- EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
- session_.OnStreamFrame(data2);
-
- std::string max_push_id_frame1 = SerializeMaxPushIdFrame(/* push_id = */ 3);
- QuicStreamFrame data3(stream_id, false, offset, max_push_id_frame1);
- offset += max_push_id_frame1.length();
-
- EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
- session_.OnStreamFrame(data3);
-
- std::string max_push_id_frame2 = SerializeMaxPushIdFrame(/* push_id = */ 1);
- QuicStreamFrame data4(stream_id, false, offset, max_push_id_frame2);
-
- EXPECT_CALL(debug_visitor, OnMaxPushIdFrameReceived(_));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_INVALID_MAX_PUSH_ID,
- "MAX_PUSH_ID received with value 1 which is "
- "smaller that previously received value 3",
- _));
- session_.OnStreamFrame(data4);
-}
-
class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
protected:
QuicSpdySessionTestClient()
@@ -2251,7 +2182,7 @@ TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+ session_.RetransmitFrames(frames, PTO_RETRANSMISSION);
}
TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
@@ -2748,11 +2679,13 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1));
EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
- "Control stream is received twice.", _));
EXPECT_QUIC_PEER_BUG(
- session_.OnStreamFrame(data2),
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+ "Control stream is received twice.", _));
+ session_.OnStreamFrame(data2);
+ },
"Received a duplicate Control stream: Closing connection.");
QuicStreamId id3 =
@@ -2767,11 +2700,14 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1));
EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
- "QPACK encoder stream is received twice.", _));
EXPECT_QUIC_PEER_BUG(
- session_.OnStreamFrame(data4),
+ {
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+ "QPACK encoder stream is received twice.", _));
+ session_.OnStreamFrame(data4);
+ },
"Received a duplicate QPACK encoder stream: Closing connection.");
QuicStreamId id5 =
@@ -2786,11 +2722,14 @@ TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1));
EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
- "QPACK decoder stream is received twice.", _));
EXPECT_QUIC_PEER_BUG(
- session_.OnStreamFrame(data6),
+ {
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
+ "QPACK decoder stream is received twice.", _));
+ session_.OnStreamFrame(data6);
+ },
"Received a duplicate QPACK decoder stream: Closing connection.");
}
@@ -3454,15 +3393,15 @@ void QuicSpdySessionTestBase::TestHttpDatagramSetting(
switch (remote_support) {
case HttpDatagramSupport::kNone:
break;
- case HttpDatagramSupport::kDraft00:
- settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
- break;
case HttpDatagramSupport::kDraft04:
settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
break;
- case HttpDatagramSupport::kDraft00And04:
- settings.values[SETTINGS_H3_DATAGRAM_DRAFT00] = 1;
+ case HttpDatagramSupport::kDraft09:
+ settings.values[SETTINGS_H3_DATAGRAM_DRAFT09] = 1;
+ break;
+ case HttpDatagramSupport::kDraft04And09:
settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
+ settings.values[SETTINGS_H3_DATAGRAM_DRAFT09] = 1;
break;
}
std::string data = std::string(1, kControlStream) + EncodeSettings(settings);
@@ -3478,84 +3417,83 @@ void QuicSpdySessionTestBase::TestHttpDatagramSetting(
EXPECT_EQ(session_.SupportsH3Datagram(), expected_datagram_supported);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
+ /*local_support=*/HttpDatagramSupport::kDraft04,
+ /*remote_support=*/HttpDatagramSupport::kDraft04,
+ /*expected_support=*/HttpDatagramSupport::kDraft04,
/*expected_datagram_supported=*/true);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote04) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
+ /*local_support=*/HttpDatagramSupport::kDraft04,
+ /*remote_support=*/HttpDatagramSupport::kDraft09,
/*expected_support=*/HttpDatagramSupport::kNone,
/*expected_datagram_supported=*/false);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00Remote00And04) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04And09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
+ /*local_support=*/HttpDatagramSupport::kDraft04,
+ /*remote_support=*/HttpDatagramSupport::kDraft04And09,
+ /*expected_support=*/HttpDatagramSupport::kDraft04,
/*expected_datagram_supported=*/true);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote04) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
+ /*local_support=*/HttpDatagramSupport::kDraft09,
+ /*remote_support=*/HttpDatagramSupport::kDraft04,
/*expected_support=*/HttpDatagramSupport::kNone,
/*expected_datagram_supported=*/false);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
+ /*local_support=*/HttpDatagramSupport::kDraft09,
+ /*remote_support=*/HttpDatagramSupport::kDraft09,
+ /*expected_support=*/HttpDatagramSupport::kDraft09,
/*expected_datagram_supported=*/true);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote00And04) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote04And09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft04,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
+ /*local_support=*/HttpDatagramSupport::kDraft09,
+ /*remote_support=*/HttpDatagramSupport::kDraft04And09,
+ /*expected_support=*/HttpDatagramSupport::kDraft09,
/*expected_datagram_supported=*/true);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote00) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04And09Remote04) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft00,
- /*expected_support=*/HttpDatagramSupport::kDraft00,
+ /*local_support=*/HttpDatagramSupport::kDraft04And09,
+ /*remote_support=*/HttpDatagramSupport::kDraft04,
+ /*expected_support=*/HttpDatagramSupport::kDraft04,
/*expected_datagram_supported=*/true);
}
-TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal00And04Remote04) {
+TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04And09Remote09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
+ /*local_support=*/HttpDatagramSupport::kDraft04And09,
+ /*remote_support=*/HttpDatagramSupport::kDraft09,
+ /*expected_support=*/HttpDatagramSupport::kDraft09,
/*expected_datagram_supported=*/true);
}
TEST_P(QuicSpdySessionTestClient,
- HttpDatagramSettingLocal00And04Remote00And04) {
+ HttpDatagramSettingLocal04And09Remote04And09) {
TestHttpDatagramSetting(
- /*local_support=*/HttpDatagramSupport::kDraft00And04,
- /*remote_support=*/HttpDatagramSupport::kDraft00And04,
- /*expected_support=*/HttpDatagramSupport::kDraft04,
+ /*local_support=*/HttpDatagramSupport::kDraft04And09,
+ /*remote_support=*/HttpDatagramSupport::kDraft04And09,
+ /*expected_support=*/HttpDatagramSupport::kDraft09,
/*expected_datagram_supported=*/true);
}
-
TEST_P(QuicSpdySessionTestClient, WebTransportSetting) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3578,7 +3516,7 @@ TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3608,7 +3546,7 @@ TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3625,7 +3563,7 @@ TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
CompleteHandshake();
@@ -3658,7 +3596,7 @@ TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
CompleteHandshake();
@@ -3699,7 +3637,7 @@ TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
if (!version().UsesHttp3()) {
return;
}
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
CompleteHandshake();
@@ -3736,7 +3674,7 @@ TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
}
SetQuicReloadableFlag(quic_verify_request_headers_2, true);
SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
- session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_.set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_.set_supports_webtransport(true);
EXPECT_FALSE(session_.SupportsWebTransport());
@@ -3757,7 +3695,7 @@ TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
EXPECT_TRUE(session_.SupportsWebTransport());
}
-// Regression bug for b/208997000.
+// Regression test for b/208997000.
TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
if (version().UsesHttp3()) {
return;
@@ -3788,43 +3726,25 @@ TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
absl::string_view stream_data(slice.data(), slice.length());
- if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
- EXPECT_EQ(absl::HexStringToBytes(
- "000009" // frame length
- "01" // frame type HEADERS
- "25"), // flags END_STREAM | END_HEADERS | PRIORITY
- stream_data.substr(0, 5));
- stream_data.remove_prefix(5);
- } else {
- EXPECT_EQ(absl::HexStringToBytes(
- "00000c" // frame length
- "01" // frame type HEADERS
- "25"), // flags END_STREAM | END_HEADERS | PRIORITY
- stream_data.substr(0, 5));
- stream_data.remove_prefix(5);
- }
+ EXPECT_EQ(absl::HexStringToBytes(
+ "000009" // frame length
+ "01" // frame type HEADERS
+ "25"), // flags END_STREAM | END_HEADERS | PRIORITY
+ stream_data.substr(0, 5));
+ stream_data.remove_prefix(5);
// Ignore stream ID as it might differ between QUIC versions.
stream_data.remove_prefix(4);
- // Ignore stream dependency and weight.
EXPECT_EQ(absl::HexStringToBytes("00000000" // stream dependency
"92"), // stream weight
stream_data.substr(0, 5));
stream_data.remove_prefix(5);
- if (GetQuicReloadableFlag(quic_limit_encoder_dynamic_table_size)) {
- EXPECT_EQ(absl::HexStringToBytes(
- "3fe17f" // Dynamic Table Size Update to 16384
- "82"), // Indexed Header Field Representation with index 2
- stream_data);
- } else {
- EXPECT_EQ(
- absl::HexStringToBytes(
- "3fe1ffffff03" // Dynamic Table Size Update to 1024 * 1024 * 1024
- "82"), // Indexed Header Field Representation with index 2
- stream_data);
- }
+ EXPECT_EQ(absl::HexStringToBytes(
+ "3fe17f" // Dynamic Table Size Update to 16384
+ "82"), // Indexed Header Field Representation with index 2
+ stream_data);
}
class QuicSpdySessionTestServerNoExtendedConnect
@@ -3878,10 +3798,12 @@ TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
: GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
EXPECT_QUIC_PEER_BUG(
- session_.OnStreamFrame(frame),
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
+ session_.OnStreamFrame(frame);
+ },
"Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc
index 82077cd9869..10d76afb171 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc
@@ -53,7 +53,7 @@ class QuicSpdyStream::HttpDecoderVisitor : public HttpDecoder::Visitor {
stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
}
- bool OnMaxPushIdFrame(const MaxPushIdFrame& /*frame*/) override {
+ bool OnMaxPushIdFrame() override {
CloseConnectionOnWrongFrame("Max Push Id");
return false;
}
@@ -193,11 +193,7 @@ QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
sequencer_offset_(0),
is_decoder_processing_input_(false),
ack_listener_(nullptr),
- last_sent_urgency_(kDefaultUrgency),
- datagram_next_available_context_id_(spdy_session->perspective() ==
- Perspective::IS_SERVER
- ? kFirstDatagramContextIdServer
- : kFirstDatagramContextIdClient) {
+ last_sent_urgency_(kDefaultUrgency) {
QUICHE_DCHECK_EQ(session()->connection(), spdy_session->connection());
QUICHE_DCHECK_EQ(transport_version(), spdy_session->transport_version());
QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
@@ -253,13 +249,6 @@ QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
QuicSpdyStream::~QuicSpdyStream() {}
-bool QuicSpdyStream::ShouldUseDatagramContexts() const {
- return spdy_session_->SupportsH3Datagram() &&
- spdy_session_->http_datagram_support() !=
- HttpDatagramSupport::kDraft00 &&
- use_datagram_contexts_;
-}
-
size_t QuicSpdyStream::WriteHeaders(
SpdyHeaderBlock header_block, bool fin,
quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
@@ -288,14 +277,7 @@ size_t QuicSpdyStream::WriteHeaders(
MaybeProcessSentWebTransportHeaders(header_block);
- if (ShouldUseDatagramContexts()) {
- // RegisterHttp3DatagramRegistrationVisitor caller wishes to use contexts,
- // inform the peer.
- header_block["sec-use-datagram-contexts"] = "?1";
- }
-
if (web_transport_ != nullptr &&
- spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
spdy_session_->perspective() == Perspective::IS_SERVER) {
header_block["sec-webtransport-http3-draft"] = "draft02";
}
@@ -313,11 +295,21 @@ size_t QuicSpdyStream::WriteHeaders(
if (web_transport_ != nullptr &&
session()->perspective() == Perspective::IS_CLIENT) {
- // This will send a capsule and therefore needs to happen after headers have
- // been sent.
- RegisterHttp3DatagramContextId(
- web_transport_->context_id(), DatagramFormatType::WEBTRANSPORT,
- /*format_additional_data=*/absl::string_view(), web_transport_.get());
+ WriteGreaseCapsule();
+ if (spdy_session_->http_datagram_support() ==
+ HttpDatagramSupport::kDraft04) {
+ // Send a REGISTER_DATAGRAM_NO_CONTEXT capsule to support servers that
+ // are running draft-ietf-masque-h3-datagram-04 or -05.
+ uint64_t capsule_type = 0xff37a2; // REGISTER_DATAGRAM_NO_CONTEXT
+ constexpr unsigned char capsule_data[4] = {
+ 0x80, 0xff, 0x7c, 0x00, // WEBTRANSPORT datagram format type
+ };
+ WriteCapsule(Capsule::Unknown(
+ capsule_type,
+ absl::string_view(reinterpret_cast<const char*>(capsule_data),
+ sizeof(capsule_data))));
+ WriteGreaseCapsule();
+ }
}
return bytes_written;
@@ -654,19 +646,6 @@ void QuicSpdyStream::OnInitialHeadersComplete(
if (!GetQuicReloadableFlag(quic_verify_request_headers_2) ||
!header_too_large) {
MaybeProcessReceivedWebTransportHeaders();
- if (ShouldUseDatagramContexts()) {
- bool peer_wishes_to_use_datagram_contexts = false;
- for (const auto& header : header_list_) {
- if (header.first == "sec-use-datagram-contexts" &&
- header.second == "?1") {
- peer_wishes_to_use_datagram_contexts = true;
- break;
- }
- }
- if (!peer_wishes_to_use_datagram_contexts) {
- use_datagram_contexts_ = false;
- }
- }
}
if (VersionUsesHttp3(transport_version())) {
@@ -775,18 +754,20 @@ void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) {
return;
}
- if (GetQuicReloadableFlag(quic_fix_on_stream_reset) &&
- VersionUsesHttp3(transport_version())) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_fix_on_stream_reset);
- if (!fin_received() && spdy_session_->qpack_decoder()) {
- spdy_session_->qpack_decoder()->OnStreamReset(id());
- qpack_decoded_headers_accumulator_.reset();
- qpack_decoded_headers_accumulator_reset_reason_ =
- QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
- }
+ if (VersionUsesHttp3(transport_version())) {
+ QUIC_CODE_COUNT(quic_fix_on_stream_reset);
+ if (GetQuicReloadableFlag(quic_fix_on_stream_reset)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_fix_on_stream_reset);
+ if (!fin_received() && spdy_session_->qpack_decoder()) {
+ spdy_session_->qpack_decoder()->OnStreamReset(id());
+ qpack_decoded_headers_accumulator_.reset();
+ qpack_decoded_headers_accumulator_reset_reason_ =
+ QpackDecodedHeadersAccumulatorResetReason::kResetInOnStreamReset2;
+ }
- QuicStream::OnStreamReset(frame);
- return;
+ QuicStream::OnStreamReset(frame);
+ return;
+ }
}
QUIC_DVLOG(1) << ENDPOINT
@@ -920,10 +901,6 @@ void QuicSpdyStream::OnClose() {
visitor->OnClose(this);
}
- if (datagram_flow_id_.has_value()) {
- spdy_session_->UnregisterHttp3DatagramFlowId(datagram_flow_id_.value());
- }
-
if (web_transport_ != nullptr) {
web_transport_->OnConnectStreamClosing();
}
@@ -1275,8 +1252,6 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
std::string method;
std::string protocol;
- absl::optional<QuicDatagramStreamId> flow_id;
- bool version_indicated = false;
for (const auto& [header_name, header_value] : header_list_) {
if (header_name == ":method") {
if (!method.empty() || header_value.empty()) {
@@ -1291,21 +1266,10 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
protocol = header_value;
}
if (header_name == "datagram-flow-id") {
- if (spdy_session_->http_datagram_support() !=
- HttpDatagramSupport::kDraft00) {
- QUIC_DLOG(ERROR) << ENDPOINT
- << "Rejecting WebTransport due to unexpected "
- "Datagram-Flow-Id header";
- return;
- }
- if (flow_id.has_value() || header_value.empty()) {
- return;
- }
- QuicDatagramStreamId flow_id_out;
- if (!absl::SimpleAtoi(header_value, &flow_id_out)) {
- return;
- }
- flow_id = flow_id_out;
+ QUIC_DLOG(ERROR) << ENDPOINT
+ << "Rejecting WebTransport due to unexpected "
+ "Datagram-Flow-Id header";
+ return;
}
if (header_name == "sec-webtransport-http3-draft02") {
if (header_value != "1") {
@@ -1314,7 +1278,6 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
"Sec-Webtransport-Http3-Draft02 header";
return;
}
- version_indicated = true;
}
}
@@ -1322,38 +1285,8 @@ void QuicSpdyStream::MaybeProcessReceivedWebTransportHeaders() {
return;
}
- if (!version_indicated &&
- spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
- QUIC_DLOG(ERROR)
- << ENDPOINT
- << "WebTransport request rejected due to missing version header.";
- return;
- }
-
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
- if (!flow_id.has_value()) {
- QUIC_DLOG(ERROR)
- << ENDPOINT
- << "Rejecting WebTransport due to missing Datagram-Flow-Id header";
- return;
- }
- RegisterHttp3DatagramFlowId(*flow_id);
- }
-
- web_transport_ = std::make_unique<WebTransportHttp3>(
- spdy_session_, this, id(),
- spdy_session_->ShouldNegotiateDatagramContexts());
-
- if (spdy_session_->http_datagram_support() != HttpDatagramSupport::kDraft00) {
- return;
- }
- // If we're in draft-ietf-masque-h3-datagram-00 mode, pretend we also received
- // a REGISTER_DATAGRAM_NO_CONTEXT capsule.
- // TODO(b/181256914) remove this when we remove support for
- // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
- RegisterHttp3DatagramContextId(
- /*context_id=*/absl::nullopt, DatagramFormatType::WEBTRANSPORT,
- /*format_additional_data=*/absl::string_view(), web_transport_.get());
+ web_transport_ =
+ std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
}
void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
@@ -1375,15 +1308,10 @@ void QuicSpdyStream::MaybeProcessSentWebTransportHeaders(
return;
}
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00) {
- headers["datagram-flow-id"] = absl::StrCat(id());
- } else {
- headers["sec-webtransport-http3-draft02"] = "1";
- }
+ headers["sec-webtransport-http3-draft02"] = "1";
- web_transport_ = std::make_unique<WebTransportHttp3>(
- spdy_session_, this, id(),
- spdy_session_->ShouldNegotiateDatagramContexts());
+ web_transport_ =
+ std::make_unique<WebTransportHttp3>(spdy_session_, this, id());
}
void QuicSpdyStream::OnCanWriteNewData() {
@@ -1443,28 +1371,12 @@ QuicSpdyStream::WebTransportDataStream::WebTransportDataStream(
: session_id(session_id),
adapter(stream->spdy_session_, stream, stream->sequencer()) {}
-void QuicSpdyStream::HandleReceivedDatagram(
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
- Http3DatagramVisitor* visitor;
- if (context_id.has_value()) {
- auto it = datagram_context_visitors_.find(context_id.value());
- if (it == datagram_context_visitors_.end()) {
- QUIC_DLOG(ERROR) << ENDPOINT
- << "Received datagram without any visitor for context "
- << context_id.value();
- return;
- }
- visitor = it->second;
- } else {
- if (datagram_no_context_visitor_ == nullptr) {
- QUIC_DLOG(ERROR)
- << ENDPOINT << "Received datagram without any visitor for no context";
- return;
- }
- visitor = datagram_no_context_visitor_;
+void QuicSpdyStream::HandleReceivedDatagram(absl::string_view payload) {
+ if (datagram_visitor_ == nullptr) {
+ QUIC_DLOG(ERROR) << ENDPOINT << "Received datagram without any visitor";
+ return;
}
- visitor->OnHttp3Datagram(id(), context_id, payload);
+ datagram_visitor_->OnHttp3Datagram(id(), payload);
}
bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
@@ -1485,65 +1397,12 @@ bool QuicSpdyStream::OnCapsule(const Capsule& capsule) {
switch (capsule.capsule_type()) {
case CapsuleType::LEGACY_DATAGRAM: {
HandleReceivedDatagram(
- capsule.legacy_datagram_capsule().context_id,
capsule.legacy_datagram_capsule().http_datagram_payload);
} break;
- case CapsuleType::DATAGRAM_WITH_CONTEXT: {
- HandleReceivedDatagram(
- capsule.datagram_with_context_capsule().context_id,
- capsule.datagram_with_context_capsule().http_datagram_payload);
- } break;
case CapsuleType::DATAGRAM_WITHOUT_CONTEXT: {
- absl::optional<QuicDatagramContextId> context_id;
- if (use_datagram_contexts_) {
- // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
- // DATAGRAM_WITHOUT_CONTEXT.
- context_id = 0;
- }
HandleReceivedDatagram(
- context_id,
capsule.datagram_without_context_capsule().http_datagram_payload);
} break;
- case CapsuleType::REGISTER_DATAGRAM_CONTEXT: {
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
- << " without any registration visitor";
- return false;
- }
- datagram_registration_visitor_->OnContextReceived(
- id(), capsule.register_datagram_context_capsule().context_id,
- capsule.register_datagram_context_capsule().format_type,
- capsule.register_datagram_context_capsule().format_additional_data);
- } break;
- case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT: {
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
- << " without any registration visitor";
- return false;
- }
- absl::optional<QuicDatagramContextId> context_id;
- if (use_datagram_contexts_) {
- // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
- // REGISTER_DATAGRAM_NO_CONTEXT.
- context_id = 0;
- }
- datagram_registration_visitor_->OnContextReceived(
- id(), context_id,
- capsule.register_datagram_no_context_capsule().format_type,
- capsule.register_datagram_no_context_capsule()
- .format_additional_data);
- } break;
- case CapsuleType::CLOSE_DATAGRAM_CONTEXT: {
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
- << " without any registration visitor";
- return false;
- }
- datagram_registration_visitor_->OnContextClosed(
- id(), capsule.close_datagram_context_capsule().context_id,
- capsule.close_datagram_context_capsule().close_code,
- capsule.close_datagram_context_capsule().close_details);
- } break;
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION: {
if (web_transport_ == nullptr) {
QUIC_DLOG(ERROR) << ENDPOINT << "Received capsule " << capsule
@@ -1588,202 +1447,50 @@ void QuicSpdyStream::WriteGreaseCapsule() {
WriteCapsule(capsule, /*fin=*/false);
}
-MessageStatus QuicSpdyStream::SendHttp3Datagram(
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
- QuicDatagramStreamId stream_id =
- datagram_flow_id_.has_value() ? datagram_flow_id_.value() : id();
- return spdy_session_->SendHttp3Datagram(stream_id, context_id, payload);
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramRegistrationVisitor(
- Http3DatagramRegistrationVisitor* visitor, bool use_datagram_contexts) {
- if (visitor == nullptr) {
- QUIC_BUG(null datagram registration visitor)
- << ENDPOINT << "Null datagram registration visitor for" << id();
- return;
- }
- if (datagram_registration_visitor_ != nullptr) {
- QUIC_BUG(double datagram registration visitor)
- << ENDPOINT << "Double datagram registration visitor for" << id();
- return;
- }
- use_datagram_contexts_ = use_datagram_contexts;
- QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram stream ID " << id()
- << " with" << (use_datagram_contexts_ ? "" : "out")
- << " contexts";
- datagram_registration_visitor_ = visitor;
- QUICHE_DCHECK(!capsule_parser_);
- capsule_parser_.reset(new CapsuleParser(this));
+MessageStatus QuicSpdyStream::SendHttp3Datagram(absl::string_view payload) {
+ return spdy_session_->SendHttp3Datagram(id(), payload);
}
-void QuicSpdyStream::UnregisterHttp3DatagramRegistrationVisitor() {
- QUIC_BUG_IF(h3 datagram unregister unknown stream ID,
- datagram_registration_visitor_ == nullptr)
- << ENDPOINT
- << "Attempted to unregister unknown HTTP/3 datagram stream ID " << id();
- QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram stream ID " << id();
- datagram_registration_visitor_ = nullptr;
-}
-
-void QuicSpdyStream::MoveHttp3DatagramRegistration(
- Http3DatagramRegistrationVisitor* visitor) {
- QUIC_BUG_IF(h3 datagram move unknown stream ID,
- datagram_registration_visitor_ == nullptr)
- << ENDPOINT << "Attempted to move unknown HTTP/3 datagram stream ID "
- << id();
- QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram stream ID " << id();
- datagram_registration_visitor_ = visitor;
-}
-
-void QuicSpdyStream::RegisterHttp3DatagramContextId(
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type, absl::string_view format_additional_data,
+void QuicSpdyStream::RegisterHttp3DatagramVisitor(
Http3DatagramVisitor* visitor) {
if (visitor == nullptr) {
QUIC_BUG(null datagram visitor)
- << ENDPOINT << "Null datagram visitor for stream ID " << id()
- << " context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none");
+ << ENDPOINT << "Null datagram visitor for stream ID " << id();
return;
}
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_BUG(context registration without registration visitor)
- << ENDPOINT << "Cannot register context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " without registration visitor for stream ID " << id();
+ QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram visitor with stream ID "
+ << id();
+
+ if (datagram_visitor_ != nullptr) {
+ QUIC_BUG(h3 datagram double registration)
+ << ENDPOINT
+ << "Attempted to doubly register HTTP/3 datagram with stream ID "
+ << id();
return;
}
- QUIC_DLOG(INFO) << ENDPOINT << "Registering datagram context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value())
- : "none")
- << " with stream ID " << id();
-
- if (context_id.has_value()) {
- if (datagram_no_context_visitor_ != nullptr) {
- QUIC_BUG(h3 datagram context ID mix1)
- << ENDPOINT
- << "Attempted to mix registrations without and with context IDs "
- "for stream ID "
- << id();
- return;
- }
- auto insertion_result =
- datagram_context_visitors_.insert({context_id.value(), visitor});
- if (!insertion_result.second) {
- QUIC_BUG(h3 datagram double context registration)
- << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
- << id() << " context ID " << context_id.value();
- return;
- }
- capsule_parser_->set_datagram_context_id_present(true);
- } else {
- // Registration without a context ID.
- if (!datagram_context_visitors_.empty()) {
- QUIC_BUG(h3 datagram context ID mix2)
- << ENDPOINT
- << "Attempted to mix registrations with and without context IDs "
- "for stream ID "
- << id();
- return;
- }
- if (datagram_no_context_visitor_ != nullptr) {
- QUIC_BUG(h3 datagram double no context registration)
- << ENDPOINT << "Attempted to doubly register HTTP/3 stream ID "
- << id() << " with no context ID";
- return;
- }
- datagram_no_context_visitor_ = visitor;
- capsule_parser_->set_datagram_context_id_present(false);
- }
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04) {
- const bool is_client = session()->perspective() == Perspective::IS_CLIENT;
- if (context_id.has_value()) {
- const bool is_client_context = context_id.value() % 2 == 0;
- if (is_client == is_client_context) {
- QuicConnection::ScopedPacketFlusher flusher(
- spdy_session_->connection());
- WriteGreaseCapsule();
- if (context_id.value() != 0) {
- WriteCapsule(Capsule::RegisterDatagramContext(
- context_id.value(), format_type, format_additional_data));
- } else {
- // draft-ietf-masque-h3-datagram-05 encodes context ID 0 using
- // REGISTER_DATAGRAM_NO_CONTEXT.
- WriteCapsule(Capsule::RegisterDatagramNoContext(
- format_type, format_additional_data));
- }
- WriteGreaseCapsule();
- }
- } else if (is_client) {
- QuicConnection::ScopedPacketFlusher flusher(spdy_session_->connection());
- WriteGreaseCapsule();
- WriteCapsule(Capsule::RegisterDatagramNoContext(format_type,
- format_additional_data));
- WriteGreaseCapsule();
- }
- }
+ datagram_visitor_ = visitor;
+ QUICHE_DCHECK(!capsule_parser_);
+ capsule_parser_ = std::make_unique<CapsuleParser>(this);
}
-void QuicSpdyStream::UnregisterHttp3DatagramContextId(
- absl::optional<QuicDatagramContextId> context_id) {
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_BUG(context unregistration without registration visitor)
- << ENDPOINT << "Cannot unregister context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " without registration visitor for stream ID " << id();
- return;
- }
- QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value())
- : "none")
- << " with stream ID " << id();
- if (context_id.has_value()) {
- size_t num_erased = datagram_context_visitors_.erase(context_id.value());
- QUIC_BUG_IF(h3 datagram unregister unknown context, num_erased != 1)
- << "Attempted to unregister unknown HTTP/3 context ID "
- << context_id.value() << " on stream ID " << id();
- } else {
- // Unregistration without a context ID.
- QUIC_BUG_IF(h3 datagram unknown context unregistration,
- datagram_no_context_visitor_ == nullptr)
- << "Attempted to unregister unknown no context on HTTP/3 stream ID "
+void QuicSpdyStream::UnregisterHttp3DatagramVisitor() {
+ if (datagram_visitor_ == nullptr) {
+ QUIC_BUG(datagram visitor empty during unregistration)
+ << ENDPOINT << "Cannot unregister datagram visitor for stream ID "
<< id();
- datagram_no_context_visitor_ = nullptr;
- }
- if (spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft04 &&
- context_id.has_value()) {
- WriteCapsule(Capsule::CloseDatagramContext(context_id.value()));
+ return;
}
+ QUIC_DLOG(INFO) << ENDPOINT << "Unregistering datagram visitor for stream ID "
+ << id();
+ datagram_visitor_ = nullptr;
}
-void QuicSpdyStream::MoveHttp3DatagramContextIdRegistration(
- absl::optional<QuicDatagramContextId> context_id,
+void QuicSpdyStream::ReplaceHttp3DatagramVisitor(
Http3DatagramVisitor* visitor) {
- if (datagram_registration_visitor_ == nullptr) {
- QUIC_BUG(context move without registration visitor)
- << ENDPOINT << "Cannot move context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " without registration visitor for stream ID " << id();
- return;
- }
- QUIC_DLOG(INFO) << ENDPOINT << "Moving datagram context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value())
- : "none")
- << " with stream ID " << id();
- if (context_id.has_value()) {
- QUIC_BUG_IF(h3 datagram move unknown context,
- !datagram_context_visitors_.contains(context_id.value()))
- << ENDPOINT << "Attempted to move unknown context ID "
- << context_id.value() << " on stream ID " << id();
- datagram_context_visitors_[context_id.value()] = visitor;
- return;
- }
- // Move without a context ID.
- QUIC_BUG_IF(h3 datagram unknown context move,
- datagram_no_context_visitor_ == nullptr)
- << "Attempted to move unknown no context on HTTP/3 stream ID " << id();
- datagram_no_context_visitor_ = visitor;
+ QUIC_BUG_IF(h3 datagram unknown move, datagram_visitor_ == nullptr)
+ << "Attempted to move missing datagram visitor on HTTP/3 stream ID "
+ << id();
+ datagram_visitor_ = visitor;
}
void QuicSpdyStream::SetMaxDatagramTimeInQueue(
@@ -1791,51 +1498,25 @@ void QuicSpdyStream::SetMaxDatagramTimeInQueue(
spdy_session_->SetMaxDatagramTimeInQueueForStreamId(id(), max_time_in_queue);
}
-QuicDatagramContextId QuicSpdyStream::GetNextDatagramContextId() {
- QuicDatagramContextId result = datagram_next_available_context_id_;
- datagram_next_available_context_id_ += kDatagramContextIdIncrement;
- return result;
-}
-
void QuicSpdyStream::OnDatagramReceived(QuicDataReader* reader) {
if (!headers_decompressed_) {
QUIC_DLOG(INFO) << "Dropping datagram received before headers on stream ID "
<< id();
return;
}
- absl::optional<QuicDatagramContextId> context_id;
- if (use_datagram_contexts_) {
- QuicDatagramContextId parsed_context_id;
- if (!reader->ReadVarInt62(&parsed_context_id)) {
- QUIC_DLOG(ERROR) << "Failed to parse context ID in received HTTP/3 "
- "datagram on stream ID "
- << id();
- return;
- }
- context_id = parsed_context_id;
- }
- absl::string_view payload = reader->ReadRemainingPayload();
- HandleReceivedDatagram(context_id, payload);
+ HandleReceivedDatagram(reader->ReadRemainingPayload());
}
-QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
- absl::optional<QuicDatagramContextId> context_id) const {
+QuicByteCount QuicSpdyStream::GetMaxDatagramSize() const {
QuicByteCount prefix_size = 0;
switch (spdy_session_->http_datagram_support()) {
- case HttpDatagramSupport::kDraft00:
- if (!datagram_flow_id_.has_value()) {
- QUIC_BUG(GetMaxDatagramSize with no flow ID)
- << "GetMaxDatagramSize() called when no flow ID available";
- break;
- }
- prefix_size = QuicDataWriter::GetVarInt62Len(*datagram_flow_id_);
- break;
case HttpDatagramSupport::kDraft04:
+ case HttpDatagramSupport::kDraft09:
prefix_size =
QuicDataWriter::GetVarInt62Len(id() / kHttpDatagramStreamIdDivisor);
break;
case HttpDatagramSupport::kNone:
- case HttpDatagramSupport::kDraft00And04:
+ case HttpDatagramSupport::kDraft04And09:
QUIC_BUG(GetMaxDatagramSize called with no datagram support)
<< "GetMaxDatagramSize() called when no HTTP/3 datagram support has "
"been negotiated. Support value: "
@@ -1847,31 +1528,17 @@ QuicByteCount QuicSpdyStream::GetMaxDatagramSize(
prefix_size = 8;
}
- if (context_id.has_value()) {
- QUIC_BUG_IF(
- context_id with draft00 in GetMaxDatagramSize,
- spdy_session_->http_datagram_support() == HttpDatagramSupport::kDraft00)
- << "GetMaxDatagramSize() called with a context ID specified, but "
- "draft00 does not support contexts.";
- prefix_size += QuicDataWriter::GetVarInt62Len(*context_id);
- }
-
QuicByteCount max_datagram_size =
session()->GetGuaranteedLargestMessagePayload();
if (max_datagram_size < prefix_size) {
QUIC_BUG(max_datagram_size smaller than prefix_size)
<< "GetGuaranteedLargestMessagePayload() returned a datagram size that "
- "is not sufficient to fit stream and/or context ID into it.";
+ "is not sufficient to fit stream ID into it.";
return 0;
}
return max_datagram_size - prefix_size;
}
-void QuicSpdyStream::RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id) {
- datagram_flow_id_ = flow_id;
- spdy_session_->RegisterHttp3DatagramFlowId(datagram_flow_id_.value(), id());
-}
-
void QuicSpdyStream::HandleBodyAvailable() {
if (!capsule_parser_) {
OnBodyAvailable();
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h
index b7fc7141d99..61cd7e36f59 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.h
@@ -129,7 +129,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
ack_listener);
// Sends |data| to the peer, or buffers if it can't be sent immediately.
- void WriteOrBufferBody(absl::string_view data, bool fin);
+ virtual void WriteOrBufferBody(absl::string_view data, bool fin);
// Writes the trailers contained in |trailer_block| on the dedicated headers
// stream or on this stream, depending on VersionUsesHttp3(). Trailers will
@@ -254,98 +254,37 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
bool OnCapsule(const Capsule& capsule) override;
void OnCapsuleParseFailure(const std::string& error_message) override;
- // Sends an HTTP/3 datagram. The stream and context IDs are not part of
- // |payload|.
- MessageStatus SendHttp3Datagram(
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload);
+ // Sends an HTTP/3 datagram. The stream ID is not part of |payload|.
+ MessageStatus SendHttp3Datagram(absl::string_view payload);
class QUIC_EXPORT_PRIVATE Http3DatagramVisitor {
public:
virtual ~Http3DatagramVisitor() {}
// Called when an HTTP/3 datagram is received. |payload| does not contain
- // the stream or context IDs. Note that this contains the stream ID even if
- // flow IDs from draft-ietf-masque-h3-datagram-00 are in use.
- virtual void OnHttp3Datagram(
- QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) = 0;
+ // the stream ID.
+ virtual void OnHttp3Datagram(QuicStreamId stream_id,
+ absl::string_view payload) = 0;
};
- class QUIC_EXPORT_PRIVATE Http3DatagramRegistrationVisitor {
- public:
- virtual ~Http3DatagramRegistrationVisitor() {}
-
- // Called when a REGISTER_DATAGRAM_CONTEXT or REGISTER_DATAGRAM_NO_CONTEXT
- // capsule is received. Note that this contains the stream ID even if flow
- // IDs from draft-ietf-masque-h3-datagram-00 are in use.
- virtual void OnContextReceived(
- QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type,
- absl::string_view format_additional_data) = 0;
-
- // Called when a CLOSE_DATAGRAM_CONTEXT capsule is received. Note that this
- // contains the stream ID even if flow IDs from
- // draft-ietf-masque-h3-datagram-00 are in use.
- virtual void OnContextClosed(
- QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code, absl::string_view close_details) = 0;
- };
+ // Registers |visitor| to receive HTTP/3 datagrams. |visitor| must be
+ // valid until a corresponding call to UnregisterHttp3DatagramVisitor.
+ void RegisterHttp3DatagramVisitor(Http3DatagramVisitor* visitor);
+
+ // Unregisters an HTTP/3 datagram visitor. Must only be called after a call to
+ // RegisterHttp3DatagramVisitor.
+ void UnregisterHttp3DatagramVisitor();
- // Registers |visitor| to receive HTTP/3 datagram context registrations. This
- // must not be called without first calling
- // UnregisterHttp3DatagramRegistrationVisitor. |visitor| must be valid until a
- // corresponding call to UnregisterHttp3DatagramRegistrationVisitor.
- void RegisterHttp3DatagramRegistrationVisitor(
- Http3DatagramRegistrationVisitor* visitor,
- bool use_datagram_contexts = false);
-
- // Unregisters for HTTP/3 datagram context registrations. Must not be called
- // unless previously registered.
- void UnregisterHttp3DatagramRegistrationVisitor();
-
- // Moves an HTTP/3 datagram registration to a different visitor. Mainly meant
- // to be used by the visitors' move operators.
- void MoveHttp3DatagramRegistration(Http3DatagramRegistrationVisitor* visitor);
-
- // Registers |visitor| to receive HTTP/3 datagrams for optional context ID
- // |context_id|. This must not be called on a previously registered context ID
- // without first calling UnregisterHttp3DatagramContextId. |visitor| must be
- // valid until a corresponding call to UnregisterHttp3DatagramContextId. If
- // this method is called multiple times, the context ID MUST either be always
- // present, or always absent.
- void RegisterHttp3DatagramContextId(
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type, absl::string_view format_additional_data,
- Http3DatagramVisitor* visitor);
-
- // Unregisters an HTTP/3 datagram context ID. Must be called on a previously
- // registered context.
- void UnregisterHttp3DatagramContextId(
- absl::optional<QuicDatagramContextId> context_id);
-
- // Moves an HTTP/3 datagram context ID to a different visitor. Mainly meant
- // to be used by the visitors' move operators.
- void MoveHttp3DatagramContextIdRegistration(
- absl::optional<QuicDatagramContextId> context_id,
- Http3DatagramVisitor* visitor);
+ // Replaces the current HTTP/3 datagram visitor with a different visitor.
+ // Mainly meant to be used by the visitors' move operators.
+ void ReplaceHttp3DatagramVisitor(Http3DatagramVisitor* visitor);
// Sets max datagram time in queue.
void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);
- // Generates a new HTTP/3 datagram context ID for this stream. A datagram
- // registration visitor must be currently registered on this stream.
- QuicDatagramContextId GetNextDatagramContextId();
-
void OnDatagramReceived(QuicDataReader* reader);
- void RegisterHttp3DatagramFlowId(QuicDatagramStreamId flow_id);
-
- QuicByteCount GetMaxDatagramSize(
- absl::optional<QuicDatagramContextId> context_id) const;
+ QuicByteCount GetMaxDatagramSize() const;
// Writes |capsule| onto the DATA stream.
void WriteCapsule(const Capsule& capsule, bool fin = false);
@@ -445,11 +384,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
void HandleBodyAvailable();
// Called when a datagram frame or capsule is received.
- void HandleReceivedDatagram(absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload);
-
- // Whether datagram contexts should be used on this stream.
- bool ShouldUseDatagramContexts() const;
+ void HandleReceivedDatagram(absl::string_view payload);
QuicSpdySession* spdy_session_;
@@ -526,13 +461,7 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream
std::unique_ptr<WebTransportDataStream> web_transport_data_;
// HTTP/3 Datagram support.
- Http3DatagramRegistrationVisitor* datagram_registration_visitor_ = nullptr;
- Http3DatagramVisitor* datagram_no_context_visitor_ = nullptr;
- absl::optional<QuicDatagramStreamId> datagram_flow_id_;
- QuicDatagramContextId datagram_next_available_context_id_;
- absl::flat_hash_map<QuicDatagramContextId, Http3DatagramVisitor*>
- datagram_context_visitors_;
- bool use_datagram_contexts_ = false;
+ Http3DatagramVisitor* datagram_visitor_ = nullptr;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc
index b0c972df366..c4526ed99ed 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc
@@ -187,6 +187,26 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
SSL* GetSsl() const override { return nullptr; }
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override {
+ return level != ENCRYPTION_ZERO_RTT;
+ }
+
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+ }
+
private:
using QuicCryptoStream::session;
@@ -979,7 +999,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
}
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
- EXPECT_CALL(*session_, SendBlocked(_));
+ EXPECT_CALL(*session_, SendBlocked(_, _));
EXPECT_CALL(*connection_, SendControlFrame(_));
stream_->WriteOrBufferBody(body, false);
@@ -1234,7 +1254,8 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
std::string body = "";
bool fin = true;
- EXPECT_CALL(*session_, SendBlocked(GetNthClientInitiatedBidirectionalId(0)))
+ EXPECT_CALL(*session_,
+ SendBlocked(GetNthClientInitiatedBidirectionalId(0), _))
.Times(0);
EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
@@ -3055,39 +3076,13 @@ TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
}
}
-TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft00) {
- if (!UsesHttp3()) {
- return;
- }
-
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_->EnableWebTransport();
- session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
- QuicSpdySessionPeer::EnableWebTransport(session_.get());
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft00);
-
- EXPECT_CALL(*stream_, WriteHeadersMock(false));
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AnyNumber());
-
- spdy::SpdyHeaderBlock headers;
- headers[":method"] = "CONNECT";
- headers[":protocol"] = "webtransport";
- headers["datagram-flow-id"] = absl::StrCat(stream_->id());
- stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
- ASSERT_TRUE(stream_->web_transport() != nullptr);
- EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeadersDatagramDraft04) {
if (!UsesHttp3()) {
return;
}
InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_->EnableWebTransport();
session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
QuicSpdySessionPeer::EnableWebTransport(session_.get());
@@ -3112,7 +3107,7 @@ TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
}
Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
session_->EnableWebTransport();
QuicSpdySessionPeer::EnableWebTransport(session_.get());
QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
@@ -3125,8 +3120,6 @@ TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
stream_->OnStreamHeadersPriority(
spdy::SpdyStreamPrecedence(kV3HighestPriority));
ProcessHeaders(false, headers_);
- stream_->OnCapsule(
- Capsule::RegisterDatagramNoContext(DatagramFormatType::WEBTRANSPORT));
EXPECT_EQ("", stream_->data());
EXPECT_FALSE(stream_->header_list().empty());
EXPECT_FALSE(stream_->IsDoneReading());
@@ -3134,278 +3127,58 @@ TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft04) {
EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
}
-TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeadersDatagramDraft00) {
- if (!UsesHttp3()) {
- return;
- }
-
- Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_->EnableWebTransport();
- QuicSpdySessionPeer::EnableWebTransport(session_.get());
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft00);
-
- headers_[":method"] = "CONNECT";
- headers_[":protocol"] = "webtransport";
- headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
-
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- ProcessHeaders(false, headers_);
- EXPECT_EQ("", stream_->data());
- EXPECT_FALSE(stream_->header_list().empty());
- EXPECT_FALSE(stream_->IsDoneReading());
- ASSERT_TRUE(stream_->web_transport() != nullptr);
- EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest,
- ProcessIncomingWebTransportHeadersWithMismatchedFlowId) {
- if (!UsesHttp3()) {
- return;
- }
- // TODO(b/181256914) Remove this test when we deprecate
- // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-
- Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- session_->EnableWebTransport();
- QuicSpdySessionPeer::EnableWebTransport(session_.get());
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft00);
-
- headers_[":method"] = "CONNECT";
- headers_[":protocol"] = "webtransport";
- headers_["datagram-flow-id"] = "2";
-
- stream_->OnStreamHeadersPriority(
- spdy::SpdyStreamPrecedence(kV3HighestPriority));
- ProcessHeaders(false, headers_);
- EXPECT_EQ("", stream_->data());
- EXPECT_FALSE(stream_->header_list().empty());
- EXPECT_FALSE(stream_->IsDoneReading());
- ASSERT_TRUE(stream_->web_transport() != nullptr);
- EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
-}
-
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdClient) {
+TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagram) {
if (!UsesHttp3()) {
return;
}
InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
- stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 0u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 2u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 4u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 6u);
- stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, GetNextDatagramContextIdServer) {
- if (!UsesHttp3()) {
- return;
- }
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_SERVER);
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor> visitor;
- stream_->RegisterHttp3DatagramRegistrationVisitor(&visitor);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 1u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 3u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 5u);
- EXPECT_EQ(stream_->GetNextDatagramContextId(), 7u);
- stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithoutContextDraft00) {
- if (!UsesHttp3()) {
- return;
- }
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft09);
QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft00);
+ HttpDatagramSupport::kDraft09);
headers_[":method"] = "CONNECT";
headers_[":protocol"] = "webtransport";
- headers_["datagram-flow-id"] = absl::StrCat(stream_->id());
ProcessHeaders(false, headers_);
- session_->RegisterHttp3DatagramFlowId(stream_->id(), stream_->id());
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor;
SavingHttp3DatagramVisitor h3_datagram_visitor;
- absl::optional<QuicDatagramContextId> context_id;
- absl::string_view format_additional_data;
ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
std::array<char, 256> datagram;
datagram[0] = stream_->id();
for (size_t i = 1; i < datagram.size(); i++) {
datagram[i] = i;
}
- stream_->RegisterHttp3DatagramRegistrationVisitor(
- &h3_datagram_registration_visitor);
- stream_->RegisterHttp3DatagramContextId(
- context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
- &h3_datagram_visitor);
- session_->OnMessageReceived(
- absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[1], datagram.size() - 1)}));
- // Test move.
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor2;
- stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
- SavingHttp3DatagramVisitor h3_datagram_visitor2;
- stream_->MoveHttp3DatagramContextIdRegistration(context_id,
- &h3_datagram_visitor2);
- EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
- session_->OnMessageReceived(
- absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[1], datagram.size() - 1)}));
- // Cleanup.
- stream_->UnregisterHttp3DatagramContextId(context_id);
- stream_->UnregisterHttp3DatagramRegistrationVisitor();
- session_->UnregisterHttp3DatagramFlowId(stream_->id());
-}
-
-TEST_P(QuicSpdyStreamTest, H3DatagramRegistrationWithoutContextDraft04) {
- if (!UsesHttp3()) {
- return;
- }
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft04);
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
- headers_[":method"] = "CONNECT";
- headers_[":protocol"] = "webtransport";
- ProcessHeaders(false, headers_);
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor;
- SavingHttp3DatagramVisitor h3_datagram_visitor;
- absl::optional<QuicDatagramContextId> context_id;
- absl::string_view format_additional_data;
- ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
- std::array<char, 256> datagram;
- datagram[0] = stream_->id();
- for (size_t i = 1; i < datagram.size(); i++) {
- datagram[i] = i;
- }
- stream_->RegisterHttp3DatagramRegistrationVisitor(
- &h3_datagram_registration_visitor);
-
- // Expect us to send a REGISTER_DATAGRAM_NO_CONTEXT capsule.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AtLeast(1));
-
- stream_->RegisterHttp3DatagramContextId(
- context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
- &h3_datagram_visitor);
- session_->OnMessageReceived(
- absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[1], datagram.size() - 1)}));
- // Test move.
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor2;
- stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
- SavingHttp3DatagramVisitor h3_datagram_visitor2;
- stream_->MoveHttp3DatagramContextIdRegistration(context_id,
- &h3_datagram_visitor2);
- EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
- session_->OnMessageReceived(
- absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[1], datagram.size() - 1)}));
- // Cleanup.
- stream_->UnregisterHttp3DatagramContextId(context_id);
- stream_->UnregisterHttp3DatagramRegistrationVisitor();
-}
-
-TEST_P(QuicSpdyStreamTest, HttpDatagramRegistrationWithContext) {
- if (!UsesHttp3()) {
- return;
- }
- InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
- QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor;
- SavingHttp3DatagramVisitor h3_datagram_visitor;
- absl::optional<QuicDatagramContextId> context_id = 42;
- absl::string_view format_additional_data;
- ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
- std::array<char, 256> datagram;
- datagram[0] = stream_->id();
- datagram[1] = context_id.value();
- for (size_t i = 2; i < datagram.size(); i++) {
- datagram[i] = i;
- }
- stream_->RegisterHttp3DatagramRegistrationVisitor(
- &h3_datagram_registration_visitor, /*use_datagram_contexts=*/true);
- headers_[":method"] = "CONNECT";
- headers_[":protocol"] = "webtransport";
- headers_["sec-use-datagram-contexts"] = "?1";
- ProcessHeaders(false, headers_);
- // Expect us to send a REGISTER_DATAGRAM_CONTEXT capsule.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AtLeast(1));
-
- stream_->RegisterHttp3DatagramContextId(
- context_id, DatagramFormatType::UDP_PAYLOAD, format_additional_data,
- &h3_datagram_visitor);
+ stream_->RegisterHttp3DatagramVisitor(&h3_datagram_visitor);
session_->OnMessageReceived(
absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[2], datagram.size() - 2)}));
+ EXPECT_THAT(
+ h3_datagram_visitor.received_h3_datagrams(),
+ ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+ stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
// Test move.
- ::testing::NiceMock<MockHttp3DatagramRegistrationVisitor>
- h3_datagram_registration_visitor2;
- stream_->MoveHttp3DatagramRegistration(&h3_datagram_registration_visitor2);
SavingHttp3DatagramVisitor h3_datagram_visitor2;
- stream_->MoveHttp3DatagramContextIdRegistration(context_id,
- &h3_datagram_visitor2);
+ stream_->ReplaceHttp3DatagramVisitor(&h3_datagram_visitor2);
EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
session_->OnMessageReceived(
absl::string_view(datagram.data(), datagram.size()));
- EXPECT_THAT(h3_datagram_visitor2.received_h3_datagrams(),
- ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
- stream_->id(), context_id,
- std::string(&datagram[2], datagram.size() - 2)}));
+ EXPECT_THAT(
+ h3_datagram_visitor2.received_h3_datagrams(),
+ ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
+ stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
// Cleanup.
-
- // Expect us to send a CLOSE_DATAGRAM_CONTEXT capsule.
- EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
- .Times(AtLeast(1));
- stream_->UnregisterHttp3DatagramContextId(context_id);
- stream_->UnregisterHttp3DatagramRegistrationVisitor();
- session_->UnregisterHttp3DatagramFlowId(stream_->id());
+ stream_->UnregisterHttp3DatagramVisitor();
}
-TEST_P(QuicSpdyStreamTest, SendHttp3Datagram) {
+TEST_P(QuicSpdyStreamTest, SendHttpDatagram) {
if (!UsesHttp3()) {
return;
}
Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft09);
QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
- absl::optional<QuicDatagramContextId> context_id;
- std::string h3_datagram_payload = {1, 2, 3, 4, 5, 6};
+ HttpDatagramSupport::kDraft09);
+ std::string http_datagram_payload = {1, 2, 3, 4, 5, 6};
EXPECT_CALL(*connection_, SendMessage(1, _, false))
.WillOnce(Return(MESSAGE_STATUS_SUCCESS));
- EXPECT_EQ(stream_->SendHttp3Datagram(context_id, h3_datagram_payload),
+ EXPECT_EQ(stream_->SendHttp3Datagram(http_datagram_payload),
MESSAGE_STATUS_SUCCESS);
}
@@ -3414,15 +3187,10 @@ TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
return;
}
Initialize(kShouldProcessData);
- session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft00And04);
+ session_->set_local_http_datagram_support(HttpDatagramSupport::kDraft09);
QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
- HttpDatagramSupport::kDraft04);
-
- QuicByteCount size = stream_->GetMaxDatagramSize(absl::nullopt);
- QuicByteCount size_with_context =
- stream_->GetMaxDatagramSize(/*context_id=*/1);
- EXPECT_GT(size, 512u);
- EXPECT_EQ(size - 1, size_with_context);
+ HttpDatagramSupport::kDraft09);
+ EXPECT_GT(stream_->GetMaxDatagramSize(), 512u);
}
TEST_P(QuicSpdyStreamTest,
@@ -3444,11 +3212,12 @@ TEST_P(QuicSpdyStreamTest,
// This private method should never be called when
// `qpack_decoded_headers_accumulator_` is nullptr. The number 1 identifies
// the site where `qpack_decoded_headers_accumulator_` was last reset.
- EXPECT_CALL(*connection_, CloseConnection(_, _, _));
- bool result = true;
- EXPECT_QUIC_BUG(result = QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_),
- "b215142466_OnHeadersFrameEnd.: 1$");
- EXPECT_FALSE(result);
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _));
+ EXPECT_FALSE(QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_));
+ },
+ "b215142466_OnHeadersFrameEnd.?: 1");
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc
index d0eac9fbde1..b8282e43127 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc
@@ -155,47 +155,6 @@ bool SpdyUtils::PopulateHeaderBlockFromUrl(const std::string url,
}
// static
-absl::optional<QuicDatagramStreamId> SpdyUtils::ParseDatagramFlowIdHeader(
- const spdy::SpdyHeaderBlock& headers) {
- auto flow_id_pair = headers.find("datagram-flow-id");
- if (flow_id_pair == headers.end()) {
- return absl::nullopt;
- }
- std::vector<absl::string_view> flow_id_strings =
- absl::StrSplit(flow_id_pair->second, ',');
- absl::optional<QuicDatagramStreamId> first_named_flow_id;
- for (absl::string_view flow_id_string : flow_id_strings) {
- std::vector<absl::string_view> flow_id_components =
- absl::StrSplit(flow_id_string, ';');
- if (flow_id_components.empty()) {
- continue;
- }
- absl::string_view flow_id_value_string = flow_id_components[0];
- quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(
- &flow_id_value_string);
- QuicDatagramStreamId flow_id;
- if (!absl::SimpleAtoi(flow_id_value_string, &flow_id)) {
- continue;
- }
- if (flow_id_components.size() == 1) {
- // This flow ID is unnamed, return this one.
- return flow_id;
- }
- // Otherwise this is a named flow ID.
- if (!first_named_flow_id.has_value()) {
- first_named_flow_id = flow_id;
- }
- }
- return first_named_flow_id;
-}
-
-// static
-void SpdyUtils::AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
- QuicDatagramStreamId flow_id) {
- (*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
-}
-
-// static
ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
const spdy::SpdyAltSvcWireFormat::AlternativeService&
alternative_service_entry,
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h
index 5654b2f1037..d88087c5436 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h
@@ -54,15 +54,6 @@ class QUIC_EXPORT_PRIVATE SpdyUtils {
static bool PopulateHeaderBlockFromUrl(const std::string url,
spdy::SpdyHeaderBlock* headers);
- // Parses the "datagram-flow-id" header, returns the flow ID on success, or
- // returns absl::nullopt if the header was not present or failed to parse.
- static absl::optional<QuicDatagramStreamId> ParseDatagramFlowIdHeader(
- const spdy::SpdyHeaderBlock& headers);
-
- // Adds the "datagram-flow-id" header.
- static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
- QuicDatagramStreamId flow_id);
-
// Returns the advertised QUIC version from the specified alternative service
// advertisement, or ParsedQuicVersion::Unsupported() if no supported version
// is advertised.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils_test.cc
index d22a0e8396e..718d54854d9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/spdy_utils_test.cc
@@ -34,14 +34,6 @@ static std::unique_ptr<QuicHeaderList> FromList(
return headers;
}
-static void ValidateDatagramFlowId(
- const std::string& header_value,
- absl::optional<QuicDatagramStreamId> expected_flow_id) {
- SpdyHeaderBlock headers;
- headers["datagram-flow-id"] = header_value;
- ASSERT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), expected_flow_id);
-}
-
} // anonymous namespace
using CopyAndValidateHeaders = QuicTest;
@@ -386,30 +378,6 @@ TEST_F(PopulateHeaderBlockFromUrl, Failure) {
SpdyUtils::PopulateHeaderBlockFromUrl("www.google.com/", &headers));
}
-using DatagramFlowIdTest = QuicTest;
-
-TEST_F(DatagramFlowIdTest, DatagramFlowId) {
- // Test missing header.
- SpdyHeaderBlock headers;
- EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), absl::nullopt);
- // Add header and verify it parses.
- QuicDatagramStreamId flow_id = 123;
- SpdyUtils::AddDatagramFlowIdHeader(&headers, flow_id);
- EXPECT_EQ(SpdyUtils::ParseDatagramFlowIdHeader(headers), flow_id);
- // Test empty header.
- ValidateDatagramFlowId("", absl::nullopt);
- // Test invalid header.
- ValidateDatagramFlowId("M4SQU3", absl::nullopt);
- // Test simple header.
- ValidateDatagramFlowId("42", 42);
- // Test with parameter.
- ValidateDatagramFlowId("42; abc=def", 42);
- // Test list.
- ValidateDatagramFlowId("42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce", 42);
- // Test reordered list.
- ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
-}
-
using ExtractQuicVersionFromAltSvcEntry = QuicTest;
TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc
index f0e38495060..a9babe80447 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc
@@ -42,8 +42,7 @@ class QUIC_NO_EXPORT NoopWebTransportVisitor : public WebTransportVisitor {
WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
QuicSpdyStream* connect_stream,
- WebTransportSessionId id,
- bool attempt_to_use_datagram_contexts)
+ WebTransportSessionId id)
: session_(session),
connect_stream_(connect_stream),
id_(id),
@@ -51,15 +50,7 @@ WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
QUICHE_DCHECK(session_->SupportsWebTransport());
QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
QUICHE_DCHECK_EQ(connect_stream_->id(), id);
- connect_stream_->RegisterHttp3DatagramRegistrationVisitor(
- this, attempt_to_use_datagram_contexts);
- if (session_->perspective() == Perspective::IS_CLIENT) {
- context_is_known_ = true;
- context_currently_registered_ = true;
- if (attempt_to_use_datagram_contexts) {
- context_id_ = connect_stream_->GetNextDatagramContextId();
- }
- }
+ connect_stream_->RegisterHttp3DatagramVisitor(this);
}
void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
@@ -87,11 +78,7 @@ void WebTransportHttp3::OnConnectStreamClosing() {
for (QuicStreamId id : streams) {
session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
}
- if (context_currently_registered_) {
- context_currently_registered_ = false;
- connect_stream_->UnregisterHttp3DatagramContextId(context_id_);
- }
- connect_stream_->UnregisterHttp3DatagramRegistrationVisitor();
+ connect_stream_->UnregisterHttp3DatagramVisitor();
MaybeNotifyClose();
}
@@ -192,7 +179,6 @@ void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
return;
}
bool should_validate_version =
- session_->http_datagram_support() != HttpDatagramSupport::kDraft00 &&
session_->ShouldValidateWebTransportVersion();
if (should_validate_version) {
auto draft_version_it = headers.find("sec-webtransport-http3-draft");
@@ -283,11 +269,11 @@ WebTransportStream* WebTransportHttp3::OpenOutgoingUnidirectionalStream() {
MessageStatus WebTransportHttp3::SendOrQueueDatagram(
quiche::QuicheMemSlice datagram) {
return connect_stream_->SendHttp3Datagram(
- context_id_, absl::string_view(datagram.data(), datagram.length()));
+ absl::string_view(datagram.data(), datagram.length()));
}
QuicByteCount WebTransportHttp3::GetMaxDatagramSize() const {
- return connect_stream_->GetMaxDatagramSize(context_id_);
+ return connect_stream_->GetMaxDatagramSize();
}
void WebTransportHttp3::SetDatagramMaxTimeInQueue(
@@ -295,88 +281,12 @@ void WebTransportHttp3::SetDatagramMaxTimeInQueue(
connect_stream_->SetMaxDatagramTimeInQueue(max_time_in_queue);
}
-void WebTransportHttp3::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
+void WebTransportHttp3::OnHttp3Datagram(QuicStreamId stream_id,
+ absl::string_view payload) {
QUICHE_DCHECK_EQ(stream_id, connect_stream_->id());
- QUICHE_DCHECK(context_id == context_id_);
visitor_->OnDatagramReceived(payload);
}
-void WebTransportHttp3::OnContextReceived(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type, absl::string_view format_additional_data) {
- if (stream_id != connect_stream_->id()) {
- QUIC_BUG(WT3 bad datagram context registration)
- << ENDPOINT << "Registered stream ID " << stream_id << ", expected "
- << connect_stream_->id();
- return;
- }
- if (format_type != DatagramFormatType::WEBTRANSPORT) {
- QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected datagram format type "
- << DatagramFormatTypeToString(format_type);
- return;
- }
- if (!format_additional_data.empty()) {
- QUIC_DLOG(ERROR)
- << ENDPOINT
- << "Received non-empty format additional data for context ID "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << connect_stream_->id();
- session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
- return;
- }
- if (!context_is_known_) {
- context_is_known_ = true;
- context_id_ = context_id;
- }
- if (context_id != context_id_) {
- QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected context ID "
- << (context_id.has_value() ? context_id.value() : 0)
- << " instead of "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << connect_stream_->id();
- return;
- }
- if (session_->perspective() == Perspective::IS_SERVER) {
- if (context_currently_registered_) {
- QUIC_DLOG(ERROR) << ENDPOINT << "Received duplicate context ID "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << connect_stream_->id();
- session_->ResetStream(connect_stream_->id(), QUIC_STREAM_CANCELLED);
- return;
- }
- context_currently_registered_ = true;
- connect_stream_->RegisterHttp3DatagramContextId(
- context_id_, format_type, format_additional_data, this);
- }
-}
-
-void WebTransportHttp3::OnContextClosed(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code, absl::string_view close_details) {
- if (stream_id != connect_stream_->id()) {
- QUIC_BUG(WT3 bad datagram context registration)
- << ENDPOINT << "Closed context on stream ID " << stream_id
- << ", expected " << connect_stream_->id();
- return;
- }
- if (context_id != context_id_) {
- QUIC_DLOG(INFO) << ENDPOINT << "Ignoring unexpected close of context ID "
- << (context_id.has_value() ? context_id.value() : 0)
- << " instead of "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << connect_stream_->id();
- return;
- }
- QUIC_DLOG(INFO) << ENDPOINT
- << "Received datagram context close with close code "
- << close_code << " close details \"" << close_details
- << "\" on stream ID " << connect_stream_->id()
- << ", resetting stream";
- session_->ResetStream(connect_stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD);
-}
-
void WebTransportHttp3::MaybeNotifyClose() {
if (close_notified_) {
return;
@@ -437,8 +347,7 @@ bool WebTransportHttp3UnidirectionalStream::ReadSessionId() {
// If all of the data has been received, and we still cannot associate the
// stream with a session, consume all of the data so that the stream can
// be closed.
- if (sequencer()->NumBytesConsumed() + sequencer()->NumBytesBuffered() >=
- sequencer()->close_offset()) {
+ if (sequencer()->IsAllDataAvailable()) {
QUIC_DLOG(WARNING)
<< ENDPOINT << "Failed to associate WebTransport stream " << id()
<< " with a session because the stream ended prematurely.";
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.h b/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.h
index 03ed764d6e8..3924a7d41f6 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.h
@@ -39,12 +39,10 @@ enum class WebTransportHttp3RejectionReason {
// <https://datatracker.ietf.org/doc/html/draft-ietf-webtrans-http3>
class QUIC_EXPORT_PRIVATE WebTransportHttp3
: public WebTransportSession,
- public QuicSpdyStream::Http3DatagramRegistrationVisitor,
public QuicSpdyStream::Http3DatagramVisitor {
public:
WebTransportHttp3(QuicSpdySession* session, QuicSpdyStream* connect_stream,
- WebTransportSessionId id,
- bool attempt_to_use_datagram_contexts);
+ WebTransportSessionId id);
void HeadersReceived(const spdy::SpdyHeaderBlock& headers);
void SetVisitor(std::unique_ptr<WebTransportVisitor> visitor) {
@@ -53,9 +51,6 @@ class QUIC_EXPORT_PRIVATE WebTransportHttp3
WebTransportSessionId id() { return id_; }
bool ready() { return ready_; }
- absl::optional<QuicDatagramContextId> context_id() const {
- return context_id_;
- }
void AssociateStream(QuicStreamId stream_id);
void OnStreamClosed(QuicStreamId stream_id) { streams_.erase(stream_id); }
@@ -91,19 +86,8 @@ class QUIC_EXPORT_PRIVATE WebTransportHttp3
// From QuicSpdyStream::Http3DatagramVisitor.
void OnHttp3Datagram(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
absl::string_view payload) override;
- // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
- void OnContextReceived(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type,
- absl::string_view format_additional_data) override;
- void OnContextClosed(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code,
- absl::string_view close_details) override;
-
bool close_received() const { return close_received_; }
WebTransportHttp3RejectionReason rejection_reason() const {
return rejection_reason_;
@@ -117,15 +101,8 @@ class QUIC_EXPORT_PRIVATE WebTransportHttp3
QuicSpdySession* const session_; // Unowned.
QuicSpdyStream* const connect_stream_; // Unowned.
const WebTransportSessionId id_;
- absl::optional<QuicDatagramContextId> context_id_;
// |ready_| is set to true when the peer has seen both sets of headers.
bool ready_ = false;
- // Whether we know which |context_id_| to use. On the client this is always
- // true, and on the server it becomes true when we receive a context
- // registration capsule.
- bool context_is_known_ = false;
- // Whether |context_id_| is currently registered with |connect_stream_|.
- bool context_currently_registered_ = false;
std::unique_ptr<WebTransportVisitor> visitor_;
absl::flat_hash_set<QuicStreamId> streams_;
quiche::QuicheCircularDeque<QuicStreamId> incoming_bidirectional_streams_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/packet_number_indexed_queue_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/packet_number_indexed_queue_test.cc
index b8a5b2af5c9..f05309beca2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/packet_number_indexed_queue_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/packet_number_indexed_queue_test.cc
@@ -11,7 +11,7 @@
#include "quiche/quic/core/quic_packet_number.h"
#include "quiche/quic/platform/api/quic_test.h"
-namespace quic {
+namespace quic::test {
namespace {
class PacketNumberIndexedQueueTest : public QuicTest {
@@ -202,4 +202,4 @@ TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h
index 4fc1029ed1f..46e75b803e7 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.h
@@ -11,7 +11,6 @@
#include "absl/container/flat_hash_map.h"
#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc
index d0386f2f2bf..d5b834df5f3 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc
@@ -7,6 +7,7 @@
#include "absl/strings/string_view.h"
#include "quiche/quic/core/qpack/qpack_static_table.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -232,7 +233,7 @@ void QpackDecoderHeaderTable::UnregisterObserver(uint64_t required_insert_count,
}
// |observer| must have been registered.
- QUIC_NOTREACHED();
+ QUICHE_NOTREACHED();
}
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h
index 212f093e715..a96424278c0 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.h
@@ -71,6 +71,9 @@ using QpackInstructionFields = std::vector<QpackInstructionField>;
// string literal type to guarantee that all bytes of the instruction are
// consumed.
struct QUIC_EXPORT_PRIVATE QpackInstruction {
+ QpackInstruction(QpackInstructionOpcode opcode, QpackInstructionFields fields)
+ : opcode(std::move(opcode)), fields(std::move(fields)) {}
+
QpackInstruction(const QpackInstruction&) = delete;
const QpackInstruction& operator=(const QpackInstruction&) = delete;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.h
index 2d8f3f1102f..8c9a764345f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.h
@@ -11,6 +11,7 @@
#include "quiche/quic/core/qpack/qpack_stream_sender_delegate.h"
#include "quiche/quic/core/quic_stream.h"
#include "quiche/quic/platform/api/quic_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -36,7 +37,7 @@ class QUIC_EXPORT_PRIVATE QpackSendStream : public QuicStream,
// The send QPACK stream is write unidirectional, so this method
// should never be called.
- void OnDataAvailable() override { QUIC_NOTREACHED(); }
+ void OnDataAvailable() override { QUICHE_NOTREACHED(); }
// Writes the instructions to peer. The stream type will be sent
// before the first instruction so that the peer can open an qpack stream.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_arena_scoped_ptr_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_arena_scoped_ptr_test.cc
index 18d4fdff8fc..fd6dd640f7c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_arena_scoped_ptr_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_arena_scoped_ptr_test.cc
@@ -7,7 +7,7 @@
#include "quiche/quic/core/quic_one_block_arena.h"
#include "quiche/quic/platform/api/quic_test.h"
-namespace quic {
+namespace quic::test {
namespace {
enum class TestParam { kFromHeap, kFromArena };
@@ -112,4 +112,4 @@ TEST_P(QuicArenaScopedPtrParamTest, Swap) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_bandwidth_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_bandwidth_test.cc
index 5f32f11f681..2d2f99471fb 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_bandwidth_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_bandwidth_test.cc
@@ -83,21 +83,21 @@ TEST_F(QuicBandwidthTest, Scale) {
}
TEST_F(QuicBandwidthTest, BytesPerPeriod) {
- EXPECT_EQ(2000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1)));
- EXPECT_EQ(2u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1)));
- EXPECT_EQ(200000u, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(100)));
- EXPECT_EQ(200u, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(100)));
+ EXPECT_EQ(2000, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+ QuicTime::Delta::FromMilliseconds(1)));
+ EXPECT_EQ(2, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+ QuicTime::Delta::FromMilliseconds(1)));
+ EXPECT_EQ(200000, QuicBandwidth::FromKBytesPerSecond(2000).ToBytesPerPeriod(
+ QuicTime::Delta::FromMilliseconds(100)));
+ EXPECT_EQ(200, QuicBandwidth::FromKBytesPerSecond(2000).ToKBytesPerPeriod(
+ QuicTime::Delta::FromMilliseconds(100)));
// 1599 * 1001 = 1600599 bits/ms = 200.074875 bytes/s.
- EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
- QuicTime::Delta::FromMilliseconds(1001)));
+ EXPECT_EQ(200, QuicBandwidth::FromBitsPerSecond(1599).ToBytesPerPeriod(
+ QuicTime::Delta::FromMilliseconds(1001)));
- EXPECT_EQ(200u, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
- QuicTime::Delta::FromSeconds(1001)));
+ EXPECT_EQ(200, QuicBandwidth::FromBitsPerSecond(1599).ToKBytesPerPeriod(
+ QuicTime::Delta::FromSeconds(1001)));
}
TEST_F(QuicBandwidthTest, TransferTime) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store.cc
index d5aa841d79a..0269cdfddd8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store.cc
@@ -6,6 +6,10 @@
#include <string>
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flags.h"
@@ -176,6 +180,39 @@ BufferedPacketList QuicBufferedPacketStore::DeliverPackets(
if (it != undecryptable_packets_.end()) {
packets_to_deliver = std::move(it->second);
undecryptable_packets_.erase(connection_id);
+ if (GetQuicReloadableFlag(quic_deliver_initial_packets_first)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_deliver_initial_packets_first);
+ std::list<BufferedPacket> initial_packets;
+ std::list<BufferedPacket> other_packets;
+ for (auto& packet : packets_to_deliver.buffered_packets) {
+ QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+ PacketHeaderFormat unused_format;
+ bool unused_version_flag;
+ bool unused_use_length_prefix;
+ QuicVersionLabel unused_version_label;
+ ParsedQuicVersion unused_parsed_version = UnsupportedQuicVersion();
+ QuicConnectionId unused_destination_connection_id;
+ QuicConnectionId unused_source_connection_id;
+ absl::optional<absl::string_view> unused_retry_token;
+ std::string unused_detailed_error;
+
+ QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+ *packet.packet, kQuicDefaultConnectionIdLength, &unused_format,
+ &long_packet_type, &unused_version_flag, &unused_use_length_prefix,
+ &unused_version_label, &unused_parsed_version,
+ &unused_destination_connection_id, &unused_source_connection_id,
+ &unused_retry_token, &unused_detailed_error);
+
+ if (error_code == QUIC_NO_ERROR && long_packet_type == INITIAL) {
+ initial_packets.push_back(std::move(packet));
+ } else {
+ other_packets.push_back(std::move(packet));
+ }
+ }
+
+ initial_packets.splice(initial_packets.end(), other_packets);
+ packets_to_deliver.buffered_packets = std::move(initial_packets);
+ }
}
return packets_to_deliver;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store_test.cc
index b6d65e1b1c9..012ae6e4fad 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_buffered_packet_store_test.cc
@@ -5,8 +5,13 @@
#include "quiche/quic/core/quic_buffered_packet_store.h"
#include <list>
+#include <memory>
#include <string>
+#include "quiche/quic/core/crypto/transport_parameters.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_test.h"
@@ -30,7 +35,14 @@ const absl::optional<ParsedClientHello> kDefaultParsedChlo =
using BufferedPacket = QuicBufferedPacketStore::BufferedPacket;
using BufferedPacketList = QuicBufferedPacketStore::BufferedPacketList;
using EnqueuePacketResult = QuicBufferedPacketStore::EnqueuePacketResult;
+using ::testing::A;
+using ::testing::Conditional;
+using ::testing::Each;
using ::testing::ElementsAre;
+using ::testing::Ne;
+using ::testing::SizeIs;
+using ::testing::Truly;
+
class QuicBufferedPacketStoreVisitor
: public QuicBufferedPacketStore::VisitorInterface {
public:
@@ -497,6 +509,94 @@ TEST_F(QuicBufferedPacketStoreTest, IngestPacketForTlsChloExtraction) {
EXPECT_FALSE(resumption_attempted);
EXPECT_FALSE(early_data_attempted);
}
+
+TEST_F(QuicBufferedPacketStoreTest, DeliverInitialPacketsFirst) {
+ QuicConfig config;
+ QuicConnectionId connection_id = TestConnectionId(1);
+
+ // Force the TLS CHLO to span multiple packets.
+ constexpr auto kCustomParameterId =
+ static_cast<TransportParameters::TransportParameterId>(0xff33);
+ std::string custom_parameter_value(2000, '-');
+ config.custom_transport_parameters_to_send()[kCustomParameterId] =
+ custom_parameter_value;
+ auto initial_packets = GetFirstFlightOfPackets(valid_version_, config);
+ ASSERT_THAT(initial_packets, SizeIs(2));
+
+ // Verify that the packets generated are INITIAL packets.
+ EXPECT_THAT(
+ initial_packets,
+ Each(Truly([](const std::unique_ptr<QuicReceivedPacket>& packet) {
+ QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+ PacketHeaderFormat unused_format;
+ bool unused_version_flag;
+ bool unused_use_length_prefix;
+ QuicVersionLabel unused_version_label;
+ ParsedQuicVersion unused_parsed_version = UnsupportedQuicVersion();
+ QuicConnectionId unused_destination_connection_id;
+ QuicConnectionId unused_source_connection_id;
+ absl::optional<absl::string_view> unused_retry_token;
+ std::string unused_detailed_error;
+ QuicErrorCode error_code = QuicFramer::ParsePublicHeaderDispatcher(
+ *packet, kQuicDefaultConnectionIdLength, &unused_format,
+ &long_packet_type, &unused_version_flag, &unused_use_length_prefix,
+ &unused_version_label, &unused_parsed_version,
+ &unused_destination_connection_id, &unused_source_connection_id,
+ &unused_retry_token, &unused_detailed_error);
+ return error_code == QUIC_NO_ERROR && long_packet_type == INITIAL;
+ })));
+
+ QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
+ PacketHeaderFormat unused_format;
+ bool unused_version_flag;
+ bool unused_use_length_prefix;
+ QuicVersionLabel unused_version_label;
+ ParsedQuicVersion unused_parsed_version = UnsupportedQuicVersion();
+ QuicConnectionId unused_destination_connection_id;
+ QuicConnectionId unused_source_connection_id;
+ absl::optional<absl::string_view> unused_retry_token;
+ std::string unused_detailed_error;
+ QuicErrorCode error_code = QUIC_NO_ERROR;
+
+ // Verify that packet_ is not an INITIAL packet.
+ error_code = QuicFramer::ParsePublicHeaderDispatcher(
+ packet_, kQuicDefaultConnectionIdLength, &unused_format,
+ &long_packet_type, &unused_version_flag, &unused_use_length_prefix,
+ &unused_version_label, &unused_parsed_version,
+ &unused_destination_connection_id, &unused_source_connection_id,
+ &unused_retry_token, &unused_detailed_error);
+ EXPECT_THAT(error_code, IsQuicNoError());
+ EXPECT_NE(long_packet_type, INITIAL);
+
+ store_.EnqueuePacket(connection_id, false, packet_, self_address_,
+ peer_address_, valid_version_, kNoParsedChlo);
+ store_.EnqueuePacket(connection_id, false, *initial_packets[0], self_address_,
+ peer_address_, valid_version_, kNoParsedChlo);
+ store_.EnqueuePacket(connection_id, false, *initial_packets[1], self_address_,
+ peer_address_, valid_version_, kNoParsedChlo);
+
+ BufferedPacketList delivered_packets = store_.DeliverPackets(connection_id);
+ EXPECT_THAT(delivered_packets.buffered_packets, SizeIs(3));
+
+ QuicLongHeaderType previous_packet_type = INITIAL;
+ for (const auto& packet : delivered_packets.buffered_packets) {
+ error_code = QuicFramer::ParsePublicHeaderDispatcher(
+ *packet.packet, kQuicDefaultConnectionIdLength, &unused_format,
+ &long_packet_type, &unused_version_flag, &unused_use_length_prefix,
+ &unused_version_label, &unused_parsed_version,
+ &unused_destination_connection_id, &unused_source_connection_id,
+ &unused_retry_token, &unused_detailed_error);
+ EXPECT_THAT(error_code, IsQuicNoError());
+
+ if (GetQuicReloadableFlag(quic_deliver_initial_packets_first)) {
+ // INITIAL packets should not follow a non-INITIAL packet.
+ EXPECT_THAT(long_packet_type,
+ Conditional(previous_packet_type == INITIAL,
+ A<QuicLongHeaderType>(), Ne(INITIAL)));
+ previous_packet_type = long_packet_type;
+ }
+ }
+}
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.cc
index 94ca72f9876..571dc599d5c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.cc
@@ -10,46 +10,8 @@
namespace quic {
-QuicClock::QuicClock()
- : is_calibrated_(false), calibration_offset_(QuicTime::Delta::Zero()) {}
-
-QuicClock::~QuicClock() {}
-
-QuicTime::Delta QuicClock::ComputeCalibrationOffset() const {
- // In the ideal world, all we need to do is to return the difference of
- // WallNow() and Now(). In the real world, things like context switch may
- // happen between the calls to WallNow() and Now(), causing their difference
- // to be arbitrarily large, so we repeat the calculation many times and use
- // the one with the minimum difference as the true offset.
- int64_t min_offset_us = std::numeric_limits<int64_t>::max();
-
- for (int i = 0; i < 128; ++i) {
- int64_t now_in_us = (Now() - QuicTime::Zero()).ToMicroseconds();
- int64_t wallnow_in_us =
- static_cast<int64_t>(WallNow().ToUNIXMicroseconds());
-
- int64_t offset_us = wallnow_in_us - now_in_us;
- if (offset_us < min_offset_us) {
- min_offset_us = offset_us;
- }
- }
-
- return QuicTime::Delta::FromMicroseconds(min_offset_us);
-}
-
-void QuicClock::SetCalibrationOffset(QuicTime::Delta offset) {
- QUICHE_DCHECK(!is_calibrated_) << "A clock should only be calibrated once";
- calibration_offset_ = offset;
- is_calibrated_ = true;
-}
-
QuicTime QuicClock::ConvertWallTimeToQuicTime(
const QuicWallTime& walltime) const {
- if (is_calibrated_) {
- int64_t time_in_us = static_cast<int64_t>(walltime.ToUNIXMicroseconds()) -
- calibration_offset_.ToMicroseconds();
- return QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_in_us);
- }
// ..........................
// | | |
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.h
index f128f9e4eef..69aed4e4d9e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_clock.h
@@ -18,25 +18,12 @@ namespace quic {
// Interface for retrieving the current time.
class QUIC_EXPORT_PRIVATE QuicClock {
public:
- QuicClock();
- virtual ~QuicClock();
+ QuicClock() = default;
+ virtual ~QuicClock() = default;
QuicClock(const QuicClock&) = delete;
QuicClock& operator=(const QuicClock&) = delete;
- // Compute the offset between this clock with the Unix Epoch clock.
- // Return the calibrated offset between WallNow() and Now(), in the form of
- // (wallnow_in_us - now_in_us).
- // The return value can be used by SetCalibrationOffset() to actually
- // calibrate the clock, or all instances of this clock type.
- QuicTime::Delta ComputeCalibrationOffset() const;
-
- // Calibrate this clock. A calibrated clock guarantees that the
- // ConvertWallTimeToQuicTime() function always return the same result for the
- // same walltime.
- // Should not be called more than once for each QuicClock.
- void SetCalibrationOffset(QuicTime::Delta offset);
-
// Returns the approximate current time as a QuicTime object.
virtual QuicTime ApproximateNow() const = 0;
@@ -57,14 +44,6 @@ class QUIC_EXPORT_PRIVATE QuicClock {
QuicTime CreateTimeFromMicroseconds(uint64_t time_us) const {
return QuicTime(time_us);
}
-
- private:
- // True if |calibration_offset_| is valid.
- bool is_calibrated_;
- // If |is_calibrated_|, |calibration_offset_| is the (fixed) offset between
- // the Unix Epoch clock and this clock.
- // In other words, the offset between WallNow() and Now().
- QuicTime::Delta calibration_offset_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.cc
index de739d6d639..92db72835af 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.cc
@@ -34,6 +34,7 @@
#include "quiche/quic/core/quic_legacy_version_encapsulator.h"
#include "quiche/quic/core/quic_packet_creator.h"
#include "quiche/quic/core/quic_packet_writer.h"
+#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_path_validator.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
@@ -127,6 +128,7 @@ class PingAlarmDelegate : public QuicConnectionAlarmDelegate {
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
+ QUICHE_DCHECK(!GetQuicReloadableFlag(quic_use_ping_manager2));
connection_->OnPingTimeout();
}
};
@@ -210,6 +212,20 @@ CongestionControlType GetDefaultCongestionControlType() {
return kCubicBytes;
}
+bool ContainsNonProbingFrame(const SerializedPacket& packet) {
+ for (const QuicFrame& frame : packet.nonretransmittable_frames) {
+ if (!QuicUtils::IsProbingFrame(frame.type)) {
+ return true;
+ }
+ }
+ for (const QuicFrame& frame : packet.retransmittable_frames) {
+ if (!QuicUtils::IsProbingFrame(frame.type)) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
#define ENDPOINT \
@@ -244,10 +260,7 @@ QuicConnection::QuicConnection(
/*stateless_reset_token=*/absl::nullopt),
active_effective_peer_migration_type_(NO_CHANGE),
support_key_update_for_connection_(false),
- last_packet_decrypted_(false),
- last_size_(0),
current_packet_data_(nullptr),
- last_decrypted_packet_level_(ENCRYPTION_INITIAL),
should_last_packet_instigate_acks_(false),
max_undecryptable_packets_(0),
max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
@@ -258,7 +271,7 @@ QuicConnection::QuicConnection(
stop_waiting_count_(0),
pending_retransmission_alarm_(false),
defer_send_in_response_to_packets_(false),
- ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
+ keep_alive_ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
initial_retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
consecutive_retransmittable_on_wire_ping_count_(0),
retransmittable_on_wire_ping_count_(0),
@@ -300,8 +313,6 @@ QuicConnection::QuicConnection(
max_consecutive_num_packets_with_no_retransmittable_frames_(
kMaxConsecutiveNonRetransmittablePackets),
bundle_retransmittable_with_pto_ack_(false),
- fill_up_link_during_probing_(false),
- probing_retransmission_pending_(false),
last_control_frame_id_(kInvalidControlFrameId),
is_path_degrading_(false),
processing_ack_frame_(false),
@@ -312,7 +323,7 @@ QuicConnection::QuicConnection(
alarm_factory_, &context_),
path_validator_(alarm_factory_, &arena_, this, random_generator_,
&context_),
- most_recent_frame_type_(NUM_FRAME_TYPES) {
+ ping_manager_(perspective, this, &arena_, alarm_factory_, &context_) {
QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT ||
default_path_.self_address.IsInitialized());
@@ -572,6 +583,16 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.HasClientRequestedIndependentOption(kFIDT, perspective_)) {
idle_network_detector_.enable_shorter_idle_timeout_on_sent_packet();
}
+ if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames()) {
+ // Only conduct those experiments in IETF QUIC because random packets may
+ // elicit reset and gQUIC PUBLIC_RESET will cause connection close.
+ if (config.HasClientRequestedIndependentOption(kROWF, perspective_)) {
+ retransmittable_on_wire_behavior_ = SEND_FIRST_FORWARD_SECURE_PACKET;
+ }
+ if (config.HasClientRequestedIndependentOption(kROWR, perspective_)) {
+ retransmittable_on_wire_behavior_ = SEND_RANDOM_BYTES;
+ }
+ }
if (config.HasClientRequestedIndependentOption(k3AFF, perspective_)) {
anti_amplification_factor_ = 3;
}
@@ -594,12 +615,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
num_rtos_for_blackhole_detection_ = 5;
}
- if (sent_packet_manager_.pto_enabled()) {
- if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
- config.HasClientSentConnectionOption(k7PTO, perspective_) ||
- config.HasClientSentConnectionOption(k8PTO, perspective_)) {
- num_rtos_for_blackhole_detection_ = 5;
- }
+ if (config.HasClientSentConnectionOption(k6PTO, perspective_) ||
+ config.HasClientSentConnectionOption(k7PTO, perspective_) ||
+ config.HasClientSentConnectionOption(k8PTO, perspective_)) {
+ num_rtos_for_blackhole_detection_ = 5;
}
if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
no_stop_waiting_frames_ = true;
@@ -628,11 +647,8 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
quic_remove_connection_migration_connection_option_v2);
}
if (framer_.version().HasIetfQuicFrames() &&
- count_bytes_on_alternative_path_separately_ &&
- GetQuicReloadableFlag(quic_server_reverse_validate_new_path3) &&
(remove_connection_migration_connection_option ||
config.HasClientSentConnectionOption(kRVCM, perspective_))) {
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 6, 6);
validate_client_addresses_ = true;
}
// Having connection_migration_use_new_cid_ depends on the same set of flags
@@ -790,14 +806,16 @@ bool QuicConnection::SelectMutualVersion(
void QuicConnection::OnError(QuicFramer* framer) {
// Packets that we can not or have not decrypted are dropped.
// TODO(rch): add stats to measure this.
- if (!connected_ || last_packet_decrypted_ == false) {
+ if (!connected_ || !last_received_packet_info_.decrypted) {
return;
}
CloseConnection(framer->error(), framer->detailed_error(),
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
-void QuicConnection::OnPacket() { last_packet_decrypted_ = false; }
+void QuicConnection::OnPacket() {
+ last_received_packet_info_.decrypted = false;
+}
void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
// Check that any public reset packet with a different connection ID that was
@@ -988,15 +1006,16 @@ bool QuicConnection::ValidateServerConnectionId(
bool QuicConnection::OnUnauthenticatedPublicHeader(
const QuicPacketHeader& header) {
- last_packet_destination_connection_id_ = header.destination_connection_id;
+ last_received_packet_info_.destination_connection_id =
+ header.destination_connection_id;
// If last packet destination connection ID is the original server
// connection ID chosen by client, replaces it with the connection ID chosen
// by server.
if (perspective_ == Perspective::IS_SERVER &&
original_destination_connection_id_.has_value() &&
- last_packet_destination_connection_id_ ==
+ last_received_packet_info_.destination_connection_id ==
*original_destination_connection_id_) {
- last_packet_destination_connection_id_ =
+ last_received_packet_info_.destination_connection_id =
original_destination_connection_id_replacement_;
}
@@ -1139,8 +1158,8 @@ void QuicConnection::OnUserAgentIdKnown(const std::string& /*user_agent_id*/) {
void QuicConnection::OnDecryptedPacket(size_t /*length*/,
EncryptionLevel level) {
- last_decrypted_packet_level_ = level;
- last_packet_decrypted_ = true;
+ last_received_packet_info_.decrypted_level = level;
+ last_received_packet_info_.decrypted = true;
if (level == ENCRYPTION_FORWARD_SECURE &&
!have_decrypted_first_one_rtt_packet_) {
have_decrypted_first_one_rtt_packet_ = true;
@@ -1156,8 +1175,7 @@ void QuicConnection::OnDecryptedPacket(size_t /*length*/,
}
}
if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
- (last_decrypted_packet_level_ == ENCRYPTION_HANDSHAKE ||
- last_decrypted_packet_level_ == ENCRYPTION_FORWARD_SECURE)) {
+ (level == ENCRYPTION_HANDSHAKE || level == ENCRYPTION_FORWARD_SECURE)) {
// Address is validated by successfully processing a HANDSHAKE or 1-RTT
// packet.
default_path_.validated = true;
@@ -1179,7 +1197,7 @@ QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPacketHeader(header, clock_->ApproximateNow(),
- last_decrypted_packet_level_);
+ last_received_packet_info_.decrypted_level);
}
// Will be decremented below if we fall through to return true.
@@ -1190,7 +1208,6 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
}
// Initialize the current packet content state.
- most_recent_frame_type_ = NUM_FRAME_TYPES;
current_packet_content_ = NO_FRAMES_RECEIVED;
is_current_packet_connectivity_probing_ = false;
has_path_challenge_in_current_packet_ = false;
@@ -1233,30 +1250,30 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
// connection ID set on path.
// 1) If client uses 1 unique server connection ID per path and the packet
// is received from an existing path, then
- // last_packet_destination_connection_id_ will always be the same as the
- // server connection ID on path. Server side will maintain the 1-to-1
- // mapping from server connection ID to path.
- // 2) If client uses multiple server connection IDs on the same path,
- // compared to the server_connection_id on path,
- // last_packet_destination_connection_id_ has the advantage that it is
- // still present in the session map since the packet can be routed here
- // regardless of packet reordering.
+ // last_received_packet_info_.destination_connection_id will always be the
+ // same as the server connection ID on path. Server side will maintain the
+ // 1-to-1 mapping from server connection ID to path. 2) If client uses
+ // multiple server connection IDs on the same path, compared to the
+ // server_connection_id on path,
+ // last_received_packet_info_.destination_connection_id has the advantage
+ // that it is still present in the session map since the packet can be
+ // routed here regardless of packet reordering.
if (IsDefaultPath(last_received_packet_info_.destination_address,
effective_peer_address)) {
default_path_.server_connection_id =
- last_packet_destination_connection_id_;
+ last_received_packet_info_.destination_connection_id;
} else if (IsAlternativePath(
last_received_packet_info_.destination_address,
effective_peer_address)) {
alternative_path_.server_connection_id =
- last_packet_destination_connection_id_;
+ last_received_packet_info_.destination_connection_id;
}
}
- if (last_packet_destination_connection_id_ !=
+ if (last_received_packet_info_.destination_connection_id !=
default_path_.server_connection_id &&
(!original_destination_connection_id_.has_value() ||
- last_packet_destination_connection_id_ !=
+ last_received_packet_info_.destination_connection_id !=
*original_destination_connection_id_)) {
QUIC_CODE_COUNT(quic_connection_id_change);
}
@@ -1271,9 +1288,10 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
--stats_.packets_dropped;
QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
- last_header_ = header;
+ last_received_packet_info_.header = header;
if (!stats_.first_decrypted_packet.IsInitialized()) {
- stats_.first_decrypted_packet = last_header_.packet_number;
+ stats_.first_decrypted_packet =
+ last_received_packet_info_.header.packet_number;
}
// Record packet receipt to populate ack info before processing stream
@@ -1283,7 +1301,8 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
receipt_time = last_received_packet_info_.receipt_time;
}
uber_received_packet_manager_.RecordPacketReceived(
- last_decrypted_packet_level_, last_header_, receipt_time);
+ last_received_packet_info_.decrypted_level,
+ last_received_packet_info_.header, receipt_time);
if (EnforceAntiAmplificationLimit() && !IsHandshakeConfirmed() &&
!header.retry_token.empty() &&
visitor_->ValidateToken(header.retry_token)) {
@@ -1298,8 +1317,9 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_3, !connected_)
- << "Processing STREAM frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing STREAM frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
// Since a stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1311,7 +1331,7 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
debug_visitor_->OnStreamFrame(frame);
}
if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
- last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
+ last_received_packet_info_.decrypted_level == ENCRYPTION_INITIAL) {
if (MaybeConsiderAsMemoryCorruption(frame)) {
CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
"Received crypto frame on non crypto stream.",
@@ -1321,7 +1341,7 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
QUIC_PEER_BUG(quic_peer_bug_10511_6)
<< ENDPOINT << "Received an unencrypted data frame: closing connection"
- << " packet_number:" << last_header_.packet_number
+ << " packet_number:" << last_received_packet_info_.header.packet_number
<< " stream_id:" << frame.stream_id
<< " received_packets:" << ack_frame();
CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
@@ -1335,14 +1355,19 @@ bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
MaybeUpdateAckTimeout();
visitor_->OnStreamFrame(frame);
stats_.stream_bytes_received += frame.data_length;
- consecutive_retransmittable_on_wire_ping_count_ = 0;
+ if (use_ping_manager_) {
+ ping_manager_.reset_consecutive_retransmittable_on_wire_count();
+ } else {
+ consecutive_retransmittable_on_wire_ping_count_ = 0;
+ }
return connected_;
}
bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_4, !connected_)
- << "Processing CRYPTO frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing CRYPTO frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
// Since a CRYPTO frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1361,8 +1386,9 @@ bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
QuicTime::Delta ack_delay_time) {
QUIC_BUG_IF(quic_bug_12714_5, !connected_)
- << "Processing ACK frame start when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing ACK frame start when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (processing_ack_frame_) {
CloseConnection(QUIC_INVALID_ACK_DATA,
@@ -1381,7 +1407,8 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
<< "OnAckFrameStart, largest_acked: " << largest_acked;
if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+ last_received_packet_info_.header.packet_number <=
+ GetLargestReceivedPacketWithAck()) {
QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
return true;
}
@@ -1393,8 +1420,8 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
<< " vs " << sent_packet_manager_.GetLargestSentPacket()
<< ". SupportsMultiplePacketNumberSpaces():"
<< SupportsMultiplePacketNumberSpaces()
- << ", last_decrypted_packet_level_:"
- << last_decrypted_packet_level_;
+ << ", last_received_packet_info_.decrypted_level:"
+ << last_received_packet_info_.decrypted_level;
// We got an ack for data we have not sent.
CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
@@ -1409,12 +1436,14 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
QUIC_BUG_IF(quic_bug_12714_6, !connected_)
- << "Processing ACK frame range when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing ACK frame range when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+ last_received_packet_info_.header.packet_number <=
+ GetLargestReceivedPacketWithAck()) {
QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
return true;
}
@@ -1426,14 +1455,15 @@ bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
QuicTime timestamp) {
QUIC_BUG_IF(quic_bug_10511_7, !connected_)
- << "Processing ACK frame time stamp when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing ACK frame time stamp when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
<< timestamp.ToDebuggingValue() << ")";
if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+ last_received_packet_info_.header.packet_number <=
+ GetLargestReceivedPacketWithAck()) {
QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
return true;
}
@@ -1444,12 +1474,14 @@ bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
QUIC_BUG_IF(quic_bug_12714_7, !connected_)
- << "Processing ACK frame end when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing ACK frame end when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
if (GetLargestReceivedPacketWithAck().IsInitialized() &&
- last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
+ last_received_packet_info_.header.packet_number <=
+ GetLargestReceivedPacketWithAck()) {
QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
return true;
}
@@ -1459,7 +1491,8 @@ bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
sent_packet_manager_.zero_rtt_packet_acked();
const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
idle_network_detector_.time_of_last_received_packet(),
- last_header_.packet_number, last_decrypted_packet_level_);
+ last_received_packet_info_.header.packet_number,
+ last_received_packet_info_.decrypted_level);
if (ack_result != PACKETS_NEWLY_ACKED &&
ack_result != NO_PACKETS_NEWLY_ACKED) {
// Error occurred (e.g., this ACK tries to ack packets in wrong packet
@@ -1488,7 +1521,8 @@ bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
// Update pace time into future because smoothed RTT is likely updated.
UpdateReleaseTimeIntoFuture();
}
- SetLargestReceivedPacketWithAck(last_header_.packet_number);
+ SetLargestReceivedPacketWithAck(
+ last_received_packet_info_.header.packet_number);
// If the incoming ack's packets set expresses missing packets: peer is still
// waiting for a packet lower than a packet that we are no longer planning to
// send.
@@ -1505,8 +1539,9 @@ bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_8, !connected_)
- << "Processing STOP_WAITING frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing STOP_WAITING frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
// Since a stop waiting frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1518,7 +1553,8 @@ bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
return true;
}
if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
- last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
+ last_received_packet_info_.header.packet_number <=
+ largest_seen_packet_with_stop_waiting_) {
QUIC_DLOG(INFO) << ENDPOINT
<< "Received an old stop waiting frame: ignoring";
return true;
@@ -1535,16 +1571,18 @@ bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
debug_visitor_->OnStopWaitingFrame(frame);
}
- largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
+ largest_seen_packet_with_stop_waiting_ =
+ last_received_packet_info_.header.packet_number;
uber_received_packet_manager_.DontWaitForPacketsBefore(
- last_decrypted_packet_level_, frame.least_unacked);
+ last_received_packet_info_.decrypted_level, frame.least_unacked);
return connected_;
}
bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_9, !connected_)
- << "Processing PADDING frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing PADDING frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(PADDING_FRAME)) {
return false;
}
@@ -1557,8 +1595,9 @@ bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_10, !connected_)
- << "Processing PING frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing PING frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(PING_FRAME)) {
return false;
}
@@ -1588,11 +1627,12 @@ const char* QuicConnection::ValidateStopWaitingFrame(
return "Least unacked too small.";
}
- if (stop_waiting.least_unacked > last_header_.packet_number) {
+ if (stop_waiting.least_unacked >
+ last_received_packet_info_.header.packet_number) {
QUIC_DLOG(ERROR) << ENDPOINT
<< "Peer sent least_unacked:" << stop_waiting.least_unacked
<< " greater than the enclosing packet number:"
- << last_header_.packet_number;
+ << last_received_packet_info_.header.packet_number;
return "Least unacked too large.";
}
@@ -1601,8 +1641,9 @@ const char* QuicConnection::ValidateStopWaitingFrame(
bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_11, !connected_)
- << "Processing RST_STREAM frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing RST_STREAM frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
// Since a reset stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1624,8 +1665,9 @@ bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_12, !connected_)
- << "Processing STOP_SENDING frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing STOP_SENDING frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
// Since a reset stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1663,9 +1705,9 @@ class ReversePathValidationContext : public QuicPathValidationContext {
bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_8, !connected_)
- << "Processing PATH_CHALLENGE frame when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing PATH_CHALLENGE frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (has_path_challenge_in_current_packet_) {
// Only respond to the 1st PATH_CHALLENGE in the packet.
return true;
@@ -1673,7 +1715,6 @@ bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
if (!validate_client_addresses_) {
return OnPathChallengeFrameInternal(frame);
}
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 1, 6);
{
// TODO(danzh) inline OnPathChallengeFrameInternal() once
// validate_client_addresses_ is deprecated.
@@ -1740,9 +1781,9 @@ bool QuicConnection::OnPathChallengeFrameInternal(
bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_9, !connected_)
- << "Processing PATH_RESPONSE frame when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing PATH_RESPONSE frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
return false;
}
@@ -1758,9 +1799,9 @@ bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
bool QuicConnection::OnConnectionCloseFrame(
const QuicConnectionCloseFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_10, !connected_)
- << "Processing CONNECTION_CLOSE frame when "
- "connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing CONNECTION_CLOSE frame when connection is closed. "
+ "Received packet info: "
+ << last_received_packet_info_;
// Since a connection close frame was received, this is not a connectivity
// probe. A probe only contains a PING and full padding.
@@ -1802,9 +1843,10 @@ bool QuicConnection::OnConnectionCloseFrame(
}
if (frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
- QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
- << " last_received_header: " << last_header_
- << " encryption_level: " << encryption_level_;
+ QUIC_LOG_FIRST_N(ERROR, 10)
+ << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
+ << " last_received_header: " << last_received_packet_info_.header
+ << " encryption_level: " << encryption_level_;
}
TearDownLocalConnectionState(frame, ConnectionCloseSource::FROM_PEER);
return connected_;
@@ -1812,8 +1854,9 @@ bool QuicConnection::OnConnectionCloseFrame(
bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_13, !connected_)
- << "Processing MAX_STREAMS frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing MAX_STREAMS frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
return false;
}
@@ -1828,9 +1871,9 @@ bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
bool QuicConnection::OnStreamsBlockedFrame(
const QuicStreamsBlockedFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_11, !connected_)
- << "Processing STREAMS_BLOCKED frame when "
- "connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing STREAMS_BLOCKED frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
return false;
}
@@ -1844,8 +1887,9 @@ bool QuicConnection::OnStreamsBlockedFrame(
bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_14, !connected_)
- << "Processing GOAWAY frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing GOAWAY frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
// Since a go away frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1867,9 +1911,9 @@ bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_12, !connected_)
- << "Processing WINDOW_UPDATE frame when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing WINDOW_UPDATE frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
// Since a window update frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -1923,29 +1967,6 @@ void QuicConnection::OnClientConnectionIdAvailable() {
}
}
-bool QuicConnection::ShouldSetRetransmissionAlarmOnPacketSent(
- bool in_flight, EncryptionLevel level) const {
- QUICHE_DCHECK(!sent_packet_manager_.simplify_set_retransmission_alarm());
- if (!retransmission_alarm_->IsSet()) {
- return true;
- }
- if (!in_flight) {
- return false;
- }
-
- if (!SupportsMultiplePacketNumberSpaces()) {
- return true;
- }
- // Before handshake gets confirmed, do not re-arm PTO timer on application
- // data. Think about this scenario: on the client side, the CHLO gets
- // acknowledged and the SHLO is not received yet. The PTO alarm is set when
- // the CHLO acknowledge is received (and there is no in flight INITIAL
- // packet). Re-arming PTO alarm on 0-RTT packet would keep postponing the PTO
- // alarm.
- return IsHandshakeConfirmed() || level == ENCRYPTION_INITIAL ||
- level == ENCRYPTION_HANDSHAKE;
-}
-
bool QuicConnection::OnNewConnectionIdFrameInner(
const QuicNewConnectionIdFrame& frame) {
if (peer_issued_cid_manager_ == nullptr) {
@@ -1974,9 +1995,9 @@ bool QuicConnection::OnNewConnectionIdFrame(
const QuicNewConnectionIdFrame& frame) {
QUICHE_DCHECK(version().HasIetfQuicFrames());
QUIC_BUG_IF(quic_bug_10511_13, !connected_)
- << "Processing NEW_CONNECTION_ID frame when "
- "connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing NEW_CONNECTION_ID frame when connection is closed. "
+ "Received packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
return false;
}
@@ -1991,9 +2012,9 @@ bool QuicConnection::OnRetireConnectionIdFrame(
const QuicRetireConnectionIdFrame& frame) {
QUICHE_DCHECK(version().HasIetfQuicFrames());
QUIC_BUG_IF(quic_bug_10511_14, !connected_)
- << "Processing RETIRE_CONNECTION_ID frame when "
- "connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing RETIRE_CONNECTION_ID frame when connection is closed. "
+ "Received packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
return false;
}
@@ -2028,8 +2049,9 @@ bool QuicConnection::OnRetireConnectionIdFrame(
bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_15, !connected_)
- << "Processing NEW_TOKEN frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing NEW_TOKEN frame when connection is closed. Received "
+ "packet info: "
+ << last_received_packet_info_;
if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
return false;
}
@@ -2050,8 +2072,9 @@ bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& frame) {
bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_16, !connected_)
- << "Processing MESSAGE frame when connection is closed. Last frame: "
- << most_recent_frame_type_;
+ << "Processing MESSAGE frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
// Since a message frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -2071,8 +2094,9 @@ bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_15, !connected_)
<< "Processing HANDSHAKE_DONE frame when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ "is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
if (!version().UsesTls()) {
CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION,
"Handshake done frame is unsupported",
@@ -2104,8 +2128,9 @@ bool QuicConnection::OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) {
bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
QUIC_BUG_IF(quic_bug_10511_16, !connected_)
<< "Processing ACK_FREQUENCY frame when connection "
- "is closed. Last frame: "
- << most_recent_frame_type_;
+ "is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
if (debug_visitor_ != nullptr) {
debug_visitor_->OnAckFrequencyFrame(frame);
}
@@ -2118,8 +2143,8 @@ bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
return false;
}
if (auto packet_number_space =
- QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_) ==
- APPLICATION_DATA) {
+ QuicUtils::GetPacketNumberSpace(
+ last_received_packet_info_.decrypted_level) == APPLICATION_DATA) {
uber_received_packet_manager_.OnAckFrequencyFrame(frame);
} else {
QUIC_LOG_EVERY_N_SEC(ERROR, 120)
@@ -2132,8 +2157,9 @@ bool QuicConnection::OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) {
bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
QUIC_BUG_IF(quic_bug_12714_17, !connected_)
- << "Processing BLOCKED frame when connection is closed. Last frame was "
- << most_recent_frame_type_;
+ << "Processing BLOCKED frame when connection is closed. Received packet "
+ "info: "
+ << last_received_packet_info_;
// Since a blocked frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
@@ -2166,11 +2192,14 @@ void QuicConnection::OnPacketComplete() {
QUIC_DVLOG(1) << ENDPOINT << "Got"
<< (SupportsMultiplePacketNumberSpaces()
- ? (" " + EncryptionLevelToString(
- last_decrypted_packet_level_))
+ ? (" " +
+ EncryptionLevelToString(
+ last_received_packet_info_.decrypted_level))
: "")
- << " packet " << last_header_.packet_number << " for "
- << GetServerConnectionIdAsRecipient(last_header_, perspective_);
+ << " packet " << last_received_packet_info_.header.packet_number
+ << " for "
+ << GetServerConnectionIdAsRecipient(
+ last_received_packet_info_.header, perspective_);
QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
<< ENDPOINT << "Received a padded PING packet. is_probing: "
@@ -2187,9 +2216,11 @@ void QuicConnection::OnPacketComplete() {
// never process a packet while an ACK for it cannot be encrypted.
if (!should_last_packet_instigate_acks_) {
uber_received_packet_manager_.MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks_, last_decrypted_packet_level_,
- last_header_.packet_number, last_received_packet_info_.receipt_time,
- clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+ should_last_packet_instigate_acks_,
+ last_received_packet_info_.decrypted_level,
+ last_received_packet_info_.header.packet_number,
+ last_received_packet_info_.receipt_time, clock_->ApproximateNow(),
+ sent_packet_manager_.GetRttStats());
}
ClearLastFrames();
@@ -2209,8 +2240,8 @@ void QuicConnection::MaybeRespondToConnectivityProbingOrMigration() {
// packet has been received anyway.
QUIC_DVLOG(1) << ENDPOINT
<< "Received a speculative connectivity probing packet for "
- << GetServerConnectionIdAsRecipient(last_header_,
- perspective_)
+ << GetServerConnectionIdAsRecipient(
+ last_received_packet_info_.header, perspective_)
<< " from ip:port: "
<< last_received_packet_info_.source_address.ToString()
<< " to ip:port: "
@@ -2318,7 +2349,8 @@ void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
sent_packet_manager_.GetLeastUnacked().ToUint64(),
", packets_processed: ", stats_.packets_processed,
", last_decrypted_packet_level: ",
- EncryptionLevelToString(last_decrypted_packet_level_)),
+ EncryptionLevelToString(
+ last_received_packet_info_.decrypted_level)),
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
}
@@ -2674,9 +2706,8 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
}
- last_received_packet_info_ =
- ReceivedPacketInfo(self_address, peer_address, packet.receipt_time());
- last_size_ = packet.length();
+ last_received_packet_info_ = ReceivedPacketInfo(
+ self_address, peer_address, packet.receipt_time(), packet.length());
current_packet_data_ = packet.data();
if (!default_path_.self_address.IsInitialized()) {
@@ -2701,16 +2732,12 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
stats_.bytes_received += packet.length();
++stats_.packets_received;
- if (!count_bytes_on_alternative_path_separately_) {
- if (EnforceAntiAmplificationLimit()) {
- default_path_.bytes_received_before_address_validation += last_size_;
- }
- } else if (IsDefaultPath(last_received_packet_info_.destination_address,
- last_received_packet_info_.source_address) &&
- EnforceAntiAmplificationLimit()) {
- QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 1, 5);
+ if (IsDefaultPath(last_received_packet_info_.destination_address,
+ last_received_packet_info_.source_address) &&
+ EnforceAntiAmplificationLimit()) {
last_received_packet_info_.received_bytes_counted = true;
- default_path_.bytes_received_before_address_validation += last_size_;
+ default_path_.bytes_received_before_address_validation +=
+ last_received_packet_info_.length;
}
// Ensure the time coming from the packet reader is within 2 minutes of now.
@@ -2731,7 +2758,7 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
// because the CHLO or SHLO packet was lost.
QUIC_DVLOG(1) << ENDPOINT
<< "Unable to process packet. Last packet processed: "
- << last_header_.packet_number;
+ << last_received_packet_info_.header.packet_number;
current_packet_data_ = nullptr;
is_current_packet_connectivity_probing_ = false;
@@ -2957,19 +2984,13 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
default_path_.self_address.ToString(),
", received packet address: ",
last_received_packet_info_.destination_address.ToString(),
- ", size: ", last_size_,
+ ", size: ", last_received_packet_info_.length,
", packet number: ", header.packet_number.ToString(),
", encryption level: ",
- EncryptionLevelToString(last_decrypted_packet_level_));
- if (GetQuicReloadableFlag(
- quic_drop_packets_with_changed_server_address)) {
- QUIC_LOG_EVERY_N_SEC(INFO, 100) << error_details;
- QUIC_CODE_COUNT(quic_dropped_packets_with_changed_server_address);
- return false;
- }
- QUIC_PEER_BUG(Server self address change) << error_details;
- CloseConnection(QUIC_ERROR_MIGRATING_ADDRESS, error_details,
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ EncryptionLevelToString(
+ last_received_packet_info_.decrypted_level));
+ QUIC_LOG_EVERY_N_SEC(INFO, 100) << error_details;
+ QUIC_CODE_COUNT(quic_dropped_packets_with_changed_server_address);
return false;
}
}
@@ -3014,17 +3035,18 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
}
}
- if (last_size_ > largest_received_packet_size_) {
- largest_received_packet_size_ = last_size_;
+ if (last_received_packet_info_.length > largest_received_packet_size_) {
+ largest_received_packet_size_ = last_received_packet_info_.length;
}
if (perspective_ == Perspective::IS_SERVER &&
encryption_level_ == ENCRYPTION_INITIAL &&
- last_size_ > packet_creator_.max_packet_length()) {
+ last_received_packet_info_.length > packet_creator_.max_packet_length()) {
if (GetQuicFlag(FLAGS_quic_use_lower_server_response_mtu_for_test)) {
- SetMaxPacketLength(std::min(last_size_, QuicByteCount(1250)));
+ SetMaxPacketLength(
+ std::min(last_received_packet_info_.length, QuicByteCount(1250)));
} else {
- SetMaxPacketLength(last_size_);
+ SetMaxPacketLength(last_received_packet_info_.length);
}
}
return true;
@@ -3035,10 +3057,11 @@ bool QuicConnection::ValidateReceivedPacketNumber(
// If this packet has already been seen, or the sender has told us that it
// will not be retransmitted, then stop processing the packet.
if (!uber_received_packet_manager_.IsAwaitingPacket(
- last_decrypted_packet_level_, packet_number)) {
+ last_received_packet_info_.decrypted_level, packet_number)) {
QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
<< " no longer being waited for at level "
- << static_cast<int>(last_decrypted_packet_level_)
+ << static_cast<int>(
+ last_received_packet_info_.decrypted_level)
<< ". Discarding.";
if (debug_visitor_ != nullptr) {
debug_visitor_->OnDuplicatePacket(packet_number);
@@ -3061,11 +3084,10 @@ void QuicConnection::WriteQueuedPackets() {
}
const BufferedPacket& packet = buffered_packets_.front();
WriteResult result = writer_->WritePacket(
- packet.encrypted_buffer.data(), packet.encrypted_buffer.length(),
- packet.self_address.host(), packet.peer_address, per_packet_options_);
+ packet.data.get(), packet.length, packet.self_address.host(),
+ packet.peer_address, per_packet_options_);
QUIC_DVLOG(1) << ENDPOINT << "Sending buffered packet, result: " << result;
- if (IsMsgTooBig(writer_, result) &&
- packet.encrypted_buffer.length() > long_term_mtu_) {
+ if (IsMsgTooBig(writer_, result) && packet.length > long_term_mtu_) {
// When MSG_TOO_BIG is returned, the system typically knows what the
// actual MTU is, so there is no need to probe further.
// TODO(wub): Reduce max packet size to a safe default, or the actual MTU.
@@ -3089,17 +3111,6 @@ void QuicConnection::WriteQueuedPackets() {
}
}
-void QuicConnection::SendProbingRetransmissions() {
- while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
- CanWrite(HAS_RETRANSMITTABLE_DATA)) {
- if (!visitor_->SendProbingData()) {
- QUIC_DVLOG(1)
- << "Cannot send probing retransmissions: nothing to retransmit.";
- break;
- }
- }
-}
-
void QuicConnection::MarkZeroRttPacketsForRetransmission(int reject_reason) {
sent_packet_manager_.MarkZeroRttPacketsForRetransmission();
if (debug_visitor_ != nullptr && version().UsesTls()) {
@@ -3143,10 +3154,6 @@ bool QuicConnection::ShouldGeneratePacket(
"generate packet.";
return false;
}
- if (!count_bytes_on_alternative_path_separately_) {
- return CanWrite(retransmittable);
- }
- QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 4, 5);
if (IsDefaultPath(default_path_.self_address,
packet_creator_.peer_address())) {
return CanWrite(retransmittable);
@@ -3360,7 +3367,18 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
WriteResult result(WRITE_STATUS_OK, encrypted_length);
QuicSocketAddress send_to_address = packet->peer_address;
// Self address is always the default self address on this code path.
- bool send_on_current_path = send_to_address == peer_address();
+ const bool send_on_current_path = send_to_address == peer_address();
+ if (!send_on_current_path && only_send_probing_frames_on_alternative_path_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_not_bundle_ack_on_alternative_path, 2, 2);
+ QUIC_BUG_IF(quic_send_non_probing_frames_on_alternative_path,
+ ContainsNonProbingFrame(*packet))
+ << "Packet " << packet->packet_number
+ << " with non-probing frames was sent on alternative path: "
+ "nonretransmittable_frames: "
+ << QuicFramesToString(packet->nonretransmittable_frames)
+ << " retransmittable_frames: "
+ << QuicFramesToString(packet->retransmittable_frames);
+ }
switch (fate) {
case DISCARD:
++stats_.packets_discarded;
@@ -3569,22 +3587,13 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
<< packet_send_time.ToDebuggingValue();
- if (!count_bytes_on_alternative_path_separately_) {
+ if (IsDefaultPath(default_path_.self_address, send_to_address)) {
if (EnforceAntiAmplificationLimit()) {
// Include bytes sent even if they are not in flight.
default_path_.bytes_sent_before_address_validation += encrypted_length;
}
} else {
- QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 2, 5);
- if (IsDefaultPath(default_path_.self_address, send_to_address)) {
- if (EnforceAntiAmplificationLimit()) {
- // Include bytes sent even if they are not in flight.
- default_path_.bytes_sent_before_address_validation += encrypted_length;
- }
- } else {
- MaybeUpdateBytesSentToAlternativeAddress(send_to_address,
- encrypted_length);
- }
+ MaybeUpdateBytesSentToAlternativeAddress(send_to_address, encrypted_length);
}
// Do not measure rtt of this packet if it's not sent on current path.
@@ -3634,13 +3643,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
return true;
}
}
- if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 1, 2);
- if (in_flight || !retransmission_alarm_->IsSet()) {
- SetRetransmissionAlarm();
- }
- } else if (ShouldSetRetransmissionAlarmOnPacketSent(
- in_flight, packet->encryption_level)) {
+ if (in_flight || !retransmission_alarm_->IsSet()) {
SetRetransmissionAlarm();
}
SetPingAlarm();
@@ -3916,6 +3919,12 @@ void QuicConnection::OnSerializedPacket(SerializedPacket serialized_packet) {
} else {
consecutive_num_packets_with_no_retransmittable_frames_ = 0;
}
+ if (retransmittable_on_wire_behavior_ == SEND_FIRST_FORWARD_SECURE_PACKET &&
+ first_serialized_one_rtt_packet_ == nullptr &&
+ serialized_packet.encryption_level == ENCRYPTION_FORWARD_SECURE) {
+ first_serialized_one_rtt_packet_ = std::make_unique<BufferedPacket>(
+ serialized_packet, self_address(), peer_address());
+ }
SendOrQueuePacket(std::move(serialized_packet));
}
@@ -4027,6 +4036,7 @@ void QuicConnection::SendOrQueuePacket(SerializedPacket packet) {
}
void QuicConnection::OnPingTimeout() {
+ QUICHE_DCHECK(!use_ping_manager_);
if (retransmission_alarm_->IsSet() ||
!visitor_->ShouldKeepConnectionAlive()) {
return;
@@ -4061,6 +4071,21 @@ void QuicConnection::SendAck() {
visitor_->OnAckNeedsRetransmittableFrame();
}
+EncryptionLevel QuicConnection::GetEncryptionLevelToSendPingForSpace(
+ PacketNumberSpace space) const {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return framer_.GetEncryptionLevelToSendApplicationData();
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+}
+
void QuicConnection::OnRetransmissionTimeout() {
ScopedRetransmissionTimeoutIndicator indicator(this);
#ifndef NDEBUG
@@ -4077,11 +4102,8 @@ void QuicConnection::OnRetransmissionTimeout() {
packet_creator_.packet_number();
const auto retransmission_mode =
sent_packet_manager_.OnRetransmissionTimeout();
- if (sent_packet_manager_.skip_packet_number_for_pto() &&
- retransmission_mode == QuicSentPacketManager::PTO_MODE &&
- sent_packet_manager_.pending_timer_transmission_count() == 1) {
- // Skip a packet number when a single PTO packet is sent to elicit an
- // immediate ACK.
+ if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
+ // Skip a packet number when PTO fires to elicit an immediate ACK.
const QuicPacketCount num_packet_numbers_to_skip = 1;
packet_creator_.SkipNPacketNumbers(
num_packet_numbers_to_skip,
@@ -4107,23 +4129,14 @@ void QuicConnection::OnRetransmissionTimeout() {
if (!connected_) {
return;
}
-
- // In the PTO and TLP cases, the SentPacketManager gives the connection the
- // opportunity to send new data before retransmitting.
- if (sent_packet_manager_.pto_enabled()) {
- sent_packet_manager_.MaybeSendProbePackets();
- } else if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
- // Send the pending retransmission now that it's been queued.
- WriteIfNotBlocked();
- }
+ // When PTO fires, the SentPacketManager gives the connection the opportunity
+ // to send new data before retransmitting.
+ sent_packet_manager_.MaybeSendProbePacket();
if (packet_creator_.packet_number() == previous_created_packet_number &&
- (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
- retransmission_mode == QuicSentPacketManager::RTO_MODE ||
- retransmission_mode == QuicSentPacketManager::PTO_MODE) &&
+ retransmission_mode == QuicSentPacketManager::PTO_MODE &&
!visitor_->WillingAndAbleToWrite()) {
- // Send PING if timer fires in TLP/RTO/PTO mode but there is no data to
- // send.
+ // Send PING if timer fires in PTO mode but there is no data to send.
QUIC_DLOG(INFO) << ENDPOINT
<< "No packet gets sent when timer fires in mode "
<< retransmission_mode << ", send PING";
@@ -4135,7 +4148,8 @@ void QuicConnection::OnRetransmissionTimeout() {
if (sent_packet_manager_
.GetEarliestPacketSentTimeForPto(&packet_number_space)
.IsInitialized()) {
- SendPingAtLevel(QuicUtils::GetEncryptionLevel(packet_number_space));
+ SendPingAtLevel(
+ GetEncryptionLevelToSendPingForSpace(packet_number_space));
} else {
// The client must PTO when there is nothing in flight if the server
// could be blocked from sending by the amplification limit
@@ -4153,13 +4167,9 @@ void QuicConnection::OnRetransmissionTimeout() {
}
}
if (retransmission_mode == QuicSentPacketManager::PTO_MODE) {
- sent_packet_manager_.AdjustPendingTimerTransmissions();
- }
- if (retransmission_mode != QuicSentPacketManager::LOSS_MODE &&
- retransmission_mode != QuicSentPacketManager::HANDSHAKE_MODE) {
- // When timer fires in TLP/RTO/PTO mode, ensure 1) at least one packet is
- // created, or there is data to send and available credit (such that
- // packets will be sent eventually).
+ // When timer fires in PTO mode, ensure 1) at least one packet is created,
+ // or there is data to send and available credit (such that packets will be
+ // sent eventually).
QUIC_BUG_IF(
quic_bug_12714_27,
packet_creator_.packet_number() == previous_created_packet_number &&
@@ -4310,14 +4320,7 @@ void QuicConnection::QueueUndecryptablePacket(
undecryptable_packets_.emplace_back(packet, decryption_level,
last_received_packet_info_);
if (perspective_ == Perspective::IS_CLIENT) {
- if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
- SetRetransmissionAlarm();
- } else if (!retransmission_alarm_->IsSet() ||
- GetRetransmissionDeadline() <
- retransmission_alarm_->deadline()) {
- // Re-arm PTO only if we can make it sooner to speed up recovery.
- SetRetransmissionAlarm();
- }
+ SetRetransmissionAlarm();
}
}
@@ -4344,7 +4347,6 @@ void QuicConnection::MaybeProcessUndecryptablePackets() {
undecryptable_packet->encryption_level);
}
last_received_packet_info_ = undecryptable_packet->packet_info;
- last_size_ = undecryptable_packet->packet->length();
current_packet_data_ = undecryptable_packet->packet->data();
const bool processed = framer_.ProcessPacket(*undecryptable_packet->packet);
current_packet_data_ = nullptr;
@@ -4382,18 +4384,7 @@ void QuicConnection::MaybeProcessUndecryptablePackets() {
undecryptable_packets_.clear();
}
if (perspective_ == Perspective::IS_CLIENT) {
- if (sent_packet_manager_.simplify_set_retransmission_alarm()) {
- SetRetransmissionAlarm();
- } else if (!retransmission_alarm_->IsSet() ||
- undecryptable_packets_.empty() ||
- GetRetransmissionDeadline() <
- retransmission_alarm_->deadline()) {
- // 1) If there is still undecryptable packet, only re-arm PTO to make it
- // sooner to speed up recovery.
- // 2) If all undecryptable packets get processed, re-arm (which may
- // postpone) PTO since no immediate recovery is needed.
- SetRetransmissionAlarm();
- }
+ SetRetransmissionAlarm();
}
}
@@ -4543,16 +4534,6 @@ void QuicConnection::SendConnectionClosePacket(
auto* frame = new QuicConnectionCloseFrame(
transport_version(), error, ietf_error, details,
framer_.current_received_frame_type());
- if (level == ENCRYPTION_FORWARD_SECURE) {
- if (connection_close_frame_sent_.has_value()) {
- QUIC_BUG(quic_send_multiple_connection_closes)
- << ENDPOINT << "Already sent connection close: "
- << connection_close_frame_sent_.value()
- << ", going to send connection close: " << *frame;
- } else {
- connection_close_frame_sent_ = *frame;
- }
- }
packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
packet_creator_.FlushCurrentPacket();
}
@@ -4605,7 +4586,11 @@ void QuicConnection::CancelAllAlarms() {
QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
ack_alarm_->PermanentCancel();
- ping_alarm_->PermanentCancel();
+ if (use_ping_manager_) {
+ ping_manager_.Stop();
+ } else {
+ ping_alarm_->PermanentCancel();
+ }
retransmission_alarm_->PermanentCancel();
send_alarm_->PermanentCancel();
mtu_discovery_alarm_->PermanentCancel();
@@ -4649,6 +4634,13 @@ void QuicConnection::SetPingAlarm() {
if (!connected_) {
return;
}
+ if (use_ping_manager_) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_use_ping_manager2);
+ ping_manager_.SetAlarm(clock_->ApproximateNow(),
+ visitor_->ShouldKeepConnectionAlive(),
+ sent_packet_manager_.HasInFlightPackets());
+ return;
+ }
if (perspective_ == Perspective::IS_SERVER &&
initial_retransmittable_on_wire_timeout_.IsInfinite()) {
// The PING alarm exists to support two features:
@@ -4670,7 +4662,7 @@ void QuicConnection::SetPingAlarm() {
GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) {
if (perspective_ == Perspective::IS_CLIENT) {
// Clients send 15s PINGs to avoid NATs from timing out.
- ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+ ping_alarm_->Update(clock_->ApproximateNow() + keep_alive_ping_timeout_,
QuicTime::Delta::FromSeconds(1));
} else {
// Servers do not send 15s PINGs.
@@ -4678,7 +4670,8 @@ void QuicConnection::SetPingAlarm() {
}
return;
}
- QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_, ping_timeout_);
+ QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_,
+ keep_alive_ping_timeout_);
QuicTime::Delta retransmittable_on_wire_timeout =
initial_retransmittable_on_wire_timeout_;
int max_aggressive_retransmittable_on_wire_ping_count =
@@ -4700,7 +4693,7 @@ void QuicConnection::SetPingAlarm() {
return;
}
- if (retransmittable_on_wire_timeout < ping_timeout_) {
+ if (retransmittable_on_wire_timeout < keep_alive_ping_timeout_) {
// Use a shorter timeout if there are open streams, but nothing on the wire.
ping_alarm_->Update(
clock_->ApproximateNow() + retransmittable_on_wire_timeout,
@@ -4712,7 +4705,7 @@ void QuicConnection::SetPingAlarm() {
return;
}
- ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
+ ping_alarm_->Update(clock_->ApproximateNow() + keep_alive_ping_timeout_,
kAlarmGranularity);
}
@@ -4736,15 +4729,13 @@ void QuicConnection::SetRetransmissionAlarm() {
return;
}
PacketNumberSpace packet_number_space;
- if (sent_packet_manager_.simplify_set_retransmission_alarm() &&
- SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
+ if (SupportsMultiplePacketNumberSpaces() && !IsHandshakeConfirmed() &&
!sent_packet_manager_
.GetEarliestPacketSentTimeForPto(&packet_number_space)
.IsInitialized()) {
// Before handshake gets confirmed, GetEarliestPacketSentTimeForPto
// returning 0 indicates no packets are in flight or only application data
// is in flight.
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_simplify_set_retransmission_alarm, 2, 2);
if (perspective_ == Perspective::IS_SERVER) {
// No need to arm PTO on server side.
retransmission_alarm_->Cancel();
@@ -4821,29 +4812,19 @@ QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
}
}
- if (connection_->flush_after_coalesce_higher_space_packets_) {
- // INITIAL or HANDSHAKE retransmission could cause peer to derive new
- // keys, such that the buffered undecryptable packets may be processed.
- // This endpoint would derive an inflated RTT sample when receiving ACKs
- // of those undecryptable packets. To mitigate this, tries to coalesce as
- // many higher space packets as possible (via for loop inside
- // MaybeCoalescePacketOfHigherSpace) to fill the remaining space in the
- // coalescer.
- QUIC_RELOADABLE_FLAG_COUNT(
- quic_flush_after_coalesce_higher_space_packets);
- if (connection_->version().CanSendCoalescedPackets()) {
- connection_->MaybeCoalescePacketOfHigherSpace();
- }
- connection_->packet_creator_.Flush();
- if (connection_->version().CanSendCoalescedPackets()) {
- connection_->FlushCoalescedPacket();
- }
- } else {
- connection_->packet_creator_.Flush();
- if (connection_->version().CanSendCoalescedPackets()) {
- connection_->MaybeCoalescePacketOfHigherSpace();
- connection_->FlushCoalescedPacket();
- }
+ // INITIAL or HANDSHAKE retransmission could cause peer to derive new
+ // keys, such that the buffered undecryptable packets may be processed.
+ // This endpoint would derive an inflated RTT sample when receiving ACKs
+ // of those undecryptable packets. To mitigate this, tries to coalesce as
+ // many higher space packets as possible (via for loop inside
+ // MaybeCoalescePacketOfHigherSpace) to fill the remaining space in the
+ // coalescer.
+ if (connection_->version().CanSendCoalescedPackets()) {
+ connection_->MaybeCoalescePacketOfHigherSpace();
+ }
+ connection_->packet_creator_.Flush();
+ if (connection_->version().CanSendCoalescedPackets()) {
+ connection_->FlushCoalescedPacket();
}
connection_->FlushPackets();
if (!handshake_packet_sent_ && connection_->handshake_packet_sent_) {
@@ -4903,21 +4884,61 @@ QuicConnection::ScopedEncryptionLevelContext::~ScopedEncryptionLevelContext() {
QuicConnection::BufferedPacket::BufferedPacket(
const SerializedPacket& packet, const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address)
- : encrypted_buffer(CopyBuffer(packet), packet.encrypted_length),
- self_address(self_address),
- peer_address(peer_address) {}
+ : BufferedPacket(packet.encrypted_buffer, packet.encrypted_length,
+ self_address, peer_address) {}
QuicConnection::BufferedPacket::BufferedPacket(
- char* encrypted_buffer, QuicPacketLength encrypted_length,
+ const char* encrypted_buffer, QuicPacketLength encrypted_length,
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address)
- : encrypted_buffer(CopyBuffer(encrypted_buffer, encrypted_length),
- encrypted_length),
+ : length(encrypted_length),
self_address(self_address),
- peer_address(peer_address) {}
+ peer_address(peer_address) {
+ data = std::make_unique<char[]>(encrypted_length);
+ memcpy(data.get(), encrypted_buffer, encrypted_length);
+}
-QuicConnection::BufferedPacket::~BufferedPacket() {
- delete[] encrypted_buffer.data();
+QuicConnection::BufferedPacket::BufferedPacket(
+ QuicRandom& random, QuicPacketLength encrypted_length,
+ const QuicSocketAddress& self_address,
+ const QuicSocketAddress& peer_address)
+ : length(encrypted_length),
+ self_address(self_address),
+ peer_address(peer_address) {
+ data = std::make_unique<char[]>(encrypted_length);
+ random.RandBytes(data.get(), encrypted_length);
+}
+
+QuicConnection::ReceivedPacketInfo::ReceivedPacketInfo(QuicTime receipt_time)
+ : receipt_time(receipt_time) {}
+QuicConnection::ReceivedPacketInfo::ReceivedPacketInfo(
+ const QuicSocketAddress& destination_address,
+ const QuicSocketAddress& source_address, QuicTime receipt_time,
+ QuicByteCount length)
+ : destination_address(destination_address),
+ source_address(source_address),
+ receipt_time(receipt_time),
+ length(length) {}
+
+std::ostream& operator<<(std::ostream& os,
+ const QuicConnection::ReceivedPacketInfo& info) {
+ os << " { destination_address: " << info.destination_address.ToString()
+ << ", source_address: " << info.source_address.ToString()
+ << ", received_bytes_counted: " << info.received_bytes_counted
+ << ", length: " << info.length
+ << ", destination_connection_id: " << info.destination_connection_id;
+ if (!info.decrypted) {
+ os << " }\n";
+ return os;
+ }
+ os << ", decrypted: " << info.decrypted
+ << ", decrypted_level: " << EncryptionLevelToString(info.decrypted_level)
+ << ", header: " << info.header << ", frames: ";
+ for (const auto frame : info.frames) {
+ os << frame;
+ }
+ os << " }\n";
+ return os;
}
HasRetransmittableData QuicConnection::IsRetransmittable(
@@ -5132,7 +5153,6 @@ void QuicConnection::OnEffectivePeerMigrationValidated() {
if (!validate_client_addresses_) {
return;
}
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 2, 6);
if (debug_visitor_ != nullptr) {
const QuicTime now = clock_->ApproximateNow();
if (now >= stats_.handshake_completion_time) {
@@ -5178,7 +5198,6 @@ void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
return;
}
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 3, 6);
if (type == NO_CHANGE) {
UpdatePeerAddress(last_received_packet_info_.source_address);
QUIC_BUG(quic_bug_10511_36)
@@ -5271,12 +5290,13 @@ void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
absl::optional<StatelessResetToken> stateless_reset_token;
FindMatchingOrNewClientConnectionIdOrToken(
previous_default_path, alternative_path_,
- last_packet_destination_connection_id_, &client_connection_id,
- &stateless_reset_token);
- SetDefaultPathState(PathState(
- last_received_packet_info_.destination_address,
- current_effective_peer_address, client_connection_id,
- last_packet_destination_connection_id_, stateless_reset_token));
+ last_received_packet_info_.destination_connection_id,
+ &client_connection_id, &stateless_reset_token);
+ SetDefaultPathState(
+ PathState(last_received_packet_info_.destination_address,
+ current_effective_peer_address, client_connection_id,
+ last_received_packet_info_.destination_connection_id,
+ stateless_reset_token));
// The path is considered validated if its peer IP address matches any
// validated path's peer IP address.
default_path_.validated =
@@ -5287,7 +5307,8 @@ void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
}
if (!last_received_packet_info_.received_bytes_counted) {
// Increment bytes counting on the new default path.
- default_path_.bytes_received_before_address_validation += last_size_;
+ default_path_.bytes_received_before_address_validation +=
+ last_received_packet_info_.length;
last_received_packet_info_.received_bytes_counted = true;
}
@@ -5389,13 +5410,14 @@ absl::string_view QuicConnection::GetCurrentPacket() {
if (current_packet_data_ == nullptr) {
return absl::string_view();
}
- return absl::string_view(current_packet_data_, last_size_);
+ return absl::string_view(current_packet_data_,
+ last_received_packet_info_.length);
}
bool QuicConnection::MaybeConsiderAsMemoryCorruption(
const QuicStreamFrame& frame) {
if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
- last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
+ last_received_packet_info_.decrypted_level != ENCRYPTION_INITIAL) {
return false;
}
@@ -5416,29 +5438,8 @@ bool QuicConnection::MaybeConsiderAsMemoryCorruption(
return false;
}
-void QuicConnection::MaybeSendProbingRetransmissions() {
- QUICHE_DCHECK(fill_up_link_during_probing_);
-
- // Don't send probing retransmissions until the handshake has completed.
- if (!IsHandshakeComplete() ||
- sent_packet_manager().HasUnackedCryptoPackets()) {
- return;
- }
-
- if (probing_retransmission_pending_) {
- QUIC_BUG(quic_bug_10511_37)
- << "MaybeSendProbingRetransmissions is called while another call "
- "to it is already in progress";
- return;
- }
-
- probing_retransmission_pending_ = true;
- SendProbingRetransmissions();
- probing_retransmission_pending_ = false;
-}
-
void QuicConnection::CheckIfApplicationLimited() {
- if (!connected_ || probing_retransmission_pending_) {
+ if (!connected_) {
return;
}
@@ -5449,18 +5450,11 @@ void QuicConnection::CheckIfApplicationLimited() {
return;
}
- if (fill_up_link_during_probing_) {
- MaybeSendProbingRetransmissions();
- if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
- return;
- }
- }
-
sent_packet_manager_.OnApplicationLimited();
}
bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
- most_recent_frame_type_ = type;
+ last_received_packet_info_.frames.push_back(type);
if (version().HasIetfQuicFrames()) {
if (!QuicUtils::IsProbingFrame(type)) {
MaybeStartIetfPeerMigration();
@@ -5468,12 +5462,10 @@ bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
}
QuicSocketAddress current_effective_peer_address =
GetEffectivePeerAddressFromCurrentPacket();
- if (!count_bytes_on_alternative_path_separately_ ||
- IsDefaultPath(last_received_packet_info_.destination_address,
+ if (IsDefaultPath(last_received_packet_info_.destination_address,
last_received_packet_info_.source_address)) {
return connected_;
}
- QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 3, 5);
if (perspective_ == Perspective::IS_SERVER &&
type == PATH_CHALLENGE_FRAME &&
!IsAlternativePath(last_received_packet_info_.destination_address,
@@ -5487,14 +5479,14 @@ bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
absl::optional<StatelessResetToken> stateless_reset_token;
FindMatchingOrNewClientConnectionIdOrToken(
default_path_, alternative_path_,
- last_packet_destination_connection_id_, &client_cid,
+ last_received_packet_info_.destination_connection_id, &client_cid,
&stateless_reset_token);
- alternative_path_ = PathState(
- last_received_packet_info_.destination_address,
- current_effective_peer_address, client_cid,
- last_packet_destination_connection_id_, stateless_reset_token);
+ alternative_path_ =
+ PathState(last_received_packet_info_.destination_address,
+ current_effective_peer_address, client_cid,
+ last_received_packet_info_.destination_connection_id,
+ stateless_reset_token);
} else if (!default_path_.validated) {
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 4, 6);
// Skip reverse path validation because either handshake hasn't
// completed or the connection is validating the default path. Using
// PATH_CHALLENGE to validate alternative client address before
@@ -5508,24 +5500,25 @@ bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
IsHandshakeConfirmed() && !alternative_path_.validated)
<< "No validated peer address to send after handshake comfirmed.";
} else if (!IsReceivedPeerAddressValidated()) {
- QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 5, 6);
QuicConnectionId client_connection_id;
absl::optional<StatelessResetToken> stateless_reset_token;
FindMatchingOrNewClientConnectionIdOrToken(
default_path_, alternative_path_,
- last_packet_destination_connection_id_, &client_connection_id,
- &stateless_reset_token);
+ last_received_packet_info_.destination_connection_id,
+ &client_connection_id, &stateless_reset_token);
// Only override alternative path state upon receiving a PATH_CHALLENGE
// from an unvalidated peer address, and the connection isn't validating
// a recent peer migration.
- alternative_path_ = PathState(
- last_received_packet_info_.destination_address,
- current_effective_peer_address, client_connection_id,
- last_packet_destination_connection_id_, stateless_reset_token);
+ alternative_path_ =
+ PathState(last_received_packet_info_.destination_address,
+ current_effective_peer_address, client_connection_id,
+ last_received_packet_info_.destination_connection_id,
+ stateless_reset_token);
should_proactively_validate_peer_address_on_path_challenge_ = true;
}
}
- MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
+ MaybeUpdateBytesReceivedFromAlternativeAddress(
+ last_received_packet_info_.length);
return connected_;
}
// Packet content is tracked to identify connectivity probe in non-IETF
@@ -5580,7 +5573,8 @@ bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
current_packet_content_ = NOT_PADDED_PING;
if (GetLargestReceivedPacket().IsInitialized() &&
- last_header_.packet_number == GetLargestReceivedPacket()) {
+ last_received_packet_info_.header.packet_number ==
+ GetLargestReceivedPacket()) {
UpdatePeerAddress(last_received_packet_info_.source_address);
if (current_effective_peer_migration_type_ != NO_CHANGE) {
// Start effective peer migration immediately when the current packet is
@@ -5613,7 +5607,8 @@ void QuicConnection::MaybeStartIetfPeerMigration() {
}
if (GetLargestReceivedPacket().IsInitialized() &&
- last_header_.packet_number == GetLargestReceivedPacket()) {
+ last_received_packet_info_.header.packet_number ==
+ GetLargestReceivedPacket()) {
if (current_effective_peer_migration_type_ != NO_CHANGE) {
// Start effective peer migration when the current packet contains a
// non-probing frame.
@@ -5634,10 +5629,10 @@ void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
bool acked_new_packet) {
if (no_stop_waiting_frames_ && !packet_creator_.has_ack()) {
uber_received_packet_manager_.DontWaitForPacketsBefore(
- last_decrypted_packet_level_,
+ last_received_packet_info_.decrypted_level,
SupportsMultiplePacketNumberSpaces()
? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
- last_decrypted_packet_level_)
+ last_received_packet_info_.decrypted_level)
: sent_packet_manager_.largest_packet_peer_knows_is_acked());
}
// Always reset the retransmission alarm when an ack comes in, since we now
@@ -5725,7 +5720,8 @@ QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
uint32_t QuicConnection::cipher_id() const {
if (version().KnowsWhichDecrypterToUse()) {
- return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
+ return framer_.GetDecrypter(last_received_packet_info_.decrypted_level)
+ ->cipher_id();
}
return framer_.decrypter()->cipher_id();
}
@@ -5824,7 +5820,8 @@ void QuicConnection::SendAllPendingAcks() {
<< PacketNumberSpaceToString(
static_cast<PacketNumberSpace>(i));
ScopedEncryptionLevelContext context(
- this, QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+ this, QuicUtils::GetEncryptionLevelToSendAckofSpace(
+ static_cast<PacketNumberSpace>(i)));
QuicFrames frames;
frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
@@ -5869,10 +5866,9 @@ bool QuicConnection::ShouldBundleRetransmittableFrameWithAck() const {
return true;
}
if (bundle_retransmittable_with_pto_ack_ &&
- (sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
- sent_packet_manager_.GetConsecutivePtoCount() > 0)) {
- // Bundle a retransmittable frame with an ACK if the PTO or RTO has fired
- // in order to recover more quickly in cases of temporary network outage.
+ sent_packet_manager_.GetConsecutivePtoCount() > 0) {
+ // Bundle a retransmittable frame with an ACK if PTO has fired in order to
+ // recover more quickly in cases of temporary network outage.
return true;
}
return false;
@@ -5884,8 +5880,7 @@ void QuicConnection::MaybeCoalescePacketOfHigherSpace() {
}
if (fill_coalesced_packet_) {
// Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant.
- QUIC_BUG_IF(quic_coalesce_packet_reentrant,
- flush_after_coalesce_higher_space_packets_);
+ QUIC_BUG(quic_coalesce_packet_reentrant);
return;
}
for (EncryptionLevel retransmission_level :
@@ -5939,11 +5934,7 @@ bool QuicConnection::FlushCoalescedPacket() {
const size_t length = packet_creator_.SerializeCoalescedPacket(
coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
if (length == 0) {
- if (packet_creator_
- .close_connection_if_fail_to_serialzie_coalesced_packet() &&
- connected_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 2, 2);
+ if (connected_) {
CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET,
"Failed to serialize coalesced packet.",
ConnectionCloseBehavior::SILENT_CLOSE);
@@ -5985,22 +5976,15 @@ bool QuicConnection::FlushCoalescedPacket() {
// Account for added padding.
if (length > coalesced_packet_.length()) {
size_t padding_size = length - coalesced_packet_.length();
- if (!count_bytes_on_alternative_path_separately_) {
+ if (IsDefaultPath(coalesced_packet_.self_address(),
+ coalesced_packet_.peer_address())) {
if (EnforceAntiAmplificationLimit()) {
+ // Include bytes sent even if they are not in flight.
default_path_.bytes_sent_before_address_validation += padding_size;
}
} else {
- QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 5, 5);
- if (IsDefaultPath(coalesced_packet_.self_address(),
- coalesced_packet_.peer_address())) {
- if (EnforceAntiAmplificationLimit()) {
- // Include bytes sent even if they are not in flight.
- default_path_.bytes_sent_before_address_validation += padding_size;
- }
- } else {
- MaybeUpdateBytesSentToAlternativeAddress(
- coalesced_packet_.peer_address(), padding_size);
- }
+ MaybeUpdateBytesSentToAlternativeAddress(coalesced_packet_.peer_address(),
+ padding_size);
}
stats_.bytes_sent += padding_size;
if (coalesced_packet_.initial_packet() != nullptr &&
@@ -6032,7 +6016,7 @@ void QuicConnection::SetLargestReceivedPacketWithAck(
QuicPacketNumber new_value) {
if (SupportsMultiplePacketNumberSpaces()) {
largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
- last_decrypted_packet_level_)] = new_value;
+ last_received_packet_info_.decrypted_level)] = new_value;
} else {
largest_seen_packet_with_ack_ = new_value;
}
@@ -6067,7 +6051,7 @@ void QuicConnection::OnForwardProgressMade() {
QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
if (SupportsMultiplePacketNumberSpaces()) {
return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
- last_decrypted_packet_level_)];
+ last_received_packet_info_.decrypted_level)];
}
return largest_seen_packet_with_ack_;
}
@@ -6075,14 +6059,14 @@ QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
if (SupportsMultiplePacketNumberSpaces()) {
return sent_packet_manager_.GetLargestAckedPacket(
- last_decrypted_packet_level_);
+ last_received_packet_info_.decrypted_level);
}
return sent_packet_manager_.GetLargestObserved();
}
QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
return uber_received_packet_manager_.GetLargestObserved(
- last_decrypted_packet_level_);
+ last_received_packet_info_.decrypted_level);
}
bool QuicConnection::EnforceAntiAmplificationLimit() const {
@@ -6148,7 +6132,8 @@ void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
const QuicAckFrame& QuicConnection::ack_frame() const {
if (SupportsMultiplePacketNumberSpaces()) {
return uber_received_packet_manager_.GetAckFrame(
- QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
+ QuicUtils::GetPacketNumberSpace(
+ last_received_packet_info_.decrypted_level));
}
return uber_received_packet_manager_.ack_frame();
}
@@ -6238,8 +6223,6 @@ void QuicConnection::OnIdleNetworkDetected() {
}
QUIC_DVLOG(1) << ENDPOINT << error_details;
const bool has_consecutive_pto =
- sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
- sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
sent_packet_manager_.GetConsecutivePtoCount() > 0;
if (has_consecutive_pto || visitor_->ShouldKeepConnectionAlive()) {
if (GetQuicReloadableFlag(quic_add_stream_info_to_idle_close_detail) &&
@@ -6263,6 +6246,64 @@ void QuicConnection::OnIdleNetworkDetected() {
idle_timeout_connection_close_behavior_);
}
+void QuicConnection::OnBandwidthUpdateTimeout() {
+ visitor_->OnBandwidthUpdateTimeout();
+}
+
+void QuicConnection::OnKeepAliveTimeout() {
+ QUICHE_DCHECK(use_ping_manager_);
+ if (retransmission_alarm_->IsSet() ||
+ !visitor_->ShouldKeepConnectionAlive()) {
+ return;
+ }
+ SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+}
+
+void QuicConnection::OnRetransmittableOnWireTimeout() {
+ QUICHE_DCHECK(use_ping_manager_);
+ if (retransmission_alarm_->IsSet() ||
+ !visitor_->ShouldKeepConnectionAlive()) {
+ return;
+ }
+ bool packet_buffered = false;
+ switch (retransmittable_on_wire_behavior_) {
+ case DEFAULT:
+ break;
+ case SEND_FIRST_FORWARD_SECURE_PACKET:
+ if (first_serialized_one_rtt_packet_ != nullptr) {
+ buffered_packets_.emplace_back(
+ first_serialized_one_rtt_packet_->data.get(),
+ first_serialized_one_rtt_packet_->length, self_address(),
+ peer_address());
+ packet_buffered = true;
+ }
+ break;
+ case SEND_RANDOM_BYTES:
+ const QuicPacketLength random_bytes_length = std::max<QuicPacketLength>(
+ QuicFramer::GetMinStatelessResetPacketLength() + 1,
+ random_generator_->RandUint64() %
+ packet_creator_.max_packet_length());
+ buffered_packets_.emplace_back(*random_generator_, random_bytes_length,
+ self_address(), peer_address());
+ packet_buffered = true;
+ break;
+ }
+ if (packet_buffered) {
+ if (!writer_->IsWriteBlocked()) {
+ WriteQueuedPackets();
+ }
+ if (connected_) {
+ // Always reset PING alarm with has_in_flight_packets=true. This is used
+ // to avoid re-arming the alarm in retransmittable-on-wire mode.
+ ping_manager_.SetAlarm(clock_->ApproximateNow(),
+ visitor_->ShouldKeepConnectionAlive(),
+ /*has_in_flight_packets=*/true);
+ }
+ return;
+ }
+ SendPingAtLevel(framer().GetEncryptionLevelToSendApplicationData());
+}
+
void QuicConnection::OnPeerIssuedConnectionIdRetired() {
QUICHE_DCHECK(peer_issued_cid_manager_ != nullptr);
QuicConnectionId* default_path_cid =
@@ -6352,9 +6393,11 @@ void QuicConnection::MaybeUpdateAckTimeout() {
}
should_last_packet_instigate_acks_ = true;
uber_received_packet_manager_.MaybeUpdateAckTimeout(
- /*should_last_packet_instigate_acks=*/true, last_decrypted_packet_level_,
- last_header_.packet_number, last_received_packet_info_.receipt_time,
- clock_->ApproximateNow(), sent_packet_manager_.GetRttStats());
+ /*should_last_packet_instigate_acks=*/true,
+ last_received_packet_info_.decrypted_level,
+ last_received_packet_info_.header.packet_number,
+ last_received_packet_info_.receipt_time, clock_->ApproximateNow(),
+ sent_packet_manager_.GetRttStats());
}
QuicTime QuicConnection::GetPathDegradingDeadline() const {
@@ -6426,28 +6469,60 @@ bool QuicConnection::SendPathChallenge(
return connected_;
}
if (connection_migration_use_new_cid_) {
- {
- QuicConnectionId client_cid, server_cid;
- FindOnPathConnectionIds(self_address, effective_peer_address, &client_cid,
- &server_cid);
+ if (!only_send_probing_frames_on_alternative_path_) {
+ {
+ QuicConnectionId client_cid, server_cid;
+ FindOnPathConnectionIds(self_address, effective_peer_address,
+ &client_cid, &server_cid);
+ QuicPacketCreator::ScopedPeerAddressContext context(
+ &packet_creator_, peer_address, client_cid, server_cid,
+ connection_migration_use_new_cid_);
+ if (writer == writer_) {
+ ScopedPacketFlusher flusher(this);
+ // It's on current path, add the PATH_CHALLENGE the same way as other
+ // frames. This may cause connection to be closed.
+ packet_creator_.AddPathChallengeFrame(data_buffer);
+ } else {
+ std::unique_ptr<SerializedPacket> probing_packet =
+ packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+ data_buffer);
+ QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
+ NO_RETRANSMITTABLE_DATA);
+ QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+ WritePacketUsingWriter(std::move(probing_packet), writer,
+ self_address, peer_address,
+ /*measure_rtt=*/false);
+ }
+ }
+ return connected_;
+ }
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_not_bundle_ack_on_alternative_path, 1, 2);
+ QuicConnectionId client_cid, server_cid;
+ FindOnPathConnectionIds(self_address, effective_peer_address, &client_cid,
+ &server_cid);
+ if (writer == writer_) {
+ ScopedPacketFlusher flusher(this);
+ {
+ QuicPacketCreator::ScopedPeerAddressContext context(
+ &packet_creator_, peer_address, client_cid, server_cid,
+ connection_migration_use_new_cid_);
+ // It's using the default writer, add the PATH_CHALLENGE the same way as
+ // other frames. This may cause connection to be closed.
+ packet_creator_.AddPathChallengeFrame(data_buffer);
+ }
+ } else {
+ // Switch to the right CID and source/peer addresses.
QuicPacketCreator::ScopedPeerAddressContext context(
&packet_creator_, peer_address, client_cid, server_cid,
connection_migration_use_new_cid_);
- if (writer == writer_) {
- ScopedPacketFlusher flusher(this);
- // It's on current path, add the PATH_CHALLENGE the same way as other
- // frames. This may cause connection to be closed.
- packet_creator_.AddPathChallengeFrame(data_buffer);
- } else {
- std::unique_ptr<SerializedPacket> probing_packet =
- packet_creator_.SerializePathChallengeConnectivityProbingPacket(
- data_buffer);
- QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
- NO_RETRANSMITTABLE_DATA);
- QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
- WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
- peer_address, /*measure_rtt=*/false);
- }
+ std::unique_ptr<SerializedPacket> probing_packet =
+ packet_creator_.SerializePathChallengeConnectivityProbingPacket(
+ data_buffer);
+ QUICHE_DCHECK_EQ(IsRetransmittable(*probing_packet),
+ NO_RETRANSMITTABLE_DATA);
+ QUICHE_DCHECK_EQ(self_address, alternative_path_.self_address);
+ WritePacketUsingWriter(std::move(probing_packet), writer, self_address,
+ peer_address, /*measure_rtt=*/false);
}
return connected_;
}
@@ -6757,11 +6832,38 @@ QuicConnectionId QuicConnection::GetOneActiveServerConnectionId() const {
std::vector<QuicConnectionId> QuicConnection::GetActiveServerConnectionIds()
const {
+ QUICHE_DCHECK_EQ(Perspective::IS_SERVER, perspective_);
+ std::vector<QuicConnectionId> result;
if (self_issued_cid_manager_ == nullptr) {
- return {default_path_.server_connection_id};
+ result.push_back(default_path_.server_connection_id);
+ } else {
+ QUICHE_DCHECK(version().HasIetfQuicFrames());
+ result = self_issued_cid_manager_->GetUnretiredConnectionIds();
}
- QUICHE_DCHECK(version().HasIetfQuicFrames());
- return self_issued_cid_manager_->GetUnretiredConnectionIds();
+ if (GetQuicReloadableFlag(
+ quic_consider_original_connection_id_as_active_pre_handshake)) {
+ QUIC_RELOADABLE_FLAG_COUNT(
+ quic_consider_original_connection_id_as_active_pre_handshake);
+ if (!IsHandshakeComplete() &&
+ original_destination_connection_id_.has_value()) {
+ // Consider original_destination_connection_id_ as active before handshake
+ // completes.
+ if (std::find(result.begin(), result.end(),
+ original_destination_connection_id_.value()) !=
+ result.end()) {
+ QUIC_BUG(quic_unexpected_original_destination_connection_id)
+ << "original_destination_connection_id: "
+ << original_destination_connection_id_.value()
+ << " is unexpectedly in active "
+ "list";
+ } else {
+ result.insert(result.end(),
+ original_destination_connection_id_.value());
+ }
+ QUIC_CODE_COUNT(quic_active_original_connection_id_pre_handshake);
+ }
+ }
+ return result;
}
void QuicConnection::CreateConnectionIdManager() {
@@ -6783,6 +6885,14 @@ void QuicConnection::CreateConnectionIdManager() {
}
}
+void QuicConnection::QuicBugIfHasPendingFrames(QuicStreamId id) const {
+ QUIC_BUG_IF(quic_has_pending_frames_unexpectedly,
+ packet_creator_.HasPendingStreamFramesOfStream(id))
+ << "Stream " << id
+ << " has pending frames unexpectedly. Received packet info: "
+ << last_received_packet_info_;
+}
+
void QuicConnection::SetUnackedMapInitialCapacity() {
sent_packet_manager_.ReserveUnackedPacketsInitialCapacity(
GetUnackedMapInitialCapacity());
@@ -6954,7 +7064,8 @@ void QuicConnection::ReversePathValidationResultDelegate::
", with active_effective_peer_migration_type_ = ",
AddressChangeTypeToString(active_effective_peer_migration_type_),
". The last received packet number ",
- connection_->last_header_.packet_number.ToString(),
+ connection_->last_received_packet_info_.header.packet_number
+ .ToString(),
" Connection is connected: ", connection_->connected_);
QUIC_BUG(quic_bug_10511_43)
<< connection_->quic_bug_10511_43_error_detail_;
@@ -7058,5 +7169,26 @@ QuicConnection::OnPeerIpAddressChanged() {
return old_send_algorithm;
}
+void QuicConnection::set_keep_alive_ping_timeout(
+ QuicTime::Delta keep_alive_ping_timeout) {
+ if (use_ping_manager_) {
+ ping_manager_.set_keep_alive_timeout(keep_alive_ping_timeout);
+ return;
+ }
+ QUICHE_DCHECK(!ping_alarm_->IsSet());
+ keep_alive_ping_timeout_ = keep_alive_ping_timeout;
+}
+
+void QuicConnection::set_initial_retransmittable_on_wire_timeout(
+ QuicTime::Delta retransmittable_on_wire_timeout) {
+ if (use_ping_manager_) {
+ ping_manager_.set_initial_retransmittable_on_wire_timeout(
+ retransmittable_on_wire_timeout);
+ return;
+ }
+ QUICHE_DCHECK(!ping_alarm_->IsSet());
+ initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
+}
+
#undef ENDPOINT // undef for jumbo builds
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.h
index 22c2c50bd9a..aab56b75837 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection.h
@@ -50,11 +50,11 @@
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_path_validator.h"
+#include "quiche/quic/core/quic_ping_manager.h"
#include "quiche/quic/core/quic_sent_packet_manager.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/uber_received_packet_manager.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
@@ -137,10 +137,6 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// Called when a blocked socket becomes writable.
virtual void OnCanWrite() = 0;
- // Called when the connection needs more data to probe for additional
- // bandwidth. Returns true if data was sent, false otherwise.
- virtual bool SendProbingData() = 0;
-
// Called when the connection experiences a change in congestion window.
virtual void OnCongestionWindowChange(QuicTime now) = 0;
@@ -238,6 +234,9 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// Whether the server address is known to the connection.
virtual bool IsKnownServerAddress(const QuicSocketAddress& address) const = 0;
+
+ // When bandwidth update alarms.
+ virtual void OnBandwidthUpdateTimeout() = 0;
};
// Interface which gets callbacks from the QuicConnection at interesting
@@ -458,7 +457,8 @@ class QUIC_EXPORT_PRIVATE QuicConnection
public QuicNetworkBlackholeDetector::Delegate,
public QuicIdleNetworkDetector::Delegate,
public QuicPathValidator::SendDelegate,
- public QuicConnectionIdManagerVisitorInterface {
+ public QuicConnectionIdManagerVisitorInterface,
+ public QuicPingManager::Delegate {
public:
// Constructs a new QuicConnection for |connection_id| and
// |initial_peer_address| using |writer| to write packets. |owns_writer|
@@ -709,6 +709,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// QuicIdleNetworkDetector::Delegate
void OnHandshakeTimeout() override;
void OnIdleNetworkDetected() override;
+ void OnBandwidthUpdateTimeout() override;
+
+ // QuicPingManager::Delegate
+ void OnKeepAliveTimeout() override;
+ void OnRetransmittableOnWireTimeout() override;
// QuicConnectionIdManagerVisitorInterface
void OnPeerIssuedConnectionIdRetired() override;
@@ -741,21 +746,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection
}
// Used in Chromium, but not internally.
// Must only be called before ping_alarm_ is set.
- void set_ping_timeout(QuicTime::Delta ping_timeout) {
- QUICHE_DCHECK(!ping_alarm_->IsSet());
- ping_timeout_ = ping_timeout;
- }
- const QuicTime::Delta ping_timeout() const { return ping_timeout_; }
+ void set_keep_alive_ping_timeout(QuicTime::Delta keep_alive_ping_timeout);
// Sets an initial timeout for the ping alarm when there is no retransmittable
// data in flight, allowing for a more aggressive ping alarm in that case.
void set_initial_retransmittable_on_wire_timeout(
- QuicTime::Delta retransmittable_on_wire_timeout) {
- QUICHE_DCHECK(!ping_alarm_->IsSet());
- initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
- }
- const QuicTime::Delta initial_retransmittable_on_wire_timeout() const {
- return initial_retransmittable_on_wire_timeout_;
- }
+ QuicTime::Delta retransmittable_on_wire_timeout);
// Used in Chromium, but not internally.
void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
packet_creator_.set_debug_delegate(visitor);
@@ -1010,20 +1005,13 @@ class QUIC_EXPORT_PRIVATE QuicConnection
EncryptionLevel encryption_level() const { return encryption_level_; }
EncryptionLevel last_decrypted_level() const {
- return last_decrypted_packet_level_;
+ return last_received_packet_info_.decrypted_level;
}
const QuicSocketAddress& last_packet_source_address() const {
return last_received_packet_info_.source_address;
}
- bool fill_up_link_during_probing() const {
- return fill_up_link_during_probing_;
- }
- void set_fill_up_link_during_probing(bool new_value) {
- fill_up_link_during_probing_ = new_value;
- }
-
// This setting may be changed during the crypto handshake in order to
// enable/disable padding of different packets in the crypto handshake.
//
@@ -1217,13 +1205,12 @@ class QUIC_EXPORT_PRIVATE QuicConnection
return connection_migration_use_new_cid_;
}
- bool count_bytes_on_alternative_path_separately() const {
- return count_bytes_on_alternative_path_separately_;
- }
-
// Instantiates connection ID manager.
void CreateConnectionIdManager();
+ // Log QUIC_BUG if there is pending frames for the stream with |id|.
+ void QuicBugIfHasPendingFrames(QuicStreamId id) const;
+
QuicConnectionContext* context() { return &context_; }
const QuicConnectionContext* context() const { return &context_; }
@@ -1295,6 +1282,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// |ietf_error| may optionally be be used to directly specify the wire
// error code. Otherwise if |ietf_error| is NO_IETF_QUIC_ERROR, the
// QuicErrorCodeToTransportErrorCode mapping of |error| will be used.
+ // Caller may choose to call SendConnectionClosePacket() directly instead of
+ // CloseConnection() to notify peer that the connection is going to be closed,
+ // for example, when the server is tearing down. Given
+ // SendConnectionClosePacket() does not close connection, multiple connection
+ // close packets could be sent to the peer.
virtual void SendConnectionClosePacket(QuicErrorCode error,
QuicIetfTransportErrorCodes ietf_error,
const std::string& details);
@@ -1302,13 +1294,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Returns true if the packet should be discarded and not sent.
virtual bool ShouldDiscardPacket(EncryptionLevel encryption_level);
- // Retransmits packets continuously until blocked by the congestion control.
- // If there are no packets to retransmit, does not do anything.
- void SendProbingRetransmissions();
-
- // Decides whether to send probing retransmissions, and does so if required.
- void MaybeSendProbingRetransmissions();
-
// Notify various components(Session etc.) that this connection has been
// migrated.
virtual void OnConnectionMigration();
@@ -1337,6 +1322,12 @@ class QUIC_EXPORT_PRIVATE QuicConnection
private:
friend class test::QuicConnectionPeer;
+ enum RetransmittableOnWireBehavior {
+ DEFAULT, // Send packet containing a PING frame.
+ SEND_FIRST_FORWARD_SECURE_PACKET, // Send 1st 1-RTT packet.
+ SEND_RANDOM_BYTES // Send random bytes which is an unprocessable packet.
+ };
+
struct QUIC_EXPORT_PRIVATE PendingPathChallenge {
QuicPathFrameBuffer received_path_challenge;
QuicSocketAddress peer_address;
@@ -1394,40 +1385,52 @@ class QUIC_EXPORT_PRIVATE QuicConnection
BufferedPacket(const SerializedPacket& packet,
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address);
- BufferedPacket(char* encrypted_buffer, QuicPacketLength encrypted_length,
+ BufferedPacket(const char* encrypted_buffer,
+ QuicPacketLength encrypted_length,
+ const QuicSocketAddress& self_address,
+ const QuicSocketAddress& peer_address);
+ // Please note, this buffered packet contains random bytes (and is not
+ // *actually* a QUIC packet).
+ BufferedPacket(QuicRandom& random, QuicPacketLength encrypted_length,
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address);
BufferedPacket(const BufferedPacket& other) = delete;
BufferedPacket(const BufferedPacket&& other) = delete;
- ~BufferedPacket();
+ ~BufferedPacket() = default;
- // encrypted_buffer is owned by buffered packet.
- absl::string_view encrypted_buffer;
+ std::unique_ptr<char[]> data;
+ const QuicPacketLength length;
// Self and peer addresses when the packet is serialized.
const QuicSocketAddress self_address;
const QuicSocketAddress peer_address;
};
- // ReceivedPacketInfo comprises the received packet information, which can be
- // retrieved before the packet gets successfully decrypted.
+ // ReceivedPacketInfo comprises the received packet information.
+ // TODO(fayang): move more fields to ReceivedPacketInfo.
struct QUIC_EXPORT_PRIVATE ReceivedPacketInfo {
- explicit ReceivedPacketInfo(QuicTime receipt_time)
- : received_bytes_counted(false), receipt_time(receipt_time) {}
+ explicit ReceivedPacketInfo(QuicTime receipt_time);
ReceivedPacketInfo(const QuicSocketAddress& destination_address,
const QuicSocketAddress& source_address,
- QuicTime receipt_time)
- : received_bytes_counted(false),
- destination_address(destination_address),
- source_address(source_address),
- receipt_time(receipt_time) {}
+ QuicTime receipt_time, QuicByteCount length);
- bool received_bytes_counted;
QuicSocketAddress destination_address;
QuicSocketAddress source_address;
- QuicTime receipt_time;
+ QuicTime receipt_time = QuicTime::Zero();
+ bool received_bytes_counted = false;
+ QuicByteCount length = 0;
+ QuicConnectionId destination_connection_id;
+ // Fields below are only populated if packet gets decrypted successfully.
+ // TODO(fayang): consider using absl::optional for following fields.
+ bool decrypted = false;
+ EncryptionLevel decrypted_level = ENCRYPTION_INITIAL;
+ QuicPacketHeader header;
+ absl::InlinedVector<QuicFrameType, 1> frames;
};
+ QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const QuicConnection::ReceivedPacketInfo& info);
+
// UndecrytablePacket comprises a undecryptable packet and related
// information.
struct QUIC_EXPORT_PRIVATE UndecryptablePacket {
@@ -1837,10 +1840,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// when a new client connection ID is received.
void OnClientConnectionIdAvailable();
- // Returns true if connection needs to set retransmission alarm after a packet
- // gets sent.
- bool ShouldSetRetransmissionAlarmOnPacketSent(bool in_flight,
- EncryptionLevel level) const;
+ // Determines encryption level to send ping in `packet_number_space`.
+ EncryptionLevel GetEncryptionLevelToSendPingForSpace(
+ PacketNumberSpace space) const;
QuicConnectionContext context_;
@@ -1905,15 +1907,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// key update but before the first packet has been sent.
QuicPacketNumber lowest_packet_sent_in_current_key_phase_;
- // True if the last packet has gotten far enough in the framer to be
- // decrypted.
- bool last_packet_decrypted_;
- QuicByteCount last_size_; // Size of the last received packet.
// TODO(rch): remove this when b/27221014 is fixed.
const char* current_packet_data_; // UDP payload of packet currently being
// parsed or nullptr.
- EncryptionLevel last_decrypted_packet_level_;
- QuicPacketHeader last_header_;
bool should_last_packet_instigate_acks_;
// Track some peer state so we can do less bookkeeping
@@ -1975,8 +1971,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// SendAlarm.
bool defer_send_in_response_to_packets_;
- // The timeout for PING.
- QuicTime::Delta ping_timeout_;
+ // TODO(fayang): remove PING related fields below when deprecating
+ // quic_use_ping_manager2.
+ // The timeout for keep-alive PING.
+ QuicTime::Delta keep_alive_ping_timeout_;
// Initial timeout for how long the wire can have no retransmittable packets.
QuicTime::Delta initial_retransmittable_on_wire_timeout_;
@@ -1998,6 +1996,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// An alarm that is scheduled when the SentPacketManager requires a delay
// before sending packets and fires when the packet may be sent.
QuicArenaScopedPtr<QuicAlarm> send_alarm_;
+ // TODO(fayang): remove ping_alarm_ when deprecating quic_use_ping_manager2.
// An alarm that fires when a ping should be sent.
QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
// An alarm that fires when an MTU probe should be sent.
@@ -2038,12 +2037,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// close.
bool connected_;
- // Destination connection ID of the last received packet. If this ID is the
- // original server connection ID chosen by client and server replaces it with
- // a different ID, last_packet_destination_connection_id_ is set to the
- // replacement connection ID on the server side.
- QuicConnectionId last_packet_destination_connection_id_;
-
// Set to false if the connection should not send truncated connection IDs to
// the peer, even if the peer supports it.
bool can_truncate_connection_ids_;
@@ -2091,22 +2084,10 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// from the peer. Default to kMaxConsecutiveNonRetransmittablePackets.
size_t max_consecutive_num_packets_with_no_retransmittable_frames_;
- // If true, bundle an ack-eliciting frame with an ACK if the PTO or RTO alarm
- // have previously fired.
+ // If true, bundle an ack-eliciting frame with an ACK if the PTO alarm have
+ // previously fired.
bool bundle_retransmittable_with_pto_ack_;
- // If true, the connection will fill up the pipe with extra data whenever the
- // congestion controller needs it in order to make a bandwidth estimate. This
- // is useful if the application pesistently underutilizes the link, but still
- // relies on having a reasonable bandwidth estimate from the connection, e.g.
- // for real time applications.
- bool fill_up_link_during_probing_;
-
- // If true, the probing retransmission will not be started again. This is
- // used to safeguard against an accidental tail recursion in probing
- // retransmission code.
- bool probing_retransmission_pending_;
-
// Id of latest sent control frame. 0 if no control frame has been sent.
QuicControlFrameId last_control_frame_id_;
@@ -2224,12 +2205,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// 2), do not override it on receiving PATH_CHALLENGE (case 1).
PathState alternative_path_;
- // This field is used to debug b/177312785.
- QuicFrameType most_recent_frame_type_;
-
- bool count_bytes_on_alternative_path_separately_ =
- GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately);
-
// If true, upon seeing a new client address, validate the client address.
bool validate_client_addresses_ = false;
@@ -2240,20 +2215,25 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Enable this via reloadable flag once this feature is complete.
bool connection_migration_use_new_cid_ = false;
- const bool flush_after_coalesce_higher_space_packets_ =
- GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets);
-
- // Records the 1-RTT connection close frame sent.
- // TODO(b/180103273): remove this after the bug gets fixed.
- absl::optional<QuicConnectionCloseFrame> connection_close_frame_sent_;
-
// If true, send connection close packet on INVALID_VERSION.
bool send_connection_close_for_invalid_version_ = false;
+ const bool use_ping_manager_ = GetQuicReloadableFlag(quic_use_ping_manager2);
+
+ QuicPingManager ping_manager_;
+
+ // Records first serialized 1-RTT packet.
+ std::unique_ptr<BufferedPacket> first_serialized_one_rtt_packet_;
+
+ RetransmittableOnWireBehavior retransmittable_on_wire_behavior_ = DEFAULT;
+
// TODO(b/205023946) Debug-only fields, to be deprecated after the bug is
// fixed.
absl::optional<QuicWallTime> quic_bug_10511_43_timestamp_;
std::string quic_bug_10511_43_error_detail_;
+
+ bool only_send_probing_frames_on_alternative_path_ =
+ GetQuicReloadableFlag(quic_not_bundle_ack_on_alternative_path);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_context_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_context_test.cc
index 0b87d012792..1f68ae93172 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_context_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_context_test.cc
@@ -9,7 +9,7 @@
using testing::ElementsAre;
-namespace quic {
+namespace quic::test {
namespace {
class TraceCollector : public QuicConnectionTracer {
@@ -170,4 +170,4 @@ TEST_F(QuicConnectionContextTest, TestAlternatingSwitch) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager_test.cc
index 543f05433de..1c2657dc581 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager_test.cc
@@ -13,7 +13,7 @@
#include "quiche/quic/test_tools/quic_connection_id_manager_peer.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
-namespace quic {
+namespace quic::test {
namespace {
using ::quic::test::IsError;
@@ -953,4 +953,4 @@ TEST_F(QuicSelfIssuedConnectionIdManagerTest,
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_test.cc
index f421e95d34c..fdd4c6f96c2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_id_test.cc
@@ -13,7 +13,7 @@
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
-namespace quic {
+namespace quic::test {
namespace {
@@ -178,4 +178,4 @@ TEST_F(QuicConnectionIdTest, ChangeLength) {
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_test.cc
index 50ae2f1cd36..ff845387b5e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_connection_test.cc
@@ -478,11 +478,6 @@ class TestConnection : public QuicConnection {
.IsInitialized();
}
- void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(
- QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
- }
-
QuicByteCount GetBytesInFlight() {
return QuicConnectionPeer::GetSentPacketManager(this)->GetBytesInFlight();
}
@@ -493,16 +488,6 @@ class TestConnection : public QuicConnection {
next_effective_peer_addr_ = std::make_unique<QuicSocketAddress>(addr);
}
- bool PtoEnabled() {
- if (QuicConnectionPeer::GetSentPacketManager(this)->pto_enabled()) {
- // TLP/RTO related tests are stale when PTO is enabled.
- QUICHE_DCHECK(PROTOCOL_TLS1_3 == version().handshake_protocol ||
- GetQuicRestartFlag(quic_default_on_pto2));
- return true;
- }
- return false;
- }
-
void SendOrQueuePacket(SerializedPacket packet) override {
QuicConnection::SendOrQueuePacket(std::move(packet));
self_address_on_default_path_while_sending_packet_ = self_address();
@@ -517,7 +502,6 @@ class TestConnection : public QuicConnection {
using QuicConnection::active_effective_peer_migration_type;
using QuicConnection::IsCurrentPacketConnectivityProbing;
using QuicConnection::SelectMutualVersion;
- using QuicConnection::SendProbingRetransmissions;
using QuicConnection::set_defer_send_in_response_to_packets;
protected:
@@ -1285,6 +1269,10 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
void SimulateNextPacketTooLarge() { writer_->SimulateNextPacketTooLarge(); }
+ void ExpectNextPacketUnprocessable() {
+ writer_->ExpectNextPacketUnprocessable();
+ }
+
void AlwaysGetPacketTooLarge() { writer_->AlwaysGetPacketTooLarge(); }
void SetWritePauseTimeDelta(QuicTime::Delta delta) {
@@ -1574,23 +1562,9 @@ TEST_P(QuicConnectionTest, SelfAddressChangeAtServer) {
QuicSocketAddress self_address(host, 123);
EXPECT_EQ(0u, connection_.GetStats().packets_dropped);
EXPECT_CALL(visitor_, AllowSelfAddressChange()).WillOnce(Return(false));
- if (GetQuicReloadableFlag(quic_drop_packets_with_changed_server_address)) {
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
- kPeerAddress, ENCRYPTION_INITIAL);
- EXPECT_TRUE(connection_.connected());
- EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
- return;
- }
- if (version().handshake_protocol == PROTOCOL_TLS1_3) {
- EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
- }
- EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
- EXPECT_QUIC_PEER_BUG(
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address,
- kPeerAddress, ENCRYPTION_INITIAL),
- "Self address migration is not supported at the server");
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_ERROR_MIGRATING_ADDRESS);
+ ProcessFramePacketWithAddresses(MakeCryptoFrame(), self_address, kPeerAddress,
+ ENCRYPTION_INITIAL);
+ EXPECT_TRUE(connection_.connected());
EXPECT_EQ(1u, connection_.GetStats().packets_dropped);
}
@@ -1688,10 +1662,8 @@ TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
rtt_stats->set_initial_rtt(default_init_rtt * 2);
EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
- EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
- EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+ QuicSentPacketManagerPeer::SetConsecutivePtoCount(manager_, 1);
+ EXPECT_EQ(1u, manager_->GetConsecutivePtoCount());
const QuicSocketAddress kNewPeerAddress =
QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
@@ -1718,8 +1690,7 @@ TEST_P(QuicConnectionTest, PeerPortChangeAtServer) {
EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
// PORT_CHANGE shouldn't state change in sent packet manager.
EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
- EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
- EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+ EXPECT_EQ(1u, manager_->GetConsecutivePtoCount());
EXPECT_EQ(manager_->GetSendAlgorithm(), send_algorithm_);
if (connection_.validate_client_address()) {
EXPECT_EQ(NO_CHANGE, connection_.active_effective_peer_migration_type());
@@ -2496,8 +2467,7 @@ TEST_P(QuicConnectionTest, ReceivePathProbingAtServer) {
connection_.GetStats().num_connectivity_probing_received);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
- if (GetParam().version.HasIetfQuicFrames() &&
- GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately)) {
+ if (GetParam().version.HasIetfQuicFrames()) {
QuicByteCount bytes_sent =
QuicConnectionPeer::BytesSentOnAlternativePath(&connection_);
EXPECT_LT(0u, bytes_sent);
@@ -3318,8 +3288,6 @@ TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
}
TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
- // Disable TLP so the RTO fires immediately.
- connection_.SetMaxTailLossProbes(0);
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
QuicConfig config;
QuicTagVector connection_options;
@@ -3346,8 +3314,7 @@ TEST_P(QuicConnectionTest, AckNeedsRetransmittableFramesAfterPto) {
connection_.GetRetransmissionAlarm()->deadline();
clock_.AdvanceTime(retransmission_time - clock_.Now());
connection_.GetRetransmissionAlarm()->Fire();
- ASSERT_TRUE(manager_->GetConsecutiveRtoCount() > 0 ||
- manager_->GetConsecutivePtoCount() > 0);
+ ASSERT_LT(0u, manager_->GetConsecutivePtoCount());
// Process a packet, which requests a retransmittable frame be bundled
// with the ACK.
@@ -4004,9 +3971,7 @@ TEST_P(QuicConnectionTest, CancelRetransmissionAlarmAfterResetStream) {
EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
}
-TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
- connection_.SetMaxTailLossProbes(0);
-
+TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnPTO) {
QuicStreamId stream_id = 2;
QuicPacketNumber last_packet;
SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
@@ -4016,17 +3981,11 @@ TEST_P(QuicConnectionTest, RetransmitForQuicRstStreamNoErrorOnRTO) {
// Fire the RTO and verify that the RST_STREAM is resent, the stream data
// is sent.
- const size_t num_retransmissions = connection_.PtoEnabled() ? 1 : 2;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(AtLeast(num_retransmissions));
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
clock_.AdvanceTime(DefaultRetransmissionTime());
connection_.GetRetransmissionAlarm()->Fire();
size_t padding_frame_count = writer_->padding_frames().size();
EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
- if (num_retransmissions == 2) {
- ASSERT_EQ(1u, writer_->rst_stream_frames().size());
- EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
- }
}
TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
@@ -4164,33 +4123,6 @@ TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
ProcessAckPacket(&frame);
}
-TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(0);
-
- for (int i = 0; i < 10; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.SendStreamDataWithString(3, "foo", i * 3, NO_FIN);
- }
-
- // Block the writer and ensure they're queued.
- BlockOnNextWrite();
- clock_.AdvanceTime(DefaultRetransmissionTime());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_TRUE(connection_.HasQueuedData());
-
- // Unblock the writer.
- writer_->SetWritable();
- clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
- 2 * DefaultRetransmissionTime().ToMicroseconds()));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.GetRetransmissionAlarm()->Fire();
- connection_.OnCanWrite();
-}
-
TEST_P(QuicConnectionTest, WriteBlockedBufferedThenSent) {
BlockOnNextWrite();
writer_->set_is_write_blocked_data_buffered(true);
@@ -4245,9 +4177,7 @@ TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
writer_->SetWritable();
connection_.OnCanWrite();
EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- uint64_t retransmission = connection_.PtoEnabled() ? 3 : 2;
- EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
- retransmission));
+ EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 3));
}
TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
@@ -4474,85 +4404,6 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
EXPECT_EQ(QuicPacketNumber(6u), stop_waiting()->least_unacked);
}
-TEST_P(QuicConnectionTest, TLP) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(1);
-
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
-
- EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
- // Simulate the retransmission alarm firing and sending a tlp,
- // so send algorithm's OnRetransmissionTimeout is not called.
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- const QuicPacketNumber retransmission(
- connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, retransmission, _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(retransmission, writer_->header().packet_number);
- // We do not raise the high water mark yet.
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-}
-
-TEST_P(QuicConnectionTest, RTO) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(0);
-
- QuicTime default_retransmission_time =
- clock_.ApproximateNow() + DefaultRetransmissionTime();
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-
- EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
- EXPECT_EQ(default_retransmission_time,
- connection_.GetRetransmissionAlarm()->deadline());
- // Simulate the retransmission alarm firing.
- clock_.AdvanceTime(DefaultRetransmissionTime());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
- // We do not raise the high water mark yet.
- EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
-}
-
-// Regression test of b/133771183.
-TEST_P(QuicConnectionTest, RtoWithNoDataToRetransmit) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.SetMaxTailLossProbes(0);
-
- SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
- // Connection is cwnd limited.
- CongestionBlockWrites();
- // Stream gets reset.
- SendRstStream(3, QUIC_ERROR_PROCESSING_STREAM, 3);
- // Simulate the retransmission alarm firing.
- clock_.AdvanceTime(DefaultRetransmissionTime());
- // RTO fires, but there is no packet to be RTOed.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
-
- EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(40);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(20);
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(false));
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
- // Receives packets 1 - 40.
- for (size_t i = 1; i <= 40; ++i) {
- ProcessDataPacket(i);
- }
-}
-
TEST_P(QuicConnectionTest, SendHandshakeMessages) {
use_tagging_decrypter();
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
@@ -4664,41 +4515,6 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_ZERO_RTT);
}
-TEST_P(QuicConnectionTest, TestRetransmitOrder) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(0);
-
- QuicByteCount first_packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&first_packet_size));
-
- connection_.SendStreamDataWithString(3, "first_packet", 0, NO_FIN);
- QuicByteCount second_packet_size;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .WillOnce(SaveArg<3>(&second_packet_size));
- connection_.SendStreamDataWithString(3, "second_packet", 12, NO_FIN);
- EXPECT_NE(first_packet_size, second_packet_size);
- // Advance the clock by huge time to make sure packets will be retransmitted.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
- {
- InSequence s;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
- }
- connection_.GetRetransmissionAlarm()->Fire();
-
- // Advance again and expect the packets to be sent again in the same order.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
- {
- InSequence s;
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
- }
- connection_.GetRetransmissionAlarm()->Fire();
-}
-
TEST_P(QuicConnectionTest, Buffer100NonDecryptablePacketsThenKeyChange) {
if (connection_.SupportsMultiplePacketNumberSpaces()) {
return;
@@ -4753,55 +4569,7 @@ TEST_P(QuicConnectionTest, SetRTOAfterWritingToSocket) {
EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
}
-TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(0);
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
- connection_.SendStreamDataWithString(3, "bar", 0, NO_FIN);
- QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
- EXPECT_TRUE(retransmission_alarm->IsSet());
- EXPECT_EQ(DefaultRetransmissionTime(),
- retransmission_alarm->deadline() - clock_.Now());
-
- // Advance the time right before the RTO, then receive an ack for the first
- // packet to delay the RTO.
- clock_.AdvanceTime(DefaultRetransmissionTime());
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- QuicAckFrame ack = InitAckFrame(1);
- ProcessAckPacket(&ack);
- // Now we have an RTT sample of DefaultRetransmissionTime(500ms),
- // so the RTO has increased to 2 * SRTT.
- EXPECT_TRUE(retransmission_alarm->IsSet());
- EXPECT_EQ(retransmission_alarm->deadline() - clock_.Now(),
- 2 * DefaultRetransmissionTime());
-
- // Move forward past the original RTO and ensure the RTO is still pending.
- clock_.AdvanceTime(2 * DefaultRetransmissionTime());
-
- // Ensure the second packet gets retransmitted when it finally fires.
- EXPECT_TRUE(retransmission_alarm->IsSet());
- EXPECT_EQ(retransmission_alarm->deadline(), clock_.ApproximateNow());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- // Manually cancel the alarm to simulate a real test.
- connection_.GetRetransmissionAlarm()->Fire();
-
- // The new retransmitted packet number should set the RTO to a larger value
- // than previously.
- EXPECT_TRUE(retransmission_alarm->IsSet());
- QuicTime next_rto_time = retransmission_alarm->deadline();
- QuicTime expected_rto_time =
- connection_.sent_packet_manager().GetRetransmissionTime();
- EXPECT_EQ(next_rto_time, expected_rto_time);
-}
-
TEST_P(QuicConnectionTest, TestQueued) {
- connection_.SetMaxTailLossProbes(0);
-
EXPECT_EQ(0u, connection_.NumQueuedPackets());
BlockOnNextWrite();
connection_.SendStreamDataWithString(1, "foo", 0, NO_FIN);
@@ -5043,7 +4811,7 @@ TEST_P(QuicConnectionTest, ReducedPingTimeout) {
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
// Use a reduced ping timeout for this connection.
- connection_.set_ping_timeout(QuicTime::Delta::FromSeconds(10));
+ connection_.set_keep_alive_ping_timeout(QuicTime::Delta::FromSeconds(10));
// Advance to 5ms, and send a packet to the peer, which will set
// the ping alarm.
@@ -5754,84 +5522,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendDuringHandshake) {
TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
}
-TEST_P(QuicConnectionTest, TimeoutAfterRetransmission) {
- if (connection_.PtoEnabled()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- connection_.SetFromConfig(config);
-
- const QuicTime start_time = clock_.Now();
- const QuicTime::Delta initial_idle_timeout =
- QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
- QuicTime default_timeout = clock_.Now() + initial_idle_timeout;
-
- connection_.SetMaxTailLossProbes(0);
- const QuicTime default_retransmission_time =
- start_time + DefaultRetransmissionTime();
-
- ASSERT_LT(default_retransmission_time, default_timeout);
-
- // When we send a packet, the timeout will change to 5 ms +
- // kInitialIdleTimeoutSecs (but it will not reschedule the alarm).
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- const QuicTime send_time = start_time + five_ms;
- clock_.AdvanceTime(five_ms);
- ASSERT_EQ(send_time, clock_.Now());
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // Move forward 5 ms and receive a packet, which will move the timeout
- // forward 5 ms more (but will not reschedule the alarm).
- const QuicTime receive_time = send_time + five_ms;
- clock_.AdvanceTime(receive_time - clock_.Now());
- ASSERT_EQ(receive_time, clock_.Now());
- ProcessPacket(1);
-
- // Now move forward to the retransmission time and retransmit the
- // packet, which should move the timeout forward again (but will not
- // reschedule the alarm).
- EXPECT_EQ(default_retransmission_time + five_ms,
- connection_.GetRetransmissionAlarm()->deadline());
- // Simulate the retransmission alarm firing.
- const QuicTime rto_time = send_time + DefaultRetransmissionTime();
- const QuicTime final_timeout = rto_time + initial_idle_timeout;
- clock_.AdvanceTime(rto_time - clock_.Now());
- ASSERT_EQ(rto_time, clock_.Now());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
-
- // Advance to the original timeout and fire the alarm. The connection should
- // timeout, and the alarm should be registered based on the time of the
- // retransmission.
- clock_.AdvanceTime(default_timeout - clock_.Now());
- ASSERT_EQ(default_timeout.ToDebuggingValue(),
- clock_.Now().ToDebuggingValue());
- EXPECT_EQ(default_timeout, clock_.Now());
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- ASSERT_EQ(final_timeout.ToDebuggingValue(),
- connection_.GetTimeoutAlarm()->deadline().ToDebuggingValue());
-
- // This time, we should time out.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- clock_.AdvanceTime(final_timeout - clock_.Now());
- EXPECT_EQ(connection_.GetTimeoutAlarm()->deadline(), clock_.Now());
- EXPECT_EQ(final_timeout, clock_.Now());
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
// When the idle timeout fires, verify that by default we do not send any
// connection close packets.
@@ -5861,6 +5551,7 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
&config, connection_.connection_id());
}
connection_.SetFromConfig(config);
+ QuicConnectionPeer::DisableBandwidthUpdate(&connection_);
const QuicTime::Delta default_idle_timeout =
QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
@@ -5911,64 +5602,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendAfterHandshake) {
IsError(QUIC_NETWORK_IDLE_TIMEOUT));
}
-TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseAndTLP) {
- if (connection_.PtoEnabled()) {
- return;
- }
- // Same test as above, but sending TLPs causes a connection close to be sent.
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
-
- // Create a handshake message that also enables silent close.
- CryptoHandshakeMessage msg;
- std::string error_details;
- QuicConfig client_config;
- client_config.SetInitialStreamFlowControlWindowToSend(
- kInitialStreamFlowControlWindowForTest);
- client_config.SetInitialSessionFlowControlWindowToSend(
- kInitialSessionFlowControlWindowForTest);
- client_config.SetIdleNetworkTimeout(
- QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
- client_config.ToHandshakeMessage(&msg, connection_.transport_version());
- const QuicErrorCode error =
- config.ProcessPeerHello(msg, CLIENT, &error_details);
- EXPECT_THAT(error, IsQuicNoError());
-
- connection_.SetFromConfig(config);
-
- const QuicTime::Delta default_idle_timeout =
- QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
- const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
- QuicTime default_timeout = clock_.ApproximateNow() + default_idle_timeout;
-
- // When we send a packet, the timeout will change to 5ms +
- // kInitialIdleTimeoutSecs.
- clock_.AdvanceTime(five_ms);
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
- EXPECT_EQ(default_timeout + five_ms,
- connection_.GetTimeoutAlarm()->deadline());
-
- // Retransmit the packet via tail loss probe.
- clock_.AdvanceTime(connection_.GetRetransmissionAlarm()->deadline() -
- clock_.Now());
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
-
- // This time, we should time out and send a connection close due to the TLP.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- clock_.AdvanceTime(connection_.GetTimeoutAlarm()->deadline() -
- clock_.ApproximateNow() + five_ms);
- connection_.GetTimeoutAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
-}
-
TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
// Same test as above, but having open streams causes a connection close
// to be sent.
@@ -5998,6 +5631,7 @@ TEST_P(QuicConnectionTest, TimeoutAfterSendSilentCloseWithOpenStreams) {
&config, connection_.connection_id());
}
connection_.SetFromConfig(config);
+ QuicConnectionPeer::DisableBandwidthUpdate(&connection_);
const QuicTime::Delta default_idle_timeout =
QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs - 1);
@@ -6093,6 +5727,7 @@ TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
connection_.SetNetworkTimeouts(
QuicTime::Delta::Infinite(),
initial_idle_timeout + QuicTime::Delta::FromSeconds(1));
+ QuicConnectionPeer::DisableBandwidthUpdate(&connection_);
const QuicTime::Delta five_ms = QuicTime::Delta::FromMilliseconds(5);
QuicTime default_timeout = clock_.ApproximateNow() + initial_idle_timeout;
@@ -6142,58 +5777,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterReceiveNotSendWhenUnacked) {
TestConnectionCloseQuicErrorCode(QUIC_NETWORK_IDLE_TIMEOUT);
}
-TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(2);
- EXPECT_TRUE(connection_.connected());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- QuicConfig config;
- QuicTagVector connection_options;
- connection_options.push_back(k5RTO);
- config.SetConnectionOptionsToSend(connection_options);
- QuicConfigPeer::SetNegotiated(&config, true);
- if (GetQuicReloadableFlag(quic_default_enable_5rto_blackhole_detection2)) {
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_COMPLETE));
- }
- if (connection_.version().UsesTls()) {
- QuicConfigPeer::SetReceivedOriginalConnectionId(
- &config, connection_.connection_id());
- QuicConfigPeer::SetReceivedInitialSourceConnectionId(
- &config, connection_.connection_id());
- }
- connection_.SetFromConfig(config);
-
- // Send stream data.
- SendStreamDataToPeer(
- GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
- 0, FIN, nullptr);
-
- // Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO.
- for (int i = 0; i < 6; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_TRUE(connection_.connected());
- }
- EXPECT_CALL(visitor_, OnPathDegrading());
- connection_.PathDegradingTimeout();
-
- EXPECT_EQ(2u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
- EXPECT_EQ(4u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
- // This time, we should time out.
- EXPECT_CALL(visitor_,
- OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
- ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
- connection_.GetBlackholeDetectorAlarm()->Fire();
- EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
- EXPECT_FALSE(connection_.connected());
- TestConnectionCloseQuicErrorCode(QUIC_TOO_MANY_RTOS);
-}
-
TEST_P(QuicConnectionTest, SendScheduler) {
// Test that if we send a packet without delay, it is not queued.
QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
@@ -7095,63 +6678,6 @@ TEST_P(QuicConnectionTest, BadVersionNegotiation) {
IsError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET));
}
-TEST_P(QuicConnectionTest, CheckSendStats) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(0);
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendStreamDataWithString(3, "first", 0, NO_FIN);
- size_t first_packet_size = writer_->last_packet_size();
-
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- connection_.SendStreamDataWithString(5, "second", 0, NO_FIN);
- size_t second_packet_size = writer_->last_packet_size();
-
- // 2 retransmissions due to rto, 1 due to explicit nack.
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
-
- // Retransmit due to RTO.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
- connection_.GetRetransmissionAlarm()->Fire();
-
- // Retransmit due to explicit nacks.
- QuicAckFrame nack_three =
- InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
- {QuicPacketNumber(4), QuicPacketNumber(5)}});
-
- LostPacketVector lost_packets;
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
- lost_packets.push_back(
- LostPacket(QuicPacketNumber(3), kMaxOutgoingPacketSize));
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
- Return(LossDetectionInterface::DetectionStats())));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- ProcessAckPacket(&nack_three);
-
- EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
- .WillOnce(Return(QuicBandwidth::Zero()));
-
- const QuicConnectionStats& stats = connection_.GetStats();
- // For IETF QUIC, version is not included as the encryption level switches to
- // FORWARD_SECURE in SendStreamDataWithString.
- size_t save_on_version =
- GetParam().version.HasIetfInvariantHeader() ? 0 : kQuicVersionSize;
- EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - save_on_version,
- stats.bytes_sent);
- EXPECT_EQ(5u, stats.packets_sent);
- EXPECT_EQ(2 * first_packet_size + second_packet_size - save_on_version,
- stats.bytes_retransmitted);
- EXPECT_EQ(3u, stats.packets_retransmitted);
- EXPECT_EQ(1u, stats.rto_count);
- EXPECT_EQ(kDefaultMaxPacketSize, stats.egress_mtu);
-}
-
TEST_P(QuicConnectionTest, ProcessFramesIfPacketClosedConnection) {
// Construct a packet with stream frame and connection close frame.
QuicPacketHeader header;
@@ -7404,7 +6930,7 @@ TEST_P(QuicConnectionTest, SendBlockedImmediately) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(1);
EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
- connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+ connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3, 0)));
EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
EXPECT_FALSE(connection_.HasQueuedData());
}
@@ -7415,7 +6941,7 @@ TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
}
MockQuicConnectionDebugVisitor debug_visitor;
connection_.set_debug_visitor(&debug_visitor);
- QuicBlockedFrame blocked(1, 3);
+ QuicBlockedFrame blocked(1, 3, 0);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
@@ -7431,14 +6957,19 @@ TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
return;
}
- EXPECT_CALL(visitor_, OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
- .WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- EXPECT_QUIC_BUG(connection_.SaveAndSendStreamData(3, {}, 0, FIN),
- "Cannot send stream data with level: ENCRYPTION_INITIAL");
- EXPECT_FALSE(connection_.connected());
- EXPECT_EQ(1, connection_close_frame_count_);
- EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
- IsError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA));
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(visitor_,
+ OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
+ .WillOnce(
+ Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
+ connection_.SaveAndSendStreamData(3, {}, 0, FIN);
+ EXPECT_FALSE(connection_.connected());
+ EXPECT_EQ(1, connection_close_frame_count_);
+ EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
+ IsError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA));
+ },
+ "Cannot send stream data with level: ENCRYPTION_INITIAL");
}
TEST_P(QuicConnectionTest, SetRetransmissionAlarmForCryptoPacket) {
@@ -7643,6 +7174,150 @@ TEST_P(QuicConnectionTest, ServerRetransmittableOnWire) {
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
}
+TEST_P(QuicConnectionTest, RetransmittableOnWireSendFirstPacket) {
+ if (!GetQuicReloadableFlag(quic_use_ping_manager2) ||
+ !VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+ return;
+ }
+ EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+ const QuicTime::Delta kRetransmittableOnWireTimeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ const QuicTime::Delta kTestRtt = QuicTime::Delta::FromMilliseconds(100);
+
+ connection_.set_initial_retransmittable_on_wire_timeout(
+ kRetransmittableOnWireTimeout);
+
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kROWF);
+ config.SetClientConnectionOptions(connection_options);
+ connection_.SetFromConfig(config);
+
+ // Send a request.
+ connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+ // Receive an ACK after 1-RTT.
+ clock_.AdvanceTime(kTestRtt);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame =
+ InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+ ProcessAckPacket(&frame);
+ ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_EQ(kRetransmittableOnWireTimeout,
+ connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+ // Fire retransmittable-on-wire alarm.
+ clock_.AdvanceTime(kRetransmittableOnWireTimeout);
+ connection_.GetPingAlarm()->Fire();
+ EXPECT_EQ(2u, writer_->packets_write_attempts());
+ // Verify alarm is set in keep-alive mode.
+ ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest, RetransmittableOnWireSendRandomBytes) {
+ if (!GetQuicReloadableFlag(quic_use_ping_manager2) ||
+ !VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+ return;
+ }
+ EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+ const QuicTime::Delta kRetransmittableOnWireTimeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ const QuicTime::Delta kTestRtt = QuicTime::Delta::FromMilliseconds(100);
+
+ connection_.set_initial_retransmittable_on_wire_timeout(
+ kRetransmittableOnWireTimeout);
+
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kROWR);
+ config.SetClientConnectionOptions(connection_options);
+ connection_.SetFromConfig(config);
+
+ // Send a request.
+ connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+ // Receive an ACK after 1-RTT.
+ clock_.AdvanceTime(kTestRtt);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame =
+ InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+ ProcessAckPacket(&frame);
+ ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_EQ(kRetransmittableOnWireTimeout,
+ connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+ // Fire retransmittable-on-wire alarm.
+ clock_.AdvanceTime(kRetransmittableOnWireTimeout);
+ // Next packet is not processable by the framer in the test writer.
+ ExpectNextPacketUnprocessable();
+ connection_.GetPingAlarm()->Fire();
+ EXPECT_EQ(2u, writer_->packets_write_attempts());
+ // Verify alarm is set in keep-alive mode.
+ ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+}
+
+TEST_P(QuicConnectionTest,
+ RetransmittableOnWireSendRandomBytesWithWriterBlocked) {
+ if (!GetQuicReloadableFlag(quic_use_ping_manager2) ||
+ !VersionHasIetfQuicFrames(connection_.version().transport_version)) {
+ return;
+ }
+ EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+
+ const QuicTime::Delta kRetransmittableOnWireTimeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ const QuicTime::Delta kTestRtt = QuicTime::Delta::FromMilliseconds(100);
+
+ connection_.set_initial_retransmittable_on_wire_timeout(
+ kRetransmittableOnWireTimeout);
+
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ QuicConfig config;
+ QuicTagVector connection_options;
+ connection_options.push_back(kROWR);
+ config.SetClientConnectionOptions(connection_options);
+ connection_.SetFromConfig(config);
+
+ // Send a request.
+ connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
+ // Receive an ACK after 1-RTT.
+ clock_.AdvanceTime(kTestRtt);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame =
+ InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
+ ProcessAckPacket(&frame);
+ ASSERT_TRUE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_EQ(kRetransmittableOnWireTimeout,
+ connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+ // Receive an out of order data packet and block the ACK packet.
+ BlockOnNextWrite();
+ ProcessDataPacket(3);
+ EXPECT_EQ(2u, writer_->packets_write_attempts());
+ EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+ // Fire retransmittable-on-wire alarm.
+ clock_.AdvanceTime(kRetransmittableOnWireTimeout);
+ connection_.GetPingAlarm()->Fire();
+ // Verify the random bytes packet gets queued.
+ EXPECT_EQ(2u, connection_.NumQueuedPackets());
+}
+
// This test verifies that the connection marks path as degrading and does not
// spin timer to detect path degrading when a new packet is sent on the
// degraded path.
@@ -7977,57 +7652,6 @@ TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) {
connection_.OnCanWrite();
}
-// Test the mode in which the link is filled up with probing retransmissions if
-// the connection becomes application-limited.
-TEST_P(QuicConnectionTest, SendDataWhenApplicationLimited) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
- .WillRepeatedly(Return(true));
- {
- InSequence seq;
- EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
- EXPECT_CALL(visitor_, WillingAndAbleToWrite())
- .WillRepeatedly(Return(false));
- }
- EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
- return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
- PROBING_RETRANSMISSION);
- });
- // Fix congestion window to be 20,000 bytes.
- EXPECT_CALL(*send_algorithm_, CanSend(Ge(20000u)))
- .WillRepeatedly(Return(false));
- EXPECT_CALL(*send_algorithm_, CanSend(Lt(20000u)))
- .WillRepeatedly(Return(true));
-
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0);
- ASSERT_EQ(0u, connection_.GetStats().packets_sent);
- connection_.set_fill_up_link_during_probing(true);
- EXPECT_CALL(visitor_, GetHandshakeState())
- .WillRepeatedly(Return(HANDSHAKE_CONFIRMED));
- connection_.OnHandshakeComplete();
- connection_.SendStreamData3();
-
- // We expect a lot of packets from a 20 kbyte window.
- EXPECT_GT(connection_.GetStats().packets_sent, 10u);
- // Ensure that the packets are padded.
- QuicByteCount average_packet_size =
- connection_.GetStats().bytes_sent / connection_.GetStats().packets_sent;
- EXPECT_GT(average_packet_size, 1000u);
-
- // Acknowledge all packets sent, except for the last one.
- QuicAckFrame ack = InitAckFrame(
- connection_.sent_packet_manager().GetLargestSentPacket() - 1);
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-
- // Ensure that since we no longer have retransmittable bytes in flight, this
- // will not cause any responses to be sent.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
- EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1);
- ProcessAckPacket(&ack);
-}
-
TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Send an ack by simulating delayed ack alarm firing.
@@ -8168,83 +7792,6 @@ TEST_P(QuicConnectionTest, ClientAlwaysSendConnectionId) {
writer_->last_packet_header().destination_connection_id_included);
}
-TEST_P(QuicConnectionTest, SendProbingRetransmissions) {
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
-
- const QuicStreamId stream_id = 2;
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "bar", 3, NO_FIN, &last_packet);
- SendStreamDataToPeer(stream_id, "test", 6, NO_FIN, &last_packet);
-
- const QuicByteCount old_bytes_in_flight =
- connection_.sent_packet_manager().GetBytesInFlight();
-
- // Allow 9 probing retransmissions to be sent.
- {
- InSequence seq;
- EXPECT_CALL(*send_algorithm_, CanSend(_))
- .Times(9 * 2)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- }
- // Expect them retransmitted in cyclic order (foo, bar, test, foo, bar...).
- QuicPacketCount sent_count = 0;
-
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _))
- .WillRepeatedly(Invoke(
- [this, &sent_count](QuicPacketNumber, QuicPacketLength, bool,
- TransmissionType, EncryptionLevel,
- const QuicFrames&, const QuicFrames&, QuicTime) {
- ASSERT_EQ(1u, writer_->stream_frames().size());
- if (connection_.version().CanSendCoalescedPackets()) {
- // There is a delay of sending coalesced packet, so (6, 0, 3, 6,
- // 0...).
- EXPECT_EQ(3 * ((sent_count + 2) % 3),
- writer_->stream_frames()[0]->offset);
- } else {
- // Identify the frames by stream offset (0, 3, 6, 0, 3...).
- EXPECT_EQ(3 * (sent_count % 3),
- writer_->stream_frames()[0]->offset);
- }
- sent_count++;
- }));
-
- EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
- return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
- PROBING_RETRANSMISSION);
- });
-
- connection_.SendProbingRetransmissions();
-
- // Ensure that the in-flight has increased.
- const QuicByteCount new_bytes_in_flight =
- connection_.sent_packet_manager().GetBytesInFlight();
- EXPECT_GT(new_bytes_in_flight, old_bytes_in_flight);
-}
-
-// Ensure that SendProbingRetransmissions() does not retransmit anything when
-// there are no outstanding packets.
-TEST_P(QuicConnectionTest,
- SendProbingRetransmissionsFailsWhenNothingToRetransmit) {
- ASSERT_TRUE(connection_.sent_packet_manager().unacked_packets().empty());
-
- MockQuicConnectionDebugVisitor debug_visitor;
- connection_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _, _, _, _, _)).Times(0);
- EXPECT_CALL(*send_algorithm_, ShouldSendProbingPacket())
- .WillRepeatedly(Return(true));
- EXPECT_CALL(visitor_, SendProbingData()).WillRepeatedly([this] {
- return connection_.sent_packet_manager().MaybeRetransmitOldestPacket(
- PROBING_RETRANSMISSION);
- });
-
- connection_.SendProbingRetransmissions();
-}
-
TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) {
const QuicTime::Delta retransmittable_on_wire_timeout =
QuicTime::Delta::FromMilliseconds(50);
@@ -8431,7 +7978,7 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
// The ping alarm is set for the ping timeout, not the shorter
// retransmittable_on_wire_timeout.
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
@@ -8462,7 +8009,8 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
// Verify subsequent pings are sent with timeout that is exponentially backed
// off.
- while (retransmittable_on_wire_timeout * 2 < connection_.ping_timeout()) {
+ while (retransmittable_on_wire_timeout * 2 <
+ QuicTime::Delta::FromSeconds(kPingTimeoutSecs)) {
// Receive an ACK for the previous PING. This should set the
// ping alarm with backed off retransmittable-on-wire timeout.
retransmittable_on_wire_timeout = retransmittable_on_wire_timeout * 2;
@@ -8483,7 +8031,7 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
// The ping alarm is set with default ping timeout.
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
// Receive an ACK for the previous PING. The ping alarm is set with an
@@ -8494,7 +8042,8 @@ TEST_P(QuicConnectionTest, BackOffRetransmittableOnWireTimeout) {
{{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
ProcessAckPacket(&frame);
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout() - QuicTime::Delta::FromMilliseconds(5),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs) -
+ QuicTime::Delta::FromMilliseconds(5),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
}
@@ -8526,7 +8075,7 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
// The ping alarm is set for the ping timeout, not the shorter
// retransmittable_on_wire_timeout.
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
// Receive an ACK of the first packet. This should set the ping alarm with
@@ -8563,6 +8112,8 @@ TEST_P(QuicConnectionTest, ResetBackOffRetransmitableOnWireTimeout) {
peer_creator_.packet_number() + 1);
EXPECT_EQ(initial_retransmittable_on_wire_timeout,
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ connection_.GetPingAlarm()->Fire();
// Verify the count of consecutive aggressive pings is reset.
for (int i = 0; i < max_aggressive_retransmittable_on_wire_ping_count; i++) {
@@ -8640,7 +8191,7 @@ TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
// The ping alarm is set for the ping timeout, not the shorter
// retransmittable_on_wire_timeout.
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
@@ -8673,7 +8224,7 @@ TEST_P(QuicConnectionTest, RetransmittableOnWirePingLimit) {
{{QuicPacketNumber(ack_num), QuicPacketNumber(ack_num + 1)}});
ProcessAckPacket(&frame);
EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
- EXPECT_EQ(connection_.ping_timeout(),
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
}
@@ -9048,10 +8599,8 @@ TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
rtt_stats->set_initial_rtt(default_init_rtt * 2);
EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(manager_, 1);
- EXPECT_EQ(1u, manager_->GetConsecutiveRtoCount());
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(manager_, 2);
- EXPECT_EQ(2u, manager_->GetConsecutiveTlpCount());
+ QuicSentPacketManagerPeer::SetConsecutivePtoCount(manager_, 1);
+ EXPECT_EQ(1u, manager_->GetConsecutivePtoCount());
const SendAlgorithmInterface* send_algorithm = manager_->GetSendAlgorithm();
// Migrate to a new address with different IP.
@@ -9061,8 +8610,7 @@ TEST_P(QuicConnectionTest, ClientsResetCwndAfterConnectionMigration) {
connection_.MigratePath(kNewSelfAddress, connection_.peer_address(),
&new_writer, false);
EXPECT_EQ(default_init_rtt, manager_->GetRttStats()->initial_rtt());
- EXPECT_EQ(0u, manager_->GetConsecutiveRtoCount());
- EXPECT_EQ(0u, manager_->GetConsecutiveTlpCount());
+ EXPECT_EQ(0u, manager_->GetConsecutivePtoCount());
EXPECT_NE(send_algorithm, manager_->GetSendAlgorithm());
}
@@ -9592,14 +9140,14 @@ TEST_P(QuicConnectionTest, CoalescedPacketThatSavesFrames) {
.Times(3)
.WillRepeatedly([this](const QuicCryptoFrame& /*frame*/) {
// QuicFrame takes ownership of the QuicBlockedFrame.
- connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+ connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3, 0)));
});
} else {
EXPECT_CALL(visitor_, OnStreamFrame(_))
.Times(3)
.WillRepeatedly([this](const QuicStreamFrame& /*frame*/) {
// QuicFrame takes ownership of the QuicBlockedFrame.
- connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3)));
+ connection_.SendControlFrame(QuicFrame(QuicBlockedFrame(1, 3, 0)));
});
}
@@ -9665,9 +9213,8 @@ TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
}
// Regresstion test for b/138962304.
-TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
+TEST_P(QuicConnectionTest, PtoAndWriteBlocked) {
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- connection_.SetMaxTailLossProbes(1);
QuicStreamId stream_id = 2;
QuicPacketNumber last_data_packet;
@@ -9690,44 +9237,6 @@ TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
EXPECT_EQ(1u, connection_.NumQueuedPackets());
}
-// Regresstion test for b/139375344.
-TEST_P(QuicConnectionTest, RtoForcesSendingPing) {
- if (connection_.PtoEnabled()) {
- return;
- }
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- connection_.SetMaxTailLossProbes(2);
- EXPECT_EQ(0u, connection_.GetStats().tlp_count);
- EXPECT_EQ(0u, connection_.GetStats().rto_count);
-
- SendStreamDataToPeer(2, "foo", 0, NO_FIN, nullptr);
- QuicTime retransmission_time =
- connection_.GetRetransmissionAlarm()->deadline();
- EXPECT_NE(QuicTime::Zero(), retransmission_time);
- // TLP fires.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, connection_.GetStats().tlp_count);
- EXPECT_EQ(0u, connection_.GetStats().rto_count);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-
- // Packet 1 gets acked.
- QuicAckFrame frame = InitAckFrame(1);
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- ProcessAckPacket(1, &frame);
- EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- retransmission_time = connection_.GetRetransmissionAlarm()->deadline();
-
- // RTO fires, verify a PING packet gets sent because there is no data to send.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _));
- clock_.AdvanceTime(retransmission_time - clock_.Now());
- connection_.GetRetransmissionAlarm()->Fire();
- EXPECT_EQ(1u, connection_.GetStats().tlp_count);
- EXPECT_EQ(1u, connection_.GetStats().rto_count);
- EXPECT_EQ(1u, writer_->ping_frames().size());
-}
-
TEST_P(QuicConnectionTest, ProbeTimeout) {
QuicConfig config;
QuicTagVector connection_options;
@@ -9792,8 +9301,6 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter6ClientPTOs) {
EXPECT_CALL(visitor_, OnPathDegrading());
connection_.PathDegradingTimeout();
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
EXPECT_EQ(5u, connection_.sent_packet_manager().GetConsecutivePtoCount());
// Closes connection on 6th PTO.
// May send multiple connecction close packets with multiple PN spaces.
@@ -9844,8 +9351,6 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter7ClientPTOs) {
EXPECT_CALL(visitor_, OnPathDegrading());
connection_.PathDegradingTimeout();
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
EXPECT_EQ(6u, connection_.sent_packet_manager().GetConsecutivePtoCount());
// Closes connection on 7th PTO.
EXPECT_CALL(visitor_,
@@ -9895,8 +9400,6 @@ TEST_P(QuicConnectionTest, CloseConnectionAfter8ClientPTOs) {
EXPECT_CALL(visitor_, OnPathDegrading());
connection_.PathDegradingTimeout();
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveTlpCount());
- EXPECT_EQ(0u, connection_.sent_packet_manager().GetConsecutiveRtoCount());
EXPECT_EQ(7u, connection_.sent_packet_manager().GetConsecutivePtoCount());
// Closes connection on 8th PTO.
EXPECT_CALL(visitor_,
@@ -10200,49 +9703,6 @@ TEST_P(QuicConnectionTest, ConnectionCloseFrameType) {
connection_close_frames[0].transport_close_frame_type);
}
-// Regression test for b/137401387 and b/138962304.
-TEST_P(QuicConnectionTest, RtoPacketAsTwo) {
- if (connection_.PtoEnabled()) {
- return;
- }
- connection_.SetMaxTailLossProbes(1);
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- std::string stream_data(3000, 's');
- // Send packets 1 - 66 and exhaust cwnd.
- for (size_t i = 0; i < 22; ++i) {
- // 3 packets for each stream, the first 2 are guaranteed to be full packets.
- SendStreamDataToPeer(i + 2, stream_data, 0, FIN, nullptr);
- }
- CongestionBlockWrites();
-
- // Fires TLP. Please note, this tail loss probe has 1 byte less stream data
- // compared to packet 1 because packet number length increases.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(67), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
- // Fires RTO. Please note, although packets 2 and 3 *should* be RTOed, but
- // packet 2 gets RTOed to two packets because packet number length increases.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(68), _, _));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(69), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
-
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- // Resets all streams except 2 and ack packets 1 and 2. Now, packet 3 is the
- // only one containing retransmittable frames.
- for (size_t i = 1; i < 22; ++i) {
- notifier_.OnStreamReset(i + 2, QUIC_STREAM_CANCELLED);
- }
- EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
- QuicAckFrame frame =
- InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(3)}});
- ProcessAckPacket(1, &frame);
- CongestionUnblockWrites();
-
- // Fires TLP, verify a PING gets sent because packet 3 is marked
- // RTO_RETRANSMITTED.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(70), _, _));
- connection_.GetRetransmissionAlarm()->Fire();
-}
-
TEST_P(QuicConnectionTest, PtoSkipsPacketNumber) {
QuicConfig config;
QuicTagVector connection_options;
@@ -10321,69 +9781,65 @@ TEST_P(QuicConnectionTest, FailToCoalescePacket) {
set_perspective(Perspective::IS_SERVER);
use_tagging_decrypter();
- EXPECT_CALL(visitor_, OnHandshakePacketSent());
+ auto test_body = [&] {
+ EXPECT_CALL(visitor_, OnHandshakePacketSent());
- if (GetQuicReloadableFlag(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
EXPECT_CALL(visitor_,
OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF))
.WillOnce(Invoke(this, &QuicConnectionTest::SaveConnectionCloseFrame));
- }
- ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
- auto test_body = [&] {
- QuicConnection::ScopedPacketFlusher flusher(&connection_);
- connection_.SetEncrypter(ENCRYPTION_INITIAL,
- std::make_unique<TaggingEncrypter>(0x01));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SendCryptoDataWithString("foo", 0);
- // Verify this packet is on hold.
- EXPECT_EQ(0u, writer_->packets_write_attempts());
-
- connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
- std::make_unique<TaggingEncrypter>(0x02));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
- connection_.SendCryptoDataWithString("bar", 3);
- EXPECT_EQ(0u, writer_->packets_write_attempts());
+ ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
- connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- std::make_unique<TaggingEncrypter>(0x03));
- connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
-
- creator_->Flush();
-
- auto& coalesced_packet =
- QuicConnectionPeer::GetCoalescedPacket(&connection_);
- QuicPacketLength coalesced_packet_max_length =
- coalesced_packet.max_packet_length();
- QuicCoalescedPacketPeer::SetMaxPacketLength(coalesced_packet,
- coalesced_packet.length());
-
- // Make the coalescer's FORWARD_SECURE packet longer.
- *QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
- coalesced_packet, ENCRYPTION_FORWARD_SECURE) += "!!! TEST !!!";
-
- QUIC_LOG(INFO) << "Reduced coalesced_packet_max_length from "
- << coalesced_packet_max_length << " to "
- << coalesced_packet.max_packet_length()
- << ", coalesced_packet.length:" << coalesced_packet.length()
- << ", coalesced_packet.packet_lengths:"
- << absl::StrJoin(coalesced_packet.packet_lengths(), ":");
- };
-
- EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
+ {
+ QuicConnection::ScopedPacketFlusher flusher(&connection_);
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ connection_.SendCryptoDataWithString("foo", 0);
+ // Verify this packet is on hold.
+ EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ connection_.SendCryptoDataWithString("bar", 3);
+ EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+ connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::make_unique<TaggingEncrypter>(0x03));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ SendStreamDataToPeer(2, "baz", 3, NO_FIN, nullptr);
+
+ creator_->Flush();
+
+ auto& coalesced_packet =
+ QuicConnectionPeer::GetCoalescedPacket(&connection_);
+ QuicPacketLength coalesced_packet_max_length =
+ coalesced_packet.max_packet_length();
+ QuicCoalescedPacketPeer::SetMaxPacketLength(coalesced_packet,
+ coalesced_packet.length());
+
+ // Make the coalescer's FORWARD_SECURE packet longer.
+ *QuicCoalescedPacketPeer::GetMutableEncryptedBuffer(
+ coalesced_packet, ENCRYPTION_FORWARD_SECURE) += "!!! TEST !!!";
+
+ QUIC_LOG(INFO) << "Reduced coalesced_packet_max_length from "
+ << coalesced_packet_max_length << " to "
+ << coalesced_packet.max_packet_length()
+ << ", coalesced_packet.length:"
+ << coalesced_packet.length()
+ << ", coalesced_packet.packet_lengths:"
+ << absl::StrJoin(coalesced_packet.packet_lengths(), ":");
+ }
- if (GetQuicReloadableFlag(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
EXPECT_FALSE(connection_.connected());
EXPECT_THAT(saved_connection_close_frame_.quic_error_code,
IsError(QUIC_FAILED_TO_SERIALIZE_PACKET));
EXPECT_EQ(saved_connection_close_frame_.error_details,
"Failed to serialize coalesced packet.");
- } else {
- EXPECT_TRUE(connection_.connected());
- }
+ };
+
+ EXPECT_QUIC_BUG(test_body(), "SerializeCoalescedPacket failed.");
}
TEST_P(QuicConnectionTest, LegacyVersionEncapsulation) {
@@ -11607,40 +11063,13 @@ TEST_P(QuicConnectionTest, ClientAckDelayForAsyncPacketProcessing) {
std::make_unique<TaggingEncrypter>(0x01));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
// Verify HANDSHAKE packet gets processed.
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
- } else {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- }
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Verify immediate ACK has been sent out when flush went out of scope.
- ASSERT_FALSE(connection_.HasPendingAcks());
- } else {
- ASSERT_TRUE(connection_.HasPendingAcks());
- // Send ACKs.
- clock_.AdvanceTime(connection_.GetAckAlarm()->deadline() - clock_.Now());
- connection_.GetAckAlarm()->Fire();
- }
+ // Verify immediate ACK has been sent out when flush went out of scope.
+ ASSERT_FALSE(connection_.HasPendingAcks());
ASSERT_FALSE(writer_->ack_frames().empty());
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Verify the ack_delay_time in the sent HANDSHAKE ACK frame is 100ms.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
- writer_->ack_frames()[0].ack_delay_time);
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- return;
- }
- // Verify the ack_delay_time in the INITIAL ACK frame is 1ms.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1),
- writer_->ack_frames()[0].ack_delay_time);
- // Process the coalesced HANDSHAKE packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- auto packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- ASSERT_FALSE(writer_->ack_frames().empty());
- // Verify the ack_delay_time in the HANDSHAKE ACK frame includes the
- // buffering time.
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(101),
+ // Verify the ack_delay_time in the sent HANDSHAKE ACK frame is 100ms.
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
writer_->ack_frames()[0].ack_delay_time);
ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
}
@@ -11679,14 +11108,14 @@ TEST_P(QuicConnectionTest, TestingLiveness) {
ASSERT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
EXPECT_FALSE(connection_.MaybeTestLiveness());
- QuicTime deadline = connection_.GetTimeoutAlarm()->deadline();
+ QuicTime deadline = QuicConnectionPeer::GetIdleNetworkDeadline(&connection_);
QuicTime::Delta timeout = deadline - clock_.ApproximateNow();
// Advance time to near the idle timeout.
clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(1));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_TRUE(connection_.MaybeTestLiveness());
// Verify idle deadline does not change.
- EXPECT_EQ(deadline, connection_.GetTimeoutAlarm()->deadline());
+ EXPECT_EQ(deadline, QuicConnectionPeer::GetIdleNetworkDeadline(&connection_));
}
TEST_P(QuicConnectionTest, SilentIdleTimeout) {
@@ -11716,6 +11145,11 @@ TEST_P(QuicConnectionTest, SilentIdleTimeout) {
EXPECT_CALL(visitor_,
OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+ if (!QuicConnectionPeer::GetBandwidthUpdateTimeout(&connection_)
+ .IsInfinite()) {
+ // Fires the bandwidth update.
+ connection_.GetTimeoutAlarm()->Fire();
+ }
connection_.GetTimeoutAlarm()->Fire();
// Verify the connection close packets get serialized and added to
// termination packets list.
@@ -14035,6 +13469,123 @@ TEST_P(QuicConnectionTest,
EXPECT_EQ(1u, connection_.GetStats().num_validated_peer_migration);
}
+// Regression test of b/228645208.
+TEST_P(QuicConnectionTest, NoNonProbingFrameOnAlternativePath) {
+ if (!connection_.connection_migration_use_new_cid()) {
+ return;
+ }
+
+ PathProbeTestInit(Perspective::IS_SERVER);
+ SetClientConnectionId(TestConnectionId(1));
+ connection_.CreateConnectionIdManager();
+
+ QuicConnectionId server_cid0 = connection_.connection_id();
+ QuicConnectionId client_cid0 = connection_.client_connection_id();
+ QuicConnectionId client_cid1 = TestConnectionId(2);
+ QuicConnectionId server_cid1;
+ // Sends new server CID to client.
+ EXPECT_CALL(visitor_, OnServerConnectionIdIssued(_))
+ .WillOnce(
+ Invoke([&](const QuicConnectionId& cid) { server_cid1 = cid; }));
+ EXPECT_CALL(visitor_, SendNewConnectionId(_));
+ connection_.MaybeSendConnectionIdToClient();
+ // Receives new client CID from client.
+ QuicNewConnectionIdFrame new_cid_frame;
+ new_cid_frame.connection_id = client_cid1;
+ new_cid_frame.sequence_number = 1u;
+ new_cid_frame.retire_prior_to = 0u;
+ connection_.OnNewConnectionIdFrame(new_cid_frame);
+ auto* packet_creator = QuicConnectionPeer::GetPacketCreator(&connection_);
+ ASSERT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+ ASSERT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+ peer_creator_.SetServerConnectionId(server_cid1);
+ const QuicSocketAddress kNewPeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback4(), /*port=*/23456);
+ QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
+ QuicFrames frames1;
+ frames1.push_back(
+ QuicFrame(QuicPathChallengeFrame(0, path_challenge_payload)));
+ QuicPathFrameBuffer payload;
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
+ .Times(AtLeast(1))
+ .WillOnce(Invoke([&]() {
+ EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ EXPECT_FALSE(writer_->path_response_frames().empty());
+ EXPECT_FALSE(writer_->path_challenge_frames().empty());
+ payload = writer_->path_challenge_frames().front().data_buffer;
+ }));
+ ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
+ ENCRYPTION_FORWARD_SECURE);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ EXPECT_TRUE(connection_.HasPendingPathValidation());
+ const auto* default_path = QuicConnectionPeer::GetDefaultPath(&connection_);
+ const auto* alternative_path =
+ QuicConnectionPeer::GetAlternativePath(&connection_);
+ EXPECT_EQ(default_path->client_connection_id, client_cid0);
+ EXPECT_EQ(default_path->server_connection_id, server_cid0);
+ EXPECT_EQ(alternative_path->client_connection_id, client_cid1);
+ EXPECT_EQ(alternative_path->server_connection_id, server_cid1);
+ EXPECT_EQ(packet_creator->GetDestinationConnectionId(), client_cid0);
+ EXPECT_EQ(packet_creator->GetSourceConnectionId(), server_cid0);
+
+ // Process non-probing packets on the default path.
+ peer_creator_.SetServerConnectionId(server_cid0);
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).WillRepeatedly(Invoke([=]() {
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ }));
+ // Receives packets 3 - 39 to send 19 ACK-only packets, which will force the
+ // connection to reach |kMaxConsecutiveNonRetransmittablePackets| while
+ // sending the next ACK.
+ for (size_t i = 3; i <= 39; ++i) {
+ ProcessDataPacket(i);
+ }
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ QuicTime ack_time = connection_.GetAckAlarm()->deadline();
+ QuicTime path_validation_retry_time =
+ connection_.GetRetryTimeout(kNewPeerAddress, writer_.get());
+ // Advance time to simultaneously fire path validation retry and ACK alarms.
+ clock_.AdvanceTime(std::max(ack_time, path_validation_retry_time) -
+ clock_.ApproximateNow());
+
+ // The 20th ACK should bundle with a WINDOW_UPDATE frame.
+ EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+ .WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicWindowUpdateFrame(1, 0, 0)));
+ }));
+ if (GetQuicReloadableFlag(quic_not_bundle_ack_on_alternative_path)) {
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(Invoke([&]() {
+ EXPECT_EQ(kNewPeerAddress, writer_->last_write_peer_address());
+ EXPECT_FALSE(writer_->path_challenge_frames().empty());
+ // Retry path validation shouldn't bundle ACK.
+ EXPECT_TRUE(writer_->ack_frames().empty());
+ }))
+ .WillOnce(Invoke([&]() {
+ EXPECT_EQ(kPeerAddress, writer_->last_write_peer_address());
+ EXPECT_FALSE(writer_->ack_frames().empty());
+ EXPECT_FALSE(writer_->window_update_frames().empty());
+ }));
+ static_cast<TestAlarmFactory::TestAlarm*>(
+ QuicPathValidatorPeer::retry_timer(
+ QuicConnectionPeer::path_validator(&connection_)))
+ ->Fire();
+ } else {
+ EXPECT_QUIC_BUG(static_cast<TestAlarmFactory::TestAlarm*>(
+ QuicPathValidatorPeer::retry_timer(
+ QuicConnectionPeer::path_validator(&connection_)))
+ ->Fire(),
+ "quic_bug_12645_2");
+ }
+}
+
TEST_P(QuicConnectionTest,
ProbedOnAnotherPathAfterPeerIpAddressChangeAtServer) {
PathProbeTestInit(Perspective::IS_SERVER);
@@ -14486,8 +14037,7 @@ TEST_P(QuicConnectionTest,
TEST_P(
QuicConnectionTest,
ReplacePeerIssuedConnectionIdOnBothPathsTriggeredByNewConnectionIdFrame) {
- if (!version().HasIetfQuicFrames() ||
- !connection_.count_bytes_on_alternative_path_separately()) {
+ if (!version().HasIetfQuicFrames()) {
return;
}
PathProbeTestInit(Perspective::IS_SERVER);
@@ -14846,21 +14396,24 @@ TEST_P(QuicConnectionTest, LostDataThenGetAcknowledged) {
QuicAckFrame ack = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)}});
frames.push_back(QuicFrame(&ack));
- EXPECT_CALL(visitor_, OnConnectionMigration(_)).Times(1);
-
// Invoke OnCanWrite.
- EXPECT_CALL(visitor_, OnStreamFrame(_))
- .WillOnce(
- InvokeWithoutArgs(&notifier_, &SimpleSessionNotifier::OnCanWrite));
QuicIpAddress ip_address;
ASSERT_TRUE(ip_address.FromString("127.0.52.223"));
- EXPECT_QUIC_BUG(ProcessFramesPacketWithAddresses(
- frames, kSelfAddress, QuicSocketAddress(ip_address, 1000),
- ENCRYPTION_FORWARD_SECURE),
- "Try to write mid packet processing");
- EXPECT_EQ(1u, writer_->path_challenge_frames().size());
- // Verify stream frame will not be retransmitted.
- EXPECT_TRUE(writer_->stream_frames().empty());
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(visitor_, OnConnectionMigration(_)).Times(1);
+ EXPECT_CALL(visitor_, OnStreamFrame(_))
+ .WillOnce(InvokeWithoutArgs(&notifier_,
+ &SimpleSessionNotifier::OnCanWrite));
+ ProcessFramesPacketWithAddresses(frames, kSelfAddress,
+ QuicSocketAddress(ip_address, 1000),
+ ENCRYPTION_FORWARD_SECURE);
+ EXPECT_EQ(1u, writer_->path_challenge_frames().size());
+
+ // Verify stream frame will not be retransmitted.
+ EXPECT_TRUE(writer_->stream_frames().empty());
+ },
+ "Try to write mid packet processing");
}
TEST_P(QuicConnectionTest, PtoSendStreamData) {
@@ -15282,21 +14835,12 @@ TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
connection_.GetAckAlarm()->deadline());
// ACK is not throttled by amplification limit, and SHLO is bundled. Also
// HANDSHAKE + 1RTT packets get coalesced.
- if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
- } else {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
- }
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
// ACK alarm fires.
clock_.AdvanceTime(kAlarmGranularity);
connection_.GetAckAlarm()->Fire();
- if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
- // Verify 1-RTT packet is coalesced.
- EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
- } else {
- // Verify HANDSHAKE packet is coalesced with INITIAL ACK + SHLO.
- EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
- }
+ // Verify 1-RTT packet is coalesced.
+ EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
// Only the first packet in the coalesced packet has been processed,
// verify SHLO is bundled with INITIAL ACK.
EXPECT_EQ(1u, writer_->ack_frames().size());
@@ -15307,16 +14851,12 @@ TEST_P(QuicConnectionTest, FailedToRetransmitShlo) {
writer_->framer()->ProcessPacket(*packet);
EXPECT_EQ(0u, writer_->ack_frames().size());
EXPECT_EQ(1u, writer_->crypto_frames().size());
- if (GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
- // Process the coalesced 1-RTT packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- EXPECT_EQ(0u, writer_->crypto_frames().size());
- EXPECT_EQ(1u, writer_->stream_frames().size());
- } else {
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- }
+ // Process the coalesced 1-RTT packet.
+ ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+ packet = writer_->coalesced_packet()->Clone();
+ writer_->framer()->ProcessPacket(*packet);
+ EXPECT_EQ(0u, writer_->crypto_frames().size());
+ EXPECT_EQ(1u, writer_->stream_frames().size());
// Received INITIAL 3.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
@@ -15388,26 +14928,17 @@ TEST_P(QuicConnectionTest, FailedToConsumeCryptoData) {
clock_.AdvanceTime(retransmission_time - clock_.Now());
connection_.GetRetransmissionAlarm()->Fire();
- if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
- // Verify the retransmission is a coalesced packet with HANDSHAKE 2 and
- // 1-RTT 3.
- EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
- // Only the first packet in the coalesced packet has been processed.
- EXPECT_EQ(1u, writer_->crypto_frames().size());
- // Process the coalesced 1-RTT packet.
- ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
- auto packet = writer_->coalesced_packet()->Clone();
- writer_->framer()->ProcessPacket(*packet);
- EXPECT_EQ(1u, writer_->stream_frames().size());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- } else {
- // Although packet 2 has not been retransmitted, it has been marked PTOed
- // and a HANDHSAKE PING gets retransmitted.
- EXPECT_EQ(0x03030303u, writer_->final_bytes_of_last_packet());
- EXPECT_EQ(1u, writer_->ping_frames().size());
- EXPECT_TRUE(writer_->stream_frames().empty());
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- }
+ // Verify the retransmission is a coalesced packet with HANDSHAKE 2 and
+ // 1-RTT 3.
+ EXPECT_EQ(0x04040404u, writer_->final_bytes_of_last_packet());
+ // Only the first packet in the coalesced packet has been processed.
+ EXPECT_EQ(1u, writer_->crypto_frames().size());
+ // Process the coalesced 1-RTT packet.
+ ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+ auto packet = writer_->coalesced_packet()->Clone();
+ writer_->framer()->ProcessPacket(*packet);
+ EXPECT_EQ(1u, writer_->stream_frames().size());
+ ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
// Verify retransmission alarm is still armed.
ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
}
@@ -15564,22 +15095,12 @@ TEST_P(QuicConnectionTest, NoExtraPaddingInReserializedInitial) {
// Server receives INITIAL 3, this will serialzie FS 7 (stream 4, stream 8),
// which will trigger a flush of a coalesced packet consists of INITIAL 4,
// HS 5 and FS 6 (stream 4).
- if (GetQuicReloadableFlag(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2)) {
- // Expect no QUIC_BUG.
- ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
- EXPECT_EQ(
- debug_visitor_sent_count,
- connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
- } else {
- // Expect QUIC_BUG due to extra padding.
- EXPECT_QUIC_BUG(
- { ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL); },
- "Reserialize initial packet in coalescer has unexpected size");
- EXPECT_EQ(
- debug_visitor_sent_count + 1,
- connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
- }
+
+ // Expect no QUIC_BUG.
+ ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
+ EXPECT_EQ(
+ debug_visitor_sent_count,
+ connection_.sent_packet_manager().GetLargestSentPacket().ToUint64());
// The error only happens if after serializing the second 1RTT packet(pkt #7),
// the pending padding bytes is non zero.
@@ -15631,27 +15152,15 @@ TEST_P(QuicConnectionTest, ReportedAckDelayIncludesQueuingDelay) {
connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
ASSERT_TRUE(connection_.HasPendingAcks());
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- EXPECT_EQ(packet_receipt_time + DefaultDelayedAckTime(),
- connection_.GetAckAlarm()->deadline());
- clock_.AdvanceTime(packet_receipt_time + DefaultDelayedAckTime() -
- clock_.Now());
- } else {
- EXPECT_EQ(clock_.Now() + DefaultDelayedAckTime(),
- connection_.GetAckAlarm()->deadline());
- clock_.AdvanceTime(DefaultDelayedAckTime());
- }
+ EXPECT_EQ(packet_receipt_time + DefaultDelayedAckTime(),
+ connection_.GetAckAlarm()->deadline());
+ clock_.AdvanceTime(packet_receipt_time + DefaultDelayedAckTime() -
+ clock_.Now());
// Fire ACK alarm.
connection_.GetAckAlarm()->Fire();
ASSERT_EQ(1u, writer_->ack_frames().size());
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Verify ACK delay time does not include queuing delay.
- EXPECT_EQ(DefaultDelayedAckTime(), writer_->ack_frames()[0].ack_delay_time);
- } else {
- // Verify ACK delay time = queuing delay + ack delay
- EXPECT_EQ(DefaultDelayedAckTime() + kQueuingDelay,
- writer_->ack_frames()[0].ack_delay_time);
- }
+ // Verify ACK delay time does not include queuing delay.
+ EXPECT_EQ(DefaultDelayedAckTime(), writer_->ack_frames()[0].ack_delay_time);
}
TEST_P(QuicConnectionTest, CoalesceOneRTTPacketWithInitialAndHandshakePackets) {
@@ -15716,10 +15225,6 @@ TEST_P(QuicConnectionTest, CoalesceOneRTTPacketWithInitialAndHandshakePackets) {
auto packet = writer_->coalesced_packet()->Clone();
writer_->framer()->ProcessPacket(*packet);
EXPECT_EQ(1u, writer_->crypto_frames().size());
- if (!GetQuicReloadableFlag(quic_flush_after_coalesce_higher_space_packets)) {
- ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
- return;
- }
// Process 1-RTT packet.
ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
packet = writer_->coalesced_packet()->Clone();
@@ -15747,16 +15252,16 @@ TEST_P(QuicConnectionTest, SendMultipleConnectionCloses) {
SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
- // Verify BeforeConnectionCloseSent gets called twice while OnConnectionClosed
- // is called once.
+ // Verify that BeforeConnectionCloseSent() gets called twice,
+ // while OnConnectionClosed() is called only once.
EXPECT_CALL(visitor_, BeforeConnectionCloseSent()).Times(2);
EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
// Send connection close w/o closing connection.
QuicConnectionPeer::SendConnectionClosePacket(
&connection_, INTERNAL_ERROR, QUIC_INTERNAL_ERROR, "internal error");
- // Fire blackhole detection alarm.
- EXPECT_QUIC_BUG(connection_.GetBlackholeDetectorAlarm()->Fire(),
- "Already sent connection close");
+ // Fire blackhole detection alarm. This will invoke
+ // SendConnectionClosePacket() a second time.
+ connection_.GetBlackholeDetectorAlarm()->Fire();
}
// Regression test for b/157895910.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_constants.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_constants.h
index 189179f6e9e..6f89ec1ac00 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_constants.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_constants.h
@@ -181,6 +181,13 @@ const int kMaxAvailableStreamsMultiplier = 10;
// create available streams entries.
const int kMaxPromisedStreamsMultiplier = kMaxAvailableStreamsMultiplier - 1;
+// The 1st PTO is armed with max of earliest in flight sent time + PTO
+// delay and kFirstPtoSrttMultiplier * srtt from last in flight packet.
+const float kFirstPtoSrttMultiplier = 1.5;
+
+// The multiplier of RTT variation when calculating PTO timeout.
+const int kPtoRttvarMultiplier = 2;
+
// TCP RFC calls for 1 second RTO however Linux differs from this default and
// define the minimum RTO to 200ms, we will use the same until we have data to
// support a higher or lower value.
@@ -300,13 +307,6 @@ QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0;
-// HTTP/3 Datagrams.
-enum : QuicDatagramContextId {
- kFirstDatagramContextIdClient = 0,
- kFirstDatagramContextIdServer = 1,
- kDatagramContextIdIncrement = 2,
-};
-
enum : uint64_t {
kHttpDatagramStreamIdDivisor = 4,
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc
index 64e5eecbf81..1553cc8fb8d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc
@@ -17,6 +17,7 @@
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
namespace quic {
@@ -81,10 +82,17 @@ void QuicControlFrameManager::WriteOrBufferWindowUpdate(
QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
}
-void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
+void QuicControlFrameManager::WriteOrBufferBlocked(
+ QuicStreamId id, QuicStreamOffset byte_offset) {
QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
- WriteOrBufferQuicFrame(
- QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id)));
+ if (GetQuicReloadableFlag(quic_include_offset_in_blocked_frames)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_include_offset_in_blocked_frames);
+ WriteOrBufferQuicFrame(
+ QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id, byte_offset)));
+ } else {
+ WriteOrBufferQuicFrame(
+ QuicFrame(QuicBlockedFrame(++last_control_frame_id_, id, 0)));
+ }
}
void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
@@ -266,8 +274,7 @@ void QuicControlFrameManager::OnCanWrite() {
bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
TransmissionType type) {
- QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
- type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+ QUICHE_DCHECK(type == PTO_RETRANSMISSION);
QuicControlFrameId id = GetControlFrameId(frame);
if (id == kInvalidControlFrameId) {
// Frame does not have a valid control frame ID, ignore it. Returns true
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.h
index b8853016d88..46a0f47e5ce 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.h
@@ -69,7 +69,7 @@ class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
// Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
// immediately.
- void WriteOrBufferBlocked(QuicStreamId id);
+ void WriteOrBufferBlocked(QuicStreamId id, QuicStreamOffset byte_offset);
// Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
// sent immediately.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager_test.cc
index 821bcca8ce8..e1d2538a05f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager_test.cc
@@ -72,7 +72,7 @@ class QuicControlFrameManagerTest : public QuicTest {
manager_->WriteOrBufferGoAway(QUIC_PEER_GOING_AWAY, kTestStreamId,
"Going away.");
manager_->WriteOrBufferWindowUpdate(kTestStreamId, 100);
- manager_->WriteOrBufferBlocked(kTestStreamId);
+ manager_->WriteOrBufferBlocked(kTestStreamId, 0);
manager_->WriteOrBufferStopSending(
QuicResetStreamError::FromInternal(kTestStopSendingCode),
kTestStreamId);
@@ -93,7 +93,7 @@ class QuicControlFrameManagerTest : public QuicTest {
QuicGoAwayFrame goaway_ = {2, QUIC_PEER_GOING_AWAY, kTestStreamId,
"Going away."};
QuicWindowUpdateFrame window_update_ = {3, kTestStreamId, 100};
- QuicBlockedFrame blocked_ = {4, kTestStreamId};
+ QuicBlockedFrame blocked_ = {4, kTestStreamId, 0};
QuicStopSendingFrame stop_sending_ = {5, kTestStreamId, kTestStopSendingCode};
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc
index aa963d54b5e..14f08e4a597 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc
@@ -11,9 +11,11 @@
#include "quiche/quic/core/crypto/crypto_protocol.h"
#include "quiche/quic/core/crypto/crypto_utils.h"
#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_client_stats.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -144,6 +146,21 @@ bool QuicCryptoClientHandshaker::encryption_established() const {
return encryption_established_;
}
+bool QuicCryptoClientHandshaker::IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel /*level*/) const {
+ return true;
+}
+
+EncryptionLevel
+QuicCryptoClientHandshaker::GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const {
+ if (space == INITIAL_DATA) {
+ return ENCRYPTION_INITIAL;
+ }
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+}
+
bool QuicCryptoClientHandshaker::one_rtt_keys_available() const {
return one_rtt_keys_available_;
}
@@ -258,7 +275,7 @@ void QuicCryptoClientHandshaker::DoHandshakeLoop(
DoInitializeServerConfigUpdate(cached);
break;
case STATE_NONE:
- QUIC_NOTREACHED();
+ QUICHE_NOTREACHED();
return;
case STATE_CONNECTION_CLOSED:
rv = QUIC_FAILURE;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.h
index 45d8016f935..dbbd942e709 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.h
@@ -11,6 +11,7 @@
#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
#include "quiche/quic/core/quic_crypto_client_stream.h"
#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
@@ -43,6 +44,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
int num_scup_messages_received() const override;
std::string chlo_hash() const override;
bool encryption_established() const override;
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override;
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override;
bool one_rtt_keys_available() const override;
const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
const override;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker_test.cc
index cf5318502ed..b31ec18b981 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker_test.cc
@@ -11,7 +11,7 @@
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
-namespace quic {
+namespace quic::test {
namespace {
class TestProofHandler : public QuicCryptoClientStream::ProofHandler {
@@ -214,4 +214,4 @@ TEST_P(QuicCryptoClientHandshakerTest, TestNoPaddingInFullHelloWhenDisabled) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc
index 60d49ed5d98..3c6dbe767e3 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc
@@ -164,4 +164,15 @@ SSL* QuicCryptoClientStream::GetSsl() const {
return tls_handshaker_ == nullptr ? nullptr : tls_handshaker_->ssl();
}
+bool QuicCryptoClientStream::IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const {
+ return handshaker_->IsCryptoFrameExpectedForEncryptionLevel(level);
+}
+
+EncryptionLevel
+QuicCryptoClientStream::GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const {
+ return handshaker_->GetEncryptionLevelToSendCryptoDataOfSpace(space);
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.h
index 96abfec5ab0..0a3e5e4df57 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.h
@@ -17,6 +17,7 @@
#include "quiche/quic/core/quic_crypto_stream.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_export.h"
@@ -169,6 +170,14 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
// for the connection.
virtual bool encryption_established() const = 0;
+ // Returns true if receiving CRYPTO_FRAME at encryption `level` is expected.
+ virtual bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const = 0;
+
+ // Returns the encryption level to send CRYPTO_FRAME for `space`.
+ virtual EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const = 0;
+
// Returns true once 1RTT keys are available.
virtual bool one_rtt_keys_available() const = 0;
@@ -283,6 +292,11 @@ class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
SSL* GetSsl() const override;
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override;
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override;
+
bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
size_t result_len, std::string* result) override;
std::string chlo_hash() const;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc
index cca4890b31c..2bd8fbdc965 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc
@@ -10,8 +10,10 @@
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "openssl/sha.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_testvalue.h"
+#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_text_utils.h"
namespace quic {
@@ -67,7 +69,6 @@ QuicCryptoServerStream::QuicCryptoServerStream(
zero_rtt_attempted_(false),
chlo_packet_size_(0),
validate_client_hello_cb_(nullptr),
- process_client_hello_cb_(nullptr),
encryption_established_(false),
one_rtt_keys_available_(false),
one_rtt_packet_decrypted_(false),
@@ -87,9 +88,10 @@ void QuicCryptoServerStream::CancelOutstandingCallbacks() {
send_server_config_update_cb_->Cancel();
send_server_config_update_cb_ = nullptr;
}
- if (process_client_hello_cb_ != nullptr) {
- process_client_hello_cb_->Cancel();
- process_client_hello_cb_ = nullptr;
+ if (std::shared_ptr<ProcessClientHelloCallback> cb =
+ process_client_hello_cb_.lock()) {
+ cb->Cancel();
+ process_client_hello_cb_.reset();
}
}
@@ -113,7 +115,7 @@ void QuicCryptoServerStream::OnHandshakeMessage(
}
if (validate_client_hello_cb_ != nullptr ||
- process_client_hello_cb_ != nullptr) {
+ !process_client_hello_cb_.expired()) {
// Already processing some other handshake message. The protocol
// does not allow for clients to send multiple handshake messages
// before the server has a chance to respond.
@@ -127,7 +129,7 @@ void QuicCryptoServerStream::OnHandshakeMessage(
std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
- QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+ QUICHE_DCHECK(process_client_hello_cb_.expired());
validate_client_hello_cb_ = cb.get();
crypto_config_->ValidateClientHello(
message, GetClientAddress(), session()->connection()->self_address(),
@@ -142,12 +144,11 @@ void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
std::unique_ptr<ProofSource::Details> details) {
// Clear the callback that got us here.
QUICHE_DCHECK(validate_client_hello_cb_ != nullptr);
- QUICHE_DCHECK(process_client_hello_cb_ == nullptr);
+ QUICHE_DCHECK(process_client_hello_cb_.expired());
validate_client_hello_cb_ = nullptr;
- std::unique_ptr<ProcessClientHelloCallback> cb(
- new ProcessClientHelloCallback(this, result));
- process_client_hello_cb_ = cb.get();
+ auto cb = std::make_shared<ProcessClientHelloCallback>(this, result);
+ process_client_hello_cb_ = cb;
ProcessClientHello(result, std::move(details), std::move(cb));
}
@@ -159,9 +160,9 @@ void QuicCryptoServerStream::
std::unique_ptr<DiversificationNonce> diversification_nonce,
std::unique_ptr<ProofSource::Details> proof_source_details) {
// Clear the callback that got us here.
- QUICHE_DCHECK(process_client_hello_cb_ != nullptr);
+ QUICHE_DCHECK(!process_client_hello_cb_.expired());
QUICHE_DCHECK(validate_client_hello_cb_ == nullptr);
- process_client_hello_cb_ = nullptr;
+ process_client_hello_cb_.reset();
proof_source_details_ = std::move(proof_source_details);
AdjustTestValue("quic::QuicCryptoServerStream::after_process_client_hello",
@@ -455,7 +456,7 @@ void QuicCryptoServerStream::ProcessClientHello(
ValidateClientHelloResultCallback::Result>
result,
std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb) {
proof_source_details_ = std::move(proof_source_details);
const CryptoHandshakeMessage& message = result->client_hello;
std::string error_details;
@@ -526,4 +527,22 @@ const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
SSL* QuicCryptoServerStream::GetSsl() const { return nullptr; }
+bool QuicCryptoServerStream::IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel /*level*/) const {
+ return true;
+}
+
+EncryptionLevel
+QuicCryptoServerStream::GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const {
+ if (space == INITIAL_DATA) {
+ return ENCRYPTION_INITIAL;
+ }
+ if (space == APPLICATION_DATA) {
+ return ENCRYPTION_ZERO_RTT;
+ }
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.h
index 2f7fb462184..665d071d074 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.h
@@ -12,6 +12,7 @@
#include "quiche/quic/core/quic_crypto_handshaker.h"
#include "quiche/quic/core/quic_crypto_server_stream_base.h"
#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
namespace quic {
@@ -72,6 +73,10 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
SSL* GetSsl() const override;
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override;
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override;
// From QuicCryptoHandshaker
void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
@@ -96,7 +101,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
ValidateClientHelloResultCallback::Result>
result,
std::unique_ptr<ProofSource::Details> proof_source_details,
- std::unique_ptr<ProcessClientHelloResultCallback> done_cb);
+ std::shared_ptr<ProcessClientHelloResultCallback> done_cb);
// Hook that allows the server to set QuicConfig defaults just
// before going through the parameter negotiation step.
@@ -249,7 +254,7 @@ class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
// ProcessClientHello and forward it to
// FinishProcessingHandshakeMessageAfterProcessClientHello. Note that this
// field is mutually exclusive with validate_client_hello_cb_.
- ProcessClientHelloCallback* process_client_hello_cb_;
+ std::weak_ptr<ProcessClientHelloCallback> process_client_hello_cb_;
// The ProofSource::Details from this connection.
std::unique_ptr<ProofSource::Details> proof_source_details_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc
index a6699820d0b..c85b9abf950 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc
@@ -6,11 +6,14 @@
#include <string>
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "quiche/quic/core/crypto/crypto_handshake.h"
#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/frames/quic_crypto_frame.h"
#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
@@ -35,10 +38,7 @@ QuicCryptoStream::QuicCryptoStream(QuicSession* session)
QuicVersionUsesCryptoFrames(session->transport_version())
? CRYPTO
: BIDIRECTIONAL),
- substreams_{{{this, ENCRYPTION_INITIAL},
- {this, ENCRYPTION_HANDSHAKE},
- {this, ENCRYPTION_ZERO_RTT},
- {this, ENCRYPTION_FORWARD_SECURE}}} {
+ substreams_{{{this}, {this}, {this}}} {
// The crypto stream is exempt from connection level flow control.
DisableConnectionFlowControlForThisStream();
}
@@ -74,9 +74,17 @@ void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 shouldn't receive CRYPTO frames";
EncryptionLevel level = session()->connection()->last_decrypted_level();
- substreams_[level].sequencer.OnCryptoFrame(frame);
+ if (!IsCryptoFrameExpectedForEncryptionLevel(level)) {
+ OnUnrecoverableError(
+ IETF_QUIC_PROTOCOL_VIOLATION,
+ absl::StrCat("CRYPTO_FRAME is unexpectedly received at level ", level));
+ return;
+ }
+ CryptoSubstream& substream =
+ substreams_[QuicUtils::GetPacketNumberSpace(level)];
+ substream.sequencer.OnCryptoFrame(frame);
EncryptionLevel frame_level = level;
- if (substreams_[level].sequencer.NumBytesBuffered() >
+ if (substream.sequencer.NumBytesBuffered() >
BufferSizeLimitForLevel(frame_level)) {
OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
"Too much crypto data received");
@@ -101,7 +109,8 @@ void QuicCryptoStream::OnDataAvailable() {
OnDataAvailableInSequencer(sequencer(), level);
return;
}
- OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
+ OnDataAvailableInSequencer(
+ &substreams_[QuicUtils::GetPacketNumberSpace(level)].sequencer, level);
}
void QuicCryptoStream::OnDataAvailableInSequencer(
@@ -137,16 +146,41 @@ void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
return;
}
const bool had_buffered_data = HasBufferedCryptoFrames();
- // Append |data| to the send buffer for this encryption level.
- QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+ QuicStreamSendBuffer* send_buffer =
+ &substreams_[QuicUtils::GetPacketNumberSpace(level)].send_buffer;
QuicStreamOffset offset = send_buffer->stream_offset();
+
+ // Ensure this data does not cause the send buffer for this encryption level
+ // to exceed its size limit.
+ if (GetQuicReloadableFlag(quic_bounded_crypto_send_buffer)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_bounded_crypto_send_buffer);
+ QUIC_BUG_IF(quic_crypto_stream_offset_lt_bytes_written,
+ offset < send_buffer->stream_bytes_written());
+ uint64_t current_buffer_size =
+ offset - std::min(offset, send_buffer->stream_bytes_written());
+ if (current_buffer_size > 0) {
+ QUIC_CODE_COUNT(quic_received_crypto_data_with_non_empty_send_buffer);
+ if (BufferSizeLimitForLevel(level) <
+ (current_buffer_size + data.length())) {
+ QUIC_BUG(quic_crypto_send_buffer_overflow)
+ << absl::StrCat("Too much data for crypto send buffer with level: ",
+ EncryptionLevelToString(level),
+ ", current_buffer_size: ", current_buffer_size,
+ ", data length: ", data.length());
+ OnUnrecoverableError(QUIC_INTERNAL_ERROR,
+ "Too much data for crypto send buffer");
+ return;
+ }
+ }
+ }
+
+ // Append |data| to the send buffer for this encryption level.
send_buffer->SaveStreamData(data);
if (kMaxStreamLength - offset < data.length()) {
QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data";
- // TODO(nharper): Switch this to an IETF QUIC error code, possibly
- // INTERNAL_ERROR?
- OnUnrecoverableError(QUIC_STREAM_LENGTH_OVERFLOW,
+ OnUnrecoverableError(QUIC_INTERNAL_ERROR,
"Writing too much crypto handshake data");
+ return;
}
if (had_buffered_data) {
// Do not try to write if there is buffered data.
@@ -165,8 +199,9 @@ size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
QuicTime::Delta /*ack_delay_time*/) {
QuicByteCount newly_acked_length = 0;
- if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
- frame.offset, frame.data_length, &newly_acked_length)) {
+ if (!substreams_[QuicUtils::GetPacketNumberSpace(frame.level)]
+ .send_buffer.OnStreamDataAcked(frame.offset, frame.data_length,
+ &newly_acked_length)) {
OnUnrecoverableError(QUIC_INTERNAL_ERROR,
"Trying to ack unsent crypto data.");
return false;
@@ -193,9 +228,10 @@ void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
}
return;
}
- QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
- // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
- // replace the following code.
+ QuicStreamSendBuffer* send_buffer =
+ &substreams_[QuicUtils::GetPacketNumberSpace(level)].send_buffer;
+ // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer
+ // to replace the following code.
QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
to_ack.Complement(0, send_buffer->stream_offset());
for (const auto& interval : to_ack) {
@@ -217,22 +253,12 @@ void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
QuicStream::OnStreamDataConsumed(bytes_consumed);
}
-namespace {
-
-constexpr std::array<EncryptionLevel, NUM_ENCRYPTION_LEVELS>
-AllEncryptionLevels() {
- return {ENCRYPTION_INITIAL, ENCRYPTION_HANDSHAKE, ENCRYPTION_ZERO_RTT,
- ENCRYPTION_FORWARD_SECURE};
-}
-
-} // namespace
-
bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
return false;
}
- for (EncryptionLevel level : AllEncryptionLevels()) {
- if (substreams_[level].send_buffer.HasPendingRetransmission()) {
+ for (const auto& substream : substreams_) {
+ if (substream.send_buffer.HasPendingRetransmission()) {
return true;
}
}
@@ -243,12 +269,15 @@ void QuicCryptoStream::WritePendingCryptoRetransmission() {
QUIC_BUG_IF(quic_bug_12573_3,
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 don't write CRYPTO frames";
- for (EncryptionLevel level : AllEncryptionLevels()) {
- QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+ for (uint8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
+ auto packet_number_space = static_cast<PacketNumberSpace>(i);
+ QuicStreamSendBuffer* send_buffer =
+ &substreams_[packet_number_space].send_buffer;
while (send_buffer->HasPendingRetransmission()) {
auto pending = send_buffer->NextPendingRetransmission();
size_t bytes_consumed = stream_delegate()->SendCryptoData(
- level, pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
+ GetEncryptionLevelToSendCryptoDataOfSpace(packet_number_space),
+ pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
if (bytes_consumed < pending.length) {
return;
@@ -343,14 +372,17 @@ uint64_t QuicCryptoStream::crypto_bytes_read() const {
return stream_bytes_read();
}
uint64_t bytes_read = 0;
- for (EncryptionLevel level : AllEncryptionLevels()) {
- bytes_read += substreams_[level].sequencer.NumBytesConsumed();
+ for (const CryptoSubstream& substream : substreams_) {
+ bytes_read += substream.sequencer.NumBytesConsumed();
}
return bytes_read;
}
+// TODO(haoyuewang) Move this test-only method under
+// quiche/quic/test_tools.
uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
- return substreams_[level].sequencer.NumBytesConsumed();
+ return substreams_[QuicUtils::GetPacketNumberSpace(level)]
+ .sequencer.NumBytesConsumed();
}
bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
@@ -360,16 +392,17 @@ bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
QUIC_BUG_IF(quic_bug_12573_4,
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 don't write CRYPTO frames (2)";
- return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
- writer);
+ return substreams_[QuicUtils::GetPacketNumberSpace(level)]
+ .send_buffer.WriteStreamData(offset, data_length, writer);
}
void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
QUIC_BUG_IF(quic_bug_12573_5,
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 don't lose CRYPTO frames";
- substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
- crypto_frame->offset, crypto_frame->data_length);
+ substreams_[QuicUtils::GetPacketNumberSpace(crypto_frame->level)]
+ .send_buffer.OnStreamDataLost(crypto_frame->offset,
+ crypto_frame->data_length);
}
bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
@@ -380,7 +413,8 @@ bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
QuicIntervalSet<QuicStreamOffset> retransmission(
crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
QuicStreamSendBuffer* send_buffer =
- &substreams_[crypto_frame->level].send_buffer;
+ &substreams_[QuicUtils::GetPacketNumberSpace(crypto_frame->level)]
+ .send_buffer;
retransmission.Difference(send_buffer->bytes_acked());
if (retransmission.Empty()) {
return true;
@@ -388,9 +422,12 @@ bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
for (const auto& interval : retransmission) {
size_t retransmission_offset = interval.min();
size_t retransmission_length = interval.max() - interval.min();
+ EncryptionLevel retransmission_encryption_level =
+ GetEncryptionLevelToSendCryptoDataOfSpace(
+ QuicUtils::GetPacketNumberSpace(crypto_frame->level));
size_t bytes_consumed = stream_delegate()->SendCryptoData(
- crypto_frame->level, retransmission_length, retransmission_offset,
- type);
+ retransmission_encryption_level, retransmission_length,
+ retransmission_offset, type);
send_buffer->OnStreamDataRetransmitted(retransmission_offset,
bytes_consumed);
if (bytes_consumed < retransmission_length) {
@@ -404,8 +441,10 @@ void QuicCryptoStream::WriteBufferedCryptoFrames() {
QUIC_BUG_IF(quic_bug_12573_7,
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 don't use CRYPTO frames";
- for (EncryptionLevel level : AllEncryptionLevels()) {
- QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
+ for (uint8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
+ auto packet_number_space = static_cast<PacketNumberSpace>(i);
+ QuicStreamSendBuffer* send_buffer =
+ &substreams_[packet_number_space].send_buffer;
const size_t data_length =
send_buffer->stream_offset() - send_buffer->stream_bytes_written();
if (data_length == 0) {
@@ -413,8 +452,8 @@ void QuicCryptoStream::WriteBufferedCryptoFrames() {
continue;
}
size_t bytes_consumed = stream_delegate()->SendCryptoData(
- level, data_length, send_buffer->stream_bytes_written(),
- NOT_RETRANSMISSION);
+ GetEncryptionLevelToSendCryptoDataOfSpace(packet_number_space),
+ data_length, send_buffer->stream_bytes_written(), NOT_RETRANSMISSION);
send_buffer->OnStreamDataConsumed(bytes_consumed);
if (bytes_consumed < data_length) {
// Connection is write blocked.
@@ -427,8 +466,8 @@ bool QuicCryptoStream::HasBufferedCryptoFrames() const {
QUIC_BUG_IF(quic_bug_12573_8,
!QuicVersionUsesCryptoFrames(session()->transport_version()))
<< "Versions less than 47 don't use CRYPTO frames";
- for (EncryptionLevel level : AllEncryptionLevels()) {
- const QuicStreamSendBuffer& send_buffer = substreams_[level].send_buffer;
+ for (const CryptoSubstream& substream : substreams_) {
+ const QuicStreamSendBuffer& send_buffer = substream.send_buffer;
QUICHE_DCHECK_GE(send_buffer.stream_offset(),
send_buffer.stream_bytes_written());
if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
@@ -449,15 +488,16 @@ bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level, size_t offset,
// the wrong transport version.
return false;
}
- return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, length);
+ return substreams_[QuicUtils::GetPacketNumberSpace(level)]
+ .send_buffer.IsStreamDataOutstanding(offset, length);
}
bool QuicCryptoStream::IsWaitingForAcks() const {
if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
return QuicStream::IsWaitingForAcks();
}
- for (EncryptionLevel level : AllEncryptionLevels()) {
- if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
+ for (const CryptoSubstream& substream : substreams_) {
+ if (substream.send_buffer.stream_bytes_outstanding()) {
return true;
}
}
@@ -465,7 +505,7 @@ bool QuicCryptoStream::IsWaitingForAcks() const {
}
QuicCryptoStream::CryptoSubstream::CryptoSubstream(
- QuicCryptoStream* crypto_stream, EncryptionLevel)
+ QuicCryptoStream* crypto_stream)
: sequencer(crypto_stream),
send_buffer(crypto_stream->session()
->connection()
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h
index 9e9b8702228..6d29d4b73ad 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h
@@ -236,17 +236,27 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
EncryptionLevel level);
- QuicStreamSequencer* GetStreamSequencerForLevel(EncryptionLevel level) {
- return &substreams_[level].sequencer;
+ QuicStreamSequencer* GetStreamSequencerForPacketNumberSpace(
+ PacketNumberSpace packet_number_space) {
+ return &substreams_[packet_number_space].sequencer;
}
+ // Called by OnCryptoFrame to check if a CRYPTO frame is received at an
+ // expected `level`.
+ virtual bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const = 0;
+
+ // Called to determine the encryption level to send/retransmit crypto data.
+ virtual EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const = 0;
+
private:
- // Data sent and received in CRYPTO frames is sent at multiple encryption
- // levels. Some of the state for the single logical crypto stream is split
- // across encryption levels, and a CryptoSubstream is used to manage that
- // state for a particular encryption level.
+ // Data sent and received in CRYPTO frames is sent at multiple packet number
+ // spaces. Some of the state for the single logical crypto stream is split
+ // across packet number spaces, and a CryptoSubstream is used to manage that
+ // state for a particular packet number space.
struct QUIC_EXPORT_PRIVATE CryptoSubstream {
- CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
+ CryptoSubstream(QuicCryptoStream* crypto_stream);
QuicStreamSequencer sequencer;
QuicStreamSendBuffer send_buffer;
@@ -257,9 +267,9 @@ class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
// TLS 1.3, which never encrypts crypto data.
QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
- // Keeps state for data sent/received in CRYPTO frames at each encryption
- // level.
- std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
+ // Keeps state for data sent/received in CRYPTO frames at each packet number
+ // space;
+ std::array<CryptoSubstream, NUM_PACKET_NUMBER_SPACES> substreams_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream_test.cc
index 6df498301fc..f5d1f2e2fdc 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream_test.cc
@@ -13,10 +13,14 @@
#include "quiche/quic/core/crypto/crypto_handshake.h"
#include "quiche/quic/core/crypto/crypto_protocol.h"
#include "quiche/quic/core/crypto/null_encrypter.h"
+#include "quiche/quic/core/quic_error_codes.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
#include "quiche/quic/test_tools/quic_stream_peer.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
@@ -95,6 +99,27 @@ class MockQuicCryptoStream : public QuicCryptoStream,
}
SSL* GetSsl() const override { return nullptr; }
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override {
+ return level != ENCRYPTION_ZERO_RTT;
+ }
+
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return QuicCryptoStream::session()
+ ->GetEncryptionLevelToSendApplicationData();
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+ }
+
private:
quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
std::vector<CryptoHandshakeMessage> messages_;
@@ -260,6 +285,17 @@ TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
+
+ // Before encryption moves to ENCRYPTION_FORWARD_SECURE, ZERO RTT data are
+ // retranmitted at ENCRYPTION_ZERO_RTT.
+ QuicCryptoFrame lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
+ stream_->OnCryptoFrameLost(&lost_frame);
+
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+ .WillOnce(Invoke(connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ stream_->WritePendingCryptoRetransmission();
+
connection_->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
@@ -267,7 +303,7 @@ TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
// Lost [0, 1000).
- QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+ lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 0, 1000);
stream_->OnCryptoFrameLost(&lost_frame);
EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
// Lost [1200, 2000).
@@ -283,7 +319,7 @@ TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_FORWARD_SECURE, 650, 0))
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
stream_->WritePendingCryptoRetransmission();
@@ -527,7 +563,7 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
// Retransmit only [1350, 1500).
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_FORWARD_SECURE, 150, 0))
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
@@ -537,10 +573,11 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
// Retransmit [1350, 2700) again and all data is sent.
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_FORWARD_SECURE, 650, 0))
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
+ EXPECT_CALL(*connection_,
+ SendCryptoData(ENCRYPTION_FORWARD_SECURE, 200, 1150))
.WillOnce(Invoke(connection_,
&MockQuicConnection::QuicConnection_SendCryptoData));
frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
@@ -617,6 +654,50 @@ TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
}
}
+TEST_F(QuicCryptoStreamTest, WriteCryptoDataExceedsSendBufferLimit) {
+ if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ return;
+ }
+ EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+ int32_t buffer_limit = GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes);
+
+ // Write data larger than the buffer limit, when there is no existing data in
+ // the buffer. Data is sent rather than closing the connection.
+ EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+ int32_t over_limit = buffer_limit + 1;
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, over_limit, 0))
+ // All the data is sent, no resulting buffer.
+ .WillOnce(Return(over_limit));
+ std::string large_data(over_limit, 'a');
+ stream_->WriteCryptoData(ENCRYPTION_INITIAL, large_data);
+
+ // Write data to the buffer up to the limit. One byte gets sent.
+ EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
+ EXPECT_CALL(*connection_,
+ SendCryptoData(ENCRYPTION_INITIAL, buffer_limit, over_limit))
+ .WillOnce(Return(1));
+ std::string data(buffer_limit, 'a');
+ stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+ EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+
+ // Write another byte that is not sent (due to there already being data in the
+ // buffer); send buffer is now full.
+ EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+ std::string data2(1, 'a');
+ stream_->WriteCryptoData(ENCRYPTION_INITIAL, data2);
+ EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
+
+ // Writing an additional byte to the send buffer closes the connection.
+ if (GetQuicReloadableFlag(quic_bounded_crypto_send_buffer)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_bounded_crypto_send_buffer);
+ EXPECT_CALL(*connection_, CloseConnection(QUIC_INTERNAL_ERROR, _, _));
+ EXPECT_QUIC_BUG(
+ stream_->WriteCryptoData(ENCRYPTION_INITIAL, data2),
+ "Too much data for crypto send buffer with level: ENCRYPTION_INITIAL, "
+ "current_buffer_size: 16384, data length: 1");
+ }
+}
+
TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
return;
@@ -674,6 +755,20 @@ TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
}
+TEST_F(QuicCryptoStreamTest, CloseConnectionWithZeroRttCryptoFrame) {
+ if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ return;
+ }
+
+ EXPECT_CALL(*connection_,
+ CloseConnection(IETF_QUIC_PROTOCOL_VIOLATION, _, _));
+
+ test::QuicConnectionPeer::SetLastDecryptedLevel(connection_,
+ ENCRYPTION_ZERO_RTT);
+ QuicStreamOffset offset = 1;
+ stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_ZERO_RTT, offset, "data"));
+}
+
TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
return;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.cc
index e133bb05250..9166a931397 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "absl/base/optimization.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/chlo_extractor.h"
@@ -147,6 +148,7 @@ class PacketCollector : public QuicPacketCreator::DelegateInterface,
class StatelessConnectionTerminator {
public:
StatelessConnectionTerminator(QuicConnectionId server_connection_id,
+ QuicConnectionId original_server_connection_id,
const ParsedQuicVersion version,
QuicConnectionHelperInterface* helper,
QuicTimeWaitListManager* time_wait_list_manager)
@@ -158,7 +160,8 @@ class StatelessConnectionTerminator {
creator_(server_connection_id, &framer_, &collector_),
time_wait_list_manager_(time_wait_list_manager) {
framer_.set_data_producer(&collector_);
- framer_.SetInitialObfuscators(server_connection_id);
+ // Always set encrypter with original_server_connection_id.
+ framer_.SetInitialObfuscators(original_server_connection_id);
}
~StatelessConnectionTerminator() {
@@ -504,19 +507,21 @@ constexpr bool IsSourceUdpPortBlocked(uint16_t port) {
111, // Portmap.
123, // NTP, vulnerable to reflection attacks.
137, // NETBIOS Name Service,
- 128, // NETBIOS Datagram Service
+ 138, // NETBIOS Datagram Service
161, // SNMP.
389, // CLDAP.
500, // IKE, can loop with QUIC.
1900, // SSDP, vulnerable to reflection attacks.
+ 3702, // WS-Discovery, vulnerable to reflection attacks.
5353, // mDNS, vulnerable to reflection attacks.
+ 5355, // LLMNR, vulnerable to reflection attacks.
11211, // memcache, vulnerable to reflection attacks.
// This list MUST be sorted in increasing order.
};
constexpr size_t num_blocked_ports = ABSL_ARRAYSIZE(blocked_ports);
constexpr uint16_t highest_blocked_port =
blocked_ports[num_blocked_ports - 1];
- if (QUICHE_PREDICT_TRUE(port > highest_blocked_port)) {
+ if (ABSL_PREDICT_TRUE(port > highest_blocked_port)) {
// Early-return to skip comparisons for the majority of traffic.
return false;
}
@@ -899,8 +904,9 @@ void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
// This serializes a connection close termination packet and adds the
// connection to the time wait list.
StatelessConnectionTerminator terminator(
- server_connection_id, connection->version(), helper_.get(),
- time_wait_list_manager_.get());
+ server_connection_id,
+ connection->GetOriginalDestinationConnectionId(),
+ connection->version(), helper_.get(), time_wait_list_manager_.get());
terminator.CloseConnection(
QUIC_HANDSHAKE_FAILED,
"Connection is closed by server before handshake confirmed",
@@ -1135,9 +1141,9 @@ void QuicDispatcher::StatelesslyTerminateConnection(
<< version << ", error_code:" << error_code
<< ", error_details:" << error_details;
- StatelessConnectionTerminator terminator(server_connection_id, version,
- helper_.get(),
- time_wait_list_manager_.get());
+ StatelessConnectionTerminator terminator(
+ server_connection_id, server_connection_id, version, helper_.get(),
+ time_wait_list_manager_.get());
// This also adds the connection to time wait list.
terminator.CloseConnection(
error_code, error_details, format != GOOGLE_QUIC_PACKET,
@@ -1311,7 +1317,7 @@ void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
std::unique_ptr<QuicSession> session = CreateQuicSession(
packet_info->destination_connection_id, packet_info->self_address,
packet_info->peer_address, alpn, packet_info->version, parsed_chlo);
- if (QUIC_PREDICT_FALSE(session == nullptr)) {
+ if (ABSL_PREDICT_FALSE(session == nullptr)) {
QUIC_BUG(quic_bug_10287_8)
<< "CreateQuicSession returned nullptr for "
<< packet_info->destination_connection_id << " from "
@@ -1319,7 +1325,9 @@ void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
<< " ALPN \"" << alpn << "\" version " << packet_info->version;
return;
}
- if (original_connection_id != packet_info->destination_connection_id) {
+ const bool replaced_connection_id =
+ original_connection_id != packet_info->destination_connection_id;
+ if (replaced_connection_id) {
session->connection()->SetOriginalDestinationConnectionId(
original_connection_id);
}
@@ -1340,8 +1348,11 @@ void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
}
session_ptr = insertion_result.first->second.get();
std::list<BufferedPacket> packets =
- buffered_packets_.DeliverPackets(packet_info->destination_connection_id)
- .buffered_packets;
+ buffered_packets_.DeliverPackets(original_connection_id).buffered_packets;
+ if (replaced_connection_id && !packets.empty()) {
+ QUIC_CODE_COUNT(
+ quic_delivered_buffered_packets_to_connection_with_replaced_id);
+ }
// Process CHLO at first.
session_ptr->ProcessUdpPacket(packet_info->self_address,
packet_info->peer_address, packet_info->packet);
@@ -1390,7 +1401,6 @@ void QuicDispatcher::MaybeResetPacketsWithNoVersion(
// recently.
if (recent_stateless_reset_addresses_.contains(packet_info.peer_address)) {
QUIC_CODE_COUNT(quic_donot_send_reset_repeatedly);
- QUICHE_DCHECK(use_recent_reset_addresses_);
return;
}
if (packet_info.form != GOOGLE_QUIC_PACKET) {
@@ -1410,24 +1420,21 @@ void QuicDispatcher::MaybeResetPacketsWithNoVersion(
return;
}
}
- if (use_recent_reset_addresses_) {
- QUIC_RESTART_FLAG_COUNT(quic_use_recent_reset_addresses);
- // Do not send a stateless reset if there are too many stateless reset
- // addresses.
- if (recent_stateless_reset_addresses_.size() >=
- GetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses)) {
- QUIC_CODE_COUNT(quic_too_many_recent_reset_addresses);
- return;
- }
- if (recent_stateless_reset_addresses_.empty()) {
- clear_stateless_reset_addresses_alarm_->Update(
- helper()->GetClock()->ApproximateNow() +
- QuicTime::Delta::FromMilliseconds(GetQuicFlag(
- FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms)),
- QuicTime::Delta::Zero());
- }
- recent_stateless_reset_addresses_.emplace(packet_info.peer_address);
+ // Do not send a stateless reset if there are too many stateless reset
+ // addresses.
+ if (recent_stateless_reset_addresses_.size() >=
+ GetQuicFlag(FLAGS_quic_max_recent_stateless_reset_addresses)) {
+ QUIC_CODE_COUNT(quic_too_many_recent_reset_addresses);
+ return;
+ }
+ if (recent_stateless_reset_addresses_.empty()) {
+ clear_stateless_reset_addresses_alarm_->Update(
+ helper()->GetClock()->ApproximateNow() +
+ QuicTime::Delta::FromMilliseconds(GetQuicFlag(
+ FLAGS_quic_recent_stateless_reset_addresses_lifetime_ms)),
+ QuicTime::Delta::Zero());
}
+ recent_stateless_reset_addresses_.emplace(packet_info.peer_address);
time_wait_list_manager()->SendPublicReset(
packet_info.self_address, packet_info.peer_address,
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h
index 74ac6947b55..f53df8b2447 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h
@@ -467,9 +467,6 @@ class QUIC_NO_EXPORT QuicDispatcher
// If true, change expected_server_connection_id_length_ to be the received
// destination connection ID length of all IETF long headers.
bool should_update_expected_server_connection_id_length_;
-
- const bool use_recent_reset_addresses_ =
- GetQuicRestartFlag(quic_use_recent_reset_addresses);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher_test.cc
index 3dad09673a2..e5e6ea2c14e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_dispatcher_test.cc
@@ -490,7 +490,8 @@ class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
ProcessFirstFlight(version, client_address, connection_id);
}
- void TestTlsMultiPacketClientHello(bool add_reordering);
+ void TestTlsMultiPacketClientHello(bool add_reordering,
+ bool long_connection_id);
void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
const QuicConnectionId& server_connection_id,
@@ -560,14 +561,23 @@ TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
}
void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
- bool add_reordering) {
+ bool add_reordering, bool long_connection_id) {
if (!version_.UsesTls()) {
return;
}
SetAddressToken("857293462398");
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
- QuicConnectionId server_connection_id = TestConnectionId();
+ QuicConnectionId original_connection_id, new_connection_id;
+ if (long_connection_id) {
+ original_connection_id = QuicConnectionId(
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09});
+ new_connection_id =
+ QuicConnectionId({0x6c, 0x6b, 0x4b, 0xad, 0x8d, 0x00, 0x24, 0xd8});
+ } else {
+ original_connection_id = TestConnectionId();
+ new_connection_id = original_connection_id;
+ }
QuicConfig client_config = DefaultQuicConfig();
// Add a 2000-byte custom parameter to increase the length of the CHLO.
constexpr auto kCustomParameterId =
@@ -576,7 +586,7 @@ void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
kCustomParameterValue;
std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
- GetFirstFlightOfPackets(version_, client_config, server_connection_id,
+ GetFirstFlightOfPackets(version_, client_config, original_connection_id,
EmptyQuicConnectionId(),
TestClientCryptoConfig());
ASSERT_EQ(packets.size(), 2u);
@@ -585,11 +595,12 @@ void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
}
// Processing the first packet should not create a new session.
- EXPECT_CALL(*dispatcher_,
- ShouldCreateOrBufferPacketForConnection(
- ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
+ EXPECT_CALL(
+ *dispatcher_,
+ ShouldCreateOrBufferPacketForConnection(
+ ReceivedPacketInfoConnectionIdEquals(original_connection_id)));
ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
- server_connection_id);
+ original_connection_id);
EXPECT_EQ(dispatcher_->NumSessions(), 0u)
<< "No session should be created before the rest of the CHLO arrives.";
@@ -597,10 +608,10 @@ void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
// Processing the second packet should create the new session.
EXPECT_CALL(
*dispatcher_,
- CreateQuicSession(server_connection_id, _, client_address,
+ CreateQuicSession(new_connection_id, _, client_address,
Eq(ExpectedAlpn()), _, Eq(ParsedClientHelloForTest())))
.WillOnce(Return(ByMove(CreateSession(
- dispatcher_.get(), config_, server_connection_id, client_address,
+ dispatcher_.get(), config_, new_connection_id, client_address,
&mock_helper_, &mock_alarm_factory_, &crypto_config_,
QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
@@ -608,16 +619,29 @@ void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
.Times(2);
ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
- server_connection_id);
+ original_connection_id);
EXPECT_EQ(dispatcher_->NumSessions(), 1u);
}
TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
- TestTlsMultiPacketClientHello(/*add_reordering=*/false);
+ TestTlsMultiPacketClientHello(/*add_reordering=*/false,
+ /*long_connection_id=*/false);
}
TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
- TestTlsMultiPacketClientHello(/*add_reordering=*/true);
+ TestTlsMultiPacketClientHello(/*add_reordering=*/true,
+ /*long_connection_id=*/false);
+}
+
+TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithLongId) {
+ TestTlsMultiPacketClientHello(/*add_reordering=*/false,
+ /*long_connection_id=*/true);
+}
+
+TEST_P(QuicDispatcherTestAllVersions,
+ TlsMultiPacketClientHelloWithReorderingAndLongId) {
+ TestTlsMultiPacketClientHello(/*add_reordering=*/true,
+ /*long_connection_id=*/true);
}
TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
@@ -979,15 +1003,10 @@ TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
QuicConnectionId connection_id = TestConnectionId(1);
- if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
- // Verify only one reset is sent to the address, although multiple packets
- // are received.
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(1);
- } else {
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(3);
- }
+ // Verify only one reset is sent to the address, although multiple packets
+ // are received.
+ EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+ .Times(1);
ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
"data");
ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
@@ -1024,43 +1043,25 @@ TEST_P(QuicDispatcherTestAllVersions,
const QuicTime expected_deadline =
mock_helper_.GetClock()->Now() +
QuicTime::Delta::FromMilliseconds(kTestLifeTimeMs);
- if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
- ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
- EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
- } else {
- EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
- }
+ ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+ EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
// Received no version packet 2 after 5ms.
mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
"data");
- if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
- ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
- // Verify deadline does not change.
- EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
- } else {
- EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
- }
- if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
- // Verify reset gets throttled since there are too many recent addresses.
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(0);
- } else {
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(1);
- }
+ ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
+ // Verify deadline does not change.
+ EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
+ // Verify reset gets throttled since there are too many recent addresses.
+ EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+ .Times(0);
ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
"data");
mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
- if (GetQuicRestartFlag(quic_use_recent_reset_addresses)) {
- GetClearResetAddressesAlarm()->Fire();
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(2);
- } else {
- EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
- .Times(3);
- }
+ GetClearResetAddressesAlarm()->Fire();
+ EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
+ .Times(2);
ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
"data");
ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
@@ -2161,20 +2162,23 @@ TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
TEST_P(QuicDispatcherWriteBlockedListTest,
RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
- dispatcher_->OnConnectionClosed(connection1()->connection_id(),
- QUIC_PACKET_WRITE_ERROR, "Closed by test.",
- ConnectionCloseSource::FROM_SELF);
-
- SetBlocked();
-
- ASSERT_FALSE(dispatcher_->HasPendingWrites());
- SetBlocked();
- dispatcher_->OnWriteBlocked(connection1());
- ASSERT_TRUE(dispatcher_->HasPendingWrites());
-
- EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
- "QuicConnection was in WriteBlockedList before destruction");
- MarkSession1Deleted();
+ EXPECT_QUIC_BUG(
+ {
+ dispatcher_->OnConnectionClosed(
+ connection1()->connection_id(), QUIC_PACKET_WRITE_ERROR,
+ "Closed by test.", ConnectionCloseSource::FROM_SELF);
+
+ SetBlocked();
+
+ ASSERT_FALSE(dispatcher_->HasPendingWrites());
+ SetBlocked();
+ dispatcher_->OnWriteBlocked(connection1());
+ ASSERT_TRUE(dispatcher_->HasPendingWrites());
+
+ dispatcher_->DeleteSessions();
+ MarkSession1Deleted();
+ },
+ "QuicConnection was in WriteBlockedList before destruction");
}
class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_clock_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_clock_test.cc
index e501fc41b65..617230f9c93 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_clock_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_clock_test.cc
@@ -44,70 +44,6 @@ TEST_F(QuicEpollClockTest, NowInUsec) {
EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
}
-TEST_F(QuicEpollClockTest, CalibrateRealEpollClock) {
- QuicEpollServer epoll_server;
-
- QuicEpollClock uncalibrated_clock(&epoll_server);
- QuicEpollClock calibrated_clock(&epoll_server);
- EXPECT_TRUE(calibrated_clock.ComputeCalibrationOffset().IsZero());
-
- for (int i = 0; i < 100; ++i) {
- QuicWallTime wallnow = uncalibrated_clock.WallNow();
- EXPECT_EQ(uncalibrated_clock.ConvertWallTimeToQuicTime(wallnow),
- calibrated_clock.ConvertWallTimeToQuicTime(wallnow));
- }
-}
-
-// ClockWithOffset is a clock whose offset(WallNow() - Now() at any instant) is
-// given at construction time.
-class ClockWithOffset : public QuicEpollClock {
- public:
- ClockWithOffset(QuicEpollServer* epoll_server, QuicTime::Delta offset)
- : QuicEpollClock(epoll_server), offset_(offset) {}
-
- QuicTime Now() const override { return QuicEpollClock::Now() - offset_; }
-
- // QuicEpollClock disables ConvertWallTimeToQuicTime since it always have a
- // zero offset. We need to re-enable it here in order to test the calibration
- // and conversion code in QuicClock.
- QuicTime ConvertWallTimeToQuicTime(
- const QuicWallTime& walltime) const override {
- return QuicClock::ConvertWallTimeToQuicTime(walltime);
- }
-
- private:
- QuicTime::Delta offset_;
-};
-
-TEST_F(QuicEpollClockTest, CalibrateClockWithOffset) {
- QuicEpollServer epoll_server;
-
- for (const QuicTime::Delta& offset : {QuicTime::Delta::FromSeconds(5000),
- QuicTime::Delta::FromSeconds(-8000)}) {
- ClockWithOffset clock(&epoll_server, offset);
- ASSERT_EQ(offset, clock.ComputeCalibrationOffset())
- << "offset (us): " << offset.ToMicroseconds();
- // Test fails without this.
- clock.SetCalibrationOffset(offset);
-
- QuicWallTime last_walltime = clock.WallNow();
- QuicTime last_time = clock.ConvertWallTimeToQuicTime(last_walltime);
-
- for (int i = 0; i < 1e5; ++i) {
- QuicWallTime wallnow = clock.WallNow();
- QuicTime now = clock.ConvertWallTimeToQuicTime(wallnow);
-
- if (wallnow.IsAfter(last_walltime)) {
- ASSERT_LT(0, (now - last_time).ToMicroseconds())
- << "offset (us): " << offset.ToMicroseconds();
-
- last_walltime = wallnow;
- last_time = now;
- }
- }
- }
-}
-
TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) {
QuicEpollServer epoll_server;
QuicEpollClock clock(&epoll_server);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_connection_helper.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_connection_helper.h
index a4247709ab3..dfc26491def 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_connection_helper.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_epoll_connection_helper.h
@@ -19,7 +19,7 @@
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/platform/api/quic_epoll.h"
-#include "quiche/quic/platform/api/quic_stream_buffer_allocator.h"
+#include "quiche/common/platform/api/quiche_stream_buffer_allocator.h"
#include "quiche/common/simple_buffer_allocator.h"
namespace quic {
@@ -48,7 +48,7 @@ class QUIC_EXPORT_PRIVATE QuicEpollConnectionHelper
QuicRandom* random_generator_;
// Set up allocators. They take up minimal memory before use.
// Allocator for stream send buffers.
- QuicStreamBufferAllocator stream_buffer_allocator_;
+ quiche::QuicheStreamBufferAllocator stream_buffer_allocator_;
quiche::SimpleBufferAllocator simple_buffer_allocator_;
QuicAllocator allocator_type_;
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flags_list.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flags_list.h
index 12cac822d2b..0fbff267b5b 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flags_list.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flags_list.h
@@ -6,121 +6,109 @@
#ifdef QUIC_FLAG
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_set_burst_token, false)
-
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_offload_pacing_to_usps2, false)
+QUIC_FLAG(quic_restart_flag_quic_offload_pacing_to_usps2, false)
// A testonly reloadable flag that will always default to false.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_false, false)
+QUIC_FLAG(quic_reloadable_flag_quic_testonly_default_false, false)
// A testonly reloadable flag that will always default to true.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_testonly_default_true, true)
+QUIC_FLAG(quic_reloadable_flag_quic_testonly_default_true, true)
// A testonly restart flag that will always default to false.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false)
+QUIC_FLAG(quic_restart_flag_quic_testonly_default_false, false)
// A testonly restart flag that will always default to true.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
+QUIC_FLAG(quic_restart_flag_quic_testonly_default_true, true)
// If bytes in flight has dipped below 1.25*MaxBW in the last round, do not exit PROBE_UP due to excess queue buildup.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_no_probe_up_exit_if_no_queue, true)
-// If true, 1) QUIC connections will use a lower minimum for trusted initial rtt, 2) When TRTT is received, QUIC server sessions will mark the initial rtt from CachedNetworkParameters as trusted.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_lower_min_for_trusted_irtt, true)
-// If true, QUIC connection will be closed if it fails to serialize a coalesced packet.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_close_connection_if_fail_to_serialzie_coalesced_packet2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_no_probe_up_exit_if_no_queue, true)
// If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
+QUIC_FLAG(quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
// If true, QuicGsoBatchWriter will support release time if it is available and the process has the permission to do so.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_support_release_time_for_gso, false)
-// If true, TlsServerHandshaker will be able to 1) request client cert, and 2) verify the client cert in the virtual method TlsServerHandshaker::VerifyCertChain.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_tls_server_support_client_cert, true)
+QUIC_FLAG(quic_restart_flag_quic_support_release_time_for_gso, false)
+// If true, TlsHandshaker::AdvanceHandshake will check if connection is closed after SSL_do_handshake.
+QUIC_FLAG(quic_reloadable_flag_quic_tls_handshaker_check_connection_closed, true)
// If true, abort async QPACK header decompression in QuicSpdyStream::Reset() and in QuicSpdyStream::OnStreamReset().
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_abort_qpack_on_stream_reset, true)
+QUIC_FLAG(quic_reloadable_flag_quic_abort_qpack_on_stream_reset, true)
// If true, ack frequency frame can be sent from server to client.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true)
+QUIC_FLAG(quic_reloadable_flag_quic_can_send_ack_frequency, true)
// If true, allow client to enable BBRv2 on server via connection option \'B2ON\'.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true)
// If true, close read side but not write side in QuicSpdyStream::OnStreamReset().
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_on_stream_reset, true)
-// If true, consolidate more logic into SetRetransmissionAlarm to ensure the logic is applied consistently.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_simplify_set_retransmission_alarm, true)
-// If true, default on PTO which unifies TLP + RTO loss recovery.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_default_on_pto2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_fix_on_stream_reset, true)
+// If true, close the connection if a crypto send buffer exceeds its size limit.
+QUIC_FLAG(quic_reloadable_flag_quic_bounded_crypto_send_buffer, false)
+// If true, consider original connection ID as active before handshake completes.
+QUIC_FLAG(quic_reloadable_flag_quic_consider_original_connection_id_as_active_pre_handshake, true)
// If true, default-enable 5RTO blachole detection.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+// If true, deliver INITIAL packets before other types of packets in QuicBufferedPacketStore.
+QUIC_FLAG(quic_reloadable_flag_quic_deliver_initial_packets_first, true)
// If true, disable QUIC version Q043.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_version_q043, false)
// If true, disable QUIC version Q046.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q046, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_version_q046, false)
// If true, disable QUIC version Q050.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_version_q050, false)
// If true, disable QUIC version h3 (RFCv1).
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_rfcv1, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_version_rfcv1, false)
// If true, disable QUIC version h3-29.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_draft_29, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_version_draft_29, false)
// If true, disable blackhole detection on server side.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_server_blackhole_detection, false)
+QUIC_FLAG(quic_reloadable_flag_quic_disable_server_blackhole_detection, false)
+// If true, disable resumption when receiving NRES connection option.
+QUIC_FLAG(quic_reloadable_flag_quic_enable_disable_resumption, true)
// If true, discard INITIAL packet if the key has been dropped.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
-// If true, do not count bytes sent/received on the alternative path into the bytes sent/received on the default path.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_count_bytes_on_alternative_path_seperately, true)
+QUIC_FLAG(quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
+// If true, do not bundle ACK while sending PATH_CHALLENGE on alternative path.
+QUIC_FLAG(quic_reloadable_flag_quic_not_bundle_ack_on_alternative_path, true)
// If true, enable server retransmittable on wire PING.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_server_on_wire_ping, true)
-// If true, flush creator after coalesce packet of higher space.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_flush_after_coalesce_higher_space_packets, true)
+QUIC_FLAG(quic_reloadable_flag_quic_enable_server_on_wire_ping, true)
// If true, flush pending frames as well as pending padding bytes on connection migration.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_flush_pending_frames_and_padding_bytes_on_migration, true)
+QUIC_FLAG(quic_reloadable_flag_quic_flush_pending_frames_and_padding_bytes_on_migration, true)
// If true, ietf connection migration is no longer conditioned on connection option RVCM.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_remove_connection_migration_connection_option_v2, false)
-// If true, ignore incoming MAX_PUSH_ID frames (expect for enforcing frame type rules).
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_ignore_max_push_id, true)
+QUIC_FLAG(quic_reloadable_flag_quic_remove_connection_migration_connection_option_v2, false)
+// If true, include offset in QUIC STREAM_DATA_BLOCKED and DATA_BLOCKED frames.
+QUIC_FLAG(quic_reloadable_flag_quic_include_offset_in_blocked_frames, false)
// If true, include stream information in idle timeout connection close detail.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true)
-// If true, limit the size of HPACK encoder dynamic table to 16 kB. Only affects gQUIC; QPACK encoder dynamic table size used in IETF QUIC is already bounded.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_limit_encoder_dynamic_table_size, true)
+QUIC_FLAG(quic_reloadable_flag_quic_add_stream_info_to_idle_close_detail, true)
// If true, quic server will send ENABLE_CONNECT_PROTOCOL setting and and endpoint will validate required request/response headers and extended CONNECT mechanism and update code counts of valid/invalid headers.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_verify_request_headers_2, true)
-// If true, record addresses that server has sent reset to recently, and do not send reset if the address lives in the set.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_use_recent_reset_addresses, true)
+QUIC_FLAG(quic_reloadable_flag_quic_verify_request_headers_2, true)
// If true, reject or send error response code upon receiving invalid request or response headers. This flag depends on --gfe2_reloadable_flag_quic_verify_request_headers_2.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_act_upon_invalid_header, false)
+QUIC_FLAG(quic_reloadable_flag_quic_act_upon_invalid_header, false)
// If true, require handshake confirmation for QUIC connections, functionally disabling 0-rtt handshakes.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation, false)
+QUIC_FLAG(quic_reloadable_flag_quic_require_handshake_confirmation, false)
// If true, server proactively retires client issued connection ID on reverse path validation failure.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_retire_cid_on_reverse_path_validation_failure, true)
-// If true, servers drop received packets with changed server address.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_drop_packets_with_changed_server_address, true)
+QUIC_FLAG(quic_reloadable_flag_quic_retire_cid_on_reverse_path_validation_failure, true)
+// If true, server sends bandwidth eastimate when network is idle for a while.
+QUIC_FLAG(quic_restart_flag_quic_enable_sending_bandwidth_estimate_when_network_idle, true)
// If true, set burst token to 2 in cwnd bootstrapping experiment.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_bursts, false)
+QUIC_FLAG(quic_reloadable_flag_quic_conservative_bursts, false)
// If true, stop resetting ideal_next_packet_send_time_ in pacing sender.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
-// If true, update ACK timeout based on packet receipt time rather than now.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_update_ack_timeout_on_receipt_time, true)
+QUIC_FLAG(quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
// If true, use BBRv2 as the default congestion controller. Takes precedence over --quic_default_to_bbr.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr_v2, false)
+QUIC_FLAG(quic_reloadable_flag_quic_default_to_bbr_v2, false)
+// If true, use PING manager to manage the PING alarm.
+QUIC_FLAG(quic_reloadable_flag_quic_use_ping_manager2, true)
// If true, use new connection ID in connection migration.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_migration_use_new_cid_v2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_connection_migration_use_new_cid_v2, true)
// If true, uses conservative cwnd gain and pacing gain when cwnd gets bootstrapped.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false)
-// If true, validate that peer owns the new address once the server detects peer migration or is probed from that address, and also apply anti-amplification limit while sending to that address.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path3, true)
-// If true, when a packet is forced retransmitted, only set packet state if all data gets retransmitted.
-QUIC_FLAG(FLAGS_quic_restart_flag_quic_set_packet_state_if_all_data_retransmitted, true)
+QUIC_FLAG(quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false)
// When the flag is true, exit STARTUP after the same number of loss events as PROBE_UP.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_probe_up_loss_events, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_startup_probe_up_loss_events, true)
// When true, defaults to BBR congestion control instead of Cubic.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_to_bbr, false)
+QUIC_FLAG(quic_reloadable_flag_quic_default_to_bbr, false)
// When true, prevents QUIC\'s PacingSender from generating bursts when the congestion controller is CWND limited and not pacing limited.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_pacing_sender_bursts, true)
+QUIC_FLAG(quic_reloadable_flag_quic_fix_pacing_sender_bursts, true)
// When true, set the initial congestion control window from connection options in QuicSentPacketManager rather than TcpCubicSenderBytes.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, true)
+QUIC_FLAG(quic_reloadable_flag_quic_unified_iw_options, true)
// When true, support draft-ietf-quic-v2-01
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_version_2_draft_01, false)
+QUIC_FLAG(quic_reloadable_flag_quic_enable_version_2_draft_01, false)
// When true, the B203 connection option causes the Bbr2Sender to ignore inflight_hi during PROBE_UP and increase it when the bytes delivered without loss are higher.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_ignore_inflight_hi_in_probe_up, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_ignore_inflight_hi_in_probe_up, true)
// When true, the B205 connection option enables extra acked in STARTUP, and B204 adds new logic to decrease it whenever max bandwidth increases.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_startup_extra_acked, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_startup_extra_acked, true)
// When true, the B207 connection option causes BBR2 to exit STARTUP if a persistent queue of 2*BDP has existed for the entire round.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_exit_startup_on_persistent_queue2, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_exit_startup_on_persistent_queue2, true)
// When true, the BBQ0 connection option causes QUIC BBR2 to add bytes_acked to probe_up_acked if the connection hasn\'t been app-limited since inflight_hi was utilized.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_add_bytes_acked_after_inflight_hi_limited, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_add_bytes_acked_after_inflight_hi_limited, true)
// When true, the BBR4 copt sets the extra_acked window to 20 RTTs and BBR5 sets it to 40 RTTs.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_bbr2_extra_acked_window, true)
+QUIC_FLAG(quic_reloadable_flag_quic_bbr2_extra_acked_window, true)
#endif
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc
index 47d3c28cf03..4acdd513f3f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc
@@ -232,10 +232,10 @@ void QuicFlowController::UpdateReceiveWindowOffsetAndSendWindowUpdate(
SendWindowUpdate();
}
-bool QuicFlowController::ShouldSendBlocked() {
+void QuicFlowController::MaybeSendBlocked() {
if (SendWindowSize() != 0 ||
last_blocked_send_window_offset_ >= send_window_offset_) {
- return false;
+ return;
}
QUIC_DLOG(INFO) << ENDPOINT << LogLabel() << " is flow control blocked. "
<< "Send window: " << SendWindowSize()
@@ -247,7 +247,7 @@ bool QuicFlowController::ShouldSendBlocked() {
// Keep track of when we last sent a BLOCKED frame so that we only send one
// at a given send offset.
last_blocked_send_window_offset_ = send_window_offset_;
- return true;
+ session_->SendBlocked(id_, last_blocked_send_window_offset_);
}
bool QuicFlowController::UpdateSendWindowOffset(
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.h
index 7f68ff5c44c..eaf660a8d2f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.h
@@ -78,8 +78,8 @@ class QUIC_EXPORT_PRIVATE QuicFlowController
QuicByteCount receive_window_size() const { return receive_window_size_; }
- // Returns whether a BLOCKED frame should be sent.
- bool ShouldSendBlocked();
+ // Sends a BLOCKED frame if needed.
+ void MaybeSendBlocked();
// Returns true if flow control send limits have been reached.
bool IsBlocked() const;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc
index 20cb5994489..567b120e682 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_flow_controller_test.cc
@@ -18,6 +18,7 @@
using testing::_;
using testing::Invoke;
+using testing::StrictMock;
namespace quic {
namespace test {
@@ -43,7 +44,7 @@ class QuicFlowControllerTest : public QuicTest {
connection_->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullEncrypter>(connection_->perspective()));
- session_ = std::make_unique<MockQuicSession>(connection_);
+ session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
flow_controller_ = std::make_unique<QuicFlowController>(
session_.get(), stream_id_, /*is_connection_flow_controller*/ false,
send_window_, receive_window_, kStreamReceiveWindowLimit,
@@ -58,7 +59,7 @@ class QuicFlowControllerTest : public QuicTest {
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
MockQuicConnection* connection_;
- std::unique_ptr<MockQuicSession> session_;
+ std::unique_ptr<StrictMock<MockQuicSession>> session_;
MockFlowController session_flow_controller_;
bool should_auto_tune_receive_window_ = false;
};
@@ -81,7 +82,8 @@ TEST_F(QuicFlowControllerTest, SendingBytes) {
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
// BLOCKED frame should get sent.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(1);
+ flow_controller_->MaybeSendBlocked();
// Update the send window, and verify this has unblocked.
EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
@@ -93,13 +95,16 @@ TEST_F(QuicFlowControllerTest, SendingBytes) {
EXPECT_EQ(send_window_, flow_controller_->SendWindowSize());
// Try to send more bytes, violating flow control.
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _));
EXPECT_QUIC_BUG(
- flow_controller_->AddBytesSent(send_window_ * 10),
+ {
+ EXPECT_CALL(
+ *connection_,
+ CloseConnection(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA, _, _));
+ flow_controller_->AddBytesSent(send_window_ * 10);
+ EXPECT_TRUE(flow_controller_->IsBlocked());
+ EXPECT_EQ(0u, flow_controller_->SendWindowSize());
+ },
absl::StrCat("Trying to send an extra ", send_window_ * 10, " bytes"));
- EXPECT_TRUE(flow_controller_->IsBlocked());
- EXPECT_EQ(0u, flow_controller_->SendWindowSize());
}
TEST_F(QuicFlowControllerTest, ReceivingBytes) {
@@ -164,14 +169,16 @@ TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
// BLOCKED frame should get sent.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(1);
+ flow_controller_->MaybeSendBlocked();
// BLOCKED frame should not get sent again until our send offset changes.
- EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
- EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
- EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
- EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
- EXPECT_FALSE(flow_controller_->ShouldSendBlocked());
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(0);
+ flow_controller_->MaybeSendBlocked();
+ flow_controller_->MaybeSendBlocked();
+ flow_controller_->MaybeSendBlocked();
+ flow_controller_->MaybeSendBlocked();
+ flow_controller_->MaybeSendBlocked();
// Update the send window, then send enough bytes to block again.
EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_));
@@ -182,7 +189,8 @@ TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
// BLOCKED frame should get sent as send offset has changed.
- EXPECT_TRUE(flow_controller_->ShouldSendBlocked());
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(1);
+ flow_controller_->MaybeSendBlocked();
}
TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer.cc
index b0f5018b40b..b6b0c5bab51 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer.cc
@@ -3121,6 +3121,8 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
// static
bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
uint64_t frame_type, EncryptionLevel level) {
+ // IETF_CRYPTO is allowed for any level here and is separately checked in
+ // QuicCryptoStream::OnCryptoFrame.
switch (level) {
case ENCRYPTION_INITIAL:
case ENCRYPTION_HANDSHAKE:
@@ -3132,7 +3134,7 @@ bool QuicFramer::IsIetfFrameTypeExpectedForEncryptionLevel(
case ENCRYPTION_ZERO_RTT:
return !(frame_type == IETF_ACK || frame_type == IETF_ACK_ECN ||
frame_type == IETF_ACK_RECEIVE_TIMESTAMPS ||
- frame_type == IETF_CRYPTO || frame_type == IETF_HANDSHAKE_DONE ||
+ frame_type == IETF_HANDSHAKE_DONE ||
frame_type == IETF_NEW_TOKEN ||
frame_type == IETF_PATH_RESPONSE ||
frame_type == IETF_RETIRE_CONNECTION_ID);
@@ -5699,7 +5701,7 @@ bool QuicFramer::AppendAckFrameAndTypeByte(const QuicAckFrame& frame,
++num_ack_blocks_written;
}
if (num_ack_blocks_written >= num_ack_blocks) {
- if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
+ if (ABSL_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
QUIC_BUG(quic_bug_10850_85)
<< "Wrote " << num_ack_blocks_written << ", expected to write "
<< num_ack_blocks;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer_test.cc
index 77515102a35..9b022a2eff5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_framer_test.cc
@@ -10446,11 +10446,14 @@ TEST_P(QuicFramerTest, EncryptEmptyPacket) {
/*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
char buffer[kMaxOutgoingPacketSize];
size_t encrypted_length = 1;
- EXPECT_QUIC_BUG(encrypted_length = framer_.EncryptPayload(
- ENCRYPTION_INITIAL, kPacketNumber, *packet, buffer,
- kMaxOutgoingPacketSize),
- "packet is shorter than associated data length");
- EXPECT_EQ(0u, encrypted_length);
+ EXPECT_QUIC_BUG(
+ {
+ encrypted_length =
+ framer_.EncryptPayload(ENCRYPTION_INITIAL, kPacketNumber, *packet,
+ buffer, kMaxOutgoingPacketSize);
+ EXPECT_EQ(0u, encrypted_length);
+ },
+ "packet is shorter than associated data length");
}
TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc
index edb54836703..a5bd8ad208f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc
@@ -5,7 +5,10 @@
#include "quiche/quic/core/quic_idle_network_detector.h"
#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
+#include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
@@ -36,10 +39,18 @@ QuicIdleNetworkDetector::QuicIdleNetworkDetector(
time_of_last_received_packet_(now),
time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
idle_network_timeout_(QuicTime::Delta::Infinite()),
+ bandwidth_update_timeout_(QuicTime::Delta::Infinite()),
alarm_(alarm_factory->CreateAlarm(
arena->New<AlarmDelegate>(this, context), arena)) {}
void QuicIdleNetworkDetector::OnAlarm() {
+ if (!bandwidth_update_timeout_.IsInfinite()) {
+ QUICHE_DCHECK(handshake_timeout_.IsInfinite());
+ bandwidth_update_timeout_ = QuicTime::Delta::Infinite();
+ SetAlarm();
+ delegate_->OnBandwidthUpdateTimeout();
+ return;
+ }
if (handshake_timeout_.IsInfinite()) {
delegate_->OnIdleNetworkDetected();
return;
@@ -60,6 +71,15 @@ void QuicIdleNetworkDetector::SetTimeouts(
QuicTime::Delta handshake_timeout, QuicTime::Delta idle_network_timeout) {
handshake_timeout_ = handshake_timeout;
idle_network_timeout_ = idle_network_timeout;
+ bandwidth_update_timeout_ = QuicTime::Delta::Infinite();
+
+ if (GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle) &&
+ handshake_timeout_.IsInfinite()) {
+ QUIC_RESTART_FLAG_COUNT_N(
+ quic_enable_sending_bandwidth_estimate_when_network_idle, 1, 3);
+ bandwidth_update_timeout_ = idle_network_timeout_ * 0.5;
+ }
SetAlarm();
}
@@ -68,6 +88,7 @@ void QuicIdleNetworkDetector::StopDetection() {
alarm_->PermanentCancel();
handshake_timeout_ = QuicTime::Delta::Infinite();
idle_network_timeout_ = QuicTime::Delta::Infinite();
+ handshake_timeout_ = QuicTime::Delta::Infinite();
stopped_ = true;
}
@@ -115,6 +136,9 @@ void QuicIdleNetworkDetector::SetAlarm() {
new_deadline = idle_network_deadline;
}
}
+ if (!bandwidth_update_timeout_.IsInfinite()) {
+ new_deadline = std::min(new_deadline, GetBandwidthUpdateDeadline());
+ }
alarm_->Update(new_deadline, kAlarmGranularity);
}
@@ -141,4 +165,9 @@ QuicTime QuicIdleNetworkDetector::GetIdleNetworkDeadline() const {
return last_network_activity_time() + idle_network_timeout_;
}
+QuicTime QuicIdleNetworkDetector::GetBandwidthUpdateDeadline() const {
+ QUICHE_DCHECK(!bandwidth_update_timeout_.IsInfinite());
+ return last_network_activity_time() + bandwidth_update_timeout_;
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.h
index 0b5a20e1639..ca431482545 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.h
@@ -34,6 +34,9 @@ class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
// Called when idle network has been detected.
virtual void OnIdleNetworkDetected() = 0;
+
+ // Called when bandwidth update alarms.
+ virtual void OnBandwidthUpdateTimeout() = 0;
};
QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
@@ -73,6 +76,10 @@ class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
+ QuicTime::Delta bandwidth_update_timeout() const {
+ return bandwidth_update_timeout_;
+ }
+
QuicTime GetIdleNetworkDeadline() const;
private:
@@ -83,13 +90,15 @@ class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
+ QuicTime GetBandwidthUpdateDeadline() const;
+
Delegate* delegate_; // Not owned.
// Start time of the detector, handshake deadline = start_time_ +
// handshake_timeout_.
const QuicTime start_time_;
- // Handshake timeout. Infinit means handshake has completed.
+ // Handshake timeout. Infinite means handshake has completed.
QuicTime::Delta handshake_timeout_;
// Time that last packet is received for this connection. Initialized to
@@ -102,9 +111,12 @@ class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
// Initialized to 0.
QuicTime time_of_first_packet_sent_after_receiving_;
- // Idle network timeout. Infinit means no idle network timeout.
+ // Idle network timeout. Infinite means no idle network timeout.
QuicTime::Delta idle_network_timeout_;
+ // Bandwidth update timeout. Infinite means no bandwidth update timeout.
+ QuicTime::Delta bandwidth_update_timeout_;
+
QuicArenaScopedPtr<QuicAlarm> alarm_;
bool shorter_idle_timeout_on_sent_packet_ = false;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector_test.cc
index 31aa8b490ba..9105ec9e4ae 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector_test.cc
@@ -5,7 +5,9 @@
#include "quiche/quic/core/quic_idle_network_detector.h"
#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
@@ -25,6 +27,7 @@ class MockDelegate : public QuicIdleNetworkDetector::Delegate {
public:
MOCK_METHOD(void, OnHandshakeTimeout, (), (override));
MOCK_METHOD(void, OnIdleNetworkDetected, (), (override));
+ MOCK_METHOD(void, OnBandwidthUpdateTimeout, (), (override));
};
class QuicIdleNetworkDetectorTest : public QuicTest {
@@ -90,6 +93,8 @@ TEST_F(QuicIdleNetworkDetectorTest,
/*handshake_timeout=*/QuicTime::Delta::FromSeconds(30),
/*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(20),
+ alarm_->deadline());
// Handshake completes in 200ms.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
@@ -97,11 +102,30 @@ TEST_F(QuicIdleNetworkDetectorTest,
detector_->SetTimeouts(
/*handshake_timeout=*/QuicTime::Delta::Infinite(),
/*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+ if (!GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle)) {
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
+ alarm_->deadline());
+
+ // No network activity for 600s.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
+ EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+ alarm_->Fire();
+ return;
+ }
+
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(300),
+ alarm_->deadline());
+
+ // No network activity for 300s.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(300));
+ EXPECT_CALL(delegate_, OnBandwidthUpdateTimeout());
+ alarm_->Fire();
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(300),
alarm_->deadline());
// No network activity for 600s.
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600));
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(300));
EXPECT_CALL(delegate_, OnIdleNetworkDetected());
alarm_->Fire();
}
@@ -115,11 +139,16 @@ TEST_F(QuicIdleNetworkDetectorTest,
EXPECT_TRUE(alarm_->IsSet());
// Handshake completes in 200ms.
+ const bool enable_sending_bandwidth_estimate_when_network_idle =
+ GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle);
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
detector_->OnPacketReceived(clock_.Now());
detector_->SetTimeouts(
/*handshake_timeout=*/QuicTime::Delta::Infinite(),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(600));
+ enable_sending_bandwidth_estimate_when_network_idle
+ ? QuicTime::Delta::FromSeconds(1200)
+ : QuicTime::Delta::FromSeconds(600));
EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(600),
alarm_->deadline());
@@ -133,22 +162,46 @@ TEST_F(QuicIdleNetworkDetectorTest,
// Sent another packet after 200ms
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(200));
detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::Zero());
- // Verify idle network deadline does not extend.
+ // Verify network deadline does not extend.
EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(600),
alarm_->deadline());
- // No network activity for 600s.
+ if (!enable_sending_bandwidth_estimate_when_network_idle) {
+ // No network activity for 600s.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
+ QuicTime::Delta::FromMilliseconds(200));
+ EXPECT_CALL(delegate_, OnIdleNetworkDetected());
+ alarm_->Fire();
+ return;
+ }
+
+ // Bandwidth update times out after no network activity for 600s.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(600) -
QuicTime::Delta::FromMilliseconds(200));
+ EXPECT_CALL(delegate_, OnBandwidthUpdateTimeout());
+ alarm_->Fire();
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(packet_sent_time + QuicTime::Delta::FromSeconds(1200),
+ alarm_->deadline());
+
+ // Network idle time out after no network activity for 1200s.
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1200) -
+ QuicTime::Delta::FromMilliseconds(600));
EXPECT_CALL(delegate_, OnIdleNetworkDetected());
alarm_->Fire();
}
TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
detector_->enable_shorter_idle_timeout_on_sent_packet();
+ QuicTime::Delta idle_network_timeout = QuicTime::Delta::Zero();
+ if (GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle)) {
+ idle_network_timeout = QuicTime::Delta::FromSeconds(60);
+ } else {
+ idle_network_timeout = QuicTime::Delta::FromSeconds(30);
+ }
detector_->SetTimeouts(
- /*handshake_timeout=*/QuicTime::Delta::Infinite(),
- /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(30));
+ /*handshake_timeout=*/QuicTime::Delta::Infinite(), idle_network_timeout);
EXPECT_TRUE(alarm_->IsSet());
const QuicTime deadline = alarm_->deadline();
EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30), deadline);
@@ -175,7 +228,7 @@ TEST_F(QuicIdleNetworkDetectorTest, ShorterIdleTimeoutOnSentPacket) {
EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(30),
alarm_->deadline());
- // Send a packet near timeout..
+ // Send a packet near timeout.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(29));
detector_->OnPacketSent(clock_.Now(), QuicTime::Delta::FromSeconds(2));
EXPECT_TRUE(alarm_->IsSet());
@@ -194,6 +247,35 @@ TEST_F(QuicIdleNetworkDetectorTest, NoAlarmAfterStopped) {
EXPECT_FALSE(alarm_->IsSet());
}
+TEST_F(QuicIdleNetworkDetectorTest,
+ ResetBandwidthTimeoutWhenHandshakeTimeoutIsSet) {
+ if (!GetQuicRestartFlag(
+ quic_enable_sending_bandwidth_estimate_when_network_idle)) {
+ return;
+ }
+ detector_->SetTimeouts(
+ /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+ /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+ // The deadline is set based on the bandwidth timeout.
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(10),
+ alarm_->deadline());
+
+ detector_->SetTimeouts(
+ /*handshake_timeout=*/QuicTime::Delta::FromSeconds(15),
+ /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+ // Bandwidth timeout is reset and the deadline is set based on the handshake
+ // timeout.
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(15),
+ alarm_->deadline());
+
+ detector_->SetTimeouts(
+ /*handshake_timeout=*/QuicTime::Delta::Infinite(),
+ /*idle_network_timeout=*/QuicTime::Delta::FromSeconds(20));
+ // The deadline is set based on the bandwidth timeout.
+ EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromSeconds(10),
+ alarm_->deadline());
+}
+
} // namespace
} // namespace test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_deque.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_deque.h
index eff9f63a4db..ed13e7a44df 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_deque.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_deque.h
@@ -137,7 +137,7 @@ class QuicIntervalDequePeer;
// // cached_index -> 1
// // container -> {{2, [25, 30)}, {3, [35, 50)}}
-template <class T, class C = QUIC_NO_EXPORT quiche::QuicheCircularDeque<T>>
+template <class T, class C = quiche::QuicheCircularDeque<T>>
class QUIC_NO_EXPORT QuicIntervalDeque {
public:
class QUIC_NO_EXPORT Iterator {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_set.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_set.h
index 7e2b11bda6d..7de036219e1 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_set.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_interval_set.h
@@ -60,8 +60,8 @@
#include <vector>
#include "quiche/quic/core/quic_interval.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_containers.h"
namespace quic {
@@ -85,7 +85,7 @@ class QUIC_NO_EXPORT QuicIntervalSet {
bool operator()(T&& point, const value_type& a) const;
};
- using Set = QuicSmallOrderedSet<value_type, IntervalLess>;
+ using Set = quiche::QuicheSmallOrderedSet<value_type, IntervalLess>;
public:
using const_iterator = typename Set::const_iterator;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena.h
index 4bebebea565..cb44217b034 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena.h
@@ -12,6 +12,7 @@
#include <cstdint>
+#include "absl/base/optimization.h"
#include "quiche/quic/core/quic_arena_scoped_ptr.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
@@ -37,7 +38,7 @@ class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
<< "Object is too large for the arena.";
static_assert(alignof(T) > 1,
"Objects added to the arena must be at least 2B aligned.");
- if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
+ if (ABSL_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
QUIC_BUG(quic_bug_10593_1)
<< "Ran out of space in QuicOneBlockArena at " << this
<< ", max size was " << ArenaSize << ", failing request was "
@@ -69,7 +70,7 @@ class QUIC_EXPORT_PRIVATE QuicOneBlockArena {
// QuicConnections currently use around 1KB of polymorphic types which would
// ordinarily be on the heap. Instead, store them inline in an arena.
-using QuicConnectionArena = QuicOneBlockArena<1152>;
+using QuicConnectionArena = QuicOneBlockArena<1280>;
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena_test.cc
index 89c774d2955..5c1079b7730 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_one_block_arena_test.cc
@@ -6,12 +6,11 @@
#include <cstdint>
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
-namespace quic {
+namespace quic::test {
namespace {
static const uint32_t kMaxAlign = 8;
@@ -57,4 +56,4 @@ TEST_F(QuicOneBlockArenaTest, NoOverlaps) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc
index c84556ceb66..66c7d14f94a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc
@@ -511,8 +511,7 @@ size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
<< "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
"packet";
- if (close_connection_if_fail_to_serialzie_coalesced_packet_ &&
- HasPendingFrames()) {
+ if (HasPendingFrames()) {
QUIC_BUG(quic_packet_creator_unexpected_queued_frames)
<< "Unexpected queued frames: " << GetPendingFramesInfo();
return 0;
@@ -549,15 +548,8 @@ size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
}
}
- if (close_connection_if_fail_to_serialzie_coalesced_packet_) {
- QUIC_RELOADABLE_FLAG_COUNT_N(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2, 1, 2);
- }
-
- if (!SerializePacket(
- QuicOwnedPacketBuffer(buffer, nullptr), buffer_len,
- /*allow_padding=*/
- !close_connection_if_fail_to_serialzie_coalesced_packet_)) {
+ if (!SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len,
+ /*allow_padding=*/false)) {
return 0;
}
const size_t encrypted_length = packet_.encrypted_length;
@@ -1883,10 +1875,6 @@ void QuicPacketCreator::MaybeAddPadding() {
return;
}
- if (packet_.transmission_type == PROBING_RETRANSMISSION) {
- needs_full_padding_ = true;
- }
-
if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
// Do not add full padding if the packet is going to be coalesced or
// encapsulated.
@@ -2084,7 +2072,7 @@ size_t QuicPacketCreator::MinPlaintextPacketSize(
// 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
// test crypters) which also only use 12 byte tags.
//
- // TODO(nharper): Set this based on the handshake protocol in use.
+ // TODO(b/234061734): Set this based on the handshake protocol in use.
return 7;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.h
index bc792e17afb..51446ba3e0d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.h
@@ -485,10 +485,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
const QuicSocketAddress& peer_address() const { return packet_.peer_address; }
- bool close_connection_if_fail_to_serialzie_coalesced_packet() const {
- return close_connection_if_fail_to_serialzie_coalesced_packet_;
- }
-
private:
friend class test::QuicPacketCreatorPeer;
@@ -692,10 +688,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Whether to attempt protecting initial packets with chaos.
bool chaos_protection_enabled_;
-
- const bool close_connection_if_fail_to_serialzie_coalesced_packet_ =
- GetQuicReloadableFlag(
- quic_close_connection_if_fail_to_serialzie_coalesced_packet2);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator_test.cc
index b2233268982..c9f8ecccfe4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_packet_creator_test.cc
@@ -1549,11 +1549,13 @@ TEST_P(QuicPacketCreatorTest, AddUnencryptedStreamDataClosesConnection) {
}
creator_.set_encryption_level(ENCRYPTION_INITIAL);
- EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
/*fin=*/false, 0u, absl::string_view());
EXPECT_QUIC_BUG(
- creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+ {
+ EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+ creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION);
+ },
"Cannot send stream data with level: ENCRYPTION_INITIAL");
}
@@ -1564,11 +1566,13 @@ TEST_P(QuicPacketCreatorTest, SendStreamDataWithEncryptionHandshake) {
}
creator_.set_encryption_level(ENCRYPTION_HANDSHAKE);
- EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
QuicStreamFrame stream_frame(GetNthClientInitiatedStreamId(0),
/*fin=*/false, 0u, absl::string_view());
EXPECT_QUIC_BUG(
- creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION),
+ {
+ EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+ creator_.AddFrame(QuicFrame(stream_frame), NOT_RETRANSMISSION);
+ },
"Cannot send stream data with level: ENCRYPTION_HANDSHAKE");
}
@@ -1932,16 +1936,16 @@ TEST_P(QuicPacketCreatorTest, PacketTransmissionType) {
EXPECT_TRUE(creator_.AddFrame(ack_frame, LOSS_RETRANSMISSION));
ASSERT_EQ(serialized_packet_, nullptr);
- EXPECT_TRUE(creator_.AddFrame(stream_frame, RTO_RETRANSMISSION));
+ EXPECT_TRUE(creator_.AddFrame(stream_frame, PTO_RETRANSMISSION));
ASSERT_EQ(serialized_packet_, nullptr);
- EXPECT_TRUE(creator_.AddFrame(padding_frame, TLP_RETRANSMISSION));
+ EXPECT_TRUE(creator_.AddFrame(padding_frame, LOSS_RETRANSMISSION));
creator_.FlushCurrentPacket();
ASSERT_TRUE(serialized_packet_->encrypted_buffer);
// The last retransmittable frame on packet is a stream frame, the packet's
// transmission type should be the same as the stream frame's.
- EXPECT_EQ(serialized_packet_->transmission_type, RTO_RETRANSMISSION);
+ EXPECT_EQ(serialized_packet_->transmission_type, PTO_RETRANSMISSION);
DeleteSerializedPacket();
}
@@ -2563,12 +2567,15 @@ TEST_F(QuicPacketCreatorMultiplePacketsTest,
delegate_.SetCanWriteAnything();
const std::string data(10000, '?');
EXPECT_CALL(delegate_, OnSerializedPacket(_)).Times(0);
- EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
- EXPECT_QUIC_BUG(creator_.ConsumeDataFastPath(
- QuicUtils::GetFirstBidirectionalStreamId(
- framer_.transport_version(), Perspective::IS_CLIENT),
- data),
- "");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(delegate_, OnUnrecoverableError(_, _));
+ creator_.ConsumeDataFastPath(
+ QuicUtils::GetFirstBidirectionalStreamId(
+ framer_.transport_version(), Perspective::IS_CLIENT),
+ data);
+ },
+ "");
}
TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_OnlyAckWritable) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.cc
new file mode 100644
index 00000000000..da7c42305c1
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_ping_manager.h"
+
+namespace quic {
+
+namespace {
+
+// Maximum shift used to calculate retransmittable on wire timeout. For 200ms
+// initial retransmittable on wire delay, this would get a maximum of 200ms * (1
+// << 10) = 204.8s
+const int kMaxRetransmittableOnWireDelayShift = 10;
+
+class AlarmDelegate : public QuicAlarm::DelegateWithContext {
+ public:
+ explicit AlarmDelegate(QuicPingManager* manager,
+ QuicConnectionContext* context)
+ : QuicAlarm::DelegateWithContext(context), manager_(manager) {}
+ AlarmDelegate(const AlarmDelegate&) = delete;
+ AlarmDelegate& operator=(const AlarmDelegate&) = delete;
+
+ void OnAlarm() override { manager_->OnAlarm(); }
+
+ private:
+ QuicPingManager* manager_;
+};
+
+} // namespace
+
+QuicPingManager::QuicPingManager(Perspective perspective, Delegate* delegate,
+ QuicConnectionArena* arena,
+ QuicAlarmFactory* alarm_factory,
+ QuicConnectionContext* context)
+ : perspective_(perspective),
+ delegate_(delegate),
+ alarm_(alarm_factory->CreateAlarm(
+ arena->New<AlarmDelegate>(this, context), arena)) {}
+
+void QuicPingManager::SetAlarm(QuicTime now, bool should_keep_alive,
+ bool has_in_flight_packets) {
+ UpdateDeadlines(now, should_keep_alive, has_in_flight_packets);
+ const QuicTime earliest_deadline = GetEarliestDeadline();
+ if (!earliest_deadline.IsInitialized()) {
+ alarm_->Cancel();
+ return;
+ }
+ if (earliest_deadline == keep_alive_deadline_) {
+ // Use 1s granularity for keep-alive time.
+ alarm_->Update(earliest_deadline, QuicTime::Delta::FromSeconds(1));
+ return;
+ }
+ alarm_->Update(earliest_deadline, kAlarmGranularity);
+}
+
+void QuicPingManager::OnAlarm() {
+ const QuicTime earliest_deadline = GetEarliestDeadline();
+ if (!earliest_deadline.IsInitialized()) {
+ QUIC_BUG(quic_ping_manager_alarm_fires_unexpectedly)
+ << "QuicPingManager alarm fires unexpectedly.";
+ return;
+ }
+ // Please note, alarm does not get re-armed here, and we are relying on caller
+ // to SetAlarm later.
+ if (earliest_deadline == retransmittable_on_wire_deadline_) {
+ retransmittable_on_wire_deadline_ = QuicTime::Zero();
+ if (GetQuicFlag(
+ FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count) !=
+ 0) {
+ ++consecutive_retransmittable_on_wire_count_;
+ }
+ ++retransmittable_on_wire_count_;
+ delegate_->OnRetransmittableOnWireTimeout();
+ return;
+ }
+ if (earliest_deadline == keep_alive_deadline_) {
+ keep_alive_deadline_ = QuicTime::Zero();
+ delegate_->OnKeepAliveTimeout();
+ }
+}
+
+void QuicPingManager::Stop() {
+ alarm_->PermanentCancel();
+ retransmittable_on_wire_deadline_ = QuicTime::Zero();
+ keep_alive_deadline_ = QuicTime::Zero();
+}
+
+void QuicPingManager::UpdateDeadlines(QuicTime now, bool should_keep_alive,
+ bool has_in_flight_packets) {
+ // Reset keep-alive deadline given it will be set later (with left edge
+ // |now|).
+ keep_alive_deadline_ = QuicTime::Zero();
+ if (perspective_ == Perspective::IS_SERVER &&
+ initial_retransmittable_on_wire_timeout_.IsInfinite()) {
+ // The PING alarm exists to support two features:
+ // 1) clients send PINGs every 15s to prevent NAT timeouts,
+ // 2) both clients and servers can send retransmittable on the wire PINGs
+ // (ROWP) while ShouldKeepConnectionAlive is true and there is no packets in
+ // flight.
+ QUICHE_DCHECK(!retransmittable_on_wire_deadline_.IsInitialized());
+ return;
+ }
+ if (!should_keep_alive) {
+ // Don't send a ping unless the application (ie: HTTP/3) says to, usually
+ // because it is expecting a response from the peer.
+ retransmittable_on_wire_deadline_ = QuicTime::Zero();
+ return;
+ }
+ if (perspective_ == Perspective::IS_CLIENT) {
+ // Clients send 15s PINGs to avoid NATs from timing out.
+ keep_alive_deadline_ = now + keep_alive_timeout_;
+ }
+ if (initial_retransmittable_on_wire_timeout_.IsInfinite() ||
+ has_in_flight_packets ||
+ retransmittable_on_wire_count_ >
+ GetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count)) {
+ // No need to set retransmittable-on-wire timeout.
+ retransmittable_on_wire_deadline_ = QuicTime::Zero();
+ return;
+ }
+
+ QUICHE_DCHECK_LT(initial_retransmittable_on_wire_timeout_,
+ keep_alive_timeout_);
+ QuicTime::Delta retransmittable_on_wire_timeout =
+ initial_retransmittable_on_wire_timeout_;
+ const int max_aggressive_retransmittable_on_wire_count =
+ GetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count);
+ QUICHE_DCHECK_LE(0, max_aggressive_retransmittable_on_wire_count);
+ if (consecutive_retransmittable_on_wire_count_ >
+ max_aggressive_retransmittable_on_wire_count) {
+ // Exponentially back off the timeout if the number of consecutive
+ // retransmittable on wire pings has exceeds the allowance.
+ int shift = std::min(consecutive_retransmittable_on_wire_count_ -
+ max_aggressive_retransmittable_on_wire_count,
+ kMaxRetransmittableOnWireDelayShift);
+ retransmittable_on_wire_timeout =
+ initial_retransmittable_on_wire_timeout_ * (1 << shift);
+ }
+ if (retransmittable_on_wire_deadline_.IsInitialized() &&
+ retransmittable_on_wire_deadline_ <
+ now + retransmittable_on_wire_timeout) {
+ // Alarm is set to an earlier time. Do not postpone it.
+ return;
+ }
+ retransmittable_on_wire_deadline_ = now + retransmittable_on_wire_timeout;
+}
+
+QuicTime QuicPingManager::GetEarliestDeadline() const {
+ QuicTime earliest_deadline = QuicTime::Zero();
+ for (QuicTime t : {retransmittable_on_wire_deadline_, keep_alive_deadline_}) {
+ if (!t.IsInitialized()) {
+ continue;
+ }
+ if (!earliest_deadline.IsInitialized() || t < earliest_deadline) {
+ earliest_deadline = t;
+ }
+ }
+ return earliest_deadline;
+}
+
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.h
new file mode 100644
index 00000000000..d88dac26f36
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_
+#define QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_
+
+#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_constants.h"
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+namespace test {
+class QuicConnectionPeer;
+class QuicPingManagerPeer;
+} // namespace test
+
+// QuicPingManager manages an alarm that has two modes:
+// 1) keep-alive. When alarm fires, send packet to extend idle timeout to keep
+// connection alive.
+// 2) retransmittable-on-wire. When alarm fires, send packets to detect path
+// degrading (used in IP/port migrations).
+class QUIC_EXPORT_PRIVATE QuicPingManager {
+ public:
+ // Interface that get notified when |alarm_| fires.
+ class QUIC_EXPORT_PRIVATE Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Called when alarm fires in keep-alive mode.
+ virtual void OnKeepAliveTimeout() = 0;
+ // Called when alarm fires in retransmittable-on-wire mode.
+ virtual void OnRetransmittableOnWireTimeout() = 0;
+ };
+
+ QuicPingManager(Perspective perspective, Delegate* delegate,
+ QuicConnectionArena* arena, QuicAlarmFactory* alarm_factory,
+ QuicConnectionContext* context);
+
+ // Called to set |alarm_|.
+ void SetAlarm(QuicTime now, bool should_keep_alive,
+ bool has_in_flight_packets);
+
+ // Called when |alarm_| fires.
+ void OnAlarm();
+
+ // Called to stop |alarm_| permanently.
+ void Stop();
+
+ void set_keep_alive_timeout(QuicTime::Delta keep_alive_timeout) {
+ QUICHE_DCHECK(!alarm_->IsSet());
+ keep_alive_timeout_ = keep_alive_timeout;
+ }
+
+ void set_initial_retransmittable_on_wire_timeout(
+ QuicTime::Delta retransmittable_on_wire_timeout) {
+ QUICHE_DCHECK(!alarm_->IsSet());
+ initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
+ }
+
+ void reset_consecutive_retransmittable_on_wire_count() {
+ consecutive_retransmittable_on_wire_count_ = 0;
+ }
+
+ private:
+ friend class test::QuicConnectionPeer;
+ friend class test::QuicPingManagerPeer;
+
+ // Update |retransmittable_on_wire_deadline_| and |keep_alive_deadline_|.
+ void UpdateDeadlines(QuicTime now, bool should_keep_alive,
+ bool has_in_flight_packets);
+
+ // Get earliest deadline of |retransmittable_on_wire_deadline_| and
+ // |keep_alive_deadline_|. Returns 0 if both deadlines are not initialized.
+ QuicTime GetEarliestDeadline() const;
+
+ Perspective perspective_;
+
+ Delegate* delegate_; // Not owned.
+
+ // Initial timeout for how long the wire can have no retransmittable packets.
+ QuicTime::Delta initial_retransmittable_on_wire_timeout_ =
+ QuicTime::Delta::Infinite();
+
+ // Indicates how many consecutive retransmittable-on-wire has been armed
+ // (since last reset).
+ int consecutive_retransmittable_on_wire_count_ = 0;
+
+ // Indicates how many retransmittable-on-wire has been armed in total.
+ int retransmittable_on_wire_count_ = 0;
+
+ QuicTime::Delta keep_alive_timeout_ =
+ QuicTime::Delta::FromSeconds(kPingTimeoutSecs);
+
+ QuicTime retransmittable_on_wire_deadline_ = QuicTime::Zero();
+
+ QuicTime keep_alive_deadline_ = QuicTime::Zero();
+
+ QuicArenaScopedPtr<QuicAlarm> alarm_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager_test.cc
new file mode 100644
index 00000000000..509022b6181
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_ping_manager_test.cc
@@ -0,0 +1,429 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/core/quic_ping_manager.h"
+
+#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+class QuicPingManagerPeer {
+ public:
+ static QuicAlarm* GetAlarm(QuicPingManager* manager) {
+ return manager->alarm_.get();
+ }
+
+ static void SetPerspective(QuicPingManager* manager,
+ Perspective perspective) {
+ manager->perspective_ = perspective;
+ }
+};
+
+namespace {
+
+const bool kShouldKeepAlive = true;
+const bool kHasInflightPackets = true;
+
+class MockDelegate : public QuicPingManager::Delegate {
+ public:
+ MOCK_METHOD(void, OnKeepAliveTimeout, (), (override));
+ MOCK_METHOD(void, OnRetransmittableOnWireTimeout, (), (override));
+};
+
+class QuicPingManagerTest : public QuicTest {
+ public:
+ QuicPingManagerTest()
+ : manager_(Perspective::IS_CLIENT, &delegate_, &arena_, &alarm_factory_,
+ /*context=*/nullptr),
+ alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
+ QuicPingManagerPeer::GetAlarm(&manager_))) {
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ }
+
+ protected:
+ testing::StrictMock<MockDelegate> delegate_;
+ MockClock clock_;
+ QuicConnectionArena arena_;
+ MockAlarmFactory alarm_factory_;
+ QuicPingManager manager_;
+ MockAlarmFactory::TestAlarm* alarm_;
+};
+
+TEST_F(QuicPingManagerTest, KeepAliveTimeout) {
+ EXPECT_FALSE(alarm_->IsSet());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Set alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Reset alarm with no in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify the deadline is set slightly less than 15 seconds in the future,
+ // because of the 1s alarm granularity.
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs) -
+ QuicTime::Delta::FromMilliseconds(5),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kPingTimeoutSecs));
+ EXPECT_CALL(delegate_, OnKeepAliveTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+
+ // Verify alarm is not armed if !kShouldKeepAlive.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.SetAlarm(clock_.ApproximateNow(), !kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_FALSE(alarm_->IsSet());
+}
+
+TEST_F(QuicPingManagerTest, CustomizedKeepAliveTimeout) {
+ EXPECT_FALSE(alarm_->IsSet());
+
+ // Set customized keep-alive timeout.
+ manager_.set_keep_alive_timeout(QuicTime::Delta::FromSeconds(10));
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Set alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(10),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Set alarm with no in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // The deadline is set slightly less than 10 seconds in the future, because
+ // of the 1s alarm granularity.
+ EXPECT_EQ(
+ QuicTime::Delta::FromSeconds(10) - QuicTime::Delta::FromMilliseconds(5),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
+ EXPECT_CALL(delegate_, OnKeepAliveTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+
+ // Verify alarm is not armed if !kShouldKeepAlive.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.SetAlarm(clock_.ApproximateNow(), !kShouldKeepAlive,
+ kHasInflightPackets);
+ EXPECT_FALSE(alarm_->IsSet());
+}
+
+TEST_F(QuicPingManagerTest, RetransmittableOnWireTimeout) {
+ const QuicTime::Delta kRtransmittableOnWireTimeout =
+ QuicTime::Delta::FromMilliseconds(50);
+ manager_.set_initial_retransmittable_on_wire_timeout(
+ kRtransmittableOnWireTimeout);
+
+ EXPECT_FALSE(alarm_->IsSet());
+
+ // Set alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ // Verify alarm is in keep-alive mode.
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Set alarm with no in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify alarm is in retransmittable-on-wire mode.
+ EXPECT_EQ(kRtransmittableOnWireTimeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(kRtransmittableOnWireTimeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ // Verify the alarm is in keep-alive mode.
+ ASSERT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+}
+
+TEST_F(QuicPingManagerTest, RetransmittableOnWireTimeoutExponentiallyBackOff) {
+ const int kMaxAggressiveRetransmittableOnWireCount = 5;
+ SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
+ kMaxAggressiveRetransmittableOnWireCount);
+ const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ manager_.set_initial_retransmittable_on_wire_timeout(
+ initial_retransmittable_on_wire_timeout);
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_FALSE(alarm_->IsSet());
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ // Verify alarm is in keep-alive mode.
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ // Verify no exponential backoff on the first few retransmittable on wire
+ // timeouts.
+ for (int i = 0; i <= kMaxAggressiveRetransmittableOnWireCount; ++i) {
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Reset alarm with no in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify alarm is in retransmittable-on-wire mode.
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ }
+
+ QuicTime::Delta retransmittable_on_wire_timeout =
+ initial_retransmittable_on_wire_timeout;
+
+ // Verify subsequent retransmittable-on-wire timeout is exponentially backed
+ // off.
+ while (retransmittable_on_wire_timeout * 2 <
+ QuicTime::Delta::FromSeconds(kPingTimeoutSecs)) {
+ retransmittable_on_wire_timeout = retransmittable_on_wire_timeout * 2;
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ }
+
+ // Verify alarm is in keep-alive mode.
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ // Reset alarm with no in flight packets
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify alarm is in keep-alive mode because retransmittable-on-wire deadline
+ // is later.
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs) -
+ QuicTime::Delta::FromMilliseconds(5),
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kPingTimeoutSecs) -
+ QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(delegate_, OnKeepAliveTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+}
+
+TEST_F(QuicPingManagerTest,
+ ResetRetransmitableOnWireTimeoutExponentiallyBackOff) {
+ const int kMaxAggressiveRetransmittableOnWireCount = 3;
+ SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
+ kMaxAggressiveRetransmittableOnWireCount);
+ const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ manager_.set_initial_retransmittable_on_wire_timeout(
+ initial_retransmittable_on_wire_timeout);
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_FALSE(alarm_->IsSet());
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ // Verify alarm is in keep-alive mode.
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify alarm is in retransmittable-on-wire mode.
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ alarm_->Fire();
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ manager_.reset_consecutive_retransmittable_on_wire_count();
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ alarm_->Fire();
+
+ for (int i = 0; i < kMaxAggressiveRetransmittableOnWireCount; i++) {
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ // Reset alarm with in flight packets.
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ // Advance 5ms to receive next packet.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ }
+
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout * 2,
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ clock_.AdvanceTime(2 * initial_retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ manager_.reset_consecutive_retransmittable_on_wire_count();
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+}
+
+TEST_F(QuicPingManagerTest, RetransmittableOnWireLimit) {
+ static constexpr int kMaxRetransmittableOnWirePingCount = 3;
+ SetQuicFlag(FLAGS_quic_max_retransmittable_on_wire_ping_count,
+ kMaxRetransmittableOnWirePingCount);
+ static constexpr QuicTime::Delta initial_retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ static constexpr QuicTime::Delta kShortDelay =
+ QuicTime::Delta::FromMilliseconds(5);
+ ASSERT_LT(kShortDelay * 10, initial_retransmittable_on_wire_timeout);
+ manager_.set_initial_retransmittable_on_wire_timeout(
+ initial_retransmittable_on_wire_timeout);
+
+ clock_.AdvanceTime(kShortDelay);
+ EXPECT_FALSE(alarm_->IsSet());
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+
+ for (int i = 0; i <= kMaxRetransmittableOnWirePingCount; i++) {
+ clock_.AdvanceTime(kShortDelay);
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ }
+
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ // Verify alarm is in keep-alive mode.
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kPingTimeoutSecs));
+ EXPECT_CALL(delegate_, OnKeepAliveTimeout());
+ alarm_->Fire();
+ EXPECT_FALSE(alarm_->IsSet());
+}
+
+TEST_F(QuicPingManagerTest, MaxRetransmittableOnWireDelayShift) {
+ QuicPingManagerPeer::SetPerspective(&manager_, Perspective::IS_SERVER);
+ const int kMaxAggressiveRetransmittableOnWireCount = 3;
+ SetQuicFlag(FLAGS_quic_max_aggressive_retransmittable_on_wire_ping_count,
+ kMaxAggressiveRetransmittableOnWireCount);
+ const QuicTime::Delta initial_retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(200);
+ manager_.set_initial_retransmittable_on_wire_timeout(
+ initial_retransmittable_on_wire_timeout);
+
+ for (int i = 0; i <= kMaxAggressiveRetransmittableOnWireCount; i++) {
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout,
+ alarm_->deadline() - clock_.ApproximateNow());
+ clock_.AdvanceTime(initial_retransmittable_on_wire_timeout);
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ kHasInflightPackets);
+ }
+ for (int i = 1; i <= 20; ++i) {
+ manager_.SetAlarm(clock_.ApproximateNow(), kShouldKeepAlive,
+ !kHasInflightPackets);
+ EXPECT_TRUE(alarm_->IsSet());
+ if (i <= 10) {
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout * (1 << i),
+ alarm_->deadline() - clock_.ApproximateNow());
+ } else {
+ // Verify shift is capped.
+ EXPECT_EQ(initial_retransmittable_on_wire_timeout * (1 << 10),
+ alarm_->deadline() - clock_.ApproximateNow());
+ }
+ clock_.AdvanceTime(alarm_->deadline() - clock_.ApproximateNow());
+ EXPECT_CALL(delegate_, OnRetransmittableOnWireTimeout());
+ alarm_->Fire();
+ }
+}
+
+} // namespace
+
+} // namespace test
+} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc
index 213f6ba59fc..bb7b87d349e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc
@@ -267,24 +267,9 @@ void QuicReceivedPacketManager::MaybeUpdateAckTimeout(
return;
}
- QuicTime ack_timeout_base = now;
- const bool quic_update_ack_timeout_on_receipt_time =
- GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time);
- if (quic_update_ack_timeout_on_receipt_time) {
- if (last_packet_receipt_time <= now) {
- QUIC_CODE_COUNT(quic_update_ack_timeout_on_receipt_time);
- ack_timeout_base = last_packet_receipt_time;
- } else {
- QUIC_CODE_COUNT(quic_update_ack_timeout_on_now);
- ack_timeout_base = now;
- }
- }
- QuicTime updated_ack_time =
- ack_timeout_base +
- GetMaxAckDelay(last_received_packet_number, *rtt_stats);
- if (quic_update_ack_timeout_on_receipt_time) {
- updated_ack_time = std::max(now, updated_ack_time);
- }
+ const QuicTime updated_ack_time = std::max(
+ now, std::min(last_packet_receipt_time, now) +
+ GetMaxAckDelay(last_received_packet_number, *rtt_stats));
if (!ack_timeout_.IsInitialized() || ack_timeout_ > updated_ack_time) {
ack_timeout_ = updated_ack_time;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager_test.cc
index 65cfa867d53..c4537076a19 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager_test.cc
@@ -650,13 +650,8 @@ TEST_F(QuicReceivedPacketManagerTest, UpdateAckTimeoutOnPacketReceiptTime) {
kInstigateAck, QuicPacketNumber(3),
/*last_packet_receipt_time=*/packet_receipt_time3,
clock_.ApproximateNow(), &rtt_stats_);
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Make sure ACK timeout is based on receipt time.
- CheckAckTimeout(packet_receipt_time3 + kDelayedAckTime);
- } else {
- // Make sure ACK timeout is based on now.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
+ // Make sure ACK timeout is based on receipt time.
+ CheckAckTimeout(packet_receipt_time3 + kDelayedAckTime);
RecordPacketReceipt(4, clock_.ApproximateNow());
MaybeUpdateAckTimeout(kInstigateAck, 4);
@@ -677,13 +672,8 @@ TEST_F(QuicReceivedPacketManagerTest,
kInstigateAck, QuicPacketNumber(3),
/*last_packet_receipt_time=*/packet_receipt_time3,
clock_.ApproximateNow(), &rtt_stats_);
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Given 100ms > ack delay, verify immediate ACK.
- CheckAckTimeout(clock_.ApproximateNow());
- } else {
- // Make sure ACK timeout is based on now.
- CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
- }
+ // Given 100ms > ack delay, verify immediate ACK.
+ CheckAckTimeout(clock_.ApproximateNow());
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc
index 47377e13a67..10835830bfb 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc
@@ -30,13 +30,6 @@ namespace quic {
namespace {
static const int64_t kDefaultRetransmissionTimeMs = 500;
-static const int64_t kMaxRetransmissionTimeMs = 60000;
-// Maximum number of exponential backoffs used for RTO timeouts.
-static const size_t kMaxRetransmissions = 10;
-// Maximum number of packets retransmitted upon an RTO.
-static const size_t kMaxRetransmissionsOnTimeout = 2;
-// The path degrading delay is the sum of this number of consecutive RTO delays.
-const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
// Ensure the handshake timer isnt't faster than 10ms.
// This limits the tenth retransmitted packet to 10s after the initial CHLO.
@@ -46,13 +39,14 @@ static const int64_t kMinHandshakeTimeoutMs = 10;
// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
static const size_t kDefaultMaxTailLossProbes = 2;
+// The multiplier for calculating PTO timeout before any RTT sample is
+// available.
+static const float kPtoMultiplierWithoutRttSamples = 3;
+
// Returns true of retransmissions of the specified type should retransmit
// the frames directly (as opposed to resulting in a loss notification).
inline bool ShouldForceRetransmission(TransmissionType transmission_type) {
return transmission_type == HANDSHAKE_RETRANSMISSION ||
- transmission_type == TLP_RETRANSMISSION ||
- transmission_type == PROBING_RETRANSMISSION ||
- transmission_type == RTO_RETRANSMISSION ||
transmission_type == PTO_RETRANSMISSION;
}
@@ -81,56 +75,25 @@ QuicSentPacketManager::QuicSentPacketManager(
network_change_visitor_(nullptr),
initial_congestion_window_(kInitialCongestionWindow),
loss_algorithm_(&uber_loss_algorithm_),
- consecutive_rto_count_(0),
- consecutive_tlp_count_(0),
consecutive_crypto_retransmission_count_(0),
pending_timer_transmission_count_(0),
- max_tail_loss_probes_(kDefaultMaxTailLossProbes),
- max_rto_packets_(kMaxRetransmissionsOnTimeout),
using_pacing_(false),
- use_new_rto_(false),
conservative_handshake_retransmits_(false),
- min_tlp_timeout_(
- QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)),
- min_rto_timeout_(
- QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
largest_mtu_acked_(0),
handshake_finished_(false),
peer_max_ack_delay_(
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
rtt_updated_(false),
acked_packets_iter_(last_ack_frame_.packets.rbegin()),
- pto_enabled_(GetQuicRestartFlag(quic_default_on_pto2)),
- max_probe_packets_per_pto_(2),
consecutive_pto_count_(0),
handshake_mode_disabled_(false),
- skip_packet_number_for_pto_(false),
- always_include_max_ack_delay_for_pto_timeout_(true),
- pto_exponential_backoff_start_point_(0),
- pto_rttvar_multiplier_(4),
- num_tlp_timeout_ptos_(0),
handshake_packet_acked_(false),
zero_rtt_packet_acked_(false),
one_rtt_packet_acked_(false),
- first_pto_srtt_multiplier_(0),
- use_standard_deviation_for_pto_(false),
- pto_multiplier_without_rtt_samples_(3),
num_ptos_for_path_degrading_(kNumProbeTimeoutsForPathDegradingDelay),
ignore_pings_(false),
ignore_ack_delay_(false) {
SetSendAlgorithm(congestion_control_type);
- if (pto_enabled_) {
- QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 1, 2);
- // TODO(fayang): change the default values when deprecating
- // quic_default_on_pto2.
- // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
- // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
- // last in flight packet.
- max_probe_packets_per_pto_ = 1;
- skip_packet_number_for_pto_ = true;
- first_pto_srtt_multiplier_ = 1.5;
- pto_rttvar_multiplier_ = 2;
- }
}
QuicSentPacketManager::~QuicSentPacketManager() {}
@@ -167,82 +130,18 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
if (config.HasClientSentConnectionOption(kMAD0, perspective)) {
ignore_ack_delay_ = true;
}
- if (config.HasClientSentConnectionOption(kMAD2, perspective)) {
- // Set the minimum to the alarm granularity.
- min_tlp_timeout_ = kAlarmGranularity;
+
+ if (config.HasClientRequestedIndependentOption(kPDP1, perspective)) {
+ num_ptos_for_path_degrading_ = 1;
}
- if (config.HasClientSentConnectionOption(kMAD3, perspective)) {
- // Set the minimum to the alarm granularity.
- min_rto_timeout_ = kAlarmGranularity;
+ if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
+ num_ptos_for_path_degrading_ = 2;
}
-
- if (!GetQuicRestartFlag(quic_default_on_pto2)) {
- if (config.HasClientSentConnectionOption(k2PTO, perspective)) {
- pto_enabled_ = true;
- }
- if (config.HasClientSentConnectionOption(k1PTO, perspective)) {
- pto_enabled_ = true;
- max_probe_packets_per_pto_ = 1;
- }
-
- if (config.HasClientSentConnectionOption(kPTOS, perspective)) {
- if (!pto_enabled_) {
- QUIC_PEER_BUG(quic_peer_bug_12552_1)
- << "PTO is not enabled when receiving PTOS connection option.";
- pto_enabled_ = true;
- max_probe_packets_per_pto_ = 1;
- }
- skip_packet_number_for_pto_ = true;
- }
- if (pto_enabled_) {
- if (config.HasClientSentConnectionOption(kPTOA, perspective)) {
- always_include_max_ack_delay_for_pto_timeout_ = false;
- }
- if (config.HasClientSentConnectionOption(kPEB1, perspective)) {
- StartExponentialBackoffAfterNthPto(1);
- }
- if (config.HasClientSentConnectionOption(kPEB2, perspective)) {
- StartExponentialBackoffAfterNthPto(2);
- }
- if (config.HasClientSentConnectionOption(kPVS1, perspective)) {
- pto_rttvar_multiplier_ = 2;
- }
- if (config.HasClientSentConnectionOption(kPAG1, perspective)) {
- QUIC_CODE_COUNT(one_aggressive_pto);
- num_tlp_timeout_ptos_ = 1;
- }
- if (config.HasClientSentConnectionOption(kPAG2, perspective)) {
- QUIC_CODE_COUNT(two_aggressive_ptos);
- num_tlp_timeout_ptos_ = 2;
- }
- if (config.HasClientSentConnectionOption(kPLE1, perspective)) {
- first_pto_srtt_multiplier_ = 0.5;
- } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) {
- first_pto_srtt_multiplier_ = 1.5;
- }
- if (config.HasClientSentConnectionOption(kAPTO, perspective)) {
- pto_multiplier_without_rtt_samples_ = 1.5;
- }
- if (config.HasClientSentConnectionOption(kPSDA, perspective)) {
- use_standard_deviation_for_pto_ = true;
- rtt_stats_.EnableStandardDeviationCalculation();
- }
- }
+ if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
+ num_ptos_for_path_degrading_ = 3;
}
-
- if (pto_enabled_) {
- if (config.HasClientRequestedIndependentOption(kPDP1, perspective)) {
- num_ptos_for_path_degrading_ = 1;
- }
- if (config.HasClientRequestedIndependentOption(kPDP2, perspective)) {
- num_ptos_for_path_degrading_ = 2;
- }
- if (config.HasClientRequestedIndependentOption(kPDP3, perspective)) {
- num_ptos_for_path_degrading_ = 3;
- }
- if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
- num_ptos_for_path_degrading_ = 5;
- }
+ if (config.HasClientRequestedIndependentOption(kPDP5, perspective)) {
+ num_ptos_for_path_degrading_ = 5;
}
// Configure congestion control.
@@ -296,19 +195,6 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
}
using_pacing_ = !GetQuicFlag(FLAGS_quic_disable_pacing_for_perf_tests);
-
- if (config.HasClientSentConnectionOption(kNTLP, perspective)) {
- max_tail_loss_probes_ = 0;
- }
- if (config.HasClientSentConnectionOption(k1TLP, perspective)) {
- max_tail_loss_probes_ = 1;
- }
- if (config.HasClientSentConnectionOption(k1RTO, perspective)) {
- max_rto_packets_ = 1;
- }
- if (config.HasClientSentConnectionOption(kNRTO, perspective)) {
- use_new_rto_ = true;
- }
// Configure loss detection.
if (config.HasClientRequestedIndependentOption(kILD0, perspective)) {
uber_loss_algorithm_.SetReorderingShift(kDefaultIetfLossDelayShift);
@@ -396,39 +282,21 @@ void QuicSentPacketManager::ResumeConnectionState(
void QuicSentPacketManager::AdjustNetworkParameters(
const SendAlgorithmInterface::NetworkParams& params) {
- if (params.burst_token != 0) {
- if (using_pacing_) {
- QUIC_RELOADABLE_FLAG_COUNT(quic_set_burst_token);
- int old_burst_size = pacing_sender_.initial_burst_size();
- pacing_sender_.SetBurstTokens(params.burst_token);
- if (debug_delegate_ != nullptr) {
- debug_delegate_->OnAdjustBurstSize(old_burst_size,
- pacing_sender_.initial_burst_size());
- }
- }
- return;
- }
const QuicBandwidth& bandwidth = params.bandwidth;
const QuicTime::Delta& rtt = params.rtt;
- if (use_lower_min_irtt()) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_lower_min_for_trusted_irtt, 2, 2);
- if (!rtt.IsZero()) {
- if (params.is_rtt_trusted) {
- // Always set initial rtt if it's trusted.
- SetInitialRtt(rtt, /*trusted=*/true);
- } else if (rtt_stats_.initial_rtt() ==
- QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
- // Only set initial rtt if we are using the default. This avoids
- // overwriting a trusted initial rtt by an untrusted one.
- SetInitialRtt(rtt, /*trusted=*/false);
- }
- }
- } else {
- if (!rtt.IsZero()) {
+ if (!rtt.IsZero()) {
+ if (params.is_rtt_trusted) {
+ // Always set initial rtt if it's trusted.
+ SetInitialRtt(rtt, /*trusted=*/true);
+ } else if (rtt_stats_.initial_rtt() ==
+ QuicTime::Delta::FromMilliseconds(kInitialRttMs)) {
+ // Only set initial rtt if we are using the default. This avoids
+ // overwriting a trusted initial rtt by an untrusted one.
SetInitialRtt(rtt, /*trusted=*/false);
}
}
+
const QuicByteCount old_cwnd = send_algorithm_->GetCongestionWindow();
if (GetQuicReloadableFlag(quic_conservative_bursts) && using_pacing_ &&
!bandwidth.IsZero()) {
@@ -470,10 +338,6 @@ void QuicSentPacketManager::PostProcessNewlyAckedPackets(
unacked_packets_.NotifyAggregatedStreamFrameAcked(
last_ack_frame_.ack_delay_time);
InvokeLossDetection(ack_receive_time);
- // Ignore losses in RTO mode.
- if (consecutive_rto_count_ > 0 && !use_new_rto_) {
- packets_lost_.clear();
- }
MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
ack_receive_time);
unacked_packets_.RemoveObsoletePackets();
@@ -486,33 +350,13 @@ void QuicSentPacketManager::PostProcessNewlyAckedPackets(
// Anytime we are making forward progress and have a new RTT estimate, reset
// the backoff counters.
if (rtt_updated) {
- if (consecutive_rto_count_ > 0) {
- // If the ack acknowledges data sent prior to the RTO,
- // the RTO was spurious.
- if (LargestAcked(ack_frame) < first_rto_transmission_) {
- // Replace SRTT with latest_rtt and increase the variance to prevent
- // a spurious RTO from happening again.
- rtt_stats_.ExpireSmoothedMetrics();
- } else {
- if (!use_new_rto_) {
- send_algorithm_->OnRetransmissionTimeout(true);
- }
- }
- }
- // Records the max consecutive RTO or PTO before forward progress has been
- // made.
- if (consecutive_rto_count_ >
+ // Records the max consecutive PTO before forward progress has been made.
+ if (consecutive_pto_count_ >
stats_->max_consecutive_rto_with_forward_progress) {
stats_->max_consecutive_rto_with_forward_progress =
- consecutive_rto_count_;
- } else if (consecutive_pto_count_ >
- stats_->max_consecutive_rto_with_forward_progress) {
- stats_->max_consecutive_rto_with_forward_progress =
consecutive_pto_count_;
}
// Reset all retransmit counters any time a new packet is acked.
- consecutive_rto_count_ = 0;
- consecutive_tlp_count_ = 0;
consecutive_pto_count_ = 0;
consecutive_crypto_retransmission_count_ = 0;
}
@@ -619,39 +463,9 @@ void QuicSentPacketManager::NeuterHandshakePackets() {
bool QuicSentPacketManager::ShouldAddMaxAckDelay(
PacketNumberSpace space) const {
- QUICHE_DCHECK(pto_enabled_);
- if (supports_multiple_packet_number_spaces() && space != APPLICATION_DATA) {
- // When the PTO is armed for Initial or Handshake packet number spaces,
- // the max_ack_delay is 0.
- return false;
- }
- if (always_include_max_ack_delay_for_pto_timeout_) {
- return true;
- }
- if (!unacked_packets_
- .GetLargestSentRetransmittableOfPacketNumberSpace(APPLICATION_DATA)
- .IsInitialized() ||
- unacked_packets_.GetLargestSentRetransmittableOfPacketNumberSpace(
- APPLICATION_DATA) <
- FirstSendingPacketNumber() + kMinReceivedBeforeAckDecimation - 1) {
- // Peer is doing TCP style acking. Expect an immediate ACK if more than 1
- // packet are outstanding.
- if (unacked_packets_.packets_in_flight() >=
- kDefaultRetransmittablePacketsBeforeAck) {
- return false;
- }
- } else if (unacked_packets_.packets_in_flight() >=
- kMaxRetransmittablePacketsBeforeAck) {
- // Peer is doing ack decimation. Expect an immediate ACK if >= 10
- // packets are outstanding.
- return false;
- }
- if (skip_packet_number_for_pto_ && consecutive_pto_count_ > 0) {
- // An immediate ACK is expected when doing PTOS. Please note, this will miss
- // cases when PTO fires and turns out to be spurious.
- return false;
- }
- return true;
+ // Do not include max_ack_delay when PTO is armed for Initial or Handshake
+ // packet number spaces.
+ return !supports_multiple_packet_number_spaces() || space == APPLICATION_DATA;
}
QuicTime QuicSentPacketManager::GetEarliestPacketSentTimeForPto(
@@ -680,38 +494,30 @@ void QuicSentPacketManager::MarkForRetransmission(
QuicPacketNumber packet_number, TransmissionType transmission_type) {
QuicTransmissionInfo* transmission_info =
unacked_packets_.GetMutableTransmissionInfo(packet_number);
- // A previous RTO retransmission may cause connection close; packets without
- // retransmittable frames can be marked for loss retransmissions.
+ // Packets without retransmittable frames can only be marked for loss
+ // retransmission.
QUIC_BUG_IF(quic_bug_12552_2, transmission_type != LOSS_RETRANSMISSION &&
- transmission_type != RTO_RETRANSMISSION &&
!unacked_packets_.HasRetransmittableFrames(
*transmission_info))
<< "packet number " << packet_number
<< " transmission_type: " << transmission_type << " transmission_info "
<< transmission_info->DebugString();
- // Handshake packets should never be sent as probing retransmissions.
- QUICHE_DCHECK(!transmission_info->has_crypto_handshake ||
- transmission_type != PROBING_RETRANSMISSION);
if (ShouldForceRetransmission(transmission_type)) {
- const bool retransmitted = unacked_packets_.RetransmitFrames(
- QuicFrames(transmission_info->retransmittable_frames),
- transmission_type);
- if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted)) {
- QUIC_RESTART_FLAG_COUNT(quic_set_packet_state_if_all_data_retransmitted);
- if (!retransmitted) {
- // Do not set packet state if the data is not fully retransmitted.
- // This should only happen if packet payload size decreases which can be
- // caused by:
- // 1) connection tries to opportunistically retransmit data
- // when sending a packet of a different packet number space, or
- // 2) path MTU decreases, or
- // 3) packet header size increases (e.g., packet number length
- // increases).
- QUIC_CODE_COUNT(quic_retransmit_frames_failed);
- return;
- }
- QUIC_CODE_COUNT(quic_retransmit_frames_succeeded);
+ if (!unacked_packets_.RetransmitFrames(
+ QuicFrames(transmission_info->retransmittable_frames),
+ transmission_type)) {
+ // Do not set packet state if the data is not fully retransmitted.
+ // This should only happen if packet payload size decreases which can be
+ // caused by:
+ // 1) connection tries to opportunistically retransmit data
+ // when sending a packet of a different packet number space, or
+ // 2) path MTU decreases, or
+ // 3) packet header size increases (e.g., packet number length
+ // increases).
+ QUIC_CODE_COUNT(quic_retransmit_frames_failed);
+ return;
}
+ QUIC_CODE_COUNT(quic_retransmit_frames_succeeded);
} else {
unacked_packets_.NotifyFramesLost(*transmission_info, transmission_type);
@@ -914,17 +720,6 @@ QuicSentPacketManager::OnRetransmissionTimeout() {
MaybeInvokeCongestionEvent(false, prior_in_flight, now);
return LOSS_MODE;
}
- case TLP_MODE:
- ++stats_->tlp_count;
- ++consecutive_tlp_count_;
- pending_timer_transmission_count_ = 1;
- // TLPs prefer sending new data instead of retransmitting data, so
- // give the connection a chance to write before completing the TLP.
- return TLP_MODE;
- case RTO_MODE:
- ++stats_->rto_count;
- RetransmitRtoPackets();
- return RTO_MODE;
case PTO_MODE:
QUIC_DVLOG(1) << ENDPOINT << "PTO mode";
++stats_->pto_count;
@@ -932,7 +727,7 @@ QuicSentPacketManager::OnRetransmissionTimeout() {
++stats_->crypto_retransmit_count;
}
++consecutive_pto_count_;
- pending_timer_transmission_count_ = max_probe_packets_per_pto_;
+ pending_timer_transmission_count_ = 1;
return PTO_MODE;
}
QUIC_BUG(quic_bug_10750_3)
@@ -972,17 +767,6 @@ void QuicSentPacketManager::RetransmitCryptoPackets() {
}
}
-bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
- QUICHE_DCHECK(!pto_enabled_);
- if (pending_timer_transmission_count_ == 0) {
- return false;
- }
- if (!MaybeRetransmitOldestPacket(TLP_RETRANSMISSION)) {
- return false;
- }
- return true;
-}
-
bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
if (!unacked_packets_.empty()) {
QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
@@ -1007,47 +791,7 @@ bool QuicSentPacketManager::MaybeRetransmitOldestPacket(TransmissionType type) {
return false;
}
-void QuicSentPacketManager::RetransmitRtoPackets() {
- QUICHE_DCHECK(!pto_enabled_);
- QUIC_BUG_IF(quic_bug_12552_3, pending_timer_transmission_count_ > 0)
- << "Retransmissions already queued:" << pending_timer_transmission_count_;
- // Mark two packets for retransmission.
- std::vector<QuicPacketNumber> retransmissions;
- if (!unacked_packets_.empty()) {
- QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked();
- QuicPacketNumber largest_sent_packet =
- unacked_packets_.largest_sent_packet();
- for (; packet_number <= largest_sent_packet; ++packet_number) {
- QuicTransmissionInfo* transmission_info =
- unacked_packets_.GetMutableTransmissionInfo(packet_number);
- if (transmission_info->state == OUTSTANDING &&
- unacked_packets_.HasRetransmittableFrames(*transmission_info) &&
- pending_timer_transmission_count_ < max_rto_packets_) {
- QUICHE_DCHECK(transmission_info->in_flight);
- retransmissions.push_back(packet_number);
- ++pending_timer_transmission_count_;
- }
- }
- }
- if (pending_timer_transmission_count_ > 0) {
- if (consecutive_rto_count_ == 0) {
- first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
- }
- ++consecutive_rto_count_;
- }
- for (QuicPacketNumber retransmission : retransmissions) {
- MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
- }
- if (retransmissions.empty()) {
- QUIC_BUG_IF(quic_bug_12552_4, pending_timer_transmission_count_ != 0);
- // No packets to be RTO retransmitted, raise up a credit to allow
- // connection to send.
- QUIC_CODE_COUNT(no_packets_to_be_rto_retransmitted);
- pending_timer_transmission_count_ = 1;
- }
-}
-
-void QuicSentPacketManager::MaybeSendProbePackets() {
+void QuicSentPacketManager::MaybeSendProbePacket() {
if (pending_timer_transmission_count_ == 0) {
return;
}
@@ -1093,42 +837,9 @@ void QuicSentPacketManager::MaybeSendProbePackets() {
// It is possible that there is not enough outstanding data for probing.
}
-void QuicSentPacketManager::AdjustPendingTimerTransmissions() {
- if (pending_timer_transmission_count_ < max_probe_packets_per_pto_) {
- // There are packets sent already, clear credit.
- pending_timer_transmission_count_ = 0;
- return;
- }
- // No packet gets sent, leave 1 credit to allow data to be write eventually.
- pending_timer_transmission_count_ = 1;
-}
-
void QuicSentPacketManager::EnableIetfPtoAndLossDetection() {
- if (pto_enabled_) {
- QUIC_RESTART_FLAG_COUNT_N(quic_default_on_pto2, 2, 2);
- // Disable handshake mode.
- handshake_mode_disabled_ = true;
- return;
- }
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- QUIC_BUG(pto_not_enabled)
- << "PTO is not enabled while quic_default_on_pto2 is true";
- return;
- }
- pto_enabled_ = true;
+ // Disable handshake mode.
handshake_mode_disabled_ = true;
- // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO
- // with max of earliest in flight sent time + PTO delay and 1.5 * srtt from
- // last in flight packet.
- max_probe_packets_per_pto_ = 1;
- skip_packet_number_for_pto_ = true;
- first_pto_srtt_multiplier_ = 1.5;
- pto_rttvar_multiplier_ = 2;
-}
-
-void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(
- size_t exponential_backoff_start_point) {
- pto_exponential_backoff_start_point_ = exponential_backoff_start_point;
}
void QuicSentPacketManager::RetransmitDataOfSpaceIfAny(
@@ -1171,15 +882,7 @@ QuicSentPacketManager::GetRetransmissionMode() const {
if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
return LOSS_MODE;
}
- if (pto_enabled_) {
- return PTO_MODE;
- }
- if (consecutive_tlp_count_ < max_tail_loss_probes_) {
- if (unacked_packets_.HasUnackedRetransmittableFrames()) {
- return TLP_MODE;
- }
- }
- return RTO_MODE;
+ return PTO_MODE;
}
void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
@@ -1283,49 +986,18 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
// Do not set the timer if there is any credit left.
return QuicTime::Zero();
}
- PacketNumberSpace packet_number_space;
- if (!simplify_set_retransmission_alarm_ &&
- supports_multiple_packet_number_spaces() &&
- unacked_packets_.perspective() == Perspective::IS_SERVER &&
- !GetEarliestPacketSentTimeForPto(&packet_number_space).IsInitialized()) {
- // Do not set the timer on the server side if the only in flight packets are
- // half RTT data.
- return QuicTime::Zero();
- }
switch (GetRetransmissionMode()) {
case HANDSHAKE_MODE:
return unacked_packets_.GetLastCryptoPacketSentTime() +
GetCryptoRetransmissionDelay();
case LOSS_MODE:
return loss_algorithm_->GetLossTimeout();
- case TLP_MODE: {
- QUICHE_DCHECK(!pto_enabled_);
- // TODO(ianswett): When CWND is available, it would be preferable to
- // set the timer based on the earliest retransmittable packet.
- // Base the updated timer on the send time of the last packet.
- const QuicTime sent_time =
- unacked_packets_.GetLastInFlightPacketSentTime();
- const QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
- // Ensure the TLP timer never gets set to a time in the past.
- return std::max(clock_->ApproximateNow(), tlp_time);
- }
- case RTO_MODE: {
- QUICHE_DCHECK(!pto_enabled_);
- // The RTO is based on the first outstanding packet.
- const QuicTime sent_time =
- unacked_packets_.GetLastInFlightPacketSentTime();
- QuicTime rto_time = sent_time + GetRetransmissionDelay();
- // Wait for TLP packets to be acked before an RTO fires.
- QuicTime tlp_time = sent_time + GetTailLossProbeDelay();
- return std::max(tlp_time, rto_time);
- }
case PTO_MODE: {
if (!supports_multiple_packet_number_spaces()) {
- if (first_pto_srtt_multiplier_ > 0 &&
- unacked_packets_.HasInFlightPackets() &&
+ if (unacked_packets_.HasInFlightPackets() &&
consecutive_pto_count_ == 0) {
// Arm 1st PTO with earliest in flight sent time, and make sure at
- // least first_pto_srtt_multiplier_ * RTT has been passed since last
+ // least kFirstPtoSrttMultiplier * RTT has been passed since last
// in flight packet.
return std::max(
clock_->ApproximateNow(),
@@ -1333,7 +1005,7 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
->sent_time +
GetProbeTimeoutDelay(NUM_PACKET_NUMBER_SPACES),
unacked_packets_.GetLastInFlightPacketSentTime() +
- first_pto_srtt_multiplier_ *
+ kFirstPtoSrttMultiplier *
rtt_stats_.SmoothedOrInitialRtt()));
}
// Ensure PTO never gets set to a time in the past.
@@ -1351,22 +1023,21 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
// Arm PTO from now if there is no in flight packets.
earliest_right_edge = clock_->ApproximateNow();
}
- if (first_pto_srtt_multiplier_ > 0 &&
- packet_number_space == APPLICATION_DATA &&
+ if (packet_number_space == APPLICATION_DATA &&
consecutive_pto_count_ == 0) {
const QuicTransmissionInfo* first_application_info =
unacked_packets_.GetFirstInFlightTransmissionInfoOfSpace(
APPLICATION_DATA);
if (first_application_info != nullptr) {
// Arm 1st PTO with earliest in flight sent time, and make sure at
- // least first_pto_srtt_multiplier_ * RTT has been passed since last
+ // least kFirstPtoSrttMultiplier * RTT has been passed since last
// in flight packet. Only do this for application data.
return std::max(
clock_->ApproximateNow(),
std::max(
first_application_info->sent_time +
GetProbeTimeoutDelay(packet_number_space),
- earliest_right_edge + first_pto_srtt_multiplier_ *
+ earliest_right_edge + kFirstPtoSrttMultiplier *
rtt_stats_.SmoothedOrInitialRtt()));
}
}
@@ -1380,18 +1051,14 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
}
const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
- if (pto_enabled_) {
- QUICHE_DCHECK_GT(num_ptos_for_path_degrading_, 0);
- return num_ptos_for_path_degrading_ * GetPtoDelay();
- }
- return GetNConsecutiveRetransmissionTimeoutDelay(
- max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
+ QUICHE_DCHECK_GT(num_ptos_for_path_degrading_, 0);
+ return num_ptos_for_path_degrading_ * GetPtoDelay();
}
const QuicTime::Delta QuicSentPacketManager::GetNetworkBlackholeDelay(
int8_t num_rtos_for_blackhole_detection) const {
return GetNConsecutiveRetransmissionTimeoutDelay(
- max_tail_loss_probes_ + num_rtos_for_blackhole_detection);
+ kDefaultMaxTailLossProbes + num_rtos_for_blackhole_detection);
}
QuicTime::Delta QuicSentPacketManager::GetMtuReductionDelay(
@@ -1418,75 +1085,22 @@ const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
delay_ms << consecutive_crypto_retransmission_count_);
}
-const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
- QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
- if (!unacked_packets_.HasMultipleInFlightPackets()) {
- // This expression really should be using the delayed ack time, but in TCP
- // MinRTO was traditionally set to 2x the delayed ack timer and this
- // expression assumed QUIC did the same.
- return std::max(2 * srtt, 1.5 * srtt + (min_rto_timeout_ * 0.5));
- }
- return std::max(min_tlp_timeout_, 2 * srtt);
-}
-
-const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
- QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
- if (rtt_stats_.smoothed_rtt().IsZero()) {
- // We are in the initial state, use default timeout values.
- retransmission_delay =
- QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
- } else {
- retransmission_delay =
- rtt_stats_.smoothed_rtt() + 4 * rtt_stats_.mean_deviation();
- if (retransmission_delay < min_rto_timeout_) {
- retransmission_delay = min_rto_timeout_;
- }
- }
-
- // Calculate exponential back off.
- retransmission_delay =
- retransmission_delay *
- (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
-
- if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
- return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
- }
- return retransmission_delay;
-}
-
const QuicTime::Delta QuicSentPacketManager::GetProbeTimeoutDelay(
PacketNumberSpace space) const {
- QUICHE_DCHECK(pto_enabled_);
if (rtt_stats_.smoothed_rtt().IsZero()) {
// Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack.
QUIC_BUG_IF(quic_bug_12552_6, rtt_stats_.initial_rtt().IsZero());
- return std::max(
- pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(),
- QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
+ return std::max(kPtoMultiplierWithoutRttSamples * rtt_stats_.initial_rtt(),
+ QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) *
(1 << consecutive_pto_count_);
}
- const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
- ? rtt_stats_.GetStandardOrMeanDeviation()
- : rtt_stats_.mean_deviation();
QuicTime::Delta pto_delay =
rtt_stats_.smoothed_rtt() +
- std::max(pto_rttvar_multiplier_ * rtt_var, kAlarmGranularity) +
+ std::max(kPtoRttvarMultiplier * rtt_stats_.mean_deviation(),
+ kAlarmGranularity) +
(ShouldAddMaxAckDelay(space) ? peer_max_ack_delay_
: QuicTime::Delta::Zero());
- pto_delay =
- pto_delay * (1 << (consecutive_pto_count_ -
- std::min(consecutive_pto_count_,
- pto_exponential_backoff_start_point_)));
- if (consecutive_pto_count_ < num_tlp_timeout_ptos_) {
- // Make first n PTOs similar to TLPs.
- if (pto_delay > 2 * rtt_stats_.smoothed_rtt()) {
- QUIC_CODE_COUNT(quic_delayed_pto);
- pto_delay = std::max(kAlarmGranularity, 2 * rtt_stats_.smoothed_rtt());
- } else {
- QUIC_CODE_COUNT(quic_faster_pto);
- }
- }
- return pto_delay;
+ return pto_delay * (1 << consecutive_pto_count_);
}
QuicTime::Delta QuicSentPacketManager::GetSlowStartDuration() const {
@@ -1529,8 +1143,6 @@ void QuicSentPacketManager::SetSendAlgorithm(
std::unique_ptr<SendAlgorithmInterface>
QuicSentPacketManager::OnConnectionMigration(bool reset_send_algorithm) {
- consecutive_rto_count_ = 0;
- consecutive_tlp_count_ = 0;
consecutive_pto_count_ = 0;
rtt_stats_.OnConnectionMigration();
if (!reset_send_algorithm) {
@@ -1787,13 +1399,16 @@ QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
QuicTime::Delta total_delay = QuicTime::Delta::Zero();
const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
int num_tlps =
- std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
+ std::min(num_timeouts, static_cast<int>(kDefaultMaxTailLossProbes));
num_timeouts -= num_tlps;
if (num_tlps > 0) {
- const QuicTime::Delta tlp_delay =
- std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
- ? min_tlp_timeout_
- : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
+ const QuicTime::Delta tlp_delay = std::max(
+ 2 * srtt,
+ unacked_packets_.HasMultipleInFlightPackets()
+ ? QuicTime::Delta::FromMilliseconds(kMinTailLossProbeTimeoutMs)
+ : (1.5 * srtt +
+ (QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs) *
+ 0.5)));
total_delay = total_delay + num_tlps * tlp_delay;
}
if (num_timeouts == 0) {
@@ -1803,7 +1418,9 @@ QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
const QuicTime::Delta retransmission_delay =
rtt_stats_.smoothed_rtt().IsZero()
? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
- : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
+ : std::max(
+ srtt + 4 * rtt_stats_.mean_deviation(),
+ QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs));
total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
return total_delay;
}
@@ -1824,8 +1441,7 @@ bool QuicSentPacketManager::IsLessThanThreePTOs(QuicTime::Delta timeout) const {
}
QuicTime::Delta QuicSentPacketManager::GetPtoDelay() const {
- return pto_enabled_ ? GetProbeTimeoutDelay(APPLICATION_DATA)
- : GetRetransmissionDelay();
+ return GetProbeTimeoutDelay(APPLICATION_DATA);
}
void QuicSentPacketManager::OnAckFrequencyFrameSent(
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.h
index a476f41aa54..f0a6bc6ded7 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.h
@@ -25,7 +25,6 @@
#include "quiche/quic/core/quic_transmission_info.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_unacked_packet_map.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/common/quiche_circular_deque.h"
@@ -110,10 +109,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// The retransmission timer is a single timer which switches modes depending
// upon connection state.
enum RetransmissionTimeoutMode {
- // A conventional TCP style RTO.
- RTO_MODE,
- // A tail loss probe. By default, QUIC sends up to two before RTOing.
- TLP_MODE,
// Retransmission of handshake packets prior to handshake completion.
HANDSHAKE_MODE,
// Re-invoke the loss detection when a packet is not acked before the
@@ -176,10 +171,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void OnConfigNegotiated();
void OnConnectionClosed();
- // Retransmits the oldest pending packet there is still a tail loss probe
- // pending. Invoked after OnRetransmissionTimeout.
- bool MaybeRetransmitTailLossProbe();
-
// Retransmits the oldest pending packet.
bool MaybeRetransmitOldestPacket(TransmissionType type);
@@ -375,10 +366,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
bool InSlowStart() const { return send_algorithm_->InSlowStart(); }
- size_t GetConsecutiveRtoCount() const { return consecutive_rto_count_; }
-
- size_t GetConsecutiveTlpCount() const { return consecutive_tlp_count_; }
-
size_t GetConsecutivePtoCount() const { return consecutive_pto_count_; }
void OnApplicationLimited();
@@ -410,7 +397,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void set_peer_max_ack_delay(QuicTime::Delta peer_max_ack_delay) {
// The delayed ack time should never be more than one half the min RTO time.
- QUICHE_DCHECK_LE(peer_max_ack_delay, (min_rto_timeout_ * 0.5));
+ QUICHE_DCHECK_LE(
+ peer_max_ack_delay,
+ (QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs) * 0.5));
peer_max_ack_delay_ = peer_max_ack_delay;
}
@@ -432,21 +421,13 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Setting the send algorithm once the connection is underway is dangerous.
void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm);
- // Sends up to max_probe_packets_per_pto_ probe packets.
- void MaybeSendProbePackets();
-
- // Called to adjust pending_timer_transmission_count_ accordingly.
- void AdjustPendingTimerTransmissions();
+ // Sends one probe packet.
+ void MaybeSendProbePacket();
// Called to disable HANDSHAKE_MODE, and only PTO and LOSS modes are used.
// Also enable IETF loss detection.
void EnableIetfPtoAndLossDetection();
- // Called to set the start point of doing exponential backoff when calculating
- // PTO timeout.
- void StartExponentialBackoffAfterNthPto(
- size_t exponential_backoff_start_point);
-
// Called to retransmit in flight packet of |space| if any.
void RetransmitDataOfSpaceIfAny(PacketNumberSpace space);
@@ -460,14 +441,8 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
return unacked_packets_.supports_multiple_packet_number_spaces();
}
- bool pto_enabled() const { return pto_enabled_; }
-
bool handshake_mode_disabled() const { return handshake_mode_disabled_; }
- bool skip_packet_number_for_pto() const {
- return skip_packet_number_for_pto_;
- }
-
bool zero_rtt_packet_acked() const { return zero_rtt_packet_acked_; }
bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
@@ -489,12 +464,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// kMinUntrustedInitialRoundTripTimeUs if not |trusted|.
void SetInitialRtt(QuicTime::Delta rtt, bool trusted);
- bool use_lower_min_irtt() const { return use_lower_min_irtt_; }
-
- bool simplify_set_retransmission_alarm() const {
- return simplify_set_retransmission_alarm_;
- }
-
private:
friend class test::QuicConnectionPeer;
friend class test::QuicSentPacketManagerPeer;
@@ -505,21 +474,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Retransmits all crypto stream packets.
void RetransmitCryptoPackets();
- // Retransmits two packets for an RTO and removes any non-retransmittable
- // packets from flight.
- void RetransmitRtoPackets();
-
// Returns the timeout for retransmitting crypto handshake packets.
const QuicTime::Delta GetCryptoRetransmissionDelay() const;
- // Calls GetTailLossProbeDelay() with values from the current state of this
- // packet manager as its params.
- const QuicTime::Delta GetTailLossProbeDelay() const;
-
- // Calls GetRetransmissionDelay() with values from the current state of this
- // packet manager as its params.
- const QuicTime::Delta GetRetransmissionDelay() const;
-
// Returns the probe timeout.
const QuicTime::Delta GetProbeTimeoutDelay(PacketNumberSpace space) const;
@@ -581,6 +538,7 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// A helper function to return total delay of |num_timeouts| retransmission
// timeout with TLP and RTO mode.
+ // TODO(fayang): remove this method and calculate blackhole delay by PTO.
QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
int num_timeouts) const;
@@ -619,32 +577,14 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
LossDetectionInterface* loss_algorithm_;
UberLossAlgorithm uber_loss_algorithm_;
- // Tracks the first RTO packet. If any packet before that packet gets acked,
- // it indicates the RTO was spurious and should be reversed(F-RTO).
- QuicPacketNumber first_rto_transmission_;
- // Number of times the RTO timer has fired in a row without receiving an ack.
- size_t consecutive_rto_count_;
- // Number of times the tail loss probe has been sent.
- size_t consecutive_tlp_count_;
// Number of times the crypto handshake has been retransmitted.
size_t consecutive_crypto_retransmission_count_;
- // Number of pending transmissions of TLP, RTO, or crypto packets.
+ // Number of pending transmissions of PTO or crypto packets.
size_t pending_timer_transmission_count_;
- // Maximum number of tail loss probes to send before firing an RTO.
- size_t max_tail_loss_probes_;
- // Maximum number of packets to send upon RTO.
- QuicPacketCount max_rto_packets_;
- // If true, send the TLP at 0.5 RTT.
+
bool using_pacing_;
- // If true, use the new RTO with loss based CWND reduction instead of the send
- // algorithms's OnRetransmissionTimeout to reduce the congestion window.
- bool use_new_rto_;
// If true, use a more conservative handshake retransmission policy.
bool conservative_handshake_retransmits_;
- // The minimum TLP timeout.
- QuicTime::Delta min_tlp_timeout_;
- // The minimum RTO.
- QuicTime::Delta min_rto_timeout_;
// Vectors packets acked and lost as a result of the last congestion event.
AckedPacketVector packets_acked_;
@@ -703,36 +643,12 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// OnAckRangeStart, and gradually moves in OnAckRange..
PacketNumberQueue::const_reverse_iterator acked_packets_iter_;
- // Indicates whether PTO mode has been enabled. PTO mode unifies TLP and RTO
- // modes.
- bool pto_enabled_;
-
- // Maximum number of probes to send when PTO fires.
- size_t max_probe_packets_per_pto_;
-
// Number of times the PTO timer has fired in a row without receiving an ack.
size_t consecutive_pto_count_;
// True if HANDSHAKE mode has been disabled.
bool handshake_mode_disabled_;
- // If true, skip packet number before sending the last PTO retransmission.
- bool skip_packet_number_for_pto_;
-
- // If true, always include peer_max_ack_delay_ when calculating PTO timeout.
- bool always_include_max_ack_delay_for_pto_timeout_;
-
- // When calculating PTO timeout, the start point of doing exponential backoff.
- // For example, 0 : always do exponential backoff. n : do exponential backoff
- // since nth PTO.
- size_t pto_exponential_backoff_start_point_;
-
- // The multiplier of rttvar when calculating PTO timeout.
- int pto_rttvar_multiplier_;
-
- // Number of PTOs similar to TLPs.
- size_t num_tlp_timeout_ptos_;
-
// True if any ENCRYPTION_HANDSHAKE packet gets acknowledged.
bool handshake_packet_acked_;
@@ -742,18 +658,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// True if any 1-RTT packet gets acknowledged.
bool one_rtt_packet_acked_;
- // If > 0, arm the 1st PTO with max of earliest in flight sent time + PTO
- // delay and multiplier * srtt from last in flight packet.
- float first_pto_srtt_multiplier_;
-
- // If true, use standard deviation (instead of mean deviation) when
- // calculating PTO timeout.
- bool use_standard_deviation_for_pto_;
-
- // The multiplier for caculating PTO timeout before any RTT sample is
- // available.
- float pto_multiplier_without_rtt_samples_;
-
// The number of PTOs needed for path degrading alarm. If equals to 0, the
// traditional path degrading mechanism will be used.
int num_ptos_for_path_degrading_;
@@ -764,13 +668,6 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Whether to ignore the ack_delay in received ACKs.
bool ignore_ack_delay_;
-
- // Latched value of --quic_use_lower_min_for_trusted_irtt.
- bool use_lower_min_irtt_ =
- GetQuicReloadableFlag(quic_use_lower_min_for_trusted_irtt);
-
- const bool simplify_set_retransmission_alarm_ =
- GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager_test.cc
index 24485e2d97c..8c8076b43e5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -98,8 +98,6 @@ class QuicSentPacketManagerTest : public QuicTest {
send_algorithm_(new StrictMock<MockSendAlgorithm>),
network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
- // Disable tail loss probes for most tests.
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
// Advance the time 1s so the send times are never QuicTime::Zero.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
manager_.SetNetworkChangeVisitor(network_change_visitor_.get());
@@ -202,7 +200,7 @@ class QuicSentPacketManagerTest : public QuicTest {
void RetransmitAndSendPacket(uint64_t old_packet_number,
uint64_t new_packet_number) {
RetransmitAndSendPacket(old_packet_number, new_packet_number,
- TLP_RETRANSMISSION);
+ PTO_RETRANSMISSION);
}
void RetransmitAndSendPacket(uint64_t old_packet_number,
@@ -210,9 +208,7 @@ class QuicSentPacketManagerTest : public QuicTest {
TransmissionType transmission_type) {
bool is_lost = false;
if (transmission_type == HANDSHAKE_RETRANSMISSION ||
- transmission_type == TLP_RETRANSMISSION ||
- transmission_type == RTO_RETRANSMISSION ||
- transmission_type == PROBING_RETRANSMISSION) {
+ transmission_type == PTO_RETRANSMISSION) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(WithArgs<1>(
Invoke([this, new_packet_number](TransmissionType type) {
@@ -316,25 +312,6 @@ class QuicSentPacketManagerTest : public QuicTest {
NO_RETRANSMITTABLE_DATA, true);
}
- void EnablePto(QuicTag tag) {
- QuicConfig config;
- QuicTagVector options;
- options.push_back(tag);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.pto_enabled());
- }
-
- int GetPtoRttvarMultiplier() {
- if (GetQuicRestartFlag(quic_default_on_pto2) ||
- manager_.handshake_mode_disabled()) {
- return 2;
- }
- return 4;
- }
-
quiche::SimpleBufferAllocator allocator_;
QuicSentPacketManager manager_;
MockClock clock_;
@@ -393,7 +370,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
return RetransmitDataPacket(2, type);
})));
QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
- TLP_RETRANSMISSION);
+ PTO_RETRANSMISSION);
// Ack 1.
ExpectAck(1);
manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
@@ -415,7 +392,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
SendDataPacket(1);
EXPECT_CALL(notifier_, RetransmitFrames(_, _)).WillRepeatedly(Return(true));
QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
- TLP_RETRANSMISSION);
+ PTO_RETRANSMISSION);
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
@@ -552,7 +529,7 @@ TEST_F(QuicSentPacketManagerTest,
TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
StrictMock<MockDebugDelegate> debug_delegate;
- EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(TLP_RETRANSMISSION,
+ EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(PTO_RETRANSMISSION,
kDefaultLength))
.Times(1);
manager_.SetDebugDelegate(&debug_delegate);
@@ -831,155 +808,6 @@ TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
-TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeout) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
- // Send 1 packet.
- SendDataPacket(1);
-
- // The first tail loss probe retransmits 1 packet.
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(2, type);
- })));
- manager_.MaybeRetransmitTailLossProbe();
-
- // The second tail loss probe retransmits 1 packet.
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type);
- })));
- manager_.MaybeRetransmitTailLossProbe();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
- // Ack the third and ensure the first two are still pending.
- ExpectAck(3);
-
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- EXPECT_TRUE(manager_.HasInFlightPackets());
-
- // Acking two more packets will lose both of them due to nacks.
- SendDataPacket(4);
- SendDataPacket(5);
- uint64_t acked[] = {4, 5};
- uint64_t lost[] = {1, 2};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), lost,
- ABSL_ARRAYSIZE(lost));
- // Frames in all packets are acked.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- // Notify session that stream frame in packets 1 and 2 get lost although
- // they are not outstanding.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
- manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
-
- EXPECT_FALSE(manager_.HasInFlightPackets());
- EXPECT_EQ(2u, stats_.tlp_count);
- EXPECT_EQ(0u, stats_.rto_count);
-}
-
-TEST_F(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
-
- // Send 100 packets.
- const size_t kNumSentPackets = 100;
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
- QuicTime rto_packet_time = clock_.Now();
- // Advance the time.
- clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
-
- // The first tail loss probe retransmits 1 packet.
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(101, type);
- })));
- manager_.MaybeRetransmitTailLossProbe();
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
- clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
-
- // The second tail loss probe retransmits 1 packet.
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(102, type);
- })));
- EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
- // Ensure the RTO is set based on the correct packet.
- rto_packet_time = clock_.Now();
- EXPECT_EQ(rto_packet_time + QuicTime::Delta::FromMilliseconds(500),
- manager_.GetRetransmissionTime());
-
- // Advance the time enough to ensure all packets are RTO'd.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(103, type);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(104, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(2u, stats_.tlp_count);
- EXPECT_EQ(1u, stats_.rto_count);
- EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
- // There are 2 RTO retransmissions.
- EXPECT_EQ(104 * kDefaultLength, manager_.GetBytesInFlight());
- QuicPacketNumber largest_acked = QuicPacketNumber(103);
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(
- true, _, _, Pointwise(PacketNumberEq(), {largest_acked}), _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- // Although frames in packet 3 gets acked, it would be kept for another
- // RTT.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- // Packets [1, 102] are lost, although stream frame in packet 3 is not
- // outstanding.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(102);
- manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- // All packets before 103 should be lost.
- // Packet 104 is still in flight.
- EXPECT_EQ(1000u, manager_.GetBytesInFlight());
- EXPECT_EQ(1u, stats_.max_consecutive_rto_with_forward_progress);
-}
-
TEST_F(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
// Send 2 crypto packets and 3 data packets.
const size_t kNumSentCryptoPackets = 2;
@@ -1137,225 +965,6 @@ TEST_F(QuicSentPacketManagerTest,
VerifyRetransmittablePackets(nullptr, 0);
}
-TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- StrictMock<MockDebugDelegate> debug_delegate;
- manager_.SetDebugDelegate(&debug_delegate);
-
- // Send 100 packets.
- const size_t kNumSentPackets = 100;
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
-
- EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(101, type);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(102, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Ack a retransmission.
- // Ensure no packets are lost.
- QuicPacketNumber largest_acked = QuicPacketNumber(102);
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(true, _, _,
- Pointwise(PacketNumberEq(), {largest_acked}),
- /*lost_packets=*/IsEmpty()));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- // RTO's use loss detection instead of immediately declaring retransmitted
- // packets lost.
- for (int i = 1; i <= 99; ++i) {
- EXPECT_CALL(debug_delegate,
- OnPacketLoss(QuicPacketNumber(i), _, LOSS_RETRANSMISSION, _));
- }
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- // Packets [1, 99] are considered as lost, although stream frame in packet
- // 2 is not outstanding.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
- manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- // Set the 1RTO connection option.
- QuicConfig client_config;
- QuicTagVector options;
- options.push_back(k1RTO);
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(client_config);
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
- StrictMock<MockDebugDelegate> debug_delegate;
- manager_.SetDebugDelegate(&debug_delegate);
-
- // Send 100 packets.
- const size_t kNumSentPackets = 100;
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
-
- EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(1)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(101, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(101 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig client_config;
- QuicTagVector options;
- options.push_back(kNRTO);
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(client_config);
- EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
- // Send 100 packets.
- const size_t kNumSentPackets = 100;
- for (size_t i = 1; i <= kNumSentPackets; ++i) {
- SendDataPacket(i);
- }
-
- EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(101, type);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(102, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(102 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Ack a retransmission and expect no call to OnRetransmissionTimeout.
- // This will include packets in the lost packet map.
- QuicPacketNumber largest_acked = QuicPacketNumber(102);
- EXPECT_CALL(*send_algorithm_,
- OnCongestionEvent(true, _, _,
- Pointwise(PacketNumberEq(), {largest_acked}),
- /*lost_packets=*/Not(IsEmpty())));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
- // Packets [1, 99] are considered as lost, although stream frame in packet
- // 2 is not outstanding.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
- manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- // Send 1 packet.
- SendDataPacket(1);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(2, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Rto a second time.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Ack a retransmission and ensure OnRetransmissionTimeout is called.
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- ExpectAck(2);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- // The original packet and newest should be outstanding.
- EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
-TEST_F(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- // Send 1 packet.
- SendDataPacket(1);
-
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(2, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Rto a second time.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(3 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Ack a retransmission and ensure OnRetransmissionTimeout is called.
- EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
- ExpectAck(3);
- manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- // The first two packets should still be outstanding.
- EXPECT_EQ(2 * kDefaultLength, manager_.GetBytesInFlight());
-}
-
TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) {
EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
}
@@ -1448,199 +1057,6 @@ TEST_F(QuicSentPacketManagerTest,
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
- SendDataPacket(1);
- SendDataPacket(2);
-
- // Check the min.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
- EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
- manager_.GetRetransmissionTime());
-
- // Test with a standard smoothed RTT.
- rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
- QuicTime::Delta srtt = rtt_stats->initial_rtt();
- QuicTime::Delta expected_tlp_delay = 2 * srtt;
- QuicTime expected_time = clock_.Now() + expected_tlp_delay;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(expected_tlp_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type);
- })));
- EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
- EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
-
- expected_time = clock_.Now() + expected_tlp_delay;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
-
- SendDataPacket(1);
- SendDataPacket(2);
- SendDataPacket(3);
- SendDataPacket(4);
-
- QuicTime::Delta expected_rto_delay =
- rtt_stats->smoothed_rtt() + 4 * rtt_stats->mean_deviation();
- QuicTime expected_time = clock_.Now() + expected_rto_delay;
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Retransmit the packet by invoking the retransmission timeout.
- clock_.AdvanceTime(expected_rto_delay);
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(5, type);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(6, type);
- })));
- manager_.OnRetransmissionTimeout();
- // All previous packets are inflight, plus two rto retransmissions.
- EXPECT_EQ(6 * kDefaultLength, manager_.GetBytesInFlight());
-
- // The delay should double the second time.
- expected_time = clock_.Now() + expected_rto_delay + expected_rto_delay;
- // Once we always base the timer on the right edge, leaving the older packets
- // in flight doesn't change the timeout.
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-
- // Ack a packet before the first RTO and ensure the RTO timeout returns to the
- // original value and OnRetransmissionTimeout is not called or reverted.
- uint64_t acked[] = {1, 2};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
- EXPECT_EQ(4 * kDefaultLength, manager_.GetBytesInFlight());
-
- // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
- // and the TLP time. In production, there would always be two TLP's first.
- // Since retransmission was spurious, smoothed_rtt_ is expired, and replaced
- // by the latest RTT sample of 500ms.
- expected_time = clock_.Now() + QuicTime::Delta::FromMilliseconds(1000);
- // Once we always base the timer on the right edge, leaving the older packets
- // in flight doesn't change the timeout.
- EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- SendDataPacket(1);
- // Provide a 1ms RTT sample.
- const_cast<RttStats*>(manager_.GetRttStats())
- ->UpdateRtt(QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::Zero(),
- QuicTime::Zero());
- QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(200);
-
- // If the delay is smaller than the min, ensure it exponentially backs off
- // from the min.
- for (int i = 0; i < 5; ++i) {
- EXPECT_EQ(delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- delay = delay + delay;
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
- return RetransmitDataPacket(i + 2, type);
- })));
- manager_.OnRetransmissionTimeout();
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- SendDataPacket(1);
- // Provide a 60s RTT sample.
- const_cast<RttStats*>(manager_.GetRttStats())
- ->UpdateRtt(QuicTime::Delta::FromSeconds(60), QuicTime::Delta::Zero(),
- QuicTime::Zero());
-
- EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- SendDataPacket(1);
- QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
-
- // Delay should back off exponentially.
- for (int i = 0; i < 5; ++i) {
- EXPECT_EQ(delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- delay = delay + delay;
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
- return RetransmitDataPacket(i + 2, type);
- })));
- manager_.OnRetransmissionTimeout();
- }
-}
-
-TEST_F(QuicSentPacketManagerTest, RetransmissionDelay) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- const int64_t kRttMs = 250;
- const int64_t kDeviationMs = 5;
-
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
- QuicTime::Delta::Zero(), clock_.Now());
-
- // Initial value is to set the median deviation to half of the initial rtt,
- // the median in then multiplied by a factor of 4 and finally the smoothed rtt
- // is added which is the initial rtt.
- QuicTime::Delta expected_delay =
- QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
- EXPECT_EQ(expected_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
-
- for (int i = 0; i < 100; ++i) {
- // Run to make sure that we converge.
- rtt_stats->UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- rtt_stats->UpdateRtt(
- QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
- QuicTime::Delta::Zero(), clock_.Now());
- }
- expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
-
- EXPECT_NEAR(kRttMs, rtt_stats->smoothed_rtt().ToMilliseconds(), 1);
- EXPECT_NEAR(expected_delay.ToMilliseconds(),
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
- .ToMilliseconds(),
- 1);
-}
-
TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
auto loss_algorithm = std::make_unique<MockLossAlgorithm>();
QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
@@ -1868,214 +1284,6 @@ TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
->GetCongestionControlType());
}
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kMAD2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillOnce(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(config);
- // Set the initial RTT to 1us.
- QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
- QuicTime::Delta::FromMicroseconds(1));
- // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-
- // Send two packets, and the TLP should be 1ms.
- QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
- SendDataPacket(1);
- SendDataPacket(2);
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig client_config;
- QuicTagVector options;
-
- options.push_back(kMAD2);
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillOnce(Return(10 * kDefaultTCPMSS));
- manager_.SetFromConfig(client_config);
- // Set the initial RTT to 1us.
- QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
- QuicTime::Delta::FromMicroseconds(1));
- // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- // Send two packets, and the TLP should be 1ms.
- QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
- SendDataPacket(1);
- SendDataPacket(2);
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kMAD3);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(config);
- // Provide one RTT measurement, because otherwise we use the default of 500ms.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
- EXPECT_EQ(expected_rto_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
- QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig client_config;
- QuicTagVector options;
-
- options.push_back(kMAD3);
- 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);
- // Provide one RTT measurement, because otherwise we use the default of 500ms.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
- EXPECT_EQ(expected_rto_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
- QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kNTLP);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(config);
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicConfig client_config;
- QuicTagVector options;
-
- options.push_back(kNTLP);
- 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(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- 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) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- 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, NegotiateNewRTOFromOptionsAtServer) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
- QuicConfig config;
- QuicTagVector options;
-
- options.push_back(kNRTO);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(config);
- EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-}
-
-TEST_F(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
- QuicConfig client_config;
- QuicTagVector options;
-
- options.push_back(kNRTO);
- QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- manager_.SetFromConfig(client_config);
- EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
-}
-
TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325);
EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt());
@@ -2116,18 +1324,15 @@ TEST_F(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
rtt_stats->set_initial_rtt(default_init_rtt * 2);
EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
- EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
- EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+ QuicSentPacketManagerPeer::SetConsecutivePtoCount(&manager_, 1);
+ EXPECT_EQ(1u, manager_.GetConsecutivePtoCount());
EXPECT_CALL(*send_algorithm_, OnConnectionMigration());
EXPECT_EQ(nullptr,
manager_.OnConnectionMigration(/*reset_send_algorithm=*/false));
EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
- EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
- EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+ EXPECT_EQ(0u, manager_.GetConsecutivePtoCount());
}
// Tests that ResetCongestionControlUponPeerAddressChange() resets send
@@ -2142,10 +1347,8 @@ TEST_F(QuicSentPacketManagerTest,
rtt_stats->set_initial_rtt(default_init_rtt * 2);
EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
- EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
- EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+ QuicSentPacketManagerPeer::SetConsecutivePtoCount(&manager_, 1);
+ EXPECT_EQ(1u, manager_.GetConsecutivePtoCount());
SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
@@ -2161,8 +1364,7 @@ TEST_F(QuicSentPacketManagerTest,
EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
manager_.GetSendAlgorithm()->GetCongestionControlType());
EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
- EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
- EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+ EXPECT_EQ(0u, manager_.GetConsecutivePtoCount());
// Packets sent earlier shouldn't be regarded as in flight.
EXPECT_EQ(0u, BytesInFlight());
@@ -2245,8 +1447,7 @@ TEST_F(QuicSentPacketManagerTest,
EXPECT_EQ(old_send_algorithm->GetCongestionControlType(),
manager_.GetSendAlgorithm()->GetCongestionControlType());
EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
- EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
- EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+ EXPECT_EQ(0u, manager_.GetConsecutivePtoCount());
EXPECT_EQ(0u, BytesInFlight());
EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
@@ -2317,8 +1518,7 @@ TEST_F(QuicSentPacketManagerTest,
old_send_algorithm =
manager_.OnConnectionMigration(/*reset_send_algorithm=*/true);
EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
- EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
- EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+ EXPECT_EQ(0u, manager_.GetConsecutivePtoCount());
EXPECT_EQ(0u, BytesInFlight());
EXPECT_TRUE(manager_.GetRttStats()->latest_rtt().IsZero());
@@ -2622,94 +1822,7 @@ TEST_F(QuicSentPacketManagerTest,
ENCRYPTION_HANDSHAKE));
}
-// Regression test for b/133771183.
-TEST_F(QuicSentPacketManagerTest, PacketInLimbo) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
- // Send SHLO.
- SendCryptoPacket(1);
- // Send data packet.
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
- // Send Ack Packet.
- SendAckPacket(3, 1, ENCRYPTION_FORWARD_SECURE);
- // Retransmit SHLO.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(
- InvokeWithoutArgs([this]() { return RetransmitCryptoPacket(4); }));
- manager_.OnRetransmissionTimeout();
-
- // Successfully decrypt a forward secure packet.
- manager_.SetHandshakeConfirmed();
- EXPECT_CALL(notifier_, HasUnackedCryptoData()).WillRepeatedly(Return(false));
- // Send Ack packet.
- SendAckPacket(5, 2, ENCRYPTION_FORWARD_SECURE);
-
- // Retransmission alarm fires.
- manager_.OnRetransmissionTimeout();
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeRetransmitTailLossProbe();
-
- // Received Ack of packets 1, 3 and 4.
- uint64_t acked[] = {1, 3, 4};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- uint64_t acked2[] = {5, 6};
- uint64_t loss[] = {2};
- // Verify packet 2 is detected lost.
- EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
- ExpectAcksAndLosses(true, acked2, ABSL_ARRAYSIZE(acked2), loss,
- ABSL_ARRAYSIZE(loss));
- manager_.OnAckFrameStart(QuicPacketNumber(6), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(7));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2),
- ENCRYPTION_INITIAL));
-}
-
-TEST_F(QuicSentPacketManagerTest, RtoFiresNoPacketToRetransmit) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- // Send 10 packets.
- for (size_t i = 1; i <= 10; ++i) {
- SendDataPacket(i);
- }
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(11, type);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(12, type);
- })));
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(1u, stats_.rto_count);
- EXPECT_EQ(0u, manager_.pending_timer_transmission_count());
-
- // RTO fires again, but there is no packet to be RTO retransmitted.
- EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
- EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(2u, stats_.rto_count);
- // Verify a credit is raised up.
- EXPECT_EQ(1u, manager_.pending_timer_transmission_count());
-}
-
TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
- EnablePto(k2PTO);
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -2722,7 +1835,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
QuicTime packet1_sent_time = clock_.Now();
EXPECT_EQ(clock_.Now() + expected_pto_delay,
@@ -2730,12 +1843,8 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set based on sent time of packet 2.
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- // Verify PTO is set based on left edge.
- deadline = packet1_sent_time + expected_pto_delay;
- }
+ // Verify PTO is set based on left edge.
+ QuicTime deadline = packet1_sent_time + expected_pto_delay;
EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
EXPECT_EQ(0u, stats_.pto_count);
@@ -2746,23 +1855,11 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
EXPECT_EQ(1u, stats_.pto_count);
EXPECT_EQ(0u, stats_.max_consecutive_rto_with_forward_progress);
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- } else {
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
- })));
- }
- manager_.MaybeSendProbePackets();
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+ .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+ return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
+ })));
+ manager_.MaybeSendProbePacket();
// Verify PTO period gets set to twice the current value.
QuicTime sent_time = clock_.Now();
EXPECT_EQ(sent_time + expected_pto_delay * 2,
@@ -2779,7 +1876,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
ENCRYPTION_FORWARD_SECURE));
expected_pto_delay =
rtt_stats->SmoothedOrInitialRtt() +
- std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+ std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
QuicTime::Delta::FromMilliseconds(1)) +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
@@ -2789,7 +1886,6 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeout) {
}
TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
- EnablePto(k1PTO);
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -2806,13 +1902,10 @@ TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
// Verify PTO period is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- // Verify PTO is set based on left edge.
- deadline = packet1_sent_time + expected_pto_delay;
- }
+ // Verify PTO is set based on left edge.
+ QuicTime deadline = packet1_sent_time + expected_pto_delay;
EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
// Invoke PTO.
@@ -2825,7 +1918,7 @@ TEST_F(QuicSentPacketManagerTest, SendOneProbePacket) {
.WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
})));
- manager_.MaybeSendProbePackets();
+ manager_.MaybeSendProbePacket();
}
TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeClient) {
@@ -2883,269 +1976,7 @@ TEST_F(QuicSentPacketManagerTest, DisableHandshakeModeServer) {
EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest, PtoTimeoutIncludesMaxAckDelay) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EnablePto(k1PTO);
- // Use PTOS and PTOA.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPTOA);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
-
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- QuicTime packet1_sent_time = clock_.Now();
- // Verify PTO is correctly set and ack delay is included.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set based on sent time of packet 2 but ack delay is
- // not included as an immediate ACK is expected.
- expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
- kDefaultDelayedAckTimeMs);
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- deadline = packet1_sent_time + expected_pto_delay;
- }
- EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
- EXPECT_EQ(0u, stats_.pto_count);
-
- // Invoke PTO.
- clock_.AdvanceTime(deadline - clock_.Now());
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- // Verify 1 probe packets get sent and packet number gets skipped.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify PTO period gets set to twice the current value. Also, ack delay is
- // not included.
- QuicTime sent_time = clock_.Now();
- EXPECT_EQ(sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Received ACK for packets 1 and 2.
- uint64_t acked[] = {1, 2};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_FORWARD_SECURE));
- expected_pto_delay =
- rtt_stats->SmoothedOrInitialRtt() +
- std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
- QuicTime::Delta::FromMilliseconds(1)) +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
- // Verify PTO is correctly re-armed based on sent time of packet 4. Because of
- // PTOS turns out to be spurious, ACK delay is included.
- EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
-
- // Received ACK for packets 4.
- ExpectAck(4);
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_FORWARD_SECURE));
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
- // Send more packets, such that peer will do ack decimation.
- std::vector<uint64_t> acked2;
- for (size_t i = 5; i <= 100; ++i) {
- SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
- acked2.push_back(i);
- }
- // Received ACK for all sent packets.
- ExpectAcksAndLosses(true, &acked2[0], acked2.size(), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(100), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(101));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(100),
- ENCRYPTION_FORWARD_SECURE));
-
- expected_pto_delay =
- rtt_stats->SmoothedOrInitialRtt() +
- std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
- QuicTime::Delta::FromMilliseconds(1)) +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- for (size_t i = 101; i < 110; i++) {
- SendDataPacket(i, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO timeout includes ACK delay as there are less than 10 packets
- // outstanding.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
- }
- expected_pto_delay = expected_pto_delay - QuicTime::Delta::FromMilliseconds(
- kDefaultDelayedAckTimeMs);
- SendDataPacket(110, ENCRYPTION_FORWARD_SECURE);
- // Verify ACK delay is excluded.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, StartExponentialBackoffSince2ndPto) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EnablePto(k2PTO);
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPEB2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- QuicTime packet1_sent_time = clock_.Now();
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(packet1_sent_time + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set based on sent time of packet 2.
- QuicTime deadline = clock_.Now() + expected_pto_delay;
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- // Verify PTO is set based on left edge.
- deadline = packet1_sent_time + expected_pto_delay;
- }
- EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
- EXPECT_EQ(0u, stats_.pto_count);
-
- // Invoke PTO.
- clock_.AdvanceTime(deadline - clock_.Now());
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify no exponential backoff.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke 2nd PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(2u, stats_.pto_count);
-
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(6, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify still no exponential backoff.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke 3rd PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(3u, stats_.pto_count);
-
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(7, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(8, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify exponential backoff starts.
- EXPECT_EQ(clock_.Now() + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-
- // Invoke 4th PTO.
- clock_.AdvanceTime(expected_pto_delay * 2);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(4u, stats_.pto_count);
-
- // Verify two probe packets get sent.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .Times(2)
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(9, type, ENCRYPTION_FORWARD_SECURE);
- })))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(10, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- // Verify exponential backoff continues.
- EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
- manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest, PtoTimeoutRttVarMultiple) {
- EnablePto(k1PTO);
- // Use 2 * rttvar
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPVS1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -3158,172 +1989,12 @@ TEST_F(QuicSentPacketManagerTest, PtoTimeoutRttVarMultiple) {
SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
// Verify PTO is correctly set based on 2 times rtt var.
QuicTime::Delta expected_pto_delay =
- srtt + 2 * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
EXPECT_EQ(clock_.Now() + expected_pto_delay,
manager_.GetRetransmissionTime());
}
-// Regression test for b/143962153
-TEST_F(QuicSentPacketManagerTest, RtoNotInFlightPacket) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
- // Send SHLO.
- QuicStreamFrame crypto_frame(1, false, 0, absl::string_view());
- SendCryptoPacket(1);
- // Send data packet.
- SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
-
- // Successfully decrypt a forward secure packet.
- EXPECT_CALL(notifier_, OnFrameAcked(_, _, _)).Times(1);
- manager_.SetHandshakeConfirmed();
-
- // 1st TLP.
- manager_.OnRetransmissionTimeout();
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeRetransmitTailLossProbe();
-
- // 2nd TLP.
- manager_.OnRetransmissionTimeout();
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(4, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeRetransmitTailLossProbe();
-
- // RTO retransmits SHLO although it is not in flight.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<0>(Invoke([&crypto_frame](const QuicFrames& frames) {
- EXPECT_EQ(1u, frames.size());
- EXPECT_NE(crypto_frame, frames[0].stream_frame);
- return true;
- })));
- manager_.OnRetransmissionTimeout();
-}
-
-TEST_F(QuicSentPacketManagerTest, Aggressive1Pto) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EnablePto(k1PTO);
- // Let the first PTO be aggressive.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPAG1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay = 2 * srtt;
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- // Verify 1 probe packets get sent and packet number gets skipped.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
-
- // Verify PTO period gets set correctly.
- QuicTime sent_time = clock_.Now();
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(sent_time + expected_pto_delay * 2,
- manager_.GetRetransmissionTime());
-}
-
-TEST_F(QuicSentPacketManagerTest, Aggressive2Ptos) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EnablePto(k1PTO);
- // Let the first PTO be aggressive.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPAG2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set.
- QuicTime::Delta expected_pto_delay = 2 * srtt;
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(1u, stats_.pto_count);
-
- // Verify 1 probe packets get sent and packet number gets skipped.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
-
- // Verify PTO period gets set correctly.
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-
- // Invoke 2nd PTO.
- clock_.AdvanceTime(expected_pto_delay);
- manager_.OnRetransmissionTimeout();
- EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
- EXPECT_EQ(2u, stats_.pto_count);
-
- // Verify 1 probe packets get sent and packet number gets skipped.
- EXPECT_CALL(notifier_, RetransmitFrames(_, _))
- .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
- return RetransmitDataPacket(5, type, ENCRYPTION_FORWARD_SECURE);
- })));
- manager_.MaybeSendProbePackets();
- expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
- // Verify PTO period gets set correctly.
- EXPECT_EQ(clock_.Now() + expected_pto_delay * 4,
- manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest, IW10ForUpAndDown) {
QuicConfig config;
QuicTagVector options;
@@ -3339,7 +2010,6 @@ TEST_F(QuicSentPacketManagerTest, IW10ForUpAndDown) {
TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -3354,7 +2024,7 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
SendDataPacket(1, ENCRYPTION_INITIAL);
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
EXPECT_EQ(clock_.Now() + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3381,7 +2051,7 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
.WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
return RetransmitDataPacket(3, type, ENCRYPTION_HANDSHAKE);
})));
- manager_.MaybeSendProbePackets();
+ manager_.MaybeSendProbePacket();
// Verify PTO period gets set to twice the current value.
const QuicTime packet3_sent_time = clock_.Now();
EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
@@ -3417,7 +2087,7 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
SendDataPacket(7, ENCRYPTION_HANDSHAKE);
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation();
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation();
// Verify PTO timeout is now based on packet 7.
EXPECT_EQ(packet7_sent_time + expected_pto_delay * 2,
manager_.GetRetransmissionTime());
@@ -3427,7 +2097,7 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
// Forward progress has been made, verify PTO counter gets reset. PTO timeout
// is armed by left edge.
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
EXPECT_EQ(packet4_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3435,7 +2105,6 @@ TEST_F(QuicSentPacketManagerTest, ClientMultiplePacketNumberSpacePtoTimeout) {
TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
@@ -3450,7 +2119,7 @@ TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
const QuicTime packet1_sent_time = clock_.Now();
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3485,7 +2154,7 @@ TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
// Discard handshake keys.
manager_.SetHandshakeConfirmed();
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
// Verify PTO timeout is now based on packet 3 as handshake is
// complete/confirmed.
@@ -3494,17 +2163,6 @@ TEST_F(QuicSentPacketManagerTest, ServerMultiplePacketNumberSpacePtoTimeout) {
}
TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
- EnablePto(k1PTO);
- // Use PTOS and PLE1.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPLE1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
@@ -3518,7 +2176,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
const QuicTime packet1_sent_time = clock_.Now();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
@@ -3541,7 +2199,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
.WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
})));
- manager_.MaybeSendProbePackets();
+ manager_.MaybeSendProbePacket();
// Verify PTO period gets set to twice the current value and based on packet3.
QuicTime packet3_sent_time = clock_.Now();
EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
@@ -3558,7 +2216,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
ENCRYPTION_FORWARD_SECURE));
expected_pto_delay =
rtt_stats->SmoothedOrInitialRtt() +
- std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+ std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
QuicTime::Delta::FromMilliseconds(1)) +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
@@ -3568,17 +2226,6 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge) {
}
TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
- EnablePto(k1PTO);
- // Use PTOS and PLE2.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPLE2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
@@ -3592,7 +2239,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
const QuicTime packet1_sent_time = clock_.Now();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
@@ -3603,7 +2250,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
expected_pto_delay.ToMilliseconds() - 10));
SendDataPacket(2, ENCRYPTION_FORWARD_SECURE);
// Verify PTO expands to packet 2 sent time + 1.5 * srtt.
- expected_pto_delay = 1.5 * rtt_stats->smoothed_rtt();
+ expected_pto_delay = kFirstPtoSrttMultiplier * rtt_stats->smoothed_rtt();
EXPECT_EQ(clock_.Now() + expected_pto_delay,
manager_.GetRetransmissionTime());
EXPECT_EQ(0u, stats_.pto_count);
@@ -3618,11 +2265,11 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
.WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
return RetransmitDataPacket(3, type, ENCRYPTION_FORWARD_SECURE);
})));
- manager_.MaybeSendProbePackets();
+ manager_.MaybeSendProbePacket();
// Verify PTO period gets set to twice the expected value and based on
// packet3 (right edge).
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
QuicTime packet3_sent_time = clock_.Now();
EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
@@ -3639,7 +2286,7 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
ENCRYPTION_FORWARD_SECURE));
expected_pto_delay =
rtt_stats->SmoothedOrInitialRtt() +
- std::max(GetPtoRttvarMultiplier() * rtt_stats->mean_deviation(),
+ std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
QuicTime::Delta::FromMilliseconds(1)) +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
@@ -3649,61 +2296,9 @@ TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutByLeftEdge2) {
manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest, ComputingProbeTimeoutUsingStandardDeviation) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- EnablePto(k1PTO);
- // Use PTOS and PSDA.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPSDA);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
- EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(50),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(75),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- QuicTime::Delta srtt = rtt_stats->smoothed_rtt();
-
- SendDataPacket(1, ENCRYPTION_FORWARD_SECURE);
- // Verify PTO is correctly set using standard deviation.
- QuicTime::Delta expected_pto_delay =
- srtt +
- GetPtoRttvarMultiplier() * rtt_stats->GetStandardOrMeanDeviation() +
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
- EXPECT_EQ(clock_.Now() + expected_pto_delay,
- manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest,
ComputingProbeTimeoutByLeftEdgeMultiplePacketNumberSpaces) {
manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
- // Use PTOS and PLE1.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPLE1);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
@@ -3719,7 +2314,7 @@ TEST_F(QuicSentPacketManagerTest,
const QuicTime packet1_sent_time = clock_.Now();
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3756,7 +2351,7 @@ TEST_F(QuicSentPacketManagerTest,
// Verify PTO timeout is now based on packet 3 as handshake is
// complete/confirmed.
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
EXPECT_EQ(packet3_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3771,17 +2366,6 @@ TEST_F(QuicSentPacketManagerTest,
TEST_F(QuicSentPacketManagerTest,
ComputingProbeTimeoutByLeftEdge2MultiplePacketNumberSpaces) {
manager_.EnableMultiplePacketNumberSpacesSupport();
- EnablePto(k1PTO);
- // Use PTOS and PLE2.
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kPTOS);
- options.push_back(kPLE2);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
- EXPECT_TRUE(manager_.skip_packet_number_for_pto());
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, PacingRate(_))
.WillRepeatedly(Return(QuicBandwidth::Zero()));
@@ -3797,7 +2381,7 @@ TEST_F(QuicSentPacketManagerTest,
const QuicTime packet1_sent_time = clock_.Now();
// Verify PTO is correctly set.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3834,7 +2418,7 @@ TEST_F(QuicSentPacketManagerTest,
// Verify PTO timeout is now based on packet 3 as handshake is
// complete/confirmed.
expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
EXPECT_EQ(packet3_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -3844,7 +2428,7 @@ TEST_F(QuicSentPacketManagerTest,
expected_pto_delay.ToMilliseconds() - 10));
SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
// Verify PTO timeout expands to packet 5 sent time + 1.5 * srtt.
- EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->smoothed_rtt(),
+ EXPECT_EQ(clock_.Now() + kFirstPtoSrttMultiplier * rtt_stats->smoothed_rtt(),
manager_.GetRetransmissionTime());
}
@@ -3908,56 +2492,7 @@ TEST_F(QuicSentPacketManagerTest, NoPacketThresholdDetectionForRuntPackets) {
QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
}
-TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayNonPto) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
- // Before RTT sample is available.
- // 2 TLPs + 2 RTOs.
- QuicTime::Delta expected_delay = QuicTime::Delta::Zero();
- for (size_t i = 0; i < 2; ++i) {
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
- expected_delay =
- expected_delay +
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
- }
- for (size_t i = 0; i < 2; ++i) {
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
- expected_delay =
- expected_delay +
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
- }
- EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-
- expected_delay = QuicTime::Delta::Zero();
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 0);
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 0);
-
- // After RTT sample is available.
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
- rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Delta::Zero(), QuicTime::Zero());
- // 2 TLPs + 2 RTOs.
- for (size_t i = 0; i < 2; ++i) {
- QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
- expected_delay =
- expected_delay +
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
- }
- for (size_t i = 0; i < 2; ++i) {
- QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
- expected_delay =
- expected_delay +
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
- }
- EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
-}
-
TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayDefaultPTO) {
- if (!GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
QuicTime::Delta expected_delay = 4 * manager_.GetPtoDelay();
EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
@@ -3965,34 +2500,26 @@ TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayDefaultPTO) {
TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing2PTO) {
QuicConfig client_config;
- QuicTagVector options;
- options.push_back(k1PTO);
QuicTagVector client_options;
client_options.push_back(kPDP2);
QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
client_config.SetClientConnectionOptions(client_options);
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
manager_.SetFromConfig(client_config);
- EXPECT_TRUE(manager_.pto_enabled());
QuicTime::Delta expected_delay = 2 * manager_.GetPtoDelay();
EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
}
TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsing1PTO) {
QuicConfig client_config;
- QuicTagVector options;
- options.push_back(k1PTO);
QuicTagVector client_options;
client_options.push_back(kPDP1);
QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
- client_config.SetConnectionOptionsToSend(options);
client_config.SetClientConnectionOptions(client_options);
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
manager_.SetFromConfig(client_config);
- EXPECT_TRUE(manager_.pto_enabled());
QuicTime::Delta expected_delay = 1 * manager_.GetPtoDelay();
EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
}
@@ -4068,10 +2595,7 @@ TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(
WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
- manager_.MaybeSendProbePackets();
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- manager_.AdjustPendingTimerTransmissions();
- }
+ manager_.MaybeSendProbePacket();
// Verify exponential backoff of the PTO timeout.
EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -4098,10 +2622,7 @@ TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(
WithArgs<1>(Invoke([this]() { return RetransmitCryptoPacket(3); })));
- manager_.MaybeSendProbePackets();
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- manager_.AdjustPendingTimerTransmissions();
- }
+ manager_.MaybeSendProbePacket();
// Verify exponential backoff of the PTO timeout.
EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -4135,7 +2656,7 @@ TEST_F(QuicSentPacketManagerTest, HandshakeAckCausesInitialKeyDropping) {
// Verify nothing to probe (and connection will send PING for current
// encryption level).
EXPECT_CALL(notifier_, RetransmitFrames(_, _)).Times(0);
- manager_.MaybeSendProbePackets();
+ manager_.MaybeSendProbePacket();
}
// Regression test for b/156487311
@@ -4171,59 +2692,12 @@ TEST_F(QuicSentPacketManagerTest, ClearLastInflightPacketsSentTime) {
RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
const QuicTime::Delta pto_delay =
rtt_stats->smoothed_rtt() +
- GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
// Verify PTO is armed based on handshake data.
EXPECT_EQ(packet2_sent_time + pto_delay, manager_.GetRetransmissionTime());
}
-// Regression test for b/157895910.
-TEST_F(QuicSentPacketManagerTest, EarliestSentTimeNotInitializedWhenPtoFires) {
- if (GetQuicReloadableFlag(quic_simplify_set_retransmission_alarm)) {
- return;
- }
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
-
- // Send INITIAL 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
-
- // Send HANDSHAKE packets.
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
- SendDataPacket(2, ENCRYPTION_HANDSHAKE);
- SendDataPacket(3, ENCRYPTION_HANDSHAKE);
- SendDataPacket(4, ENCRYPTION_HANDSHAKE);
-
- // Send half RTT packet.
- SendDataPacket(5, ENCRYPTION_FORWARD_SECURE);
-
- // Received ACK for INITIAL packet 1.
- ExpectAck(1);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
- manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
- ENCRYPTION_INITIAL));
-
- // Received ACK for HANDSHAKE packets.
- uint64_t acked[] = {2, 3, 4};
- ExpectAcksAndLosses(true, acked, ABSL_ARRAYSIZE(acked), nullptr, 0);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(90));
- manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
- clock_.Now());
- manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(5));
- EXPECT_EQ(PACKETS_NEWLY_ACKED,
- manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(4),
- ENCRYPTION_HANDSHAKE));
- // Verify PTO will not be armed.
- EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
manager_.EnableMultiplePacketNumberSpacesSupport();
EXPECT_CALL(*send_algorithm_, PacingRate(_))
@@ -4246,7 +2720,7 @@ TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
SendDataPacket(3, ENCRYPTION_HANDSHAKE);
// Verify PTO is correctly set based on packet 1.
QuicTime::Delta expected_pto_delay =
- srtt + GetPtoRttvarMultiplier() * rtt_stats->mean_deviation() +
+ srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
QuicTime::Delta::Zero();
EXPECT_EQ(packet1_sent_time + expected_pto_delay,
manager_.GetRetransmissionTime());
@@ -4274,33 +2748,6 @@ TEST_F(QuicSentPacketManagerTest, MaybeRetransmitInitialData) {
manager_.GetRetransmissionTime());
}
-TEST_F(QuicSentPacketManagerTest,
- AggressivePtoBeforeAnyRttSamplesAreAvailable) {
- if (GetQuicRestartFlag(quic_default_on_pto2)) {
- return;
- }
- manager_.EnableMultiplePacketNumberSpacesSupport();
- EXPECT_CALL(*send_algorithm_, PacingRate(_))
- .WillRepeatedly(Return(QuicBandwidth::Zero()));
- EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
- .WillRepeatedly(Return(10 * kDefaultTCPMSS));
- RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
-
- QuicConfig config;
- QuicTagVector options;
- options.push_back(kAPTO);
- QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
- EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
- EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
- manager_.SetFromConfig(config);
-
- // Send INITIAL 1.
- SendDataPacket(1, ENCRYPTION_INITIAL);
- // Verify retransmission timeout is expected.
- EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(),
- manager_.GetRetransmissionTime());
-}
-
TEST_F(QuicSentPacketManagerTest, SendPathChallengeAndGetAck) {
QuicPacketNumber packet_number(1);
EXPECT_CALL(*send_algorithm_,
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_server_id_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_server_id_test.cc
index c4e5368f895..226a5176222 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_server_id_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_server_id_test.cc
@@ -8,7 +8,7 @@
#include "quiche/quic/platform/api/quic_test.h"
-namespace quic {
+namespace quic::test {
namespace {
@@ -121,4 +121,4 @@ TEST_F(QuicServerIdTest, Equals) {
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.cc
index 8868fc59e42..d29760062ad 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.cc
@@ -543,7 +543,7 @@ void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
// streams: if we have a large window then maybe something
// had gone wrong with the flow control accounting.
QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: "
- << frame.stream_id;
+ << frame.stream_id << ", offset: " << frame.offset;
}
bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
@@ -692,14 +692,6 @@ void QuicSession::OnCanWrite() {
}
}
-bool QuicSession::SendProbingData() {
- if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
- PROBING_RETRANSMISSION)) {
- return true;
- }
- return false;
-}
-
bool QuicSession::WillingAndAbleToWrite() const {
// Schedule a write when:
// 1) control frame manager has pending or new control frames, or
@@ -939,8 +931,8 @@ void QuicSession::SendGoAway(QuicErrorCode error_code,
reason);
}
-void QuicSession::SendBlocked(QuicStreamId id) {
- control_frame_manager_.WriteOrBufferBlocked(id);
+void QuicSession::SendBlocked(QuicStreamId id, QuicStreamOffset byte_offset) {
+ control_frame_manager_.WriteOrBufferBlocked(id, byte_offset);
}
void QuicSession::SendWindowUpdate(QuicStreamId id,
@@ -1002,11 +994,7 @@ void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
closed_streams_clean_up_alarm_->Set(
connection_->clock()->ApproximateNow());
}
- QUIC_BUG_IF(
- 364846171_1,
- connection_->packet_creator().HasPendingStreamFramesOfStream(stream_id))
- << "Stream " << stream_id
- << " gets closed while there are pending frames.";
+ connection_->QuicBugIfHasPendingFrames(stream_id);
}
if (!stream->HasReceivedFinalOffset()) {
@@ -1562,7 +1550,7 @@ bool QuicSession::OnNewDecryptionKeyAvailable(
bool set_alternative_decrypter, bool latch_once_used) {
if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
!connection()->framer().HasEncrypterOfEncryptionLevel(
- QuicUtils::GetEncryptionLevel(
+ QuicUtils::GetEncryptionLevelToSendAckofSpace(
QuicUtils::GetPacketNumberSpace(level)))) {
// This should never happen because connection should never decrypt a packet
// while an ACK for it cannot be encrypted.
@@ -2177,9 +2165,7 @@ void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
}
// Do not retransmit data of a closed stream.
streams_with_pending_retransmission_.erase(id);
- QUIC_BUG_IF(364846171_2,
- connection_->packet_creator().HasPendingStreamFramesOfStream(id))
- << "Stream " << id << " gets closed while there are pending frames.";
+ connection_->QuicBugIfHasPendingFrames(id);
}
QuicStream* QuicSession::GetStream(QuicStreamId id) const {
@@ -2285,10 +2271,7 @@ bool QuicSession::RetransmitFrames(const QuicFrames& frames,
continue;
}
if (frame.type == CRYPTO_FRAME) {
- const bool data_retransmitted =
- GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type);
- if (GetQuicRestartFlag(quic_set_packet_state_if_all_data_retransmitted) &&
- !data_retransmitted) {
+ if (!GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type)) {
return false;
}
continue;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.h
index 3051cf60133..7bdcaa95f4d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session.h
@@ -138,7 +138,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
const QuicSocketAddress& peer_address,
bool is_connectivity_probe) override;
void OnCanWrite() override;
- bool SendProbingData() override;
void OnCongestionWindowChange(QuicTime /*now*/) override {}
void OnConnectionMigration(AddressChangeType /*type*/) override {}
// Adds a connection level WINDOW_UPDATE frame.
@@ -173,6 +172,7 @@ class QUIC_EXPORT_PRIVATE QuicSession
const QuicSocketAddress& /*address*/) const override {
return false;
}
+ void OnBandwidthUpdateTimeout() override {}
// QuicStreamFrameDataProducer
WriteStreamDataResult WriteStreamData(QuicStreamId id,
@@ -265,7 +265,7 @@ class QUIC_EXPORT_PRIVATE QuicSession
virtual void SendGoAway(QuicErrorCode error_code, const std::string& reason);
// Sends a BLOCKED frame.
- virtual void SendBlocked(QuicStreamId id);
+ virtual void SendBlocked(QuicStreamId id, QuicStreamOffset byte_offset);
// Sends a WINDOW_UPDATE frame.
virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
@@ -616,9 +616,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
virtual QuicSSLConfig GetSSLConfig() const { return QuicSSLConfig(); }
- // Latched value of flag --quic_tls_server_support_client_cert.
- bool support_client_cert() const { return support_client_cert_; }
-
// Try converting all pending streams to normal streams.
void ProcessAllPendingStreams();
@@ -1005,9 +1002,6 @@ class QUIC_EXPORT_PRIVATE QuicSession
// Whether BoringSSL randomizes the order of TLS extensions.
bool permutes_tls_extensions_ = true;
-
- const bool support_client_cert_ =
- GetQuicRestartFlag(quic_tls_server_support_client_cert);
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session_test.cc
index ddda101d33c..9b90c4f169f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_session_test.cc
@@ -38,6 +38,7 @@
#include "quiche/quic/test_tools/quic_stream_peer.h"
#include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
+#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_mem_slice_storage.h"
using spdy::kV3HighestPriority;
@@ -181,6 +182,26 @@ class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
SSL* GetSsl() const override { return nullptr; }
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override {
+ return level != ENCRYPTION_ZERO_RTT;
+ }
+
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+ }
+
private:
using QuicCryptoStream::session;
@@ -2483,7 +2504,7 @@ TEST_P(QuicSessionTestServer, RetransmitFrames) {
EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
- session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+ session_.RetransmitFrames(frames, PTO_RETRANSMISSION);
}
// Regression test of b/110082001.
@@ -2954,7 +2975,11 @@ TEST_P(QuicSessionTestServer, WriteBufferedCryptoFrames) {
EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
.WillOnce(Return(350));
- EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
+ EXPECT_CALL(
+ *connection_,
+ SendCryptoData(crypto_stream->GetEncryptionLevelToSendCryptoDataOfSpace(
+ QuicUtils::GetPacketNumberSpace(ENCRYPTION_ZERO_RTT)),
+ 1350, 0))
.WillOnce(Return(1350));
session_.OnCanWrite();
EXPECT_FALSE(session_.HasPendingHandshake());
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream.cc
index 7d1a9ddf49d..dcbb02acd22 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream.cc
@@ -150,7 +150,7 @@ void PendingStream::AddBytesConsumed(QuicByteCount bytes) {
void PendingStream::ResetWithError(QuicResetStreamError /*error*/) {
// Currently PendingStream is only read-unidirectional. It shouldn't send
// Reset.
- QUIC_NOTREACHED();
+ QUICHE_NOTREACHED();
}
void PendingStream::OnUnrecoverableError(QuicErrorCode error,
@@ -741,15 +741,12 @@ void QuicStream::MaybeSendBlocked() {
<< ENDPOINT << "MaybeSendBlocked called on stream without flow control";
return;
}
- if (flow_controller_->ShouldSendBlocked()) {
- session_->SendBlocked(id_);
- }
+ flow_controller_->MaybeSendBlocked();
if (!stream_contributes_to_connection_flow_control_) {
return;
}
- if (connection_flow_controller_->ShouldSendBlocked()) {
- session_->SendBlocked(QuicUtils::GetInvalidStreamId(transport_version()));
- }
+ connection_flow_controller_->MaybeSendBlocked();
+
// If the stream is blocked by connection-level flow control but not by
// stream-level flow control, add the stream to the write blocked list so that
// the stream will be given a chance to write when a connection-level
@@ -1139,8 +1136,7 @@ void QuicStream::OnStreamFrameLost(QuicStreamOffset offset,
bool QuicStream::RetransmitStreamData(QuicStreamOffset offset,
QuicByteCount data_length, bool fin,
TransmissionType type) {
- QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
- type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
+ QUICHE_DCHECK(type == PTO_RETRANSMISSION);
if (HasDeadlinePassed()) {
OnDeadlinePassed();
return true;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc
index 03fd99035d1..fa7684106ab 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc
@@ -292,6 +292,11 @@ QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
return buffered_frames_.BytesConsumed();
}
+bool QuicStreamSequencer::IsAllDataAvailable() const {
+ QUICHE_DCHECK_LE(NumBytesConsumed() + NumBytesBuffered(), close_offset_);
+ return NumBytesConsumed() + NumBytesBuffered() >= close_offset_;
+}
+
const std::string QuicStreamSequencer::DebugString() const {
// clang-format off
return absl::StrCat("QuicStreamSequencer:",
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h
index e201cc14067..9953c7555f3 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.h
@@ -139,6 +139,10 @@ class QUIC_EXPORT_PRIVATE QuicStreamSequencer {
// Number of bytes has been consumed.
QuicStreamOffset NumBytesConsumed() const;
+ // Returns true if all of the data within the stream up until the FIN is
+ // available.
+ bool IsAllDataAvailable() const;
+
QuicStreamOffset close_offset() const { return close_offset_; }
int num_frames_received() const { return num_frames_received_; }
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_test.cc
index 0e57b094825..3ac6d88ba8d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_test.cc
@@ -223,8 +223,10 @@ TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
ConsumeData(3);
}));
EXPECT_FALSE(sequencer_->IsClosed());
+ EXPECT_FALSE(sequencer_->IsAllDataAvailable());
OnFinFrame(3, "def");
EXPECT_TRUE(sequencer_->IsClosed());
+ EXPECT_TRUE(sequencer_->IsAllDataAvailable());
}
TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
@@ -239,6 +241,7 @@ TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
ConsumeData(3);
}));
EXPECT_FALSE(sequencer_->IsClosed());
+ EXPECT_TRUE(sequencer_->IsAllDataAvailable());
sequencer_->SetUnblocked();
EXPECT_TRUE(sequencer_->IsClosed());
EXPECT_EQ(0u, NumBufferedBytes());
@@ -260,6 +263,7 @@ TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
OnFinFrame(0, "");
EXPECT_EQ(0u, NumBufferedBytes());
EXPECT_EQ(0u, sequencer_->NumBytesConsumed());
+ EXPECT_TRUE(sequencer_->IsAllDataAvailable());
}
TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
@@ -560,11 +564,14 @@ TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
// Now, attempt to mark consumed more data than was readable and expect the
// stream to be closed.
- EXPECT_CALL(stream_, ResetWithError(QuicResetStreamError::FromInternal(
- QUIC_ERROR_PROCESSING_STREAM)));
- EXPECT_QUIC_BUG(sequencer_->MarkConsumed(4),
- "Invalid argument to MarkConsumed."
- " expect to consume: 4, but not enough bytes available.");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(stream_, ResetWithError(QuicResetStreamError::FromInternal(
+ QUIC_ERROR_PROCESSING_STREAM)));
+ sequencer_->MarkConsumed(4);
+ },
+ "Invalid argument to MarkConsumed."
+ " expect to consume: 4, but not enough bytes available.");
}
TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_test.cc
index dad793f936f..51b25a5f322 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_stream_test.cc
@@ -480,9 +480,13 @@ TEST_P(QuicStreamTest, WriteOrBufferDataReachStreamLimit) {
.WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
stream_->WriteOrBufferData(data, false, nullptr);
EXPECT_TRUE(session_->HasUnackedStreamData());
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
- EXPECT_QUIC_BUG(stream_->WriteOrBufferData("a", false, nullptr),
- "Write too many data via stream");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ stream_->WriteOrBufferData("a", false, nullptr);
+ },
+ "Write too many data via stream");
}
TEST_P(QuicStreamTest, ConnectionCloseAfterStreamClose) {
@@ -789,11 +793,14 @@ TEST_P(QuicStreamTest, OnStreamFrameUpperLimit) {
TEST_P(QuicStreamTest, StreamTooLong) {
Initialize();
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
- .Times(1);
QuicStreamFrame stream_frame(stream_->id(), false, kMaxStreamLength, ".");
EXPECT_QUIC_PEER_BUG(
- stream_->OnStreamFrame(stream_frame),
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _))
+ .Times(1);
+ stream_->OnStreamFrame(stream_frame);
+ },
absl::StrCat("Receive stream frame on stream ", stream_->id(),
" reaches max stream length"));
}
@@ -1237,9 +1244,13 @@ TEST_P(QuicStreamTest, WritevDataReachStreamLimit) {
quiche::QuicheMemSliceStorage storage2(
&iov2, 1,
session_->connection()->helper()->GetStreamSendBufferAllocator(), 1024);
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
- EXPECT_QUIC_BUG(stream_->WriteMemSlices(storage2.ToSpan(), false),
- "Write too many data via stream");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ stream_->WriteMemSlices(storage2.ToSpan(), false);
+ },
+ "Write too many data via stream");
}
TEST_P(QuicStreamTest, WriteMemSlices) {
@@ -1328,9 +1339,13 @@ TEST_P(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
EXPECT_EQ(5u, consumed.bytes_consumed);
quiche::QuicheMemSlice slice2 = MemSliceFromString("6");
- EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
- EXPECT_QUIC_BUG(stream_->WriteMemSlice(std::move(slice2), false),
- "Write too many data via stream");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_STREAM_LENGTH_OVERFLOW, _, _));
+ stream_->WriteMemSlice(std::move(slice2), false);
+ },
+ "Write too many data via stream");
}
TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
@@ -1510,8 +1525,7 @@ TEST_P(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(1);
std::string data(1024, '.');
stream->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
@@ -1544,8 +1558,7 @@ TEST_P(QuicStreamTest,
std::string data(100, '.');
EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
.WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
- EXPECT_CALL(*session_, WriteControlFrame(_, _))
- .WillOnce(Invoke(&ClearControlFrameWithTransmissionType));
+ EXPECT_CALL(*session_, SendBlocked(_, _)).Times(1);
stream->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_trace_visitor_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_trace_visitor_test.cc
index 9e255b97182..5584ebe65e4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_trace_visitor_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_trace_visitor_test.cc
@@ -11,7 +11,7 @@
#include "quiche/quic/test_tools/simulator/simulator.h"
#include "quiche/quic/test_tools/simulator/switch.h"
-namespace quic {
+namespace quic::test {
namespace {
const QuicByteCount kTransferSize = 1000 * kMaxOutgoingPacketSize;
@@ -181,4 +181,4 @@ TEST_F(QuicTraceVisitorTest, EncryptionLevels) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.cc
index 389477bf598..62760c9678d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.cc
@@ -214,10 +214,7 @@ std::string TransmissionTypeToString(TransmissionType transmission_type) {
RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMISSION);
RETURN_STRING_LITERAL(ALL_ZERO_RTT_RETRANSMISSION);
RETURN_STRING_LITERAL(LOSS_RETRANSMISSION);
- RETURN_STRING_LITERAL(RTO_RETRANSMISSION);
- RETURN_STRING_LITERAL(TLP_RETRANSMISSION);
RETURN_STRING_LITERAL(PTO_RETRANSMISSION);
- RETURN_STRING_LITERAL(PROBING_RETRANSMISSION);
RETURN_STRING_LITERAL(PATH_RETRANSMISSION);
RETURN_STRING_LITERAL(ALL_INITIAL_RETRANSMISSION);
default:
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.h
index b136708e4ff..c79633c70ea 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_types.h
@@ -28,13 +28,6 @@ using QuicPacketLength = uint16_t;
using QuicControlFrameId = uint32_t;
using QuicMessageId = uint32_t;
-// TODO(b/181256914) replace QuicDatagramStreamId with QuicStreamId once we
-// remove support for draft-ietf-masque-h3-datagram-00 in favor of later drafts.
-using QuicDatagramStreamId = uint64_t;
-using QuicDatagramContextId = uint64_t;
-// Note that for draft-ietf-masque-h3-datagram-00, we represent the flow ID as a
-// QuicDatagramStreamId.
-
// IMPORTANT: IETF QUIC defines stream IDs and stream counts as being unsigned
// 62-bit numbers. However, we have decided to only support up to 2^32-1 streams
// in order to reduce the size of data structures such as QuicStreamFrame
@@ -187,10 +180,7 @@ enum TransmissionType : int8_t {
ALL_ZERO_RTT_RETRANSMISSION, // Retransmits all packets encrypted with 0-RTT
// key.
LOSS_RETRANSMISSION, // Retransmits due to loss detection.
- RTO_RETRANSMISSION, // Retransmits due to retransmit time out.
- TLP_RETRANSMISSION, // Tail loss probes.
PTO_RETRANSMISSION, // Retransmission due to probe timeout.
- PROBING_RETRANSMISSION, // Retransmission in order to probe bandwidth.
PATH_RETRANSMISSION, // Retransmission proactively due to underlying
// network change.
ALL_INITIAL_RETRANSMISSION, // Retransmit all packets encrypted with INITIAL
@@ -552,14 +542,8 @@ enum SentPacketState : uint8_t {
HANDSHAKE_RETRANSMITTED,
// This packet is considered as lost, this is used for LOST_RETRANSMISSION.
LOST,
- // This packet has been retransmitted when TLP fires.
- TLP_RETRANSMITTED,
- // This packet has been retransmitted when RTO fires.
- RTO_RETRANSMITTED,
// This packet has been retransmitted when PTO fires.
PTO_RETRANSMITTED,
- // This packet has been retransmitted for probing purpose.
- PROBE_RETRANSMITTED,
// This packet is sent on a different path or is a PING only packet.
// Do not update RTT stats and congestion control if the packet is the
// largest_acked of an incoming ACK.
@@ -842,6 +826,8 @@ QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason);
+using QuicSignatureAlgorithmVector = absl::InlinedVector<uint16_t, 8>;
+
// QuicSSLConfig contains configurations to be applied on a SSL object, which
// overrides the configurations in SSL_CTX.
struct QUIC_NO_EXPORT QuicSSLConfig {
@@ -852,7 +838,7 @@ struct QUIC_NO_EXPORT QuicSSLConfig {
absl::optional<bool> disable_ticket_support;
// If set, used to configure the SSL object with
// SSL_set_signing_algorithm_prefs.
- absl::optional<absl::InlinedVector<uint16_t, 8>> signing_algorithm_prefs;
+ absl::optional<QuicSignatureAlgorithmVector> signing_algorithm_prefs;
// Client certificate mode for mTLS support. Only used at server side.
ClientCertMode client_cert_mode = ClientCertMode::kNone;
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket_posix.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket_posix.cc
index c1ce940a7b5..c77d560c640 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket_posix.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket_posix.cc
@@ -9,6 +9,7 @@
#include <sys/socket.h>
#include <sys/types.h>
+#include "absl/base/optimization.h"
#include "quiche/quic/core/quic_udp_socket.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_udp_socket_platform_api.h"
@@ -413,13 +414,13 @@ void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
return;
}
- if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
QUIC_BUG(quic_bug_10751_3)
<< "Control buffer too small. size:" << control_buffer.buffer_len;
return;
}
- if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC) ||
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC) ||
// Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
// bit is set, but it is not the case if tested with config=android_arm64.
static_cast<size_t>(bytes_read) > packet_buffer.buffer_len) {
@@ -502,14 +503,14 @@ size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
}
msghdr& hdr = hdrs[i].msg_hdr;
- if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
<< (*results)[i].control_buffer.buffer_len
<< ", need:" << hdr.msg_controllen;
continue;
}
- if (QUIC_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
QUIC_LOG_FIRST_N(WARNING, 100)
<< "Received truncated QUIC packet: buffer size:"
<< (*results)[i].packet_buffer.buffer_len
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map_test.cc
index 3acb13a1c79..fc8ea983f95 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map_test.cc
@@ -402,8 +402,8 @@ TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
std::vector<uint64_t> retransmittable2 = {1, 3};
VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
- // TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
- RetransmitAndSendPacket(3, 4, TLP_RETRANSMISSION);
+ // PTO 3 (formerly 1) as 4, and don't remove 1 from unacked.
+ RetransmitAndSendPacket(3, 4, PTO_RETRANSMISSION);
SerializedPacket packet5(CreateRetransmittablePacket(5));
unacked_packets_.AddSentPacket(&packet5, NOT_RETRANSMISSION, now_, true,
true);
@@ -551,7 +551,7 @@ TEST_P(QuicUnackedPacketMapTest, CannotAggregateAckedControlFrames) {
QuicWindowUpdateFrame window_update(1, 5, 100);
QuicStreamFrame stream_frame1(3, false, 0, 100);
QuicStreamFrame stream_frame2(3, false, 100, 100);
- QuicBlockedFrame blocked(2, 5);
+ QuicBlockedFrame blocked(2, 5, 0);
QuicGoAwayFrame go_away(3, QUIC_PEER_GOING_AWAY, 5, "Going away.");
QuicTransmissionInfo info1;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.cc
index fcda2e6fa6e..fdfce7ef4b8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.cc
@@ -170,10 +170,7 @@ const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
RETURN_STRING_LITERAL(NEUTERED);
RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMITTED);
RETURN_STRING_LITERAL(LOST);
- RETURN_STRING_LITERAL(TLP_RETRANSMITTED);
- RETURN_STRING_LITERAL(RTO_RETRANSMITTED);
RETURN_STRING_LITERAL(PTO_RETRANSMITTED);
- RETURN_STRING_LITERAL(PROBE_RETRANSMITTED);
RETURN_STRING_LITERAL(NOT_CONTRIBUTING_RTT);
}
return "INVALID_SENT_PACKET_STATE";
@@ -289,14 +286,8 @@ SentPacketState QuicUtils::RetransmissionTypeToPacketState(
return HANDSHAKE_RETRANSMITTED;
case LOSS_RETRANSMISSION:
return LOST;
- case TLP_RETRANSMISSION:
- return TLP_RETRANSMITTED;
- case RTO_RETRANSMISSION:
- return RTO_RETRANSMITTED;
case PTO_RETRANSMISSION:
return PTO_RETRANSMITTED;
- case PROBING_RETRANSMISSION:
- return PROBE_RETRANSMITTED;
case PATH_RETRANSMISSION:
return NOT_CONTRIBUTING_RTT;
case ALL_INITIAL_RETRANSMISSION:
@@ -601,7 +592,7 @@ PacketNumberSpace QuicUtils::GetPacketNumberSpace(
}
// static
-EncryptionLevel QuicUtils::GetEncryptionLevel(
+EncryptionLevel QuicUtils::GetEncryptionLevelToSendAckofSpace(
PacketNumberSpace packet_number_space) {
switch (packet_number_space) {
case INITIAL_DATA:
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.h
index 202dc4ba323..2d4d5e889f1 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils.h
@@ -209,8 +209,8 @@ class QUIC_EXPORT_PRIVATE QuicUtils {
static PacketNumberSpace GetPacketNumberSpace(
EncryptionLevel encryption_level);
- // Determines encryption level to send packets in |packet_number_space|.
- static EncryptionLevel GetEncryptionLevel(
+ // Determines encryption level to send ACK in |packet_number_space|.
+ static EncryptionLevel GetEncryptionLevelToSendAckofSpace(
PacketNumberSpace packet_number_space);
// Get the maximum value for a V99/IETF QUIC stream count. If a count
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils_test.cc
index 19ce4462e49..835cb977a3e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_utils_test.cc
@@ -129,14 +129,8 @@ TEST_F(QuicUtilsTest, RetransmissionTypeToPacketState) {
EXPECT_EQ(LOST, state);
} else if (i == ALL_ZERO_RTT_RETRANSMISSION) {
EXPECT_EQ(UNACKABLE, state);
- } else if (i == TLP_RETRANSMISSION) {
- EXPECT_EQ(TLP_RETRANSMITTED, state);
- } else if (i == RTO_RETRANSMISSION) {
- EXPECT_EQ(RTO_RETRANSMITTED, state);
} else if (i == PTO_RETRANSMISSION) {
EXPECT_EQ(PTO_RETRANSMITTED, state);
- } else if (i == PROBING_RETRANSMISSION) {
- EXPECT_EQ(PROBE_RETRANSMITTED, state);
} else if (i == PATH_RETRANSMISSION) {
EXPECT_EQ(NOT_CONTRIBUTING_RTT, state);
} else if (i == ALL_INITIAL_RETRANSMISSION) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_versions_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_versions_test.cc
index 5dbfdd07ddf..58bab07c21a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_versions_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_versions_test.cc
@@ -8,7 +8,6 @@
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
-#include "quiche/quic/platform/api/quic_mock_log.h"
#include "quiche/quic/platform/api/quic_test.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h
index 8aa355e253c..3020c22b2fd 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h
@@ -13,7 +13,6 @@
#include "quiche/http2/core/priority_write_scheduler.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_flags.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc
index 90a9d7419be..36edcacc28d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc
@@ -236,8 +236,7 @@ bool TlsClientHandshaker::SetTransportParameters() {
session()->connection()->OnTransportParametersSent(params);
std::vector<uint8_t> param_bytes;
- return SerializeTransportParameters(session()->connection()->version(),
- params, &param_bytes) &&
+ return SerializeTransportParameters(params, &param_bytes) &&
SSL_set_quic_transport_params(ssl(), param_bytes.data(),
param_bytes.size()) == 1;
}
@@ -357,6 +356,24 @@ bool TlsClientHandshaker::encryption_established() const {
return encryption_established_;
}
+bool TlsClientHandshaker::IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const {
+ return level != ENCRYPTION_ZERO_RTT;
+}
+
+EncryptionLevel TlsClientHandshaker::GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+}
+
bool TlsClientHandshaker::one_rtt_keys_available() const {
return state_ >= HANDSHAKE_COMPLETE;
}
@@ -425,7 +442,7 @@ void TlsClientHandshaker::OnNewTokenReceived(absl::string_view token) {
void TlsClientHandshaker::SetWriteSecret(
EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
+ absl::Span<const uint8_t> write_secret) {
if (is_connection_closed()) {
return;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h
index 15727e1d0e0..06581b54db4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h
@@ -54,6 +54,10 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
// From QuicCryptoClientStream::HandshakerInterface and TlsHandshaker
bool encryption_established() const override;
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override;
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override;
bool one_rtt_keys_available() const override;
const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
const override;
@@ -70,7 +74,7 @@ class QUIC_EXPORT_PRIVATE TlsClientHandshaker
void OnHandshakeDoneReceived() override;
void OnNewTokenReceived(absl::string_view token) override;
void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) override;
+ absl::Span<const uint8_t> write_secret) override;
// Override to drop initial keys if trying to write ENCRYPTION_HANDSHAKE data.
void WriteMessage(EncryptionLevel level, absl::string_view data) override;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker_test.cc
index 91593d6e265..a1d5984dd1f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker_test.cc
@@ -577,18 +577,22 @@ TEST_P(TlsClientHandshakerTest, ClientSendsNoSNI) {
TEST_P(TlsClientHandshakerTest, ClientSendingTooManyALPNs) {
std::string long_alpn(250, 'A');
- EXPECT_CALL(*session_, GetAlpnsToOffer())
- .WillOnce(testing::Return(std::vector<std::string>({
- long_alpn + "1",
- long_alpn + "2",
- long_alpn + "3",
- long_alpn + "4",
- long_alpn + "5",
- long_alpn + "6",
- long_alpn + "7",
- long_alpn + "8",
- })));
- EXPECT_QUIC_BUG(stream()->CryptoConnect(), "Failed to set ALPN");
+ EXPECT_QUIC_BUG(
+ {
+ EXPECT_CALL(*session_, GetAlpnsToOffer())
+ .WillOnce(testing::Return(std::vector<std::string>({
+ long_alpn + "1",
+ long_alpn + "2",
+ long_alpn + "3",
+ long_alpn + "4",
+ long_alpn + "5",
+ long_alpn + "6",
+ long_alpn + "7",
+ long_alpn + "8",
+ })));
+ stream()->CryptoConnect();
+ },
+ "Failed to set ALPN");
}
TEST_P(TlsClientHandshakerTest, ServerRequiresCustomALPN) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc
index 6f4f4ffbef7..0449c6779ae 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc
@@ -85,7 +85,7 @@ bool TlsHandshaker::ProcessInput(absl::string_view input,
}
void TlsHandshaker::AdvanceHandshake() {
- if (is_connection_closed_) {
+ if (is_connection_closed()) {
return;
}
if (GetHandshakeState() >= HANDSHAKE_COMPLETE) {
@@ -101,6 +101,13 @@ void TlsHandshaker::AdvanceHandshake() {
QUIC_VLOG(1) << ENDPOINT << "Continuing handshake";
int rv = SSL_do_handshake(ssl());
+ if (GetQuicReloadableFlag(quic_tls_handshaker_check_connection_closed) &&
+ is_connection_closed()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_handshaker_check_connection_closed, 1,
+ 2);
+ return;
+ }
+
// If SSL_do_handshake return success(1) and we are in early data, it is
// possible that we have provided ServerHello to BoringSSL but it hasn't been
// processed. Retry SSL_do_handshake once will advance the handshake more in
@@ -109,6 +116,14 @@ void TlsHandshaker::AdvanceHandshake() {
if (rv == 1 && SSL_in_early_data(ssl())) {
OnEnterEarlyData();
rv = SSL_do_handshake(ssl());
+
+ if (GetQuicReloadableFlag(quic_tls_handshaker_check_connection_closed) &&
+ is_connection_closed()) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_tls_handshaker_check_connection_closed,
+ 2, 2);
+ return;
+ }
+
QUIC_VLOG(1) << ENDPOINT
<< "SSL_do_handshake returned when entering early data. After "
<< "retry, rv=" << rv
@@ -120,7 +135,7 @@ void TlsHandshaker::AdvanceHandshake() {
// SSL_in_early_data should be false.
//
// In either case, it should not both return 1 and stay in early data.
- if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed_) {
+ if (rv == 1 && SSL_in_early_data(ssl()) && !is_connection_closed()) {
QUIC_BUG(quic_handshaker_stay_in_early_data)
<< "The original and the retry of SSL_do_handshake both returned "
"success and in early data";
@@ -139,7 +154,7 @@ void TlsHandshaker::AdvanceHandshake() {
return;
}
if (ShouldCloseConnectionOnUnexpectedError(ssl_error) &&
- !is_connection_closed_) {
+ !is_connection_closed()) {
QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
<< ssl_error;
ERR_print_errors_fp(stderr);
@@ -235,7 +250,7 @@ enum ssl_verify_result_t TlsHandshaker::VerifyCert(uint8_t* out_alert) {
void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
+ absl::Span<const uint8_t> write_secret) {
QUIC_DVLOG(1) << ENDPOINT << "SetWriteSecret level=" << level;
std::unique_ptr<QuicEncrypter> encrypter =
QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
@@ -252,7 +267,7 @@ void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
header_protection_key.size()));
if (level == ENCRYPTION_FORWARD_SECURE) {
QUICHE_DCHECK(latest_write_secret_.empty());
- latest_write_secret_ = write_secret;
+ latest_write_secret_.assign(write_secret.begin(), write_secret.end());
one_rtt_write_header_protection_key_ = header_protection_key;
}
handshaker_delegate_->OnNewEncryptionKeyAvailable(level,
@@ -261,7 +276,7 @@ void TlsHandshaker::SetWriteSecret(EncryptionLevel level,
bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) {
+ absl::Span<const uint8_t> read_secret) {
QUIC_DVLOG(1) << ENDPOINT << "SetReadSecret level=" << level;
std::unique_ptr<QuicDecrypter> decrypter =
QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher));
@@ -278,7 +293,7 @@ bool TlsHandshaker::SetReadSecret(EncryptionLevel level,
header_protection_key.size()));
if (level == ENCRYPTION_FORWARD_SECURE) {
QUICHE_DCHECK(latest_read_secret_.empty());
- latest_read_secret_ = read_secret;
+ latest_read_secret_.assign(read_secret.begin(), read_secret.end());
one_rtt_read_header_protection_key_ = header_protection_key;
}
return handshaker_delegate_->OnNewDecryptionKeyAvailable(
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h
index ddd44c67fb8..d2e0ee487ba 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h
@@ -138,14 +138,14 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public TlsConnection::Delegate,
// traffic secrets and application traffic secrets. The provided write secret
// must be used with the provided cipher suite |cipher|.
void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) override;
+ absl::Span<const uint8_t> write_secret) override;
// SetReadSecret is similar to SetWriteSecret, except that it is used for
// decrypting messages. SetReadSecret at a particular level is always called
// after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT, where
// the EncryptionLevel for SetWriteSecret is ENCRYPTION_FORWARD_SECURE.
bool SetReadSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& read_secret) override;
+ absl::Span<const uint8_t> read_secret) override;
// WriteMessage is called when there is |data| from the TLS stack ready for
// the QUIC stack to write in a crypto frame. The data must be transmitted at
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc
index ce63767bad3..c9781ccb583 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc
@@ -185,9 +185,8 @@ TlsServerHandshaker::TlsServerHandshaker(
crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
tls_connection_(crypto_config->ssl_ctx(), this, session->GetSSLConfig()),
crypto_config_(crypto_config) {
- QUIC_DVLOG(1) << "TlsServerHandshaker: support_client_cert:"
- << session->support_client_cert()
- << ", client_cert_mode initial value: " << client_cert_mode();
+ QUIC_DVLOG(1) << "TlsServerHandshaker: client_cert_mode initial value: "
+ << client_cert_mode();
QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3,
session->connection()->version().handshake_protocol);
@@ -528,8 +527,7 @@ TlsServerHandshaker::SetTransportParameters() {
{ // Ensure |server_params_bytes| is not accessed out of the scope.
std::vector<uint8_t> server_params_bytes;
- if (!SerializeTransportParameters(session()->connection()->version(),
- server_params, &server_params_bytes) ||
+ if (!SerializeTransportParameters(server_params, &server_params_bytes) ||
SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
server_params_bytes.size()) != 1) {
return result;
@@ -557,7 +555,7 @@ TlsServerHandshaker::SetTransportParameters() {
void TlsServerHandshaker::SetWriteSecret(
EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) {
+ absl::Span<const uint8_t> write_secret) {
if (is_connection_closed()) {
return;
}
@@ -612,13 +610,6 @@ QuicAsyncStatus TlsServerHandshaker::VerifyCertChain(
const std::vector<std::string>& /*certs*/, std::string* /*error_details*/,
std::unique_ptr<ProofVerifyDetails>* /*details*/, uint8_t* /*out_alert*/,
std::unique_ptr<ProofVerifierCallback> /*callback*/) {
- if (!session()->support_client_cert()) {
- QUIC_BUG(quic_bug_10341_5)
- << "Client certificates are not yet supported on the server";
- return QUIC_FAILURE;
- }
-
- QUIC_RESTART_FLAG_COUNT_N(quic_tls_server_support_client_cert, 2, 2);
QUIC_DVLOG(1) << "VerifyCertChain returning success";
// No real verification here. A subclass can override this function to verify
@@ -751,9 +742,8 @@ ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
}
if (!ticket_decryption_callback_) {
- ticket_decryption_callback_ = new DecryptCallback(this);
- proof_source_->GetTicketCrypter()->Decrypt(
- in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
+ ticket_decryption_callback_ = std::make_shared<DecryptCallback>(this);
+ proof_source_->GetTicketCrypter()->Decrypt(in, ticket_decryption_callback_);
// Decrypt can run the callback synchronously. In that case, the callback
// will clear the ticket_decryption_callback_ pointer, and instead of
@@ -981,13 +971,13 @@ void TlsServerHandshaker::OnSelectCertificateDone(
ticket_encryption_key_ = std::string(ticket_encryption_key);
select_cert_status_ = QUIC_FAILURE;
cert_matched_sni_ = cert_matched_sni;
- if (session()->support_client_cert()) {
- if (delayed_ssl_config.client_cert_mode.has_value()) {
- tls_connection_.SetClientCertMode(*delayed_ssl_config.client_cert_mode);
- QUIC_DVLOG(1) << "client_cert_mode after cert selection: "
- << client_cert_mode();
- }
+
+ if (delayed_ssl_config.client_cert_mode.has_value()) {
+ tls_connection_.SetClientCertMode(*delayed_ssl_config.client_cert_mode);
+ QUIC_DVLOG(1) << "client_cert_mode after cert selection: "
+ << client_cert_mode();
}
+
if (ok) {
if (chain && !chain->certs.empty()) {
tls_connection_.SetCertChain(chain->ToCryptoBuffers().value);
@@ -1134,4 +1124,24 @@ TlsServerHandshaker::SetApplicationSettings(absl::string_view alpn) {
SSL* TlsServerHandshaker::GetSsl() const { return ssl(); }
+bool TlsServerHandshaker::IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const {
+ return level != ENCRYPTION_ZERO_RTT;
+}
+
+EncryptionLevel TlsServerHandshaker::GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+}
+
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.h b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.h
index 6385eda3c9b..05b63ae9663 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.h
@@ -71,6 +71,10 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
size_t result_len, std::string* result) override;
SSL* GetSsl() const override;
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ EncryptionLevel level) const override;
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override;
// From QuicCryptoServerStreamBase and TlsHandshaker
ssl_early_data_reason_t EarlyDataReason() const override;
@@ -87,7 +91,7 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
override;
std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
- const std::vector<uint8_t>& write_secret) override;
+ absl::Span<const uint8_t> write_secret) override;
// Called with normalized SNI hostname as |hostname|. Return value will be
// sent in an ACCEPT_CH frame in the TLS ALPS extension, unless empty.
@@ -321,7 +325,7 @@ class QUIC_EXPORT_PRIVATE TlsServerHandshaker
// |ticket_decryption_callback_| points to the non-owned callback that was
// passed to ProofSource::TicketCrypter::Decrypt but hasn't finished running
// yet.
- DecryptCallback* ticket_decryption_callback_ = nullptr;
+ std::shared_ptr<DecryptCallback> ticket_decryption_callback_;
// |decrypted_session_ticket_| contains the decrypted session ticket after the
// callback has run but before it is passed to BoringSSL.
std::vector<uint8_t> decrypted_session_ticket_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker_test.cc
index 34ec60c1654..e652f052c75 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker_test.cc
@@ -924,11 +924,7 @@ TEST_P(TlsServerHandshakerTest, RequestClientCert) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_TRUE(server_handshaker_->received_client_cert());
- } else {
- EXPECT_FALSE(server_handshaker_->received_client_cert());
- }
+ EXPECT_TRUE(server_handshaker_->received_client_cert());
}
TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
@@ -950,11 +946,7 @@ TEST_P(TlsServerHandshakerTest, RequestClientCertByDelayedSslConfig) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_TRUE(server_handshaker_->received_client_cert());
- } else {
- EXPECT_FALSE(server_handshaker_->received_client_cert());
- }
+ EXPECT_TRUE(server_handshaker_->received_client_cert());
}
TEST_P(TlsServerHandshakerTest, RequestClientCert_NoCert) {
@@ -983,12 +975,7 @@ TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
-
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_TRUE(server_handshaker_->received_client_cert());
- } else {
- EXPECT_FALSE(server_handshaker_->received_client_cert());
- }
+ EXPECT_TRUE(server_handshaker_->received_client_cert());
}
TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
@@ -1010,11 +997,7 @@ TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCertByDelayedSslConfig) {
CompleteCryptoHandshake();
ExpectHandshakeSuccessful();
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_TRUE(server_handshaker_->received_client_cert());
- } else {
- EXPECT_FALSE(server_handshaker_->received_client_cert());
- }
+ EXPECT_TRUE(server_handshaker_->received_client_cert());
}
TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
@@ -1025,10 +1008,9 @@ TEST_P(TlsServerHandshakerTest, RequestAndRequireClientCert_NoCert) {
/*compute_signature_action=*/FakeProofSourceHandle::Action::
DELEGATE_SYNC);
- if (GetQuicRestartFlag(quic_tls_server_support_client_cert)) {
- EXPECT_CALL(*server_connection_,
- CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
- }
+ EXPECT_CALL(*server_connection_,
+ CloseConnection(QUIC_TLS_CERTIFICATE_REQUIRED, _, _, _));
+
AdvanceHandshakeWithFakeClient();
AdvanceHandshakeWithFakeClient();
EXPECT_FALSE(server_handshaker_->received_client_cert());
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager_test.cc
index 030e55c4cac..ad62d8fe2a8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager_test.cc
@@ -33,6 +33,20 @@ const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
const QuicTime::Delta kDelayedAckTime =
QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+EncryptionLevel GetEncryptionLevel(PacketNumberSpace packet_number_space) {
+ switch (packet_number_space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+}
+
class UberReceivedPacketManagerTest : public QuicTest {
protected:
UberReceivedPacketManagerTest() {
@@ -108,7 +122,7 @@ class UberReceivedPacketManagerTest : public QuicTest {
continue;
}
manager_->ResetAckStates(
- QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+ GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
}
}
@@ -544,15 +558,9 @@ TEST_F(UberReceivedPacketManagerTest,
CheckAckTimeout(clock_.ApproximateNow());
EXPECT_TRUE(HasPendingAck());
- if (GetQuicReloadableFlag(quic_update_ack_timeout_on_receipt_time)) {
- // Verify ACK delay is based on packet receipt time.
- CheckAckTimeout(clock_.ApproximateNow() -
- QuicTime::Delta::FromMilliseconds(11) + kDelayedAckTime);
- } else {
- // Delayed ack is scheduled.
- CheckAckTimeout(clock_.ApproximateNow() -
- QuicTime::Delta::FromMilliseconds(1) + kDelayedAckTime);
- }
+ // Verify ACK delay is based on packet receipt time.
+ CheckAckTimeout(clock_.ApproximateNow() -
+ QuicTime::Delta::FromMilliseconds(11) + kDelayedAckTime);
}
} // namespace
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_bin.cc
index 8fd5e52d63a..2d686dfad08 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_bin.cc
@@ -29,9 +29,9 @@ DEFINE_QUICHE_COMMAND_LINE_FLAG(
bool, disable_certificate_verification, false,
"If true, don't verify the server certificate.");
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, masque_mode, "",
+ "Allows setting MASQUE mode, currently only valid value is \"open\".");
namespace quic {
@@ -54,14 +54,16 @@ int RunMasqueClient(int argc, char* argv[]) {
}
const bool disable_certificate_verification =
- GetQuicFlag(FLAGS_disable_certificate_verification);
+ quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification);
QuicEpollServer epoll_server;
std::string uri_template = urls[0];
if (!absl::StrContains(uri_template, '/')) {
- // Allow passing in authority instead of URI template.
+ // If an authority is passed in instead of a URI template, use the default
+ // URI template.
uri_template =
- absl::StrCat("https://", uri_template, "/{target_host}/{target_port}/");
+ absl::StrCat("https://", uri_template,
+ "/.well-known/masque/udp/{target_host}/{target_port}/");
}
url::Parsed parsed_uri_template;
url::ParseStandardURL(uri_template.c_str(), uri_template.length(),
@@ -82,10 +84,8 @@ int RunMasqueClient(int argc, char* argv[]) {
proof_verifier = CreateDefaultProofVerifier(host);
}
MasqueMode masque_mode = MasqueMode::kOpen;
- std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
- if (mode_string == "legacy") {
- masque_mode = MasqueMode::kLegacy;
- } else if (!mode_string.empty() && mode_string != "open") {
+ std::string mode_string = quiche::GetQuicheCommandLineFlag(FLAGS_masque_mode);
+ if (!mode_string.empty() && mode_string != "open") {
std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.cc
index fc6da5acccd..28ba839f758 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.cc
@@ -4,12 +4,14 @@
#include "quiche/quic/masque/masque_client_session.h"
+#include <cstring>
#include <string>
#include "absl/algorithm/container.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
#include "url/url_canon.h"
#include "quiche/quic/core/http/spdy_utils.h"
#include "quiche/quic/core/quic_data_reader.h"
@@ -30,42 +32,7 @@ MasqueClientSession::MasqueClientSession(
crypto_config, push_promise_index),
masque_mode_(masque_mode),
uri_template_(uri_template),
- owner_(owner),
- compression_engine_(this) {}
-
-void MasqueClientSession::OnMessageReceived(absl::string_view message) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
- QuicConnectionId client_connection_id, server_connection_id;
- QuicSocketAddress target_server_address;
- std::vector<char> packet;
- bool version_present;
- if (!compression_engine_.DecompressDatagram(
- message, &client_connection_id, &server_connection_id,
- &target_server_address, &packet, &version_present)) {
- return;
- }
-
- auto connection_id_registration =
- client_connection_id_registrations_.find(client_connection_id);
- if (connection_id_registration ==
- client_connection_id_registrations_.end()) {
- QUIC_DLOG(ERROR) << "MasqueClientSession failed to dispatch "
- << client_connection_id;
- return;
- }
- EncapsulatedClientSession* encapsulated_client_session =
- connection_id_registration->second;
- encapsulated_client_session->ProcessPacket(
- absl::string_view(packet.data(), packet.size()), target_server_address);
-
- QUIC_DVLOG(1) << "Sent " << packet.size() << " bytes to connection for "
- << client_connection_id;
- return;
- }
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- QuicSpdySession::OnMessageReceived(message);
-}
+ owner_(owner) {}
void MasqueClientSession::OnMessageAcked(QuicMessageId message_id,
QuicTime /*receive_timestamp*/) {
@@ -157,10 +124,7 @@ MasqueClientSession::GetOrCreateConnectUdpClientState(
headers[":scheme"] = scheme;
headers[":authority"] = authority;
headers[":path"] = canonicalized_path;
- headers["connect-udp-version"] = "6";
- if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
- SpdyUtils::AddDatagramFlowIdHeader(&headers, stream->id());
- }
+ headers["connect-udp-version"] = "12";
size_t bytes_sent =
stream->SendRequest(std::move(headers), /*body=*/"", /*fin=*/false);
if (bytes_sent == 0) {
@@ -168,24 +132,14 @@ MasqueClientSession::GetOrCreateConnectUdpClientState(
return nullptr;
}
- absl::optional<QuicDatagramContextId> context_id;
- connect_udp_client_states_.push_back(
- ConnectUdpClientState(stream, encapsulated_client_session, this,
- context_id, target_server_address));
+ connect_udp_client_states_.push_back(ConnectUdpClientState(
+ stream, encapsulated_client_session, this, target_server_address));
return &connect_udp_client_states_.back();
}
void MasqueClientSession::SendPacket(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id, absl::string_view packet,
- const QuicSocketAddress& target_server_address,
+ absl::string_view packet, const QuicSocketAddress& target_server_address,
EncapsulatedClientSession* encapsulated_client_session) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- compression_engine_.CompressAndSendPacket(packet, client_connection_id,
- server_connection_id,
- target_server_address);
- return;
- }
const ConnectUdpClientState* connect_udp = GetOrCreateConnectUdpClientState(
target_server_address, encapsulated_client_session);
if (connect_udp == nullptr) {
@@ -193,55 +147,25 @@ void MasqueClientSession::SendPacket(
return;
}
- MessageStatus message_status = SendHttp3Datagram(
- connect_udp->stream()->id(), connect_udp->context_id(), packet);
+ std::string http_payload;
+ http_payload.resize(1 + packet.size());
+ http_payload[0] = 0;
+ memcpy(&http_payload[1], packet.data(), packet.size());
+ MessageStatus message_status =
+ SendHttp3Datagram(connect_udp->stream()->id(), http_payload);
QUIC_DVLOG(1) << "Sent packet to " << target_server_address
<< " compressed with stream ID " << connect_udp->stream()->id()
- << " context ID "
- << (connect_udp->context_id().has_value()
- ? absl::StrCat(connect_udp->context_id().value())
- : "none")
<< " and got message status "
<< MessageStatusToString(message_status);
}
-void MasqueClientSession::RegisterConnectionId(
- QuicConnectionId client_connection_id,
+void MasqueClientSession::CloseConnectUdpStream(
EncapsulatedClientSession* encapsulated_client_session) {
- QUIC_DLOG(INFO) << "Registering " << client_connection_id
- << " to encapsulated client";
- QUICHE_DCHECK(
- client_connection_id_registrations_.find(client_connection_id) ==
- client_connection_id_registrations_.end() ||
- client_connection_id_registrations_[client_connection_id] ==
- encapsulated_client_session);
- client_connection_id_registrations_[client_connection_id] =
- encapsulated_client_session;
-}
-
-void MasqueClientSession::UnregisterConnectionId(
- QuicConnectionId client_connection_id,
- EncapsulatedClientSession* encapsulated_client_session) {
- QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
- if (masque_mode_ == MasqueMode::kLegacy) {
- if (client_connection_id_registrations_.find(client_connection_id) !=
- client_connection_id_registrations_.end()) {
- client_connection_id_registrations_.erase(client_connection_id);
- owner_->UnregisterClientConnectionId(client_connection_id);
- compression_engine_.UnregisterClientConnectionId(client_connection_id);
- }
- return;
- }
-
for (auto it = connect_udp_client_states_.begin();
it != connect_udp_client_states_.end();) {
if (it->encapsulated_client_session() == encapsulated_client_session) {
- QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id()
- << " context ID "
- << (it->context_id().has_value()
- ? absl::StrCat(it->context_id().value())
- : "none");
+ QUIC_DLOG(INFO) << "Removing state for stream ID " << it->stream()->id();
auto* stream = it->stream();
it = connect_udp_client_states_.erase(it);
if (!stream->write_side_closed()) {
@@ -279,10 +203,7 @@ void MasqueClientSession::OnStreamClosed(QuicStreamId stream_id) {
it != connect_udp_client_states_.end();) {
if (it->stream()->id() == stream_id) {
QUIC_DLOG(INFO) << "Stream " << stream_id
- << " was closed, removing state for context ID "
- << (it->context_id().has_value()
- ? absl::StrCat(it->context_id().value())
- : "none");
+ << " was closed, removing state";
auto* encapsulated_client_session = it->encapsulated_client_session();
it = connect_udp_client_states_.erase(it);
encapsulated_client_session->CloseConnection(
@@ -316,24 +237,18 @@ MasqueClientSession::ConnectUdpClientState::ConnectUdpClientState(
QuicSpdyClientStream* stream,
EncapsulatedClientSession* encapsulated_client_session,
MasqueClientSession* masque_session,
- absl::optional<QuicDatagramContextId> context_id,
const QuicSocketAddress& target_server_address)
: stream_(stream),
encapsulated_client_session_(encapsulated_client_session),
masque_session_(masque_session),
- context_id_(context_id),
target_server_address_(target_server_address) {
QUICHE_DCHECK_NE(masque_session_, nullptr);
- this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
- this->stream()->RegisterHttp3DatagramContextId(
- this->context_id(), DatagramFormatType::UDP_PAYLOAD,
- /*format_additional_data=*/absl::string_view(), this);
+ this->stream()->RegisterHttp3DatagramVisitor(this);
}
MasqueClientSession::ConnectUdpClientState::~ConnectUdpClientState() {
if (stream() != nullptr) {
- stream()->UnregisterHttp3DatagramContextId(context_id());
- stream()->UnregisterHttp3DatagramRegistrationVisitor();
+ stream()->UnregisterHttp3DatagramVisitor();
}
}
@@ -348,88 +263,33 @@ MasqueClientSession::ConnectUdpClientState::operator=(
stream_ = other.stream_;
encapsulated_client_session_ = other.encapsulated_client_session_;
masque_session_ = other.masque_session_;
- context_id_ = other.context_id_;
target_server_address_ = other.target_server_address_;
other.stream_ = nullptr;
if (stream() != nullptr) {
- stream()->MoveHttp3DatagramRegistration(this);
- stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
+ stream()->ReplaceHttp3DatagramVisitor(this);
}
return *this;
}
void MasqueClientSession::ConnectUdpClientState::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
+ QuicStreamId stream_id, absl::string_view payload) {
QUICHE_DCHECK_EQ(stream_id, stream()->id());
- QUICHE_DCHECK(context_id == context_id_);
- encapsulated_client_session_->ProcessPacket(payload, target_server_address_);
- QUIC_DVLOG(1) << "Sent " << payload.size()
- << " bytes to connection for stream ID " << stream_id
- << " context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value())
- : "none");
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextReceived(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type, absl::string_view format_additional_data) {
- if (stream_id != stream_->id()) {
- QUIC_BUG(MASQUE client bad datagram context registration)
- << "Registered stream ID " << stream_id << ", expected "
- << stream_->id();
- return;
- }
- if (format_type != DatagramFormatType::UDP_PAYLOAD) {
- QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
- << DatagramFormatTypeToString(format_type);
- return;
- }
- if (!format_additional_data.empty()) {
- QUIC_DLOG(ERROR)
- << "Received non-empty format additional data for context ID "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << stream()->id();
- masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
- return;
- }
- if (context_id != context_id_) {
- QUIC_DLOG(INFO)
- << "Ignoring unexpected context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " instead of "
- << (context_id_.has_value() ? absl::StrCat(context_id_.value())
- : "none")
- << " on stream ID " << stream_->id();
- return;
- }
- // Do nothing since the client registers first and we currently ignore
- // extensions.
-}
-
-void MasqueClientSession::ConnectUdpClientState::OnContextClosed(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code, absl::string_view close_details) {
- if (stream_id != stream_->id()) {
- QUIC_BUG(MASQUE client bad datagram context registration)
- << "Closed context on stream ID " << stream_id << ", expected "
- << stream_->id();
+ QuicDataReader reader(payload);
+ uint64_t context_id;
+ if (!reader.ReadVarInt62(&context_id)) {
+ QUIC_DLOG(ERROR) << "Failed to read context ID";
return;
}
- if (context_id != context_id_) {
- QUIC_DLOG(INFO)
- << "Ignoring unexpected close of context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " instead of "
- << (context_id_.has_value() ? absl::StrCat(context_id_.value())
- : "none")
- << " on stream ID " << stream_->id();
+ if (context_id != 0) {
+ QUIC_DLOG(ERROR) << "Ignoring HTTP Datagram with unexpected context ID "
+ << context_id;
return;
}
- QUIC_DLOG(INFO) << "Received datagram context close with close code "
- << close_code << " close details \"" << close_details
- << "\" on stream ID " << stream_->id() << ", closing stream";
- masque_session_->ResetStream(stream_->id(), QUIC_STREAM_CANCELLED);
+ absl::string_view http_payload = reader.ReadRemainingPayload();
+ encapsulated_client_session_->ProcessPacket(http_payload,
+ target_server_address_);
+ QUIC_DVLOG(1) << "Sent " << http_payload.size()
+ << " bytes to connection for stream ID " << stream_id;
}
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h
index 07673c32aaf..66c7e2ee35a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_client_session.h
@@ -10,7 +10,6 @@
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/http/quic_spdy_client_session.h"
-#include "quiche/quic/masque/masque_compression_engine.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
@@ -30,10 +29,6 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
public:
virtual ~Owner() {}
- // Notifies the owner that the client connection ID is no longer in use.
- virtual void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) = 0;
-
// Notifies the owner that a settings frame has been received.
virtual void OnSettingsReceived() = 0;
};
@@ -70,7 +65,6 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
MasqueClientSession& operator=(const MasqueClientSession&) = delete;
// From QuicSession.
- void OnMessageReceived(absl::string_view message) override;
void OnMessageAcked(QuicMessageId message_id,
QuicTime receive_timestamp) override;
void OnMessageLost(QuicMessageId message_id) override;
@@ -82,33 +76,18 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
bool OnSettingsFrame(const SettingsFrame& frame) override;
// Send encapsulated packet.
- void SendPacket(QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- absl::string_view packet,
+ void SendPacket(absl::string_view packet,
const QuicSocketAddress& target_server_address,
EncapsulatedClientSession* encapsulated_client_session);
- // Register encapsulated client. This allows clients that are encapsulated
- // within this MASQUE session to indicate they own a given client connection
- // ID so incoming packets with that connection ID are routed back to them.
- // Callers must not register a second different |encapsulated_client_session|
- // with the same |client_connection_id|. Every call must be matched with a
- // call to UnregisterConnectionId.
- void RegisterConnectionId(
- QuicConnectionId client_connection_id,
- EncapsulatedClientSession* encapsulated_client_session);
-
- // Unregister encapsulated client. |client_connection_id| must match a
- // value previously passed to RegisterConnectionId.
- void UnregisterConnectionId(
- QuicConnectionId client_connection_id,
+ // Close CONNECT-UDP stream tied to this encapsulated client session.
+ void CloseConnectUdpStream(
EncapsulatedClientSession* encapsulated_client_session);
private:
// State that the MasqueClientSession keeps for each CONNECT-UDP request.
class QUIC_NO_EXPORT ConnectUdpClientState
- : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
- public QuicSpdyStream::Http3DatagramVisitor {
+ : public QuicSpdyStream::Http3DatagramVisitor {
public:
// |stream| and |encapsulated_client_session| must be valid for the lifetime
// of the ConnectUdpClientState.
@@ -116,7 +95,6 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
QuicSpdyClientStream* stream,
EncapsulatedClientSession* encapsulated_client_session,
MasqueClientSession* masque_session,
- absl::optional<QuicDatagramContextId> context_id,
const QuicSocketAddress& target_server_address);
~ConnectUdpClientState();
@@ -131,38 +109,23 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
EncapsulatedClientSession* encapsulated_client_session() const {
return encapsulated_client_session_;
}
- absl::optional<QuicDatagramContextId> context_id() const {
- return context_id_;
- }
const QuicSocketAddress& target_server_address() const {
return target_server_address_;
}
// From QuicSpdyStream::Http3DatagramVisitor.
void OnHttp3Datagram(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
absl::string_view payload) override;
- // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
- void OnContextReceived(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type,
- absl::string_view format_additional_data) override;
- void OnContextClosed(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code,
- absl::string_view close_details) override;
-
private:
QuicSpdyClientStream* stream_; // Unowned.
EncapsulatedClientSession* encapsulated_client_session_; // Unowned.
MasqueClientSession* masque_session_; // Unowned.
- absl::optional<QuicDatagramContextId> context_id_;
QuicSocketAddress target_server_address_;
};
HttpDatagramSupport LocalHttpDatagramSupport() override {
- return HttpDatagramSupport::kDraft00And04;
+ return HttpDatagramSupport::kDraft09;
}
const ConnectUdpClientState* GetOrCreateConnectUdpClientState(
@@ -172,11 +135,7 @@ class QUIC_NO_EXPORT MasqueClientSession : public QuicSpdyClientSession {
MasqueMode masque_mode_;
std::string uri_template_;
std::list<ConnectUdpClientState> connect_udp_client_states_;
- absl::flat_hash_map<QuicConnectionId, EncapsulatedClientSession*,
- QuicConnectionIdHash>
- client_connection_id_registrations_;
Owner* owner_; // Unowned;
- MasqueCompressionEngine compression_engine_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.cc
deleted file mode 100644
index 3d057407c5c..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quiche/quic/masque/masque_compression_engine.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/quic_data_reader.h"
-#include "quiche/quic/core/quic_data_writer.h"
-#include "quiche/quic/core/quic_framer.h"
-#include "quiche/quic/core/quic_session.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_containers.h"
-#include "quiche/common/platform/api/quiche_mem_slice.h"
-#include "quiche/common/quiche_buffer_allocator.h"
-#include "quiche/common/quiche_text_utils.h"
-
-namespace quic {
-
-namespace {
-// |kFlowId0| is used to indicate creation of a new compression context.
-const QuicDatagramStreamId kFlowId0 = 0;
-
-enum MasqueAddressFamily : uint8_t {
- MasqueAddressFamilyIPv4 = 4,
- MasqueAddressFamilyIPv6 = 6,
-};
-
-} // namespace
-
-MasqueCompressionEngine::MasqueCompressionEngine(
- QuicSpdySession* masque_session)
- : masque_session_(masque_session),
- next_available_flow_id_(
- masque_session_->perspective() == Perspective::IS_CLIENT ? 0 : 1) {}
-
-QuicDatagramStreamId MasqueCompressionEngine::FindOrCreateCompressionContext(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address, bool client_connection_id_present,
- bool server_connection_id_present, bool* validated) {
- QuicDatagramStreamId flow_id = kFlowId0;
- *validated = false;
- for (const auto& kv : contexts_) {
- const MasqueCompressionContext& context = kv.second;
- if (context.server_address != server_address) {
- continue;
- }
- if (client_connection_id_present &&
- context.client_connection_id != client_connection_id) {
- continue;
- }
- if (server_connection_id_present &&
- context.server_connection_id != server_connection_id) {
- continue;
- }
-
- flow_id = kv.first;
- QUICHE_DCHECK_NE(flow_id, kFlowId0);
- *validated = context.validated;
- QUIC_DVLOG(1) << "Compressing using " << (*validated ? "" : "un")
- << "validated flow_id " << flow_id << " to "
- << context.server_address << " client "
- << context.client_connection_id << " server "
- << context.server_connection_id;
- break;
- }
-
- if (flow_id != kFlowId0) {
- // Found a compression context, use it.
- return flow_id;
- }
-
- // Create new compression context.
- next_available_flow_id_ += 2;
- flow_id = next_available_flow_id_;
- QUIC_DVLOG(1) << "Compression assigning new flow_id " << flow_id << " to "
- << server_address << " client " << client_connection_id
- << " server " << server_connection_id;
- MasqueCompressionContext context;
- context.client_connection_id = client_connection_id;
- context.server_connection_id = server_connection_id;
- context.server_address = server_address;
- contexts_[flow_id] = context;
-
- return flow_id;
-}
-
-bool MasqueCompressionEngine::WriteCompressedPacketToSlice(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id, QuicDatagramStreamId flow_id,
- bool validated, uint8_t first_byte, bool long_header,
- QuicDataReader* reader, QuicDataWriter* writer) {
- if (validated) {
- QUIC_DVLOG(1) << "Compressing using validated flow_id " << flow_id;
- if (!writer->WriteVarInt62(flow_id)) {
- QUIC_BUG(quic_bug_10981_1) << "Failed to write flow_id";
- return false;
- }
- } else {
- QUIC_DVLOG(1) << "Compressing using unvalidated flow_id " << flow_id;
- if (!writer->WriteVarInt62(kFlowId0)) {
- QUIC_BUG(quic_bug_10981_2) << "Failed to write kFlowId0";
- return false;
- }
- if (!writer->WriteVarInt62(flow_id)) {
- QUIC_BUG(quic_bug_10981_3) << "Failed to write flow_id";
- return false;
- }
- if (!writer->WriteLengthPrefixedConnectionId(client_connection_id)) {
- QUIC_BUG(quic_bug_10981_4) << "Failed to write client_connection_id";
- return false;
- }
- if (!writer->WriteLengthPrefixedConnectionId(server_connection_id)) {
- QUIC_BUG(quic_bug_10981_5) << "Failed to write server_connection_id";
- return false;
- }
- if (!writer->WriteUInt16(server_address.port())) {
- QUIC_BUG(quic_bug_10981_6) << "Failed to write port";
- return false;
- }
- QuicIpAddress peer_ip = server_address.host();
- QUICHE_DCHECK(peer_ip.IsInitialized());
- std::string peer_ip_bytes = peer_ip.ToPackedString();
- QUICHE_DCHECK(!peer_ip_bytes.empty());
- uint8_t address_id;
- if (peer_ip.address_family() == IpAddressFamily::IP_V6) {
- address_id = MasqueAddressFamilyIPv6;
- if (peer_ip_bytes.length() != QuicIpAddress::kIPv6AddressSize) {
- QUIC_BUG(quic_bug_10981_7) << "Bad IPv6 length " << server_address;
- return false;
- }
- } else if (peer_ip.address_family() == IpAddressFamily::IP_V4) {
- address_id = MasqueAddressFamilyIPv4;
- if (peer_ip_bytes.length() != QuicIpAddress::kIPv4AddressSize) {
- QUIC_BUG(quic_bug_10981_8) << "Bad IPv4 length " << server_address;
- return false;
- }
- } else {
- QUIC_BUG(quic_bug_10981_9)
- << "Unexpected server_address " << server_address;
- return false;
- }
- if (!writer->WriteUInt8(address_id)) {
- QUIC_BUG(quic_bug_10981_10) << "Failed to write address_id";
- return false;
- }
- if (!writer->WriteStringPiece(peer_ip_bytes)) {
- QUIC_BUG(quic_bug_10981_11) << "Failed to write IP address";
- return false;
- }
- }
- if (!writer->WriteUInt8(first_byte)) {
- QUIC_BUG(quic_bug_10981_12) << "Failed to write first_byte";
- return false;
- }
- if (long_header) {
- QuicVersionLabel version_label;
- if (!reader->ReadUInt32(&version_label)) {
- QUIC_DLOG(ERROR) << "Failed to read version";
- return false;
- }
- if (!writer->WriteUInt32(version_label)) {
- QUIC_BUG(quic_bug_10981_13) << "Failed to write version";
- return false;
- }
- QuicConnectionId packet_destination_connection_id,
- packet_source_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(
- &packet_destination_connection_id) ||
- !reader->ReadLengthPrefixedConnectionId(&packet_source_connection_id)) {
- QUIC_DLOG(ERROR) << "Failed to parse long header connection IDs";
- return false;
- }
- if (packet_destination_connection_id != destination_connection_id) {
- QUIC_DLOG(ERROR) << "Long header packet's destination_connection_id "
- << packet_destination_connection_id
- << " does not match expected "
- << destination_connection_id;
- return false;
- }
- if (packet_source_connection_id != source_connection_id) {
- QUIC_DLOG(ERROR) << "Long header packet's source_connection_id "
- << packet_source_connection_id
- << " does not match expected " << source_connection_id;
- return false;
- }
- } else {
- QuicConnectionId packet_destination_connection_id;
- if (!reader->ReadConnectionId(&packet_destination_connection_id,
- destination_connection_id.length())) {
- QUIC_DLOG(ERROR)
- << "Failed to read short header packet's destination_connection_id";
- return false;
- }
- if (packet_destination_connection_id != destination_connection_id) {
- QUIC_DLOG(ERROR) << "Short header packet's destination_connection_id "
- << packet_destination_connection_id
- << " does not match expected "
- << destination_connection_id;
- return false;
- }
- }
- absl::string_view packet_payload = reader->ReadRemainingPayload();
- if (!writer->WriteStringPiece(packet_payload)) {
- QUIC_BUG(quic_bug_10981_14) << "Failed to write packet_payload";
- return false;
- }
- return true;
-}
-
-void MasqueCompressionEngine::CompressAndSendPacket(
- absl::string_view packet, QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address) {
- QUIC_DVLOG(2) << "Compressing client " << client_connection_id << " server "
- << server_connection_id << "\n"
- << quiche::QuicheTextUtils::HexDump(packet);
- QUICHE_DCHECK(server_address.IsInitialized());
- if (packet.empty()) {
- QUIC_BUG(quic_bug_10981_15) << "Tried to send empty packet";
- return;
- }
- QuicDataReader reader(packet.data(), packet.length());
- uint8_t first_byte;
- if (!reader.ReadUInt8(&first_byte)) {
- QUIC_BUG(quic_bug_10981_16) << "Failed to read first_byte";
- return;
- }
- const bool long_header = (first_byte & FLAGS_LONG_HEADER) != 0;
- bool client_connection_id_present = true, server_connection_id_present = true;
- QuicConnectionId destination_connection_id, source_connection_id;
- if (masque_session_->perspective() == Perspective::IS_SERVER) {
- destination_connection_id = client_connection_id;
- source_connection_id = server_connection_id;
- if (!long_header) {
- server_connection_id_present = false;
- }
- } else {
- destination_connection_id = server_connection_id;
- source_connection_id = client_connection_id;
- if (!long_header) {
- client_connection_id_present = false;
- }
- }
-
- bool validated = false;
- QuicDatagramStreamId flow_id = FindOrCreateCompressionContext(
- client_connection_id, server_connection_id, server_address,
- client_connection_id_present, server_connection_id_present, &validated);
-
- size_t slice_length = packet.length() - destination_connection_id.length();
- if (long_header) {
- slice_length -= sizeof(uint8_t) * 2 + source_connection_id.length();
- }
- if (validated) {
- slice_length += QuicDataWriter::GetVarInt62Len(flow_id);
- } else {
- slice_length += QuicDataWriter::GetVarInt62Len(kFlowId0) +
- QuicDataWriter::GetVarInt62Len(flow_id) + sizeof(uint8_t) +
- client_connection_id.length() + sizeof(uint8_t) +
- server_connection_id.length() +
- sizeof(server_address.port()) + sizeof(uint8_t) +
- server_address.host().ToPackedString().length();
- }
- quiche::QuicheBuffer buffer(
- masque_session_->connection()->helper()->GetStreamSendBufferAllocator(),
- slice_length);
- QuicDataWriter writer(buffer.size(), buffer.data());
-
- if (!WriteCompressedPacketToSlice(
- client_connection_id, server_connection_id, server_address,
- destination_connection_id, source_connection_id, flow_id, validated,
- first_byte, long_header, &reader, &writer)) {
- return;
- }
-
- MessageResult message_result =
- masque_session_->SendMessage(quiche::QuicheMemSlice(std::move(buffer)));
-
- QUIC_DVLOG(1) << "Sent packet compressed with flow ID " << flow_id
- << " and got message result " << message_result;
-}
-
-bool MasqueCompressionEngine::ParseCompressionContext(
- QuicDataReader* reader, MasqueCompressionContext* context) {
- QuicDatagramStreamId new_flow_id;
- if (!reader->ReadVarInt62(&new_flow_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_flow_id";
- return false;
- }
- QuicConnectionId new_client_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(&new_client_connection_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_client_connection_id";
- return false;
- }
- QuicConnectionId new_server_connection_id;
- if (!reader->ReadLengthPrefixedConnectionId(&new_server_connection_id)) {
- QUIC_DLOG(ERROR) << "Could not read new_server_connection_id";
- return false;
- }
- uint16_t port;
- if (!reader->ReadUInt16(&port)) {
- QUIC_DLOG(ERROR) << "Could not read port";
- return false;
- }
- uint8_t address_id;
- if (!reader->ReadUInt8(&address_id)) {
- QUIC_DLOG(ERROR) << "Could not read address_id";
- return false;
- }
- size_t ip_bytes_length;
- if (address_id == MasqueAddressFamilyIPv6) {
- ip_bytes_length = QuicIpAddress::kIPv6AddressSize;
- } else if (address_id == MasqueAddressFamilyIPv4) {
- ip_bytes_length = QuicIpAddress::kIPv4AddressSize;
- } else {
- QUIC_DLOG(ERROR) << "Unknown address_id " << static_cast<int>(address_id);
- return false;
- }
- char ip_bytes[QuicIpAddress::kMaxAddressSize];
- if (!reader->ReadBytes(ip_bytes, ip_bytes_length)) {
- QUIC_DLOG(ERROR) << "Could not read IP address";
- return false;
- }
- QuicIpAddress ip_address;
- ip_address.FromPackedString(ip_bytes, ip_bytes_length);
- if (!ip_address.IsInitialized()) {
- QUIC_BUG(quic_bug_10981_17) << "Failed to parse IP address";
- return false;
- }
- QuicSocketAddress new_server_address = QuicSocketAddress(ip_address, port);
- auto context_pair = contexts_.find(new_flow_id);
- if (context_pair == contexts_.end()) {
- context->client_connection_id = new_client_connection_id;
- context->server_connection_id = new_server_connection_id;
- context->server_address = new_server_address;
- context->validated = true;
- contexts_[new_flow_id] = *context;
- QUIC_DVLOG(1) << "Registered new flow_id " << new_flow_id << " to "
- << new_server_address << " client "
- << new_client_connection_id << " server "
- << new_server_connection_id;
- } else {
- *context = context_pair->second;
- if (context->client_connection_id != new_client_connection_id) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched client "
- << context->client_connection_id << " " << new_client_connection_id;
- return false;
- }
- if (context->server_connection_id != new_server_connection_id) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched server "
- << context->server_connection_id << " " << new_server_connection_id;
- return false;
- }
- if (context->server_address != new_server_address) {
- QUIC_LOG(ERROR)
- << "Received incorrect context registration for existing flow_id "
- << new_flow_id << " mismatched server " << context->server_address
- << " " << new_server_address;
- return false;
- }
- if (!context->validated) {
- context->validated = true;
- contexts_[new_flow_id] = *context;
- QUIC_DLOG(INFO) << "Successfully validated remotely-unvalidated flow_id "
- << new_flow_id << " to " << new_server_address
- << " client " << new_client_connection_id << " server "
- << new_server_connection_id;
- } else {
- QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
- "remotely-unvalidated flow_id "
- << new_flow_id << " to " << new_server_address << " client "
- << new_client_connection_id << " server "
- << new_server_connection_id;
- }
- }
- return true;
-}
-
-bool MasqueCompressionEngine::WriteDecompressedPacket(
- QuicDataReader* reader, const MasqueCompressionContext& context,
- std::vector<char>* packet, bool* version_present) {
- QuicConnectionId destination_connection_id, source_connection_id;
- if (masque_session_->perspective() == Perspective::IS_SERVER) {
- destination_connection_id = context.server_connection_id;
- source_connection_id = context.client_connection_id;
- } else {
- destination_connection_id = context.client_connection_id;
- source_connection_id = context.server_connection_id;
- }
-
- size_t packet_length =
- reader->BytesRemaining() + destination_connection_id.length();
- uint8_t first_byte;
- if (!reader->ReadUInt8(&first_byte)) {
- QUIC_DLOG(ERROR) << "Failed to read first_byte";
- return false;
- }
- *version_present = (first_byte & FLAGS_LONG_HEADER) != 0;
- if (*version_present) {
- packet_length += sizeof(uint8_t) * 2 + source_connection_id.length();
- }
- *packet = std::vector<char>(packet_length);
- QuicDataWriter writer(packet->size(), packet->data());
- if (!writer.WriteUInt8(first_byte)) {
- QUIC_BUG(quic_bug_10981_18) << "Failed to write first_byte";
- return false;
- }
- if (*version_present) {
- QuicVersionLabel version_label;
- if (!reader->ReadUInt32(&version_label)) {
- QUIC_DLOG(ERROR) << "Failed to read version";
- return false;
- }
- if (!writer.WriteUInt32(version_label)) {
- QUIC_BUG(quic_bug_10981_19) << "Failed to write version";
- return false;
- }
- if (!writer.WriteLengthPrefixedConnectionId(destination_connection_id)) {
- QUIC_BUG(quic_bug_10981_20)
- << "Failed to write long header destination_connection_id";
- return false;
- }
- if (!writer.WriteLengthPrefixedConnectionId(source_connection_id)) {
- QUIC_BUG(quic_bug_10981_21)
- << "Failed to write long header source_connection_id";
- return false;
- }
- } else {
- if (!writer.WriteConnectionId(destination_connection_id)) {
- QUIC_BUG(quic_bug_10981_22)
- << "Failed to write short header destination_connection_id";
- return false;
- }
- }
- absl::string_view payload = reader->ReadRemainingPayload();
- if (!writer.WriteStringPiece(payload)) {
- QUIC_BUG(quic_bug_10981_23) << "Failed to write payload";
- return false;
- }
- return true;
-}
-
-bool MasqueCompressionEngine::DecompressDatagram(
- absl::string_view datagram, QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id, QuicSocketAddress* server_address,
- std::vector<char>* packet, bool* version_present) {
- QUIC_DVLOG(1) << "Decompressing DATAGRAM frame of length "
- << datagram.length();
- QuicDataReader reader(datagram);
- QuicDatagramStreamId flow_id;
- if (!reader.ReadVarInt62(&flow_id)) {
- QUIC_DLOG(ERROR) << "Could not read flow_id";
- return false;
- }
- MasqueCompressionContext context;
- if (flow_id == kFlowId0) {
- if (!ParseCompressionContext(&reader, &context)) {
- return false;
- }
- } else {
- auto context_pair = contexts_.find(flow_id);
- if (context_pair == contexts_.end()) {
- QUIC_DLOG(ERROR) << "Received unknown flow_id " << flow_id;
- return false;
- }
- context = context_pair->second;
-
- if (!context.validated) {
- context.validated = true;
- contexts_[flow_id] = context;
- QUIC_DLOG(INFO) << "Successfully validated remotely-validated flow_id "
- << flow_id << " to " << context.server_address
- << " client " << context.client_connection_id
- << " server " << context.server_connection_id;
- } else {
- QUIC_DVLOG(1) << "Decompressing using incoming locally-validated "
- "remotely-validated flow_id "
- << flow_id << " to " << context.server_address << " client "
- << context.client_connection_id << " server "
- << context.server_connection_id;
- }
- }
-
- if (!WriteDecompressedPacket(&reader, context, packet, version_present)) {
- return false;
- }
-
- *server_address = context.server_address;
- *client_connection_id = context.client_connection_id;
- *server_connection_id = context.server_connection_id;
-
- QUIC_DVLOG(2) << "Decompressed client " << context.client_connection_id
- << " server " << context.server_connection_id << "\n"
- << quiche::QuicheTextUtils::HexDump(
- absl::string_view(packet->data(), packet->size()));
-
- return true;
-}
-
-void MasqueCompressionEngine::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- std::vector<QuicDatagramStreamId> flow_ids_to_remove;
- for (const auto& kv : contexts_) {
- const MasqueCompressionContext& context = kv.second;
- if (context.client_connection_id == client_connection_id) {
- flow_ids_to_remove.push_back(kv.first);
- }
- }
- for (QuicDatagramStreamId flow_id : flow_ids_to_remove) {
- contexts_.erase(flow_id);
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.h
deleted file mode 100644
index 8c09de25f25..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_compression_engine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
-#define QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/http/quic_spdy_session.h"
-#include "quiche/quic/core/quic_connection_id.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
-#include "quiche/quic/platform/api/quic_export.h"
-#include "quiche/quic/platform/api/quic_socket_address.h"
-
-namespace quic {
-
-// MASQUE compression engine used by client and servers.
-// This class allows converting QUIC packets into a compressed form suitable
-// for sending over QUIC DATAGRAM frames. It leverages a flow identifier at the
-// start of each datagram to indicate which compression context was used to
-// compress this packet, or to create new compression contexts.
-// Compression contexts contain client and server connection IDs and the
-// server's IP and port. This allows compressing that information in most
-// packets without requiring access to the cryptographic keys of the end-to-end
-// encapsulated session. When the flow identifier is 0, the DATAGRAM contains
-// all the contents of the compression context. When the flow identifier is
-// non-zero, those fields are removed so the encapsulated QUIC packet is
-// transmitted without connection IDs and reassembled by the peer on
-// decompression. This only needs to contain the HTTP server's IP address since
-// the client's IP address is not visible to the HTTP server.
-
-class QUIC_NO_EXPORT MasqueCompressionEngine {
- public:
- // Caller must ensure that |masque_session| has a lifetime longer than the
- // newly constructed MasqueCompressionEngine.
- explicit MasqueCompressionEngine(QuicSpdySession* masque_session);
-
- // Disallow copy and assign.
- MasqueCompressionEngine(const MasqueCompressionEngine&) = delete;
- MasqueCompressionEngine& operator=(const MasqueCompressionEngine&) = delete;
-
- // Compresses packet and sends it in a DATAGRAM frame over a MASQUE session.
- // When used from MASQUE client to MASQUE server, the MASQUE server will then
- // send the packet to the provided |server_address|.
- // When used from MASQUE server to MASQUE client, the MASQUE client will then
- // hand off the uncompressed packet to an encapsulated session that will treat
- // it as having come from the provided |server_address|.
- // The connection IDs are the one used by the encapsulated |packet|.
- void CompressAndSendPacket(absl::string_view packet,
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address);
-
- // Decompresses received DATAGRAM frame contents from |datagram| and places
- // them in |packet|. Reverses the transformation from CompressAndSendPacket.
- // The connection IDs are the one used by the encapsulated |packet|.
- // |server_address| will be filled with the |server_address| passed to
- // CompressAndSendPacket. |version_present| will contain whether the
- // encapsulated |packet| contains a Version field.
- bool DecompressDatagram(absl::string_view datagram,
- QuicConnectionId* client_connection_id,
- QuicConnectionId* server_connection_id,
- QuicSocketAddress* server_address,
- std::vector<char>* packet, bool* version_present);
-
- // Clears all entries referencing |client_connection_id| from the
- // compression table.
- void UnregisterClientConnectionId(QuicConnectionId client_connection_id);
-
- private:
- struct QUIC_NO_EXPORT MasqueCompressionContext {
- QuicConnectionId client_connection_id;
- QuicConnectionId server_connection_id;
- QuicSocketAddress server_address;
- bool validated = false;
- };
-
- // Finds or creates a new compression context to use during compression.
- // |client_connection_id_present| and |server_connection_id_present| indicate
- // whether the corresponding connection ID is present in the current packet.
- // |validated| will contain whether the compression context that matches
- // these arguments is currently validated or not.
- QuicDatagramStreamId FindOrCreateCompressionContext(
- QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- bool client_connection_id_present, bool server_connection_id_present,
- bool* validated);
-
- // Writes compressed packet to |slice| during compression.
- bool WriteCompressedPacketToSlice(QuicConnectionId client_connection_id,
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& server_address,
- QuicConnectionId destination_connection_id,
- QuicConnectionId source_connection_id,
- QuicDatagramStreamId flow_id,
- bool validated, uint8_t first_byte,
- bool long_header, QuicDataReader* reader,
- QuicDataWriter* writer);
-
- // Parses compression context from flow ID 0 during decompression.
- bool ParseCompressionContext(QuicDataReader* reader,
- MasqueCompressionContext* context);
-
- // Writes decompressed packet to |packet| during decompression.
- bool WriteDecompressedPacket(QuicDataReader* reader,
- const MasqueCompressionContext& context,
- std::vector<char>* packet,
- bool* version_present);
-
- QuicSpdySession* masque_session_; // Unowned.
- absl::flat_hash_map<QuicDatagramStreamId, MasqueCompressionContext> contexts_;
- QuicDatagramStreamId next_available_flow_id_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_MASQUE_MASQUE_COMPRESSION_ENGINE_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.cc
index 6db6f8ce009..d0440a6cd14 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.cc
@@ -38,50 +38,11 @@ std::unique_ptr<QuicSession> MasqueDispatcher::CreateQuicSession(
ParsedQuicVersionVector{version});
auto session = std::make_unique<MasqueServerSession>(
- masque_mode_, config(), GetSupportedVersions(), connection, this, this,
+ masque_mode_, config(), GetSupportedVersions(), connection, this,
epoll_server_, session_helper(), crypto_config(),
compressed_certs_cache(), masque_server_backend_);
session->Initialize();
return session;
}
-bool MasqueDispatcher::OnFailedToDispatchPacket(
- const ReceivedPacketInfo& packet_info) {
- auto connection_id_registration = client_connection_id_registrations_.find(
- packet_info.destination_connection_id);
- if (connection_id_registration == client_connection_id_registrations_.end()) {
- QUIC_DLOG(INFO) << "MasqueDispatcher failed to dispatch " << packet_info;
- return false;
- }
- MasqueServerSession* masque_server_session =
- connection_id_registration->second;
- masque_server_session->HandlePacketFromServer(packet_info);
- return true;
-}
-
-void MasqueDispatcher::RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) {
- QUIC_DLOG(INFO) << "Registering encapsulated " << client_connection_id
- << " to MASQUE session "
- << masque_server_session->connection_id();
-
- // Make sure we don't try to overwrite an existing registration with a
- // different session.
- QUIC_BUG_IF(quic_bug_12013_1,
- client_connection_id_registrations_.find(client_connection_id) !=
- client_connection_id_registrations_.end() &&
- client_connection_id_registrations_[client_connection_id] !=
- masque_server_session)
- << "Overwriting existing registration for " << client_connection_id;
- client_connection_id_registrations_[client_connection_id] =
- masque_server_session;
-}
-
-void MasqueDispatcher::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- QUIC_DLOG(INFO) << "Unregistering " << client_connection_id;
- client_connection_id_registrations_.erase(client_connection_id);
-}
-
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.h
index 90d319cee0a..b5ef5bb22ed 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_dispatcher.h
@@ -17,8 +17,7 @@ namespace quic {
// QUIC dispatcher that handles new MASQUE connections and can proxy traffic
// between MASQUE clients and QUIC servers.
-class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher,
- public MasqueServerSession::Visitor {
+class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher {
public:
explicit MasqueDispatcher(
MasqueMode masque_mode, const QuicConfig* config,
@@ -41,25 +40,10 @@ class QUIC_NO_EXPORT MasqueDispatcher : public QuicSimpleDispatcher,
const ParsedQuicVersion& version,
const quic::ParsedClientHello& parsed_chlo) override;
- bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info) override;
-
- // From MasqueServerSession::Visitor.
- void RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) override;
-
- void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) override;
-
private:
MasqueMode masque_mode_;
QuicEpollServer* epoll_server_; // Unowned.
MasqueServerBackend* masque_server_backend_; // Unowned.
- // Mapping from client connection IDs to server sessions, allows routing
- // incoming packets to the right MASQUE connection.
- absl::flat_hash_map<QuicConnectionId, MasqueServerSession*,
- QuicConnectionIdHash>
- client_connection_id_registrations_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_client_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_client_session.cc
index 988b51170d9..077430fa6a9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_client_session.cc
@@ -33,8 +33,7 @@ void MasqueEncapsulatedClientSession::CloseConnection(
void MasqueEncapsulatedClientSession::OnConnectionClosed(
const QuicConnectionCloseFrame& frame, ConnectionCloseSource source) {
QuicSpdyClientSession::OnConnectionClosed(frame, source);
- masque_client_session_->UnregisterConnectionId(
- connection()->client_connection_id(), this);
+ masque_client_session_->CloseConnectUdpStream(this);
}
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.cc
index 41dde4ecf5f..242d26594d0 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.cc
@@ -29,9 +29,7 @@ class MasquePacketWriter : public QuicPacketWriter {
<< " bytes to " << peer_address;
absl::string_view packet(buffer, buf_len);
client_->masque_client()->masque_client_session()->SendPacket(
- client_->session()->connection()->client_connection_id(),
- client_->session()->connection()->connection_id(), packet, peer_address,
- client_->masque_encapsulated_client_session());
+ packet, peer_address, client_->masque_encapsulated_client_session());
return WriteResult(WRITE_STATUS_OK, buf_len);
}
@@ -93,8 +91,8 @@ MasqueEncapsulatedEpollClient::MasqueEncapsulatedEpollClient(
masque_client_(masque_client) {}
MasqueEncapsulatedEpollClient::~MasqueEncapsulatedEpollClient() {
- masque_client_->masque_client_session()->UnregisterConnectionId(
- client_connection_id_, masque_encapsulated_client_session());
+ masque_client_->masque_client_session()->CloseConnectUdpStream(
+ masque_encapsulated_client_session());
}
std::unique_ptr<QuicSession>
@@ -113,13 +111,4 @@ MasqueEncapsulatedEpollClient::masque_encapsulated_client_session() {
return static_cast<MasqueEncapsulatedClientSession*>(QuicClient::session());
}
-QuicConnectionId MasqueEncapsulatedEpollClient::GetClientConnectionId() {
- if (client_connection_id_.IsEmpty()) {
- client_connection_id_ = QuicUtils::CreateRandomConnectionId();
- masque_client_->masque_client_session()->RegisterConnectionId(
- client_connection_id_, masque_encapsulated_client_session());
- }
- return client_connection_id_;
-}
-
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.h
index cbe1bcd3450..2b98652755a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_encapsulated_epoll_client.h
@@ -32,8 +32,6 @@ class QUIC_NO_EXPORT MasqueEncapsulatedEpollClient : public QuicClient {
const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection) override;
- QuicConnectionId GetClientConnectionId() override;
-
// MASQUE client that this client is encapsulated in.
MasqueEpollClient* masque_client() { return masque_client_; }
@@ -42,7 +40,6 @@ class QUIC_NO_EXPORT MasqueEncapsulatedEpollClient : public QuicClient {
private:
MasqueEpollClient* masque_client_; // Unowned.
- QuicConnectionId client_connection_id_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
index 6d6470bc099..705ea15cd95 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.cc
@@ -91,36 +91,6 @@ std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
return nullptr;
}
- if (masque_client->masque_mode() == MasqueMode::kLegacy) {
- // Construct the legacy mode init request.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "POST";
- header_block[":scheme"] = "https";
- header_block[":authority"] = masque_client->authority();
- header_block[":path"] = "/.well-known/masque/init";
- std::string body = "foo";
-
- // Make sure to store the response, for later output.
- masque_client->set_store_response(true);
-
- // Send the MASQUE init command.
- masque_client->SendRequestAndWaitForResponse(header_block, body,
- /*fin=*/true);
-
- if (!masque_client->connected()) {
- QUIC_LOG(ERROR)
- << "MASQUE init request caused connection failure. Error: "
- << QuicErrorCodeToString(masque_client->session()->error());
- return nullptr;
- }
-
- const int response_code = masque_client->latest_response_code();
- if (response_code != 200) {
- QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
- << response_code;
- return nullptr;
- }
- }
return masque_client;
}
@@ -133,22 +103,4 @@ bool MasqueEpollClient::WaitUntilSettingsReceived() {
return connected() && settings_received_;
}
-void MasqueEpollClient::UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) {
- std::string body(client_connection_id.data(), client_connection_id.length());
-
- // Construct a GET or POST request for supplied URL.
- spdy::Http2HeaderBlock header_block;
- header_block[":method"] = "POST";
- header_block[":scheme"] = "https";
- header_block[":authority"] = authority();
- header_block[":path"] = "/.well-known/masque/unregister";
-
- // Make sure to store the response, for later output.
- set_store_response(true);
-
- // Send the MASQUE unregister command.
- SendRequest(header_block, body, /*fin=*/true);
-}
-
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.h
index 7b36bf68faa..7eff270ee4e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_epoll_client.h
@@ -38,9 +38,6 @@ class QUIC_NO_EXPORT MasqueEpollClient : public QuicClient,
// From MasqueClientSession::Owner.
void OnSettingsReceived() override;
- // Send a MASQUE client connection ID unregister command to the server.
- void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) override;
MasqueMode masque_mode() const { return masque_mode_; }
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.cc
index 8dfe8b8452e..b42a055c56c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.cc
@@ -20,7 +20,6 @@ MasqueServerBackend::MasqueServerBackend(MasqueMode masque_mode,
bool MasqueServerBackend::MaybeHandleMasqueRequest(
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) {
auto method_pair = request_headers.find(":method");
if (method_pair == request_headers.end()) {
@@ -29,34 +28,11 @@ bool MasqueServerBackend::MaybeHandleMasqueRequest(
}
absl::string_view method = method_pair->second;
std::string masque_path = "";
- if (masque_mode_ == MasqueMode::kLegacy) {
- auto path_pair = request_headers.find(":path");
- auto scheme_pair = request_headers.find(":scheme");
- if (path_pair == request_headers.end() ||
- scheme_pair == request_headers.end()) {
- // This request is missing required headers.
- return false;
- }
- absl::string_view path = path_pair->second;
- absl::string_view scheme = scheme_pair->second;
- if (scheme != "https" || method != "POST" || request_body.empty()) {
- // MASQUE requests MUST be a non-empty https POST.
- return false;
- }
-
- if (path.rfind("/.well-known/masque/", 0) != 0) {
- // This request is not a MASQUE path.
- return false;
- }
- masque_path = std::string(path.substr(sizeof("/.well-known/masque/") - 1));
- } else {
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- auto protocol_pair = request_headers.find(":protocol");
- if (method != "CONNECT" || protocol_pair == request_headers.end() ||
- protocol_pair->second != "connect-udp") {
- // This is not a MASQUE request.
- return false;
- }
+ auto protocol_pair = request_headers.find(":protocol");
+ if (method != "CONNECT" || protocol_pair == request_headers.end() ||
+ protocol_pair->second != "connect-udp") {
+ // This is not a MASQUE request.
+ return false;
}
if (!server_authority_.empty()) {
@@ -82,8 +58,7 @@ bool MasqueServerBackend::MaybeHandleMasqueRequest(
BackendClient* backend_client = it->second.backend_client;
std::unique_ptr<QuicBackendResponse> response =
- backend_client->HandleMasqueRequest(masque_path, request_headers,
- request_body, request_handler);
+ backend_client->HandleMasqueRequest(request_headers, request_handler);
if (response == nullptr) {
QUIC_LOG(ERROR) << "Backend client did not process request for "
<< masque_path << request_headers.DebugString();
@@ -103,8 +78,7 @@ void MasqueServerBackend::FetchResponseFromBackend(
const spdy::Http2HeaderBlock& request_headers,
const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) {
- if (MaybeHandleMasqueRequest(request_headers, request_body,
- request_handler)) {
+ if (MaybeHandleMasqueRequest(request_headers, request_handler)) {
// Request was handled as a MASQUE request.
return;
}
@@ -114,6 +88,19 @@ void MasqueServerBackend::FetchResponseFromBackend(
request_headers, request_body, request_handler);
}
+void MasqueServerBackend::HandleConnectHeaders(
+ const spdy::Http2HeaderBlock& request_headers,
+ RequestHandler* request_handler) {
+ if (MaybeHandleMasqueRequest(request_headers, request_handler)) {
+ // Request was handled as a MASQUE request.
+ return;
+ }
+ QUIC_DLOG(INFO) << "Fetching non-MASQUE CONNECT response for "
+ << request_headers.DebugString();
+ QuicMemoryCacheBackend::HandleConnectHeaders(request_headers,
+ request_handler);
+}
+
void MasqueServerBackend::CloseBackendResponseStream(
QuicSimpleServerBackend::RequestHandler* request_handler) {
QUIC_DLOG(INFO) << "Closing response stream";
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.h
index 7480a86e97b..a86209731a6 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_backend.h
@@ -21,9 +21,7 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
class QUIC_NO_EXPORT BackendClient {
public:
virtual std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
- const std::string& masque_path,
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) = 0;
virtual ~BackendClient() = default;
};
@@ -41,6 +39,8 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
const spdy::Http2HeaderBlock& request_headers,
const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) override;
+ void HandleConnectHeaders(const spdy::Http2HeaderBlock& request_headers,
+ RequestHandler* request_handler) override;
void CloseBackendResponseStream(
QuicSimpleServerBackend::RequestHandler* request_handler) override;
@@ -56,7 +56,6 @@ class QUIC_NO_EXPORT MasqueServerBackend : public QuicMemoryCacheBackend {
// Handle MASQUE request.
bool MaybeHandleMasqueRequest(
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler);
MasqueMode masque_mode_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_bin.cc
index ac1c1898463..23d9d69c284 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_bin.cc
@@ -31,9 +31,9 @@ DEFINE_QUICHE_COMMAND_LINE_FLAG(
"Specifies the authority over which the server will accept MASQUE "
"requests. Defaults to empty which allows all authorities.");
-DEFINE_QUICHE_COMMAND_LINE_FLAG(std::string, masque_mode, "",
- "Allows setting MASQUE mode, valid values are "
- "open and legacy. Defaults to open.");
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
+ std::string, masque_mode, "",
+ "Allows setting MASQUE mode, currently only valid value is \"open\".");
int main(int argc, char* argv[]) {
quiche::QuicheSystemEventLoop event_loop("masque_server");
@@ -46,23 +46,22 @@ int main(int argc, char* argv[]) {
}
quic::MasqueMode masque_mode = quic::MasqueMode::kOpen;
- std::string mode_string = GetQuicFlag(FLAGS_masque_mode);
- if (mode_string == "legacy") {
- masque_mode = quic::MasqueMode::kLegacy;
- } else if (!mode_string.empty() && mode_string != "open") {
+ std::string mode_string = quiche::GetQuicheCommandLineFlag(FLAGS_masque_mode);
+ if (!mode_string.empty() && mode_string != "open") {
std::cerr << "Invalid masque_mode \"" << mode_string << "\"" << std::endl;
return 1;
}
auto backend = std::make_unique<quic::MasqueServerBackend>(
- masque_mode, GetQuicFlag(FLAGS_server_authority),
- GetQuicFlag(FLAGS_cache_dir));
+ masque_mode, quiche::GetQuicheCommandLineFlag(FLAGS_server_authority),
+ quiche::GetQuicheCommandLineFlag(FLAGS_cache_dir));
auto server =
std::make_unique<quic::MasqueEpollServer>(masque_mode, backend.get());
if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
- quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
+ quic::QuicIpAddress::Any6(),
+ quiche::GetQuicheCommandLineFlag(FLAGS_port)))) {
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.cc
index f2210946077..742b0c654f9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.cc
@@ -78,7 +78,7 @@ std::unique_ptr<QuicBackendResponse> CreateBackendErrorResponse(
MasqueServerSession::MasqueServerSession(
MasqueMode masque_mode, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+ QuicConnection* connection, QuicSession::Visitor* visitor,
QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
const QuicCryptoServerConfig* crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
@@ -87,9 +87,7 @@ MasqueServerSession::MasqueServerSession(
helper, crypto_config, compressed_certs_cache,
masque_server_backend),
masque_server_backend_(masque_server_backend),
- owner_(owner),
epoll_server_(epoll_server),
- compression_engine_(this),
masque_mode_(masque_mode) {
// Artificially increase the max packet length to 1350 to ensure we can fit
// QUIC packets inside DATAGRAM frames.
@@ -100,44 +98,6 @@ MasqueServerSession::MasqueServerSession(
QUICHE_DCHECK_NE(epoll_server_, nullptr);
}
-void MasqueServerSession::OnMessageReceived(absl::string_view message) {
- if (masque_mode_ == MasqueMode::kLegacy) {
- QUIC_DVLOG(1) << "Received DATAGRAM frame of length " << message.length();
- QuicConnectionId client_connection_id, server_connection_id;
- QuicSocketAddress target_server_address;
- std::vector<char> packet;
- bool version_present;
- if (!compression_engine_.DecompressDatagram(
- message, &client_connection_id, &server_connection_id,
- &target_server_address, &packet, &version_present)) {
- return;
- }
-
- QUIC_DVLOG(1) << "Received packet of length " << packet.size() << " for "
- << target_server_address << " client "
- << client_connection_id;
-
- if (version_present) {
- if (client_connection_id.length() != kQuicDefaultConnectionIdLength) {
- QUIC_DLOG(ERROR)
- << "Dropping long header with invalid client_connection_id "
- << client_connection_id;
- return;
- }
- owner_->RegisterClientConnectionId(client_connection_id, this);
- }
-
- WriteResult write_result = connection()->writer()->WritePacket(
- packet.data(), packet.size(), connection()->self_address().host(),
- target_server_address, nullptr);
- QUIC_DVLOG(1) << "Got " << write_result << " for " << packet.size()
- << " bytes to " << target_server_address;
- return;
- }
- QUICHE_DCHECK_EQ(masque_mode_, MasqueMode::kOpen);
- QuicSpdySession::OnMessageReceived(message);
-}
-
void MasqueServerSession::OnMessageAcked(QuicMessageId message_id,
QuicTime /*receive_timestamp*/) {
QUIC_DVLOG(1) << "Received ack for DATAGRAM frame " << message_id;
@@ -166,211 +126,132 @@ void MasqueServerSession::OnStreamClosed(QuicStreamId stream_id) {
}
std::unique_ptr<QuicBackendResponse> MasqueServerSession::HandleMasqueRequest(
- const std::string& masque_path,
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) {
- if (masque_mode_ != MasqueMode::kLegacy) {
- auto path_pair = request_headers.find(":path");
- auto scheme_pair = request_headers.find(":scheme");
- auto method_pair = request_headers.find(":method");
- auto protocol_pair = request_headers.find(":protocol");
- auto authority_pair = request_headers.find(":authority");
- if (path_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
- return CreateBackendErrorResponse("400", "Missing :path");
- }
- if (scheme_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
- return CreateBackendErrorResponse("400", "Missing :scheme");
- }
- if (method_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
- return CreateBackendErrorResponse("400", "Missing :method");
- }
- if (protocol_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
- return CreateBackendErrorResponse("400", "Missing :protocol");
- }
- if (authority_pair == request_headers.end()) {
- QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
- return CreateBackendErrorResponse("400", "Missing :authority");
- }
- absl::string_view path = path_pair->second;
- absl::string_view scheme = scheme_pair->second;
- absl::string_view method = method_pair->second;
- absl::string_view protocol = protocol_pair->second;
- absl::string_view authority = authority_pair->second;
- if (path.empty()) {
- QUIC_DLOG(ERROR) << "MASQUE request with empty path";
- return CreateBackendErrorResponse("400", "Empty path");
- }
- if (scheme.empty()) {
- return CreateBackendErrorResponse("400", "Empty scheme");
- }
- if (method != "CONNECT") {
- QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
- return CreateBackendErrorResponse("400", "Bad method");
- }
- if (protocol != "connect-udp") {
- QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
- << "\"";
- return CreateBackendErrorResponse("400", "Bad protocol");
- }
- absl::optional<QuicDatagramStreamId> flow_id;
- if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
- flow_id = SpdyUtils::ParseDatagramFlowIdHeader(request_headers);
- if (!flow_id.has_value()) {
- QUIC_DLOG(ERROR)
- << "MASQUE request with bad or missing DatagramFlowId header";
- return CreateBackendErrorResponse(
- "400", "Bad or missing DatagramFlowId header");
- }
- }
- // Extract target host and port from path using default template.
- std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
- if (path_split.size() != 4 || !path_split[0].empty() ||
- path_split[1].empty() || path_split[2].empty() ||
- !path_split[3].empty()) {
- QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
- return CreateBackendErrorResponse("400", "Bad path");
- }
- absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[1]);
- if (!host.has_value()) {
- QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[1] << "\"";
- return CreateBackendErrorResponse("500", "Failed to decode host");
- }
- absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[2]);
- if (!port.has_value()) {
- QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[2] << "\"";
- return CreateBackendErrorResponse("500", "Failed to decode port");
- }
-
- // Perform DNS resolution.
- addrinfo hint = {};
- hint.ai_protocol = IPPROTO_UDP;
-
- addrinfo* info_list = nullptr;
- int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
- &info_list);
- if (result != 0) {
- QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
- << gai_strerror(result);
- return CreateBackendErrorResponse("500", "DNS resolution failed");
- }
-
- QUICHE_CHECK_NE(info_list, nullptr);
- std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(
- info_list, freeaddrinfo);
- QuicSocketAddress target_server_address(info_list->ai_addr,
- info_list->ai_addrlen);
- QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
- << request_handler->stream_id() << " flow_id="
- << (flow_id.has_value() ? absl::StrCat(*flow_id) : "none")
- << " target_server_address=\"" << target_server_address
- << "\"";
-
- FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
- if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
- QUIC_DLOG(ERROR) << "Socket creation failed";
- return CreateBackendErrorResponse("500", "Socket creation failed");
- }
- QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
- if (target_server_address.host().IsIPv4()) {
- empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
- }
- QuicUdpSocketApi socket_api;
- if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
- QUIC_DLOG(ERROR) << "Socket bind failed";
- return CreateBackendErrorResponse("500", "Socket bind failed");
- }
- epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
-
- absl::optional<QuicDatagramContextId> context_id;
- QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
- GetActiveStream(request_handler->stream_id()));
- if (stream == nullptr) {
- QUIC_BUG(bad masque server stream type)
- << "Unexpected stream type for stream ID "
- << request_handler->stream_id();
- return CreateBackendErrorResponse("500", "Bad stream type");
- }
- if (flow_id.has_value()) {
- stream->RegisterHttp3DatagramFlowId(*flow_id);
- }
- connect_udp_server_states_.push_back(
- ConnectUdpServerState(stream, context_id, target_server_address,
- fd_wrapper.extract_fd(), this));
-
- if (http_datagram_support() == HttpDatagramSupport::kDraft00) {
- // TODO(b/181256914) remove this when we drop support for
- // draft-ietf-masque-h3-datagram-00 in favor of later drafts.
- stream->RegisterHttp3DatagramContextId(
- context_id, DatagramFormatType::UDP_PAYLOAD,
- /*format_additional_data=*/absl::string_view(),
- &connect_udp_server_states_.back());
- }
-
- spdy::Http2HeaderBlock response_headers;
- response_headers[":status"] = "200";
- if (flow_id.has_value()) {
- SpdyUtils::AddDatagramFlowIdHeader(&response_headers, *flow_id);
- }
- auto response = std::make_unique<QuicBackendResponse>();
- response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
- response->set_headers(std::move(response_headers));
- response->set_body("");
-
- return response;
+ auto path_pair = request_headers.find(":path");
+ auto scheme_pair = request_headers.find(":scheme");
+ auto method_pair = request_headers.find(":method");
+ auto protocol_pair = request_headers.find(":protocol");
+ auto authority_pair = request_headers.find(":authority");
+ if (path_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :path";
+ return CreateBackendErrorResponse("400", "Missing :path");
+ }
+ if (scheme_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :scheme";
+ return CreateBackendErrorResponse("400", "Missing :scheme");
+ }
+ if (method_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :method";
+ return CreateBackendErrorResponse("400", "Missing :method");
+ }
+ if (protocol_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :protocol";
+ return CreateBackendErrorResponse("400", "Missing :protocol");
+ }
+ if (authority_pair == request_headers.end()) {
+ QUIC_DLOG(ERROR) << "MASQUE request is missing :authority";
+ return CreateBackendErrorResponse("400", "Missing :authority");
+ }
+ absl::string_view path = path_pair->second;
+ absl::string_view scheme = scheme_pair->second;
+ absl::string_view method = method_pair->second;
+ absl::string_view protocol = protocol_pair->second;
+ absl::string_view authority = authority_pair->second;
+ if (path.empty()) {
+ QUIC_DLOG(ERROR) << "MASQUE request with empty path";
+ return CreateBackendErrorResponse("400", "Empty path");
+ }
+ if (scheme.empty()) {
+ return CreateBackendErrorResponse("400", "Empty scheme");
+ }
+ if (method != "CONNECT") {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad method \"" << method << "\"";
+ return CreateBackendErrorResponse("400", "Bad method");
+ }
+ if (protocol != "connect-udp") {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad protocol \"" << protocol
+ << "\"";
+ return CreateBackendErrorResponse("400", "Bad protocol");
+ }
+ // Extract target host and port from path using default template.
+ std::vector<absl::string_view> path_split = absl::StrSplit(path, '/');
+ if (path_split.size() != 7 || !path_split[0].empty() ||
+ path_split[1] != ".well-known" || path_split[2] != "masque" ||
+ path_split[3] != "udp" || path_split[4].empty() ||
+ path_split[5].empty() || !path_split[6].empty()) {
+ QUIC_DLOG(ERROR) << "MASQUE request with bad path \"" << path << "\"";
+ return CreateBackendErrorResponse("400", "Bad path");
+ }
+ absl::optional<std::string> host = quiche::AsciiUrlDecode(path_split[4]);
+ if (!host.has_value()) {
+ QUIC_DLOG(ERROR) << "Failed to decode host \"" << path_split[4] << "\"";
+ return CreateBackendErrorResponse("500", "Failed to decode host");
+ }
+ absl::optional<std::string> port = quiche::AsciiUrlDecode(path_split[5]);
+ if (!port.has_value()) {
+ QUIC_DLOG(ERROR) << "Failed to decode port \"" << path_split[5] << "\"";
+ return CreateBackendErrorResponse("500", "Failed to decode port");
}
- QUIC_DLOG(INFO) << "MasqueServerSession handling MASQUE request";
+ // Perform DNS resolution.
+ addrinfo hint = {};
+ hint.ai_protocol = IPPROTO_UDP;
+
+ addrinfo* info_list = nullptr;
+ int result = getaddrinfo(host.value().c_str(), port.value().c_str(), &hint,
+ &info_list);
+ if (result != 0 || info_list == nullptr) {
+ QUIC_DLOG(ERROR) << "Failed to resolve " << authority << ": "
+ << gai_strerror(result);
+ return CreateBackendErrorResponse("500", "DNS resolution failed");
+ }
- if (masque_path == "init") {
- if (masque_initialized_) {
- QUIC_DLOG(ERROR) << "Got second MASQUE init request";
- return nullptr;
- }
- masque_initialized_ = true;
- } else if (masque_path == "unregister") {
- QuicConnectionId connection_id(request_body.data(), request_body.length());
- QUIC_DLOG(INFO) << "Received MASQUE request to unregister "
- << connection_id;
- owner_->UnregisterClientConnectionId(connection_id);
- compression_engine_.UnregisterClientConnectionId(connection_id);
- } else {
- if (!masque_initialized_) {
- QUIC_DLOG(ERROR) << "Got MASQUE request before init";
- return nullptr;
- }
+ std::unique_ptr<addrinfo, void (*)(addrinfo*)> info_list_owned(info_list,
+ freeaddrinfo);
+ QuicSocketAddress target_server_address(info_list->ai_addr,
+ info_list->ai_addrlen);
+ QUIC_DLOG(INFO) << "Got CONNECT_UDP request on stream ID "
+ << request_handler->stream_id() << " target_server_address=\""
+ << target_server_address << "\"";
+
+ FdWrapper fd_wrapper(target_server_address.host().AddressFamilyToInt());
+ if (fd_wrapper.fd() == kQuicInvalidSocketFd) {
+ QUIC_DLOG(ERROR) << "Socket creation failed";
+ return CreateBackendErrorResponse("500", "Socket creation failed");
+ }
+ QuicSocketAddress empty_address(QuicIpAddress::Any6(), 0);
+ if (target_server_address.host().IsIPv4()) {
+ empty_address = QuicSocketAddress(QuicIpAddress::Any4(), 0);
+ }
+ QuicUdpSocketApi socket_api;
+ if (!socket_api.Bind(fd_wrapper.fd(), empty_address)) {
+ QUIC_DLOG(ERROR) << "Socket bind failed";
+ return CreateBackendErrorResponse("500", "Socket bind failed");
+ }
+ epoll_server_->RegisterFDForRead(fd_wrapper.fd(), this);
+
+ QuicSpdyStream* stream =
+ static_cast<QuicSpdyStream*>(GetActiveStream(request_handler->stream_id()));
+ if (stream == nullptr) {
+ QUIC_BUG(bad masque server stream type)
+ << "Unexpected stream type for stream ID "
+ << request_handler->stream_id();
+ return CreateBackendErrorResponse("500", "Bad stream type");
}
+ connect_udp_server_states_.push_back(ConnectUdpServerState(
+ stream, target_server_address, fd_wrapper.extract_fd(), this));
- // TODO(dschinazi) implement binary protocol sent in response body.
- const std::string response_body = "";
spdy::Http2HeaderBlock response_headers;
response_headers[":status"] = "200";
auto response = std::make_unique<QuicBackendResponse>();
- response->set_response_type(QuicBackendResponse::REGULAR_RESPONSE);
+ response->set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
response->set_headers(std::move(response_headers));
- response->set_body(response_body);
+ response->set_body("");
return response;
}
-void MasqueServerSession::HandlePacketFromServer(
- const ReceivedPacketInfo& packet_info) {
- QUIC_DVLOG(1) << "MasqueServerSession received " << packet_info;
- if (masque_mode_ == MasqueMode::kLegacy) {
- compression_engine_.CompressAndSendPacket(
- packet_info.packet.AsStringPiece(),
- packet_info.destination_connection_id, packet_info.source_connection_id,
- packet_info.peer_address);
- return;
- }
- QUIC_LOG(ERROR) << "Ignoring packet from server in " << masque_mode_
- << " mode";
-}
-
void MasqueServerSession::OnRegistration(QuicEpollServer* /*eps*/,
QuicUdpSocketFd fd, int event_mask) {
QUIC_DVLOG(1) << "OnRegistration " << fd << " event_mask " << event_mask;
@@ -403,11 +284,12 @@ void MasqueServerSession::OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) {
<< " server " << expected_target_server_address;
QuicUdpSocketApi socket_api;
BitMask64 packet_info_interested(QuicUdpPacketInfoBit::PEER_ADDRESS);
- char packet_buffer[kMaxIncomingPacketSize];
+ char packet_buffer[1 + kMaxIncomingPacketSize];
+ packet_buffer[0] = 0; // context ID.
char control_buffer[kDefaultUdpPacketControlBufferSize];
while (true) {
QuicUdpSocketApi::ReadPacketResult read_result;
- read_result.packet_buffer = {packet_buffer, sizeof(packet_buffer)};
+ read_result.packet_buffer = {packet_buffer + 1, sizeof(packet_buffer) - 1};
read_result.control_buffer = {control_buffer, sizeof(control_buffer)};
socket_api.ReadPacket(fd, packet_info_interested, &read_result);
if (!read_result.ok) {
@@ -436,10 +318,9 @@ void MasqueServerSession::OnEvent(QuicUdpSocketFd fd, QuicEpollEvent* event) {
return;
}
// The packet is valid, send it to the client in a DATAGRAM frame.
- MessageStatus message_status = it->stream()->SendHttp3Datagram(
- it->context_id(),
- absl::string_view(read_result.packet_buffer.buffer,
- read_result.packet_buffer.buffer_len));
+ MessageStatus message_status =
+ it->stream()->SendHttp3Datagram(absl::string_view(
+ packet_buffer, read_result.packet_buffer.buffer_len + 1));
QUIC_DVLOG(1) << "Sent UDP packet from " << expected_target_server_address
<< " of length " << read_result.packet_buffer.buffer_len
<< " with stream ID " << it->stream()->id()
@@ -476,25 +357,20 @@ bool MasqueServerSession::OnSettingsFrame(const SettingsFrame& frame) {
}
MasqueServerSession::ConnectUdpServerState::ConnectUdpServerState(
- QuicSpdyStream* stream, absl::optional<QuicDatagramContextId> context_id,
- const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
- MasqueServerSession* masque_session)
+ QuicSpdyStream* stream, const QuicSocketAddress& target_server_address,
+ QuicUdpSocketFd fd, MasqueServerSession* masque_session)
: stream_(stream),
- context_id_(context_id),
target_server_address_(target_server_address),
fd_(fd),
masque_session_(masque_session) {
QUICHE_DCHECK_NE(fd_, kQuicInvalidSocketFd);
QUICHE_DCHECK_NE(masque_session_, nullptr);
- this->stream()->RegisterHttp3DatagramRegistrationVisitor(this);
+ this->stream()->RegisterHttp3DatagramVisitor(this);
}
MasqueServerSession::ConnectUdpServerState::~ConnectUdpServerState() {
if (stream() != nullptr) {
- if (context_registered_) {
- stream()->UnregisterHttp3DatagramContextId(context_id());
- }
- stream()->UnregisterHttp3DatagramRegistrationVisitor();
+ stream()->UnregisterHttp3DatagramVisitor();
}
if (fd_ == kQuicInvalidSocketFd) {
return;
@@ -522,107 +398,38 @@ MasqueServerSession::ConnectUdpServerState::operator=(
}
stream_ = other.stream_;
other.stream_ = nullptr;
- context_id_ = other.context_id_;
target_server_address_ = other.target_server_address_;
fd_ = other.fd_;
masque_session_ = other.masque_session_;
other.fd_ = kQuicInvalidSocketFd;
- context_registered_ = other.context_registered_;
- other.context_registered_ = false;
if (stream() != nullptr) {
- stream()->MoveHttp3DatagramRegistration(this);
- if (context_registered_) {
- stream()->MoveHttp3DatagramContextIdRegistration(context_id(), this);
- }
+ stream()->ReplaceHttp3DatagramVisitor(this);
}
return *this;
}
void MasqueServerSession::ConnectUdpServerState::OnHttp3Datagram(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- absl::string_view payload) {
+ QuicStreamId stream_id, absl::string_view payload) {
QUICHE_DCHECK_EQ(stream_id, stream()->id());
- QUICHE_DCHECK(context_id == context_id_);
+ QuicDataReader reader(payload);
+ uint64_t context_id;
+ if (!reader.ReadVarInt62(&context_id)) {
+ QUIC_DLOG(ERROR) << "Failed to read context ID";
+ return;
+ }
+ if (context_id != 0) {
+ QUIC_DLOG(ERROR) << "Ignoring HTTP Datagram with unexpected context ID "
+ << context_id;
+ return;
+ }
+ absl::string_view http_payload = reader.ReadRemainingPayload();
QuicUdpSocketApi socket_api;
QuicUdpPacketInfo packet_info;
packet_info.SetPeerAddress(target_server_address_);
WriteResult write_result = socket_api.WritePacket(
- fd_, payload.data(), payload.length(), packet_info);
- QUIC_DVLOG(1) << "Wrote packet of length " << payload.length() << " to "
+ fd_, http_payload.data(), http_payload.length(), packet_info);
+ QUIC_DVLOG(1) << "Wrote packet of length " << http_payload.length() << " to "
<< target_server_address_ << " with result " << write_result;
}
-void MasqueServerSession::ConnectUdpServerState::OnContextReceived(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type, absl::string_view format_additional_data) {
- if (stream_id != stream()->id()) {
- QUIC_BUG(MASQUE server bad datagram context registration)
- << "Registered stream ID " << stream_id << ", expected "
- << stream()->id();
- return;
- }
- if (format_type != DatagramFormatType::UDP_PAYLOAD) {
- QUIC_DLOG(INFO) << "Ignoring unexpected datagram format type "
- << DatagramFormatTypeToString(format_type);
- return;
- }
- if (!format_additional_data.empty()) {
- QUIC_DLOG(ERROR)
- << "Received non-empty format additional data for context ID "
- << (context_id_.has_value() ? context_id_.value() : 0)
- << " on stream ID " << stream()->id();
- masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
- return;
- }
- if (!context_received_) {
- context_received_ = true;
- context_id_ = context_id;
- }
- if (context_id != context_id_) {
- QUIC_DLOG(INFO)
- << "Ignoring unexpected context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " instead of "
- << (context_id_.has_value() ? absl::StrCat(context_id_.value())
- : "none")
- << " on stream ID " << stream()->id();
- return;
- }
- if (context_registered_) {
- QUIC_BUG(MASQUE server double datagram context registration)
- << "Try to re-register stream ID " << stream_id << " context ID "
- << (context_id_.has_value() ? absl::StrCat(context_id_.value())
- : "none");
- return;
- }
- context_registered_ = true;
- stream()->RegisterHttp3DatagramContextId(context_id_, format_type,
- format_additional_data, this);
-}
-
-void MasqueServerSession::ConnectUdpServerState::OnContextClosed(
- QuicStreamId stream_id, absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code, absl::string_view close_details) {
- if (stream_id != stream()->id()) {
- QUIC_BUG(MASQUE server bad datagram context registration)
- << "Closed context on stream ID " << stream_id << ", expected "
- << stream()->id();
- return;
- }
- if (context_id != context_id_) {
- QUIC_DLOG(INFO)
- << "Ignoring unexpected close of context ID "
- << (context_id.has_value() ? absl::StrCat(context_id.value()) : "none")
- << " instead of "
- << (context_id_.has_value() ? absl::StrCat(context_id_.value())
- : "none")
- << " on stream ID " << stream()->id();
- return;
- }
- QUIC_DLOG(INFO) << "Received datagram context close with close code "
- << close_code << " close details \"" << close_details
- << "\" on stream ID " << stream()->id() << ", closing stream";
- masque_session_->ResetStream(stream()->id(), QUIC_STREAM_CANCELLED);
-}
-
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.h
index 746779e423a..59b33c29b72 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_server_session.h
@@ -7,7 +7,6 @@
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_udp_socket.h"
-#include "quiche/quic/masque/masque_compression_engine.h"
#include "quiche/quic/masque/masque_server_backend.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_epoll.h"
@@ -22,25 +21,10 @@ class QUIC_NO_EXPORT MasqueServerSession
public MasqueServerBackend::BackendClient,
public QuicEpollCallbackInterface {
public:
- // Interface meant to be implemented by owner of this MasqueServerSession
- // instance.
- class QUIC_NO_EXPORT Visitor {
- public:
- virtual ~Visitor() {}
- // Register a client connection ID as being handled by this session.
- virtual void RegisterClientConnectionId(
- QuicConnectionId client_connection_id,
- MasqueServerSession* masque_server_session) = 0;
-
- // Unregister a client connection ID.
- virtual void UnregisterClientConnectionId(
- QuicConnectionId client_connection_id) = 0;
- };
-
explicit MasqueServerSession(
MasqueMode masque_mode, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- QuicConnection* connection, QuicSession::Visitor* visitor, Visitor* owner,
+ QuicConnection* connection, QuicSession::Visitor* visitor,
QuicEpollServer* epoll_server, QuicCryptoServerStreamBase::Helper* helper,
const QuicCryptoServerConfig* crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
@@ -51,7 +35,6 @@ class QUIC_NO_EXPORT MasqueServerSession
MasqueServerSession& operator=(const MasqueServerSession&) = delete;
// From QuicSession.
- void OnMessageReceived(absl::string_view message) override;
void OnMessageAcked(QuicMessageId message_id,
QuicTime receive_timestamp) override;
void OnMessageLost(QuicMessageId message_id) override;
@@ -61,9 +44,7 @@ class QUIC_NO_EXPORT MasqueServerSession
// From MasqueServerBackend::BackendClient.
std::unique_ptr<QuicBackendResponse> HandleMasqueRequest(
- const std::string& masque_path,
const spdy::Http2HeaderBlock& request_headers,
- const std::string& request_body,
QuicSimpleServerBackend::RequestHandler* request_handler) override;
// From QuicEpollCallbackInterface.
@@ -75,24 +56,18 @@ class QUIC_NO_EXPORT MasqueServerSession
void OnShutdown(QuicEpollServer* eps, QuicUdpSocketFd fd) override;
std::string Name() const override;
- // Handle packet for client, meant to be called by MasqueDispatcher.
- void HandlePacketFromServer(const ReceivedPacketInfo& packet_info);
-
QuicEpollServer* epoll_server() const { return epoll_server_; }
private:
// State that the MasqueServerSession keeps for each CONNECT-UDP request.
class QUIC_NO_EXPORT ConnectUdpServerState
- : public QuicSpdyStream::Http3DatagramRegistrationVisitor,
- public QuicSpdyStream::Http3DatagramVisitor {
+ : public QuicSpdyStream::Http3DatagramVisitor {
public:
// ConnectUdpServerState takes ownership of |fd|. It will unregister it
// from |epoll_server| and close the file descriptor when destructed.
explicit ConnectUdpServerState(
- QuicSpdyStream* stream,
- absl::optional<QuicDatagramContextId> context_id,
- const QuicSocketAddress& target_server_address, QuicUdpSocketFd fd,
- MasqueServerSession* masque_session);
+ QuicSpdyStream* stream, const QuicSocketAddress& target_server_address,
+ QuicUdpSocketFd fd, MasqueServerSession* masque_session);
~ConnectUdpServerState();
@@ -103,9 +78,6 @@ class QUIC_NO_EXPORT MasqueServerSession
ConnectUdpServerState& operator=(ConnectUdpServerState&&);
QuicSpdyStream* stream() const { return stream_; }
- absl::optional<QuicDatagramContextId> context_id() const {
- return context_id_;
- }
const QuicSocketAddress& target_server_address() const {
return target_server_address_;
}
@@ -113,39 +85,23 @@ class QUIC_NO_EXPORT MasqueServerSession
// From QuicSpdyStream::Http3DatagramVisitor.
void OnHttp3Datagram(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
absl::string_view payload) override;
- // From QuicSpdyStream::Http3DatagramRegistrationVisitor.
- void OnContextReceived(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type,
- absl::string_view format_additional_data) override;
- void OnContextClosed(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code,
- absl::string_view close_details) override;
-
private:
QuicSpdyStream* stream_;
- absl::optional<QuicDatagramContextId> context_id_;
QuicSocketAddress target_server_address_;
QuicUdpSocketFd fd_; // Owned.
MasqueServerSession* masque_session_; // Unowned.
- bool context_received_ = false;
- bool context_registered_ = false;
};
// From QuicSpdySession.
bool OnSettingsFrame(const SettingsFrame& frame) override;
HttpDatagramSupport LocalHttpDatagramSupport() override {
- return HttpDatagramSupport::kDraft00And04;
+ return HttpDatagramSupport::kDraft09;
}
MasqueServerBackend* masque_server_backend_; // Unowned.
- Visitor* owner_; // Unowned.
QuicEpollServer* epoll_server_; // Unowned.
- MasqueCompressionEngine compression_engine_;
MasqueMode masque_mode_;
std::list<ConnectUdpServerState> connect_udp_server_states_;
bool masque_initialized_ = false;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.cc
index b440bd1e9de..d09fc497575 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.cc
@@ -30,8 +30,6 @@ std::string MasqueModeToString(MasqueMode masque_mode) {
switch (masque_mode) {
case MasqueMode::kInvalid:
return "Invalid";
- case MasqueMode::kLegacy:
- return "Legacy";
case MasqueMode::kOpen:
return "Open";
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.h
index 652bf358764..12faae0087c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/masque/masque_utils.h
@@ -26,10 +26,6 @@ enum : QuicByteCount {
// Mode that MASQUE is operating in.
enum class MasqueMode : uint8_t {
kInvalid = 0, // Should never be used.
- kLegacy = 1, // Legacy mode uses the legacy MASQUE protocol as documented in
- // <https://tools.ietf.org/html/draft-schinazi-masque-protocol>. That version
- // of MASQUE uses a custom application-protocol over HTTP/3, and also allows
- // unauthenticated clients.
kOpen = 2, // Open mode uses the MASQUE HTTP CONNECT-UDP method as documented
// in <https://tools.ietf.org/html/draft-ietf-masque-connect-udp>. This mode
// allows unauthenticated clients (a more restricted mode will be added to
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_containers.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_containers.h
deleted file mode 100644
index 9420393edf7..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_containers.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
-
-#include "quiche/common/platform/api/quiche_containers.h"
-
-namespace quic {
-
-// An ordered container optimized for small sets.
-// An implementation with O(n) mutations might be chosen
-// in case it has better memory usage and/or faster access.
-//
-// DOES NOT GUARANTEE POINTER OR ITERATOR STABILITY!
-template <typename Key, typename Compare = std::less<Key>>
-using QuicSmallOrderedSet = ::quiche::QuicheSmallOrderedSet<Key, Compare>;
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_CONTAINERS_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h
index b4f82aa15f4..5edb835799d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h
@@ -5,17 +5,17 @@
#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
#define QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
-#include "quiche_platform_impl/quiche_export_impl.h"
+#include "quiche/common/platform/api/quiche_export.h"
// QUIC_EXPORT is not meant to be used.
-#define QUIC_EXPORT QUICHE_EXPORT_IMPL
+#define QUIC_EXPORT QUICHE_EXPORT
// QUIC_EXPORT_PRIVATE is meant for QUIC functionality that is built in Chromium
// as part of //net, and not fully contained in headers.
-#define QUIC_EXPORT_PRIVATE QUICHE_EXPORT_PRIVATE_IMPL
+#define QUIC_EXPORT_PRIVATE QUICHE_EXPORT_PRIVATE
// QUIC_NO_EXPORT is meant for QUIC functionality that is either fully defined
// in a header, or is built in Chromium as part of tests or tools.
-#define QUIC_NO_EXPORT QUICHE_NO_EXPORT_IMPL
+#define QUIC_NO_EXPORT QUICHE_NO_EXPORT
#endif // QUICHE_QUIC_PLATFORM_API_QUIC_EXPORT_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h
index c25f160b497..3b36c8fafb0 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "quiche_platform_impl/quic_flags_impl.h"
#include "quiche/common/platform/api/quiche_flags.h"
#define GetQuicReloadableFlag(flag) GetQuicheReloadableFlag(quic, flag)
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_ip_address.cc b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_ip_address.cc
index 2dc20717f46..d8412c5e3d6 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_ip_address.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_ip_address.cc
@@ -91,17 +91,13 @@ bool operator==(QuicIpAddress lhs, QuicIpAddress rhs) {
return false;
}
-bool operator!=(QuicIpAddress lhs, QuicIpAddress rhs) {
- return !(lhs == rhs);
-}
+bool operator!=(QuicIpAddress lhs, QuicIpAddress rhs) { return !(lhs == rhs); }
bool QuicIpAddress::IsInitialized() const {
return family_ != IpAddressFamily::IP_UNSPEC;
}
-IpAddressFamily QuicIpAddress::address_family() const {
- return family_;
-}
+IpAddressFamily QuicIpAddress::address_family() const { return family_; }
int QuicIpAddress::AddressFamilyToInt() const {
return ToPlatformAddressFamily(family_);
@@ -193,13 +189,9 @@ bool QuicIpAddress::FromString(std::string str) {
return false;
}
-bool QuicIpAddress::IsIPv4() const {
- return family_ == IpAddressFamily::IP_V4;
-}
+bool QuicIpAddress::IsIPv4() const { return family_ == IpAddressFamily::IP_V4; }
-bool QuicIpAddress::IsIPv6() const {
- return family_ == IpAddressFamily::IP_V6;
-}
+bool QuicIpAddress::IsIPv6() const { return family_ == IpAddressFamily::IP_V6; }
bool QuicIpAddress::InSameSubnet(const QuicIpAddress& other,
int subnet_length) {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_logging.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_logging.h
index 442e39c57a9..c44e53f54a4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_logging.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_logging.h
@@ -22,12 +22,6 @@
#define QUIC_LOG_EVERY_N_SEC QUICHE_LOG_EVERY_N_SEC
#define QUIC_LOG_IF QUICHE_LOG_IF
-#define QUIC_PREDICT_FALSE QUICHE_PREDICT_FALSE
-#define QUIC_PREDICT_TRUE QUICHE_PREDICT_TRUE
-
-// This is a noop in release build.
-#define QUIC_NOTREACHED QUICHE_NOTREACHED
-
#define QUIC_PLOG QUICHE_PLOG
#define QUIC_DLOG_INFO_IS_ON QUICHE_DLOG_INFO_IS_ON
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_mock_log.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_mock_log.h
deleted file mode 100644
index 0402f10213d..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_mock_log.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
-
-#include "quiche/common/platform/api/quiche_mock_log.h"
-
-using QuicMockLog = QuicheMockLogImpl;
-
-#define CREATE_QUIC_MOCK_LOG(log) CREATE_QUICHE_MOCK_LOG(log)
-
-#define EXPECT_QUIC_LOG_CALL(log) EXPECT_QUICHE_LOG_CALL(log)
-
-#define EXPECT_QUIC_LOG_CALL_CONTAINS(log, level, content) \
- EXPECT_QUICHE_LOG_CALL_CONTAINS(log, level, content)
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_MOCK_LOG_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc
index 0a35e8661e0..f14faea0f5a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc
@@ -81,9 +81,7 @@ bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
return !(lhs == rhs);
}
-bool QuicSocketAddress::IsInitialized() const {
- return host_.IsInitialized();
-}
+bool QuicSocketAddress::IsInitialized() const { return host_.IsInitialized(); }
std::string QuicSocketAddress::ToString() const {
switch (host_.address_family()) {
@@ -114,13 +112,9 @@ QuicSocketAddress QuicSocketAddress::Normalized() const {
return QuicSocketAddress(host_.Normalized(), port_);
}
-QuicIpAddress QuicSocketAddress::host() const {
- return host_;
-}
+QuicIpAddress QuicSocketAddress::host() const { return host_; }
-uint16_t QuicSocketAddress::port() const {
- return port_;
-}
+uint16_t QuicSocketAddress::port() const { return port_; }
sockaddr_storage QuicSocketAddress::generic_address() const {
union {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_stream_buffer_allocator.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_stream_buffer_allocator.h
deleted file mode 100644
index 174e8783645..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_stream_buffer_allocator.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
-#define QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
-
-#include "quiche/common/platform/api/quiche_stream_buffer_allocator.h"
-
-namespace quic {
-
-using QuicStreamBufferAllocator = quiche::QuicheStreamBufferAllocator;
-}
-
-#endif // QUICHE_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h
index 9e63acca3c6..0d1d2b0b166 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h
@@ -8,22 +8,19 @@
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/common/platform/api/quiche_test.h"
-using QuicFlagSaver = QuicheFlagSaver;
+namespace quic::test {
+
+using QuicFlagSaver = quiche::test::QuicheFlagSaver;
// Defines the base classes to be used in QUIC tests.
-using QuicTest = QuicheTest;
+using QuicTest = quiche::test::QuicheTest;
template <class T>
-using QuicTestWithParam = QuicheTestWithParam<T>;
+using QuicTestWithParam = quiche::test::QuicheTestWithParam<T>;
-// Class which needs to be instantiated in tests which use threads.
-using ScopedEnvironmentForThreads = ScopedEnvironmentForThreadsImpl;
+} // namespace quic::test
#define QUIC_TEST_DISABLED_IN_CHROME(name) QUICHE_TEST_DISABLED_IN_CHROME(name)
-inline std::string QuicGetTestMemoryCachePath() {
- return QuicheGetTestMemoryCachePath();
-}
-
#define QUIC_SLOW_TEST(test) QUICHE_SLOW_TEST(test)
#endif // QUICHE_QUIC_PLATFORM_API_QUIC_TEST_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_udp_socket_platform_api.h b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_udp_socket_platform_api.h
index d6009d92530..16b1025e39d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_udp_socket_platform_api.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/platform/api/quic_udp_socket_platform_api.h
@@ -13,9 +13,7 @@ const size_t kCmsgSpaceForGooglePacketHeader =
quiche::kCmsgSpaceForGooglePacketHeader;
inline bool GetGooglePacketHeadersFromControlMessage(
- struct ::cmsghdr* cmsg,
- char** packet_headers,
- size_t* packet_headers_len) {
+ struct ::cmsghdr* cmsg, char** packet_headers, size_t* packet_headers_len) {
return quiche::GetGooglePacketHeadersFromControlMessage(cmsg, packet_headers,
packet_headers_len);
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/icmp_reachable_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/icmp_reachable_test.cc
index ffb1092ed30..7a0ebe644de 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/icmp_reachable_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/icmp_reachable_test.cc
@@ -7,13 +7,12 @@
#include <netinet/ip6.h>
#include "absl/container/node_hash_map.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_epoll.h"
#include "quiche/quic/platform/api/quic_ip_address.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/platform/mock_kernel.h"
-namespace quic {
+namespace quic::test {
namespace {
using ::testing::_;
@@ -264,4 +263,4 @@ TEST_F(IcmpReachableTest, HandlesReadErrors) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h
index 207ae299fec..409bc476420 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h
@@ -36,6 +36,8 @@ class MockQboneTunnel : public QboneTunnelInterface {
MOCK_METHOD(State, state, ());
MOCK_METHOD(std::string, HealthString, ());
+
+ MOCK_METHOD(std::string, ServerRegionString, ());
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h
index deb3b37dfe9..c4bd7b4bfa4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h
@@ -61,6 +61,8 @@ class QboneTunnelInterface : public quic::QboneClientControlStream::Handler {
virtual State state() = 0;
virtual std::string HealthString() = 0;
+
+ virtual std::string ServerRegionString() = 0;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_controller_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_controller_test.cc
index 65daa157c84..62cb8630b59 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_controller_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_controller_test.cc
@@ -14,7 +14,7 @@
ABSL_DECLARE_FLAG(bool, qbone_tun_device_replace_default_routing_rules);
-namespace quic {
+namespace quic::test {
namespace {
using ::testing::Eq;
@@ -255,4 +255,4 @@ TEST_F(DisabledTunDeviceControllerTest, UpdateAddressIsNop) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
index f7bf062324a..a6d3a39bfcf 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
@@ -9,7 +9,7 @@
#include "quiche/quic/qbone/mock_qbone_client.h"
#include "quiche/quic/qbone/platform/mock_kernel.h"
-namespace quic {
+namespace quic::test {
namespace {
const size_t kMtu = 1000;
@@ -116,4 +116,4 @@ TEST_F(TunDevicePacketExchangerTest,
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_test.cc
index 4af7b20c59a..cc82a2f5ba5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/bonnet/tun_device_test.cc
@@ -11,7 +11,7 @@
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/platform/mock_kernel.h"
-namespace quic {
+namespace quic::test {
namespace {
using ::testing::_;
@@ -208,4 +208,4 @@ TEST_F(TunDeviceTest, FailToUp) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/internet_checksum.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/internet_checksum.cc
index e819f37ca9d..f9901e5c8ec 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/internet_checksum.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/internet_checksum.cc
@@ -4,15 +4,20 @@
#include "quiche/quic/qbone/platform/internet_checksum.h"
+#include <stdint.h>
+#include <string.h>
+
namespace quic {
void InternetChecksum::Update(const char* data, size_t size) {
const char* current;
for (current = data; current + 1 < data + size; current += 2) {
- accumulator_ += *reinterpret_cast<const uint16_t*>(current);
+ uint16_t v;
+ memcpy(&v, current, sizeof(v));
+ accumulator_ += v;
}
if (current < data + size) {
- accumulator_ += *reinterpret_cast<const uint8_t*>(current);
+ accumulator_ += *reinterpret_cast<const unsigned char*>(current);
}
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_test.cc
index a858eaf4979..9bd91b07d13 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/netlink_test.cc
@@ -8,12 +8,11 @@
#include "absl/container/node_hash_set.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/platform/mock_kernel.h"
#include "quiche/quic/qbone/qbone_constants.h"
-namespace quic {
+namespace quic::test {
namespace {
using ::testing::_;
@@ -762,4 +761,4 @@ TEST_F(NetlinkTest, ChangeRouteReplace) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/tcp_packet.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/tcp_packet.cc
index 8bc8cb7f4a6..e73e284a010 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/tcp_packet.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/platform/tcp_packet.cc
@@ -6,6 +6,7 @@
#include <netinet/ip6.h>
+#include "absl/base/optimization.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/qbone/platform/internet_checksum.h"
@@ -35,17 +36,17 @@ void CreateTcpResetPacket(absl::string_view original_packet,
// By the time this method is called, original_packet should be fairly
// strongly validated. However, it's better to be more paranoid than not, so
// here are a bunch of very obvious checks.
- if (QUIC_PREDICT_FALSE(original_packet.size() < sizeof(ip6_hdr))) {
+ if (ABSL_PREDICT_FALSE(original_packet.size() < sizeof(ip6_hdr))) {
return;
}
auto* ip6_header = reinterpret_cast<const ip6_hdr*>(original_packet.data());
- if (QUIC_PREDICT_FALSE(ip6_header->ip6_vfc >> 4 != 6)) {
+ if (ABSL_PREDICT_FALSE(ip6_header->ip6_vfc >> 4 != 6)) {
return;
}
- if (QUIC_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
+ if (ABSL_PREDICT_FALSE(ip6_header->ip6_nxt != IPPROTO_TCP)) {
return;
}
- if (QUIC_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
+ if (ABSL_PREDICT_FALSE(quiche::QuicheEndian::NetToHost16(
ip6_header->ip6_plen) < sizeof(tcphdr))) {
return;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_session.cc
index 4c22d235b6a..cfc6001abd4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_session.cc
@@ -58,7 +58,8 @@ void QboneClientSession::Initialize() {
QboneSessionBase::Initialize();
static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
->CryptoConnect();
- if (!GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation)) {
+ if (!quiche::GetQuicheCommandLineFlag(
+ FLAGS_qbone_client_defer_control_stream_creation)) {
CreateControlStream();
}
}
@@ -66,7 +67,8 @@ void QboneClientSession::Initialize() {
void QboneClientSession::SetDefaultEncryptionLevel(
quic::EncryptionLevel level) {
QboneSessionBase::SetDefaultEncryptionLevel(level);
- if (GetQuicFlag(FLAGS_qbone_client_defer_control_stream_creation) &&
+ if (quiche::GetQuicheCommandLineFlag(
+ FLAGS_qbone_client_defer_control_stream_creation) &&
level == quic::ENCRYPTION_FORWARD_SECURE) {
CreateControlStream();
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_test.cc
index f796c461405..5fd7229ba91 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_client_test.cc
@@ -32,6 +32,8 @@ namespace quic {
namespace test {
namespace {
+using ::testing::ElementsAre;
+
ParsedQuicVersionVector GetTestParams() {
ParsedQuicVersionVector test_versions;
@@ -206,9 +208,11 @@ INSTANTIATE_TEST_SUITE_P(Tests, QboneClientTest,
::testing::PrintToStringParamName());
TEST_P(QboneClientTest, SendDataFromClient) {
- auto server = new QboneTestServer(crypto_test_utils::ProofSourceForTesting());
+ auto server = std::make_unique<QboneTestServer>(
+ crypto_test_utils::ProofSourceForTesting());
+ QboneTestServer* server_ptr = server.get();
QuicSocketAddress server_address(TestLoopback(), 0);
- ServerThread server_thread(server, server_address);
+ ServerThread server_thread(std::move(server), server_address);
server_thread.Initialize();
server_address =
QuicSocketAddress(server_address.host(), server_thread.GetPort());
@@ -229,29 +233,27 @@ TEST_P(QboneClientTest, SendDataFromClient) {
// Wait until the server has received at least two packets, timeout after 5s.
ASSERT_TRUE(
- server_thread.WaitUntil([&] { return server->data().size() >= 2; },
+ server_thread.WaitUntil([&] { return server_ptr->data().size() >= 2; },
QuicTime::Delta::FromSeconds(5)));
- std::string long_data(
- QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
-
// Pretend the server gets data.
- server_thread.Schedule([&server, &long_data]() {
- EXPECT_THAT(server->data()[0], testing::Eq(TestPacketOut("hello")));
- EXPECT_THAT(server->data()[1], testing::Eq(TestPacketOut("world")));
+ std::string long_data(1000, 'A');
+ server_thread.Schedule([server_ptr, &long_data]() {
+ EXPECT_THAT(server_ptr->data(),
+ ElementsAre(TestPacketOut("hello"), TestPacketOut("world")));
auto server_session = static_cast<QboneServerSession*>(
QuicDispatcherPeer::GetFirstSessionIfAny(
- QuicServerPeer::GetDispatcher(server)));
+ QuicServerPeer::GetDispatcher(server_ptr)));
server_session->ProcessPacketFromNetwork(
TestPacketIn("Somethingsomething"));
server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
server_session->ProcessPacketFromNetwork(TestPacketIn(long_data));
});
- ASSERT_TRUE(client.WaitForDataSize(3, QuicTime::Delta::FromSeconds(5)));
- EXPECT_THAT(client.data()[0],
- testing::Eq(TestPacketOut("Somethingsomething")));
- EXPECT_THAT(client.data()[1], testing::Eq(TestPacketOut(long_data)));
- EXPECT_THAT(client.data()[2], testing::Eq(TestPacketOut(long_data)));
+
+ EXPECT_TRUE(client.WaitForDataSize(3, QuicTime::Delta::FromSeconds(5)));
+ EXPECT_THAT(client.data(),
+ ElementsAre(TestPacketOut("Somethingsomething"),
+ TestPacketOut(long_data), TestPacketOut(long_data)));
client.Disconnect();
server_thread.Quit();
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor.cc
index cad6cff1b37..abf77d5a663 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor.cc
@@ -6,6 +6,7 @@
#include <cstring>
+#include "absl/base/optimization.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_ip_address_family.h"
@@ -62,7 +63,7 @@ QbonePacketProcessor::Filter::FilterPacket(Direction direction,
void QbonePacketProcessor::ProcessPacket(std::string* packet,
Direction direction) {
- if (QUIC_PREDICT_FALSE(!IsValid())) {
+ if (ABSL_PREDICT_FALSE(!IsValid())) {
QUIC_BUG(quic_bug_11024_1)
<< "QuicPacketProcessor is invoked in an invalid state.";
stats_->OnPacketDroppedSilently(direction);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor_test.cc
index ed3b45c61a7..e11fd5cea58 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_packet_processor_test.cc
@@ -10,7 +10,7 @@
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/qbone_packet_processor_test_tools.h"
-namespace quic {
+namespace quic::test {
namespace {
using Direction = QbonePacketProcessor::Direction;
@@ -277,4 +277,4 @@ TEST_F(QbonePacketProcessorTest, FilterHelperFunctions) {
}
} // namespace
-} // namespace quic
+} // namespace quic::test
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_server_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_server_session.cc
index 6f189e723bb..c6d622f2ee5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_server_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_server_session.cc
@@ -79,7 +79,8 @@ QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
void QboneServerSession::Initialize() {
QboneSessionBase::Initialize();
- if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
+ if (!quiche::GetQuicheCommandLineFlag(
+ FLAGS_qbone_server_defer_control_stream_creation)) {
CreateControlStream();
}
}
@@ -87,7 +88,8 @@ void QboneServerSession::Initialize() {
void QboneServerSession::SetDefaultEncryptionLevel(
quic::EncryptionLevel level) {
QboneSessionBase::SetDefaultEncryptionLevel(level);
- if (GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation) &&
+ if (quiche::GetQuicheCommandLineFlag(
+ FLAGS_qbone_server_defer_control_stream_creation) &&
level == quic::ENCRYPTION_FORWARD_SECURE) {
CreateControlStream();
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.cc
index 95bd7c7da61..36517b75f5c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.cc
@@ -18,6 +18,7 @@
#include "quiche/quic/qbone/platform/icmp_packet.h"
#include "quiche/quic/qbone/qbone_constants.h"
#include "quiche/common/platform/api/quiche_command_line_flags.h"
+#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
#include "quiche/common/quiche_buffer_allocator.h"
@@ -74,7 +75,7 @@ void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) {
flow_controller()->AddBytesConsumed(frame.data_length);
// TODO(b/147817422): Add a counter for how many streams were actually
// closed here.
- if (GetQuicFlag(FLAGS_qbone_close_ephemeral_frames)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_qbone_close_ephemeral_frames)) {
ResetStream(frame.stream_id, QUIC_STREAM_CANCELLED);
}
return;
@@ -92,7 +93,7 @@ QuicStream* QboneSessionBase::CreateIncomingStream(QuicStreamId id) {
}
QuicStream* QboneSessionBase::CreateIncomingStream(PendingStream* /*pending*/) {
- QUIC_NOTREACHED();
+ QUICHE_NOTREACHED();
return nullptr;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.h b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.h
index b1278bd39a9..e643f0d942b 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_session_base.h
@@ -10,7 +10,6 @@
#include "quiche/quic/core/quic_crypto_stream.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_session.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/qbone/qbone_packet_writer.h"
#include "quiche/quic/qbone/qbone_stream.h"
@@ -89,10 +88,9 @@ class QUIC_EXPORT_PRIVATE QboneSessionBase : public QuicSession {
QbonePacketWriter* writer_;
- // If true, MESSAGE frames are used for short datagrams. If false, ephemeral
- // streams are used instead. Note that receiving MESSAGE frames is always
- // supported.
- bool send_packets_as_messages_ = false;
+ // If true, send QUIC DATAGRAM (aka MESSAGE) frames instead of ephemeral
+ // streams. Note that receiving DATAGRAM frames is always supported.
+ bool send_packets_as_messages_ = true;
private:
// Used for the crypto handshake.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_stream.cc
index 3ee8634908b..6465d5953ce 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/qbone/qbone_stream.cc
@@ -22,8 +22,8 @@ QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id,
: QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL) {
// QBONE uses a LIFO queue to try to always make progress. An individual
// packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
- MaybeSetTtl(
- QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
+ MaybeSetTtl(QuicTime::Delta::FromSeconds(
+ quiche::GetQuicheCommandLineFlag(FLAGS_qbone_stream_ttl_secs)));
}
void QboneWriteOnlyStream::WritePacketToQuicStream(absl::string_view packet) {
@@ -39,8 +39,8 @@ QboneReadOnlyStream::QboneReadOnlyStream(QuicStreamId id,
session_(session) {
// QBONE uses a LIFO queue to try to always make progress. An individual
// packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
- MaybeSetTtl(
- QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
+ MaybeSetTtl(QuicTime::Delta::FromSeconds(
+ quiche::GetQuicheCommandLineFlag(FLAGS_qbone_stream_ttl_secs)));
}
void QboneReadOnlyStream::OnDataAvailable() {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.cc
index e2f5c8c432f..4df4f8f3cb2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.cc
@@ -10,14 +10,19 @@
#include <utility>
#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#include "openssl/bn.h"
#include "openssl/ec.h"
#include "openssl/ecdsa.h"
#include "openssl/nid.h"
#include "openssl/sha.h"
+#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/channel_id.h"
#include "quiche/quic/core/crypto/crypto_handshake.h"
+#include "quiche/quic/core/crypto/crypto_utils.h"
+#include "quiche/quic/core/crypto/proof_source_x509.h"
#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
#include "quiche/quic/core/crypto/quic_decrypter.h"
#include "quiche/quic/core/crypto/quic_encrypter.h"
@@ -28,9 +33,11 @@
#include "quiche/quic/core/quic_crypto_server_stream_base.h"
#include "quiche/quic/core/quic_crypto_stream.h"
#include "quiche/quic/core/quic_server_id.h"
+#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
+#include "quiche/quic/platform/api/quic_hostname_utils.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_test.h"
@@ -39,6 +46,7 @@
#include "quiche/quic/test_tools/quic_stream_peer.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/quic/test_tools/simple_quic_framer.h"
+#include "quiche/quic/test_tools/test_certificates.h"
#include "quiche/common/test_tools/quiche_test_utils.h"
namespace quic {
@@ -376,7 +384,7 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
<< client_conn->encrypted_packets_.size() - client_i
<< " packets client->server";
MovePackets(client_conn, &client_i, server, server_conn,
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, /*process_stream_data=*/false);
if (client->one_rtt_keys_available() && server->one_rtt_keys_available() &&
server_conn->encrypted_packets_.size() == server_i) {
@@ -387,7 +395,7 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
<< server_conn->encrypted_packets_.size() - server_i
<< " packets server->client";
MovePackets(server_conn, &server_i, client, client_conn,
- Perspective::IS_CLIENT);
+ Perspective::IS_CLIENT, /*process_stream_data=*/false);
}
}
@@ -396,7 +404,8 @@ bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
std::function<bool()> client_condition,
PacketSavingConnection* server_conn,
QuicCryptoStream* server,
- std::function<bool()> server_condition) {
+ std::function<bool()> server_condition,
+ bool process_stream_data) {
size_t client_next_packet_to_deliver =
client_conn->number_of_packets_delivered_;
size_t server_next_packet_to_deliver =
@@ -413,7 +422,7 @@ bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
client_next_packet_to_deliver
<< " packets client->server";
MovePackets(client_conn, &client_next_packet_to_deliver, server,
- server_conn, Perspective::IS_SERVER);
+ server_conn, Perspective::IS_SERVER, process_stream_data);
}
if (!client_condition()) {
QUIC_LOG(INFO) << "Processing "
@@ -421,7 +430,7 @@ bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
server_next_packet_to_deliver
<< " packets server->client";
MovePackets(server_conn, &server_next_packet_to_deliver, client,
- client_conn, Perspective::IS_CLIENT);
+ client_conn, Perspective::IS_CLIENT, process_stream_data);
}
}
client_conn->number_of_packets_delivered_ = client_next_packet_to_deliver;
@@ -449,7 +458,7 @@ std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
<< client_conn->encrypted_packets_.size() - client_i
<< " packets client->server";
MovePackets(client_conn, &client_i, server, server_conn,
- Perspective::IS_SERVER);
+ Perspective::IS_SERVER, /*process_stream_data=*/false);
}
if (server_conn->encrypted_packets_.size() != server_i) {
@@ -457,7 +466,7 @@ std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
<< server_conn->encrypted_packets_.size() - server_i
<< " packets server->client";
MovePackets(server_conn, &server_i, client, client_conn,
- Perspective::IS_CLIENT);
+ Perspective::IS_CLIENT, /*process_stream_data=*/false);
}
return std::make_pair(client_i, server_i);
@@ -701,7 +710,7 @@ CryptoHandshakeMessage CreateCHLO(
void MovePackets(PacketSavingConnection* source_conn,
size_t* inout_packet_index, QuicCryptoStream* dest_stream,
PacketSavingConnection* dest_conn,
- Perspective dest_perspective) {
+ Perspective dest_perspective, bool process_stream_data) {
SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
QuicFramerPeer::SetLastSerializedServerConnectionId(framer.framer(),
TestConnectionId());
@@ -771,10 +780,17 @@ void MovePackets(PacketSavingConnection* source_conn,
QuicConnectionPeer::SetCurrentPacket(
dest_conn, source_conn->encrypted_packets_[index]->AsStringPiece());
for (const auto& stream_frame : framer.stream_frames()) {
- // Ignore stream frames that are sent on other streams in the crypto
- // event.
- if (stream_frame->stream_id == dest_stream->id()) {
- dest_stream->OnStreamFrame(*stream_frame);
+ if (process_stream_data &&
+ dest_stream->handshake_protocol() == PROTOCOL_TLS1_3) {
+ // Deliver STREAM_FRAME such that application state is available and can
+ // be stored along with resumption ticket in session cache,
+ dest_conn->OnStreamFrame(*stream_frame);
+ } else {
+ // Ignore stream frames that are sent on other streams in the crypto
+ // event.
+ if (stream_frame->stream_id == dest_stream->id()) {
+ dest_stream->OnStreamFrame(*stream_frame);
+ }
}
}
for (const auto& crypto_frame : framer.crypto_frames()) {
@@ -852,6 +868,112 @@ void GenerateFullCHLO(
signed_config, generator.GetValidateClientHelloCallback());
}
+namespace {
+
+constexpr char kTestProofHostname[] = "test.example.com";
+
+class TestProofSource : public ProofSourceX509 {
+ public:
+ TestProofSource()
+ : ProofSourceX509(
+ quiche::QuicheReferenceCountedPointer<ProofSource::Chain>(
+ new ProofSource::Chain(
+ std::vector<std::string>{std::string(kTestCertificate)})),
+ std::move(*CertificatePrivateKey::LoadFromDer(
+ kTestCertificatePrivateKey))) {
+ QUICHE_DCHECK(valid());
+ }
+
+ protected:
+ void MaybeAddSctsForHostname(absl::string_view /*hostname*/,
+ std::string& leaf_cert_scts) override {
+ leaf_cert_scts = "Certificate Transparency is really nice";
+ }
+};
+
+class TestProofVerifier : public ProofVerifier {
+ public:
+ TestProofVerifier()
+ : certificate_(std::move(
+ *CertificateView::ParseSingleCertificate(kTestCertificate))) {}
+
+ class Details : public ProofVerifyDetails {
+ public:
+ ProofVerifyDetails* Clone() const override { return new Details(*this); }
+ };
+
+ QuicAsyncStatus VerifyProof(
+ const std::string& hostname, const uint16_t port,
+ const std::string& server_config,
+ QuicTransportVersion /*transport_version*/, absl::string_view chlo_hash,
+ const std::vector<std::string>& certs, const std::string& cert_sct,
+ const std::string& signature, const ProofVerifyContext* context,
+ std::string* error_details, std::unique_ptr<ProofVerifyDetails>* details,
+ std::unique_ptr<ProofVerifierCallback> callback) override {
+ absl::optional<std::string> payload =
+ CryptoUtils::GenerateProofPayloadToBeSigned(chlo_hash, server_config);
+ if (!payload.has_value()) {
+ *error_details = "Failed to serialize signed payload";
+ return QUIC_FAILURE;
+ }
+ if (!certificate_.VerifySignature(*payload, signature,
+ SSL_SIGN_RSA_PSS_RSAE_SHA256)) {
+ *error_details = "Invalid signature";
+ return QUIC_FAILURE;
+ }
+
+ uint8_t out_alert;
+ return VerifyCertChain(hostname, port, certs, /*ocsp_response=*/"",
+ cert_sct, context, error_details, details,
+ &out_alert, std::move(callback));
+ }
+
+ QuicAsyncStatus VerifyCertChain(
+ const std::string& hostname, const uint16_t /*port*/,
+ const std::vector<std::string>& certs,
+ const std::string& /*ocsp_response*/, const std::string& /*cert_sct*/,
+ const ProofVerifyContext* /*context*/, std::string* error_details,
+ std::unique_ptr<ProofVerifyDetails>* details, uint8_t* /*out_alert*/,
+ std::unique_ptr<ProofVerifierCallback> /*callback*/) override {
+ std::string normalized_hostname =
+ QuicHostnameUtils::NormalizeHostname(hostname);
+ if (normalized_hostname != kTestProofHostname) {
+ *error_details = absl::StrCat("Invalid hostname, expected ",
+ kTestProofHostname, " got ", hostname);
+ return QUIC_FAILURE;
+ }
+ if (certs.empty() || certs.front() != kTestCertificate) {
+ *error_details = "Received certificate different from the expected";
+ return QUIC_FAILURE;
+ }
+ *details = std::make_unique<Details>();
+ return QUIC_SUCCESS;
+ }
+
+ std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
+ return nullptr;
+ }
+
+ private:
+ CertificateView certificate_;
+};
+
+} // namespace
+
+std::unique_ptr<ProofSource> ProofSourceForTesting() {
+ return std::make_unique<TestProofSource>();
+}
+
+std::unique_ptr<ProofVerifier> ProofVerifierForTesting() {
+ return std::make_unique<TestProofVerifier>();
+}
+
+std::string CertificateHostnameForTesting() { return kTestProofHostname; }
+
+std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting() {
+ return nullptr;
+}
+
} // namespace crypto_test_utils
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h
index a1cd35e244d..d21e8978b4b 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h
@@ -109,15 +109,18 @@ void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
// CommunicateHandshakeMessagesUntil:
// 1) Moves messages from |client| to |server| until |server_condition| is met.
// 2) Moves messages from |server| to |client| until |client_condition| is met.
-// 3) Returns true if both conditions are met.
-// 4) Returns false if either connection is closed or there is no more packet to
+// 3) For IETF QUIC, if `process_stream_data` is true, STREAM_FRAME within the
+// packet containing crypto messages is also processed.
+// 4) Returns true if both conditions are met.
+// 5) Returns false if either connection is closed or there is no more packet to
// deliver before both conditions are met.
bool CommunicateHandshakeMessagesUntil(PacketSavingConnection* client_conn,
QuicCryptoStream* client,
std::function<bool()> client_condition,
PacketSavingConnection* server_conn,
QuicCryptoStream* server,
- std::function<bool()> server_condition);
+ std::function<bool()> server_condition,
+ bool process_stream_data);
// AdvanceHandshake attempts to moves messages from |client| to |server| and
// |server| to |client|. Returns the number of messages moved.
@@ -137,6 +140,9 @@ std::unique_ptr<ProofSource> ProofSourceForTesting();
// Returns a new |ProofVerifier| that uses the QUIC testing root CA.
std::unique_ptr<ProofVerifier> ProofVerifierForTesting();
+// Returns the hostname used by the proof source and the proof verifier above.
+std::string CertificateHostnameForTesting();
+
// Returns a hash of the leaf test certificate.
uint64_t LeafCertHashForTesting();
@@ -173,11 +179,13 @@ CryptoHandshakeMessage CreateCHLO(
// MovePackets parses crypto handshake messages from packet number
// |*inout_packet_index| through to the last packet (or until a packet fails
// to decrypt) and has |dest_stream| process them. |*inout_packet_index| is
-// updated with an index one greater than the last packet processed.
+// updated with an index one greater than the last packet processed. For IETF
+// QUIC, if `process_stream_data` is true, STREAM_FRAME within the packet
+// containing crypto messages is also processed.
void MovePackets(PacketSavingConnection* source_conn,
size_t* inout_packet_index, QuicCryptoStream* dest_stream,
PacketSavingConnection* dest_conn,
- Perspective dest_perspective);
+ Perspective dest_perspective, bool process_stream_data);
// Return an inchoate CHLO with some basic tag value pairs.
CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.cc
index 03b65005d71..69aae1456f2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.cc
@@ -4,7 +4,6 @@
#include "quiche/quic/test_tools/packet_dropping_test_writer.h"
-#include "quiche/quic/core/quic_epoll_connection_helper.h"
#include "quiche/quic/platform/api/quic_logging.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.h
index 0cc684e7f6b..a7e91d3465c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/packet_dropping_test_writer.h
@@ -11,9 +11,11 @@
#include "absl/base/attributes.h"
#include "quiche/quic/core/quic_alarm.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_clock.h"
+#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_packet_writer_wrapper.h"
-#include "quiche/quic/test_tools/quic_test_client.h"
+#include "quiche/quic/platform/api/quic_mutex.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.cc
index e124580ebd2..e38bfc3980f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.cc
@@ -60,10 +60,28 @@ QuicTime::Delta QuicConnectionPeer::GetHandshakeTimeout(
}
// static
+QuicTime::Delta QuicConnectionPeer::GetBandwidthUpdateTimeout(
+ QuicConnection* connection) {
+ return connection->idle_network_detector_.bandwidth_update_timeout_;
+}
+
+// static
+void QuicConnectionPeer::DisableBandwidthUpdate(QuicConnection* connection) {
+ if (connection->idle_network_detector_.bandwidth_update_timeout_
+ .IsInfinite()) {
+ return;
+ }
+ connection->idle_network_detector_.bandwidth_update_timeout_ =
+ QuicTime::Delta::Infinite();
+ connection->idle_network_detector_.SetAlarm();
+}
+
+// static
void QuicConnectionPeer::SetPerspective(QuicConnection* connection,
Perspective perspective) {
connection->perspective_ = perspective;
QuicFramerPeer::SetPerspective(&connection->framer_, perspective);
+ connection->ping_manager_.perspective_ = perspective;
}
// static
@@ -101,7 +119,7 @@ void QuicConnectionPeer::SwapCrypters(QuicConnection* connection,
void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection,
absl::string_view current_packet) {
connection->current_packet_data_ = current_packet.data();
- connection->last_size_ = current_packet.size();
+ connection->last_received_packet_info_.length = current_packet.size();
}
// static
@@ -128,6 +146,9 @@ QuicAlarm* QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
// static
QuicAlarm* QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
+ if (GetQuicReloadableFlag(quic_use_ping_manager2)) {
+ return connection->ping_manager_.alarm_.get();
+ }
return connection->ping_alarm_.get();
}
@@ -219,7 +240,7 @@ QuicEncryptedPacket* QuicConnectionPeer::GetConnectionClosePacket(
// static
QuicPacketHeader* QuicConnectionPeer::GetLastHeader(
QuicConnection* connection) {
- return &connection->last_header_;
+ return &connection->last_received_packet_info_.header;
}
// static
@@ -303,12 +324,6 @@ QuicConnection::PacketContent QuicConnectionPeer::GetCurrentPacketContent(
}
// static
-void QuicConnectionPeer::SetLastHeaderFormat(QuicConnection* connection,
- PacketHeaderFormat format) {
- connection->last_header_.form = format;
-}
-
-// static
void QuicConnectionPeer::AddBytesReceived(QuicConnection* connection,
size_t length) {
if (connection->EnforceAntiAmplificationLimit()) {
@@ -519,7 +534,7 @@ QuicConnectionPeer::MakeSelfIssuedConnectionIdManager(
// static
void QuicConnectionPeer::SetLastDecryptedLevel(QuicConnection* connection,
EncryptionLevel level) {
- connection->last_decrypted_packet_level_ = level;
+ connection->last_received_packet_info_.decrypted_level = level;
}
// static
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h
index ffe3b3cbb16..d1a41f99006 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h
@@ -53,6 +53,10 @@ class QuicConnectionPeer {
static QuicTime::Delta GetHandshakeTimeout(QuicConnection* connection);
+ static QuicTime::Delta GetBandwidthUpdateTimeout(QuicConnection* connection);
+
+ static void DisableBandwidthUpdate(QuicConnection* connection);
+
static void SetPerspective(QuicConnection* connection,
Perspective perspective);
@@ -128,8 +132,6 @@ class QuicConnectionPeer {
static bool SupportsReleaseTime(QuicConnection* connection);
static QuicConnection::PacketContent GetCurrentPacketContent(
QuicConnection* connection);
- static void SetLastHeaderFormat(QuicConnection* connection,
- PacketHeaderFormat format);
static void AddBytesReceived(QuicConnection* connection, size_t length);
static void SetAddressValidated(QuicConnection* connection);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/index.html b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/index.html
new file mode 100644
index 00000000000..5edaf9af7b5
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/index.html
@@ -0,0 +1,63 @@
+HTTP/1.1 200 OK
+Date: Tue, 28 Aug 2012 15:08:56 GMT
+Server: Apache/2.2.3 (CentOS)
+X-Powered-By: PHP/5.1.6
+Set-Cookie: bblastvisit=1346166536; expires=Wed, 28-Aug-2013 15:08:56 GMT; path=/; domain=.nasioc.com
+Set-Cookie: bblastactivity=0; expires=Wed, 28-Aug-2013 15:08:56 GMT; path=/; domain=.nasioc.com
+Expires: 0
+Cache-Control: private, post-check=0, pre-check=0, max-age=0
+Pragma: no-cache
+X-UA-Compatible: IE=7
+Connection: close
+Content-Type: text/html; charset=ISO-8859-1
+
+<!doctype html>
+<html>
+<head>
+ <title>Example Domain</title>
+
+ <meta charset="utf-8" />
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <style type="text/css">
+ body {
+ background-color: #f0f0f2;
+ margin: 0;
+ padding: 0;
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+ }
+ div {
+ width: 600px;
+ margin: 5em auto;
+ padding: 50px;
+ background-color: #fff;
+ border-radius: 1em;
+ }
+ a:link, a:visited {
+ color: #38488f;
+ text-decoration: none;
+ }
+ @media (max-width: 700px) {
+ body {
+ background-color: #fff;
+ }
+ div {
+ width: auto;
+ margin: 0 auto;
+ border-radius: 0;
+ padding: 1em;
+ }
+ }
+ </style>
+</head>
+
+<body>
+<div>
+ <h1>Example Domain</h1>
+ <p>This domain is established to be used for illustrative examples in documents. You may use this
+ domain in examples without prior coordination or asking for permission.</p>
+ <p><a href="http://www.iana.org/domains/example">More information...</a></p>
+</div>
+</body>
+</html>
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/map.html b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/map.html
new file mode 100644
index 00000000000..b34c3b085f0
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/map.html
@@ -0,0 +1,65 @@
+HTTP/1.1 200 OK
+Date: Tue, 28 Aug 2012 15:08:56 GMT
+Server: Apache/2.2.3 (CentOS)
+X-Powered-By: PHP/5.1.6
+Set-Cookie: bblastvisit=1346166536; expires=Wed, 28-Aug-2013 15:08:56 GMT; path=/; domain=.nasioc.com
+Set-Cookie: bblastactivity=0; expires=Wed, 28-Aug-2013 15:08:56 GMT; path=/; domain=.nasioc.com
+Expires: 0
+Cache-Control: private, post-check=0, pre-check=0, max-age=0
+Pragma: no-cache
+X-UA-Compatible: IE=7
+Connection: close
+Content-Type: text/html; charset=ISO-8859-1
+X-Original-Url: http://test.example.com/site_map.html
+
+
+<!doctype html>
+<html>
+<head>
+ <title>Example Domain</title>
+
+ <meta charset="utf-8" />
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <style type="text/css">
+ body {
+ background-color: #f0f0f2;
+ margin: 0;
+ padding: 0;
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+ }
+ div {
+ width: 600px;
+ margin: 5em auto;
+ padding: 50px;
+ background-color: #fff;
+ border-radius: 1em;
+ }
+ a:link, a:visited {
+ color: #38488f;
+ text-decoration: none;
+ }
+ @media (max-width: 700px) {
+ body {
+ background-color: #fff;
+ }
+ div {
+ width: auto;
+ margin: 0 auto;
+ border-radius: 0;
+ padding: 1em;
+ }
+ }
+ </style>
+</head>
+
+<body>
+<div>
+ <h1>Example Domain</h1>
+ <p>This domain is established to be used for illustrative examples in documents. You may use this
+ domain in examples without prior coordination or asking for permission.</p>
+ <p><a href="http://www.iana.org/domains/example">More information...</a></p>
+</div>
+</body>
+</html>
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc
index dc410411754..2f3cb6375c1 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -13,23 +13,6 @@
namespace quic {
namespace test {
-// static
-size_t QuicSentPacketManagerPeer::GetMaxTailLossProbes(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->max_tail_loss_probes_;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetMaxTailLossProbes(
- QuicSentPacketManager* sent_packet_manager, size_t max_tail_loss_probes) {
- sent_packet_manager->max_tail_loss_probes_ = max_tail_loss_probes;
-}
-
-// static
-bool QuicSentPacketManagerPeer::GetUseNewRto(
- QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->use_new_rto_;
-}
// static
void QuicSentPacketManagerPeer::SetPerspective(
@@ -91,18 +74,6 @@ void QuicSentPacketManagerPeer::MarkForRetransmission(
}
// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
- const QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->GetRetransmissionDelay();
-}
-
-// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
- const QuicSentPacketManager* sent_packet_manager) {
- return sent_packet_manager->GetTailLossProbeDelay();
-}
-
-// static
size_t QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
const QuicSentPacketManager* sent_packet_manager) {
size_t num_unacked_packets = 0;
@@ -116,15 +87,9 @@ size_t QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
}
// static
-void QuicSentPacketManagerPeer::SetConsecutiveRtoCount(
- QuicSentPacketManager* sent_packet_manager, size_t count) {
- sent_packet_manager->consecutive_rto_count_ = count;
-}
-
-// static
-void QuicSentPacketManagerPeer::SetConsecutiveTlpCount(
+void QuicSentPacketManagerPeer::SetConsecutivePtoCount(
QuicSentPacketManager* sent_packet_manager, size_t count) {
- sent_packet_manager->consecutive_tlp_count_ = count;
+ sent_packet_manager->consecutive_pto_count_ = count;
}
// static
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.h
index be2a7bd7b80..aef38d30252 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -18,13 +18,6 @@ class QuicSentPacketManagerPeer {
public:
QuicSentPacketManagerPeer() = delete;
- static size_t GetMaxTailLossProbes(
- QuicSentPacketManager* sent_packet_manager);
-
- static void SetMaxTailLossProbes(QuicSentPacketManager* sent_packet_manager,
- size_t max_tail_loss_probes);
-
- static bool GetUseNewRto(QuicSentPacketManager* sent_packet_manager);
static void SetPerspective(QuicSentPacketManager* sent_packet_manager,
Perspective perspective);
@@ -51,18 +44,10 @@ class QuicSentPacketManagerPeer {
uint64_t packet_number,
TransmissionType transmission_type);
- static QuicTime::Delta GetRetransmissionDelay(
- const QuicSentPacketManager* sent_packet_manager);
- static QuicTime::Delta GetTailLossProbeDelay(
- const QuicSentPacketManager* sent_packet_manager);
-
static size_t GetNumRetransmittablePackets(
const QuicSentPacketManager* sent_packet_manager);
- static void SetConsecutiveRtoCount(QuicSentPacketManager* sent_packet_manager,
- size_t count);
-
- static void SetConsecutiveTlpCount(QuicSentPacketManager* sent_packet_manager,
+ static void SetConsecutivePtoCount(QuicSentPacketManager* sent_packet_manager,
size_t count);
static QuicSustainedBandwidthRecorder& GetBandwidthRecorder(
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h
index b01c925d202..041d9214616 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h
@@ -13,7 +13,6 @@
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_write_blocked_list.h"
-#include "quiche/quic/platform/api/quic_containers.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.cc
index d2ec5fd13a9..15806b372ab 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.cc
@@ -25,11 +25,6 @@ QuicSpdyStreamPeer::unacked_frame_headers_offsets(QuicSpdyStream* stream) {
}
// static
-bool QuicSpdyStreamPeer::use_datagram_contexts(QuicSpdyStream* stream) {
- return stream->use_datagram_contexts_;
-}
-
-// static
bool QuicSpdyStreamPeer::OnHeadersFrameEnd(QuicSpdyStream* stream) {
return stream->OnHeadersFrameEnd();
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.h
index e92f89eca50..8b5083d2620 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_stream_peer.h
@@ -7,7 +7,6 @@
#include "quiche/quic/core/quic_ack_listener_interface.h"
#include "quiche/quic/core/quic_interval_set.h"
-#include "quiche/quic/platform/api/quic_containers.h"
namespace quic {
@@ -24,7 +23,6 @@ class QuicSpdyStreamPeer {
ack_listener);
static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets(
QuicSpdyStream* stream);
- static bool use_datagram_contexts(QuicSpdyStream* stream);
static bool OnHeadersFrameEnd(QuicSpdyStream* stream);
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_backend.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_backend.h
index 8fef41a2336..33549cce8f9 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_backend.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_backend.h
@@ -26,12 +26,6 @@ class QuicTestBackend : public QuicMemoryCacheBackend {
enable_webtransport_ = enable_webtransport;
}
- bool UsesDatagramContexts() override { return use_datagram_contexts_; }
-
- void set_use_datagram_contexts(bool use_datagram_contexts) {
- use_datagram_contexts_ = use_datagram_contexts;
- }
-
bool SupportsExtendedConnect() override { return enable_extended_connect_; }
void set_enable_extended_connect(bool enable_extended_connect) {
@@ -40,7 +34,6 @@ class QuicTestBackend : public QuicMemoryCacheBackend {
private:
bool enable_webtransport_ = false;
- bool use_datagram_contexts_ = false;
bool enable_extended_connect_ = true;
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.cc
index b182dc5f713..6582ee715f8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.cc
@@ -657,9 +657,10 @@ MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection,
return QuicSpdySession::SendWindowUpdate(id, byte_offset);
});
- ON_CALL(*this, SendBlocked(_)).WillByDefault([this](QuicStreamId id) {
- return QuicSpdySession::SendBlocked(id);
- });
+ ON_CALL(*this, SendBlocked(_, _))
+ .WillByDefault([this](QuicStreamId id, QuicStreamOffset byte_offset) {
+ return QuicSpdySession::SendBlocked(id, byte_offset);
+ });
ON_CALL(*this, OnCongestionWindowChange(_)).WillByDefault(testing::Return());
}
@@ -1335,9 +1336,10 @@ WriteResult TestPacketWriter::WritePacket(const char* buffer, size_t buf_len,
ENCRYPTION_FORWARD_SECURE,
std::make_unique<NullDecrypter>(framer_.framer()->perspective()));
}
- EXPECT_TRUE(framer_.ProcessPacket(packet))
+ EXPECT_EQ(next_packet_processable_, framer_.ProcessPacket(packet))
<< framer_.framer()->detailed_error() << " perspective "
<< framer_.framer()->perspective();
+ next_packet_processable_ = true;
if (block_on_next_write_) {
write_blocked_ = true;
block_on_next_write_ = false;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h
index a26349bd7f6..0e2c20c509e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h
@@ -453,7 +453,6 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
(override));
MOCK_METHOD(void, OnWriteBlocked, (), (override));
MOCK_METHOD(void, OnCanWrite, (), (override));
- MOCK_METHOD(bool, SendProbingData, (), (override));
MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
MOCK_METHOD(void, OnConnectionMigration, (AddressChangeType type),
(override));
@@ -504,6 +503,8 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
const QuicSocketAddress& /*address*/) const override {
return false;
}
+
+ void OnBandwidthUpdateTimeout() override {}
};
class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
@@ -777,6 +778,8 @@ class MockQuicSession : public QuicSession {
(override));
MOCK_METHOD(void, MaybeSendStopSendingFrame,
(QuicStreamId stream_id, QuicResetStreamError error), (override));
+ MOCK_METHOD(void, SendBlocked,
+ (QuicStreamId stream_id, QuicStreamOffset offset), (override));
MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
@@ -853,6 +856,24 @@ class MockQuicCryptoStream : public QuicCryptoStream {
return false;
}
SSL* GetSsl() const override { return nullptr; }
+ bool IsCryptoFrameExpectedForEncryptionLevel(
+ quic::EncryptionLevel level) const override {
+ return level != ENCRYPTION_ZERO_RTT;
+ }
+ EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
+ PacketNumberSpace space) const override {
+ switch (space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ QUICHE_DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+ }
private:
quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
@@ -908,7 +929,8 @@ class MockQuicSpdySession : public QuicSpdySession {
(QuicStreamId stream_id, QuicResetStreamError error), (override));
MOCK_METHOD(void, SendWindowUpdate,
(QuicStreamId id, QuicStreamOffset byte_offset), (override));
- MOCK_METHOD(void, SendBlocked, (QuicStreamId id), (override));
+ MOCK_METHOD(void, SendBlocked,
+ (QuicStreamId id, QuicStreamOffset byte_offset), (override));
MOCK_METHOD(void, OnStreamHeadersPriority,
(QuicStreamId stream_id,
const spdy::SpdyStreamPrecedence& precedence),
@@ -959,8 +981,6 @@ class MockHttp3DebugVisitor : public Http3DebugVisitor {
MOCK_METHOD(void, OnSettingsFrameReceived, (const SettingsFrame&),
(override));
MOCK_METHOD(void, OnGoAwayFrameReceived, (const GoAwayFrame&), (override));
- MOCK_METHOD(void, OnMaxPushIdFrameReceived, (const MaxPushIdFrame&),
- (override));
MOCK_METHOD(void, OnPriorityUpdateFrameReceived, (const PriorityUpdateFrame&),
(override));
MOCK_METHOD(void, OnAcceptChFrameReceived, (const AcceptChFrame&),
@@ -1033,11 +1053,7 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase {
void set_early_data_enabled(bool enabled) { early_data_enabled_ = enabled; }
- void set_client_cert_mode(ClientCertMode mode) {
- if (support_client_cert()) {
- client_cert_mode_ = mode;
- }
- }
+ void set_client_cert_mode(ClientCertMode mode) { client_cert_mode_ = mode; }
private:
MockQuicSessionVisitor visitor_;
@@ -1192,7 +1208,6 @@ class MockSendAlgorithm : public SendAlgorithmInterface {
MOCK_METHOD(std::string, GetDebugState, (), (const, override));
MOCK_METHOD(bool, InSlowStart, (), (const, override));
MOCK_METHOD(bool, InRecovery, (), (const, override));
- MOCK_METHOD(bool, ShouldSendProbingPacket, (), (const, override));
MOCK_METHOD(QuicByteCount, GetSlowStartThreshold, (), (const, override));
MOCK_METHOD(CongestionControlType, GetCongestionControlType, (),
(const, override));
@@ -1777,6 +1792,8 @@ class TestPacketWriter : public QuicPacketWriter {
void SimulateNextPacketTooLarge() { next_packet_too_large_ = true; }
+ void ExpectNextPacketUnprocessable() { next_packet_processable_ = false; }
+
void AlwaysGetPacketTooLarge() { always_get_packet_too_large_ = true; }
// Sets the amount of time that the writer should before the actual write.
@@ -1923,6 +1940,7 @@ class TestPacketWriter : public QuicPacketWriter {
bool block_on_next_flush_ = false;
bool block_on_next_write_ = false;
bool next_packet_too_large_ = false;
+ bool next_packet_processable_ = true;
bool always_get_packet_too_large_ = false;
bool is_write_blocked_data_buffered_ = false;
bool is_batch_mode_ = false;
@@ -1987,11 +2005,9 @@ class SavingHttp3DatagramVisitor : public QuicSpdyStream::Http3DatagramVisitor {
public:
struct SavedHttp3Datagram {
QuicStreamId stream_id;
- absl::optional<QuicDatagramContextId> context_id;
std::string payload;
bool operator==(const SavedHttp3Datagram& o) const {
- return stream_id == o.stream_id && context_id == o.context_id &&
- payload == o.payload;
+ return stream_id == o.stream_id && payload == o.payload;
}
};
const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
@@ -2000,33 +2016,15 @@ class SavingHttp3DatagramVisitor : public QuicSpdyStream::Http3DatagramVisitor {
// Override from QuicSpdyStream::Http3DatagramVisitor.
void OnHttp3Datagram(QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
absl::string_view payload) override {
received_h3_datagrams_.push_back(
- SavedHttp3Datagram{stream_id, context_id, std::string(payload)});
+ SavedHttp3Datagram{stream_id, std::string(payload)});
}
private:
std::vector<SavedHttp3Datagram> received_h3_datagrams_;
};
-class MockHttp3DatagramRegistrationVisitor
- : public QuicSpdyStream::Http3DatagramRegistrationVisitor {
- public:
- MOCK_METHOD(void, OnContextReceived,
- (QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- DatagramFormatType format_type,
- absl::string_view format_additional_data),
- (override));
-
- MOCK_METHOD(void, OnContextClosed,
- (QuicStreamId stream_id,
- absl::optional<QuicDatagramContextId> context_id,
- ContextCloseCode close_code, absl::string_view close_details),
- (override));
-};
-
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.cc
index 12d2fc2c7c2..7e8ab1ef873 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.cc
@@ -5,7 +5,6 @@
#include "quiche/quic/test_tools/server_thread.h"
#include "quiche/quic/core/quic_dispatcher.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/test_tools/crypto_test_utils.h"
#include "quiche/quic/test_tools/quic_dispatcher_peer.h"
#include "quiche/quic/test_tools/quic_server_peer.h"
@@ -13,10 +12,11 @@
namespace quic {
namespace test {
-ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
+ServerThread::ServerThread(std::unique_ptr<QuicServer> server,
+ const QuicSocketAddress& address)
: QuicThread("server_thread"),
- server_(server),
- clock_(server->epoll_server()),
+ server_(std::move(server)),
+ clock_(server_->epoll_server()),
address_(address),
port_(0),
initialized_(false) {}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.h
index 7f5d45a8851..fc534679ae6 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/server_thread.h
@@ -9,7 +9,6 @@
#include "quiche/quic/core/quic_config.h"
#include "quiche/quic/core/quic_epoll_clock.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_mutex.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_thread.h"
@@ -21,7 +20,8 @@ namespace test {
// Simple wrapper class to run QuicServer in a dedicated thread.
class ServerThread : public QuicThread {
public:
- ServerThread(QuicServer* server, const QuicSocketAddress& address);
+ ServerThread(std::unique_ptr<QuicServer> server,
+ const QuicSocketAddress& address);
ServerThread(const ServerThread&) = delete;
ServerThread& operator=(const ServerThread&) = delete;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h
index dd312d91c71..96952d744a8 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h
@@ -9,7 +9,6 @@
#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_stream_frame_data_producer.h"
#include "quiche/quic/core/quic_stream_send_buffer.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/common/simple_buffer_allocator.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_session_notifier_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_session_notifier_test.cc
index 2aa35e51213..513394ccbfe 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_session_notifier_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simple_session_notifier_test.cc
@@ -358,7 +358,7 @@ TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
// stream 3 data [0, 3) is retransmitted and connection is blocked.
EXPECT_CALL(connection_, SendStreamData(3, 3, 0, NO_FIN))
.WillOnce(Return(QuicConsumedData(2, false)));
- notifier_.RetransmitFrames(frames, RTO_RETRANSMISSION);
+ notifier_.RetransmitFrames(frames, PTO_RETRANSMISSION);
EXPECT_FALSE(notifier_.WillingToWrite());
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.cc
index 72f62ade3f7..64005ece38f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.cc
@@ -151,14 +151,6 @@ void QuicEndpoint::OnCanWrite() {
WriteStreamData();
}
-bool QuicEndpoint::SendProbingData() {
- if (connection()->sent_packet_manager().MaybeRetransmitOldestPacket(
- PROBING_RETRANSMISSION)) {
- return true;
- }
- return false;
-}
-
bool QuicEndpoint::WillingAndAbleToWrite() const {
if (notifier_ != nullptr) {
return notifier_->WillingToWrite();
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.h
index e1a8c3e5b63..d3741c50615 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint.h
@@ -13,7 +13,6 @@
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_stream_frame_data_producer.h"
#include "quiche/quic/core/quic_trace_visitor.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/test_tools/simple_session_notifier.h"
#include "quiche/quic/test_tools/simulator/link.h"
#include "quiche/quic/test_tools/simulator/queue.h"
@@ -47,7 +46,6 @@ class QuicEndpoint : public QuicEndpointBase,
void OnStreamFrame(const QuicStreamFrame& frame) override;
void OnCryptoFrame(const QuicCryptoFrame& frame) override;
void OnCanWrite() override;
- bool SendProbingData() override;
bool WillingAndAbleToWrite() const override;
bool ShouldKeepConnectionAlive() const override;
@@ -108,6 +106,7 @@ class QuicEndpoint : public QuicEndpointBase,
const QuicSocketAddress& /*address*/) const override {
return false;
}
+ void OnBandwidthUpdateTimeout() override {}
// End QuicConnectionVisitorInterface implementation.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_base.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_base.h
index 26bb0144e29..8eece0bc06a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_base.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_base.h
@@ -15,7 +15,6 @@
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_stream_frame_data_producer.h"
#include "quiche/quic/core/quic_trace_visitor.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/test_tools/simple_session_notifier.h"
#include "quiche/quic/test_tools/simulator/link.h"
#include "quiche/quic/test_tools/simulator/queue.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_test.cc
index 823c190fe34..5850a8bdef5 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/quic_endpoint_test.cc
@@ -28,7 +28,7 @@ const QuicByteCount kDefaultBdp = kDefaultBandwidth * kDefaultPropagationDelay;
// A simple test harness where all hosts are connected to a switch with
// identical links.
-class QuicEndpointTest : public QuicTest {
+class QuicEndpointTest : public quic::test::QuicTest {
public:
QuicEndpointTest()
: simulator_(), switch_(&simulator_, "Switch", 8, kDefaultBdp * 2) {}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator.h
index 0dabe4adc48..805d7c2dc88 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator.h
@@ -11,7 +11,6 @@
#include "absl/container/flat_hash_set.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/test_tools/simulator/actor.h"
#include "quiche/quic/test_tools/simulator/alarm_factory.h"
#include "quiche/common/simple_buffer_allocator.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc
index e43c79cd1b6..4ae04a7803e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc
@@ -7,7 +7,6 @@
#include <utility>
#include "absl/container/node_hash_map.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
@@ -48,7 +47,7 @@ class Counter : public Actor {
QuicTime::Delta period_;
};
-class SimulatorTest : public QuicTest {};
+class SimulatorTest : public quic::test::QuicTest {};
// Test that the basic event handling works, and that Actors can be created and
// destroyed mid-simulation.
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h
index b73541c7b84..1bafed41493 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/simulator/switch.h
@@ -8,7 +8,6 @@
#include <deque>
#include "absl/container/flat_hash_map.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/test_tools/simulator/queue.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc
index b886dde967a..dbdb2a9d35f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc
@@ -55,7 +55,7 @@ std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) {
void TestTicketCrypter::Decrypt(
absl::string_view in,
- std::unique_ptr<ProofSource::DecryptCallback> callback) {
+ std::shared_ptr<ProofSource::DecryptCallback> callback) {
auto decrypted_ticket = Decrypt(in);
if (run_async_) {
pending_callbacks_.push_back({std::move(callback), decrypted_ticket});
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.h b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.h
index 84430994582..888bdef932d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.h
@@ -22,7 +22,7 @@ class TestTicketCrypter : public ProofSource::TicketCrypter {
std::vector<uint8_t> Encrypt(absl::string_view in,
absl::string_view encryption_key) override;
void Decrypt(absl::string_view in,
- std::unique_ptr<ProofSource::DecryptCallback> callback) override;
+ std::shared_ptr<ProofSource::DecryptCallback> callback) override;
void SetRunCallbacksAsync(bool run_async);
size_t NumPendingCallbacks();
@@ -36,7 +36,7 @@ class TestTicketCrypter : public ProofSource::TicketCrypter {
std::vector<uint8_t> Decrypt(absl::string_view in);
struct PendingCallback {
- std::unique_ptr<ProofSource::DecryptCallback> callback;
+ std::shared_ptr<ProofSource::DecryptCallback> callback;
std::vector<uint8_t> decrypted_ticket;
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_message_printer_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/crypto_message_printer_bin.cc
index eb7393d549e..eb7393d549e 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_message_printer_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/crypto_message_printer_bin.cc
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/qpack_offline_decoder_bin.cc
index a5cbc856dd4..a5cbc856dd4 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/core/qpack/qpack_offline_decoder_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/qpack_offline_decoder_bin.cc
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.cc
index b024ac61fc1..b3e4705e102 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.cc
@@ -130,8 +130,7 @@ std::unique_ptr<QuicSession> QuicClient::CreateQuicClientSession(
QuicConnection* connection) {
return std::make_unique<QuicSimpleClientSession>(
*config(), supported_versions, connection, server_id(), crypto_config(),
- push_promise_index(), drop_response_body(), enable_web_transport(),
- use_datagram_contexts());
+ push_promise_index(), drop_response_body(), enable_web_transport());
}
QuicClientEpollNetworkHelper* QuicClient::epoll_network_helper() {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.h
index ebf8cb921d4..e0106c79465 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client.h
@@ -16,7 +16,6 @@
#include "quiche/quic/core/http/quic_spdy_client_session.h"
#include "quiche/quic/core/quic_config.h"
#include "quiche/quic/core/quic_packet_reader.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_epoll.h"
#include "quiche/quic/tools/quic_client_epoll_network_helper.h"
#include "quiche/quic/tools/quic_spdy_client_base.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client_interop_test_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client_interop_test_bin.cc
index 549be2ebfd5..9a29afeec25 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client_interop_test_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_client_interop_test_bin.cc
@@ -395,9 +395,9 @@ int main(int argc, char* argv[]) {
quiche::QuichePrintCommandLineFlagHelp(usage);
exit(1);
}
- std::string dns_host = GetQuicFlag(FLAGS_host);
+ std::string dns_host = quiche::GetQuicheCommandLineFlag(FLAGS_host);
std::string url_host = "";
- int port = GetQuicFlag(FLAGS_port);
+ int port = quiche::GetQuicheCommandLineFlag(FLAGS_port);
if (!args.empty()) {
quic::QuicUrl url(args[0], "https");
@@ -423,7 +423,8 @@ int main(int argc, char* argv[]) {
// Pick QUIC version to use.
quic::QuicVersionInitializeSupportForIetfDraft();
quic::ParsedQuicVersion version = quic::UnsupportedQuicVersion();
- std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
+ std::string quic_version_string =
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_version);
if (!quic_version_string.empty()) {
version = quic::ParseQuicVersionString(quic_version_string);
} else {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h
index e272351a648..1738e3c8acf 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h
@@ -13,7 +13,6 @@
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/http/spdy_utils.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_mutex.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/quic/tools/quic_simple_server_backend.h"
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend_test.cc
index bb5e67520c7..a75b46ec58c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend_test.cc
@@ -11,6 +11,7 @@
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/common/platform/api/quiche_file_utils.h"
+#include "quiche/common/platform/api/quiche_test.h"
namespace quic {
namespace test {
@@ -30,7 +31,9 @@ class QuicMemoryCacheBackendTest : public QuicTest {
(*headers)[":scheme"] = "https";
}
- std::string CacheDirectory() { return QuicGetTestMemoryCachePath(); }
+ std::string CacheDirectory() {
+ return quiche::test::QuicheGetTestMemoryCachePath();
+ }
QuicMemoryCacheBackend cache_;
};
@@ -97,36 +100,6 @@ TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDir) {
// TODO(crbug.com/1249712) This test is failing on iOS.
#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDirWithServerPushResource \
- DISABLED_ReadsCacheDirWithServerPushResource
-#else
-#define MAYBE_ReadsCacheDirWithServerPushResource \
- ReadsCacheDirWithServerPushResource
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResource) {
- cache_.InitializeBackend(CacheDirectory() + "_with_push");
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources("test.example.com/");
- ASSERT_EQ(1UL, resources.size());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
-#define MAYBE_ReadsCacheDirWithServerPushResources \
- DISABLED_ReadsCacheDirWithServerPushResources
-#else
-#define MAYBE_ReadsCacheDirWithServerPushResources \
- ReadsCacheDirWithServerPushResources
-#endif
-TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDirWithServerPushResources) {
- cache_.InitializeBackend(CacheDirectory() + "_with_push");
- std::list<ServerPushInfo> resources =
- cache_.GetServerPushResources("test.example.com/index2.html");
- ASSERT_EQ(2UL, resources.size());
-}
-
-// TODO(crbug.com/1249712) This test is failing on iOS.
-#if defined(OS_IOS)
#define MAYBE_UsesOriginalUrl DISABLED_UsesOriginalUrl
#else
#define MAYBE_UsesOriginalUrl UsesOriginalUrl
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc
index 8867e44df9f..740971c078c 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_packet_printer_bin.cc
@@ -271,8 +271,8 @@ int main(int argc, char* argv[]) {
quic::QuicTime start(quic::QuicTime::Zero());
quic::QuicFramer framer(versions, start, perspective,
quic::kQuicDefaultConnectionIdLength);
- const quic::ParsedQuicVersion& version =
- quic::ParseQuicVersionString(GetQuicFlag(FLAGS_quic_version));
+ const quic::ParsedQuicVersion& version = quic::ParseQuicVersionString(
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_version));
if (version != quic::ParsedQuicVersion::Unsupported()) {
framer.set_version(version);
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.cc
index fa211aca59e..1a001fb414a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.cc
@@ -16,20 +16,18 @@ QuicSimpleClientSession::QuicSimpleClientSession(
: QuicSimpleClientSession(config, supported_versions, connection, server_id,
crypto_config, push_promise_index,
drop_response_body,
- /*enable_web_transport=*/false,
- /*use_datagram_contexts=*/false) {}
+ /*enable_web_transport=*/false) {}
QuicSimpleClientSession::QuicSimpleClientSession(
const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
QuicConnection* connection, const QuicServerId& server_id,
QuicCryptoClientConfig* crypto_config,
QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
- bool enable_web_transport, bool use_datagram_contexts)
+ bool enable_web_transport)
: QuicSpdyClientSession(config, supported_versions, connection, server_id,
crypto_config, push_promise_index),
drop_response_body_(drop_response_body),
- enable_web_transport_(enable_web_transport),
- use_datagram_contexts_(use_datagram_contexts) {}
+ enable_web_transport_(enable_web_transport) {}
std::unique_ptr<QuicSpdyClientStream>
QuicSimpleClientSession::CreateClientStream() {
@@ -42,10 +40,6 @@ bool QuicSimpleClientSession::ShouldNegotiateWebTransport() {
return enable_web_transport_;
}
-bool QuicSimpleClientSession::ShouldNegotiateDatagramContexts() {
- return use_datagram_contexts_;
-}
-
HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
return enable_web_transport_ ? HttpDatagramSupport::kDraft04
: HttpDatagramSupport::kNone;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.h
index 75ed195c249..6b6f4a7437d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_client_session.h
@@ -25,18 +25,15 @@ class QuicSimpleClientSession : public QuicSpdyClientSession {
const QuicServerId& server_id,
QuicCryptoClientConfig* crypto_config,
QuicClientPushPromiseIndex* push_promise_index,
- bool drop_response_body, bool enable_web_transport,
- bool use_datagram_contexts);
+ bool drop_response_body, bool enable_web_transport);
std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
bool ShouldNegotiateWebTransport() override;
- bool ShouldNegotiateDatagramContexts() override;
HttpDatagramSupport LocalHttpDatagramSupport() override;
private:
const bool drop_response_body_;
const bool enable_web_transport_;
- const bool use_datagram_contexts_;
};
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_backend.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_backend.h
index f976e72bc11..c603468b134 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_backend.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_backend.h
@@ -5,10 +5,14 @@
#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
+#include <cstdint>
#include <memory>
+#include "absl/strings/string_view.h"
+#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/spdy/core/spdy_header_block.h"
@@ -33,6 +37,14 @@ class QuicSimpleServerBackend {
// the QUIC client.
virtual void OnResponseBackendComplete(
const QuicBackendResponse* response) = 0;
+ // Sends additional non-full-response data (without headers) to the request
+ // stream, e.g. for CONNECT data. May only be called after sending an
+ // incomplete response (using `QuicBackendResponse::INCOMPLETE_RESPONSE`).
+ // Sends the data with the FIN bit to close the stream if `close_stream` is
+ // true.
+ virtual void SendStreamData(absl::string_view data, bool close_stream) = 0;
+ // Abruptly terminates (resets) the request stream with `error`.
+ virtual void TerminateStreamWithError(QuicResetStreamError error) = 0;
};
struct WebTransportResponse {
@@ -49,12 +61,43 @@ class QuicSimpleServerBackend {
virtual bool IsBackendInitialized() const = 0;
// Triggers a HTTP request to be sent to the backend server or cache
// If response is immediately available, the function synchronously calls
- // the |request_handler| with the HTTP response.
+ // the `request_handler` with the HTTP response.
// If the response has to be fetched over the network, the function
- // asynchronously calls |request_handler| with the HTTP response.
+ // asynchronously calls `request_handler` with the HTTP response.
+ //
+ // Not called for requests using the CONNECT method.
virtual void FetchResponseFromBackend(
const spdy::Http2HeaderBlock& request_headers,
const std::string& request_body, RequestHandler* request_handler) = 0;
+
+ // Handles headers for requests using the CONNECT method. Called immediately
+ // on receiving the headers, potentially before the request is complete or
+ // data is received. Any response (complete or incomplete) should be sent,
+ // potentially asynchronously, using `request_handler`.
+ //
+ // If not overridden by backend, sends an error appropriate for a server that
+ // does not handle CONNECT requests.
+ virtual void HandleConnectHeaders(
+ const spdy::Http2HeaderBlock& /*request_headers*/,
+ RequestHandler* request_handler) {
+ spdy::Http2HeaderBlock headers;
+ headers[":status"] = "405";
+ QuicBackendResponse response;
+ response.set_headers(std::move(headers));
+ request_handler->OnResponseBackendComplete(&response);
+ }
+ // Handles data for requests using the CONNECT method. Called repeatedly
+ // whenever new data is available. If `data_complete` is true, data was
+ // received with the FIN bit, and this is the last call to this method.
+ //
+ // If not overridden by backend, abruptly terminates the stream.
+ virtual void HandleConnectData(absl::string_view /*data*/,
+ bool /*data_complete*/,
+ RequestHandler* request_handler) {
+ request_handler->TerminateStreamWithError(
+ QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR));
+ }
+
// Clears the state of the backend instance
virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0;
@@ -66,7 +109,6 @@ class QuicSimpleServerBackend {
return response;
}
virtual bool SupportsWebTransport() { return false; }
- virtual bool UsesDatagramContexts() { return false; }
virtual bool SupportsExtendedConnect() { return true; }
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session.h
index 872a4577bcd..0530ce26a3a 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session.h
@@ -20,7 +20,6 @@
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/quic_crypto_server_stream_base.h"
#include "quiche/quic/core/quic_packets.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/quic/tools/quic_simple_server_backend.h"
#include "quiche/quic/tools/quic_simple_server_stream.h"
@@ -70,10 +69,6 @@ class QuicSimpleServerSession : public QuicServerSessionBase {
void OnCanCreateNewOutgoingStream(bool unidirectional) override;
- bool ShouldNegotiateDatagramContexts() override {
- return quic_simple_server_backend_->UsesDatagramContexts();
- }
-
protected:
// QuicSession methods:
QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override;
@@ -102,7 +97,7 @@ class QuicSimpleServerSession : public QuicServerSessionBase {
}
HttpDatagramSupport LocalHttpDatagramSupport() override {
if (ShouldNegotiateWebTransport()) {
- return HttpDatagramSupport::kDraft00And04;
+ return HttpDatagramSupport::kDraft04;
}
return QuicServerSessionBase::LocalHttpDatagramSupport();
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session_test.cc
index a5124ea41ab..d1db8c9aa9d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_session_test.cc
@@ -19,7 +19,6 @@
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/core/tls_server_handshaker.h"
-#include "quiche/quic/platform/api/quic_containers.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
@@ -180,7 +179,7 @@ class MockQuicSimpleServerSession : public QuicSimpleServerSession {
const spdy::Http2HeaderBlock& headers),
());
- MOCK_METHOD(void, SendBlocked, (QuicStreamId), (override));
+ MOCK_METHOD(void, SendBlocked, (QuicStreamId, QuicStreamOffset), (override));
MOCK_METHOD(bool, WriteControlFrame,
(const QuicFrame& frame, TransmissionType type), (override));
};
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.cc
index 91f91d31875..608d7b58289 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.cc
@@ -4,16 +4,18 @@
#include "quiche/quic/tools/quic_simple_server_stream.h"
+#include <cstdint>
#include <list>
#include <utility>
-#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#include "quiche/quic/core/http/quic_spdy_stream.h"
#include "quiche/quic/core/http/spdy_utils.h"
#include "quiche/quic/core/http/web_transport_http3.h"
+#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flags.h"
@@ -61,15 +63,36 @@ void QuicSimpleServerStream::OnInitialHeadersComplete(
SendErrorResponse();
}
ConsumeHeaderList();
- if (!fin && !response_sent_) {
- // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) require
- // sending the response right after parsing the headers even though the FIN
- // bit has not been received on the request stream.
- auto it = request_headers_.find(":method");
- if (it != request_headers_.end() &&
- absl::StartsWith(it->second, "CONNECT")) {
- SendResponse();
+
+ // CONNECT requests do not carry any message content but carry data after the
+ // headers, so they require sending the response right after parsing the
+ // headers even though the FIN bit has not been received on the request
+ // stream.
+ if (!fin && !response_sent_ && IsConnectRequest()) {
+ if (quic_simple_server_backend_ == nullptr) {
+ QUIC_DVLOG(1) << "Backend is missing on CONNECT headers.";
+ SendErrorResponse();
+ return;
+ }
+
+ if (web_transport() != nullptr) {
+ QuicSimpleServerBackend::WebTransportResponse response =
+ quic_simple_server_backend_->ProcessWebTransportRequest(
+ request_headers_, web_transport());
+ if (response.response_headers[":status"] == "200") {
+ WriteHeaders(std::move(response.response_headers), false, nullptr);
+ if (response.visitor != nullptr) {
+ web_transport()->SetVisitor(std::move(response.visitor));
+ }
+ web_transport()->HeadersReceived(request_headers_);
+ } else {
+ WriteHeaders(std::move(response.response_headers), true, nullptr);
+ }
+ return;
}
+
+ quic_simple_server_backend_->HandleConnectHeaders(request_headers_,
+ /*request_handler=*/this);
}
}
@@ -99,7 +122,11 @@ void QuicSimpleServerStream::OnBodyAvailable() {
}
MarkConsumed(iov.iov_len);
}
+
if (!sequencer()->IsClosed()) {
+ if (IsConnectRequest()) {
+ HandleRequestConnectData(/*fin_received=*/false);
+ }
sequencer()->SetUnblocked();
return;
}
@@ -112,7 +139,11 @@ void QuicSimpleServerStream::OnBodyAvailable() {
return;
}
- SendResponse();
+ if (IsConnectRequest()) {
+ HandleRequestConnectData(/*fin_received=*/true);
+ } else {
+ SendResponse();
+ }
}
void QuicSimpleServerStream::PushResponse(
@@ -134,7 +165,28 @@ void QuicSimpleServerStream::PushResponse(
SendResponse();
}
+void QuicSimpleServerStream::HandleRequestConnectData(bool fin_received) {
+ QUICHE_DCHECK(IsConnectRequest());
+
+ if (quic_simple_server_backend_ == nullptr) {
+ QUIC_DVLOG(1) << "Backend is missing on CONNECT data.";
+ ResetWriteSide(
+ QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR));
+ return;
+ }
+
+ // Clear `body_`, so only new data is sent to the backend next time.
+ std::string data = std::move(body_);
+ body_.clear();
+
+ quic_simple_server_backend_->HandleConnectData(data,
+ /*data_complete=*/fin_received,
+ this);
+}
+
void QuicSimpleServerStream::SendResponse() {
+ QUICHE_DCHECK(!IsConnectRequest());
+
if (request_headers_.empty()) {
QUIC_DVLOG(1) << "Request headers empty.";
SendErrorResponse();
@@ -156,19 +208,13 @@ void QuicSimpleServerStream::SendResponse() {
}
if (!request_headers_.contains(":path")) {
- // CONNECT and other CONNECT-like methods (such as CONNECT-UDP) do not all
- // require :path to be present.
- auto it = request_headers_.find(":method");
- if (it == request_headers_.end() ||
- !absl::StartsWith(it->second, "CONNECT")) {
- QUIC_DVLOG(1) << "Request headers do not contain :path.";
- SendErrorResponse();
- return;
- }
+ QUIC_DVLOG(1) << "Request headers do not contain :path.";
+ SendErrorResponse();
+ return;
}
if (quic_simple_server_backend_ == nullptr) {
- QUIC_DVLOG(1) << "Backend is missing.";
+ QUIC_DVLOG(1) << "Backend is missing in SendResponse().";
SendErrorResponse();
return;
}
@@ -309,6 +355,27 @@ void QuicSimpleServerStream::OnResponseBackendComplete(
response->trailers().Clone());
}
+void QuicSimpleServerStream::SendStreamData(absl::string_view data,
+ bool close_stream) {
+ // Doesn't make sense to call this without data or `close_stream`.
+ QUICHE_DCHECK(!data.empty() || close_stream);
+
+ if (close_stream) {
+ SendHeadersAndBodyAndTrailers(
+ /*response_headers=*/absl::nullopt, data,
+ /*response_trailers=*/spdy::Http2HeaderBlock());
+ } else {
+ SendIncompleteResponse(/*response_headers=*/absl::nullopt, data);
+ }
+}
+
+void QuicSimpleServerStream::TerminateStreamWithError(
+ QuicResetStreamError error) {
+ QUIC_DVLOG(1) << "Stream " << id() << " abruptly terminating with error "
+ << error.internal_code();
+ ResetWriteSide(error);
+}
+
void QuicSimpleServerStream::OnCanWrite() {
QuicSpdyStream::OnCanWrite();
WriteGeneratedBytes();
@@ -351,12 +418,16 @@ void QuicSimpleServerStream::SendErrorResponse(int resp_code) {
}
void QuicSimpleServerStream::SendIncompleteResponse(
- Http2HeaderBlock response_headers, absl::string_view body) {
- QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : "
- << response_headers.DebugString();
- WriteHeaders(std::move(response_headers), /*fin=*/false, nullptr);
- QUICHE_DCHECK(!response_sent_);
- response_sent_ = true;
+ absl::optional<Http2HeaderBlock> response_headers, absl::string_view body) {
+ // Headers should be sent iff not sent in a previous response.
+ QUICHE_DCHECK_NE(response_headers.has_value(), response_sent_);
+
+ if (response_headers.has_value()) {
+ QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : "
+ << response_headers.value().DebugString();
+ WriteHeaders(std::move(response_headers).value(), /*fin=*/false, nullptr);
+ response_sent_ = true;
+ }
QUIC_DLOG(INFO) << "Stream " << id()
<< " writing body (fin = false) with size: " << body.size();
@@ -372,22 +443,27 @@ void QuicSimpleServerStream::SendHeadersAndBody(
}
void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
- Http2HeaderBlock response_headers, absl::string_view body,
+ absl::optional<Http2HeaderBlock> response_headers, absl::string_view body,
Http2HeaderBlock response_trailers) {
- // Send the headers, with a FIN if there's nothing else to send.
- bool send_fin = (body.empty() && response_trailers.empty());
- QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin
- << ") : " << response_headers.DebugString();
- WriteHeaders(std::move(response_headers), send_fin, nullptr);
- QUICHE_DCHECK(!response_sent_);
- response_sent_ = true;
- if (send_fin) {
- // Nothing else to send.
- return;
+ // Headers should be sent iff not sent in a previous response.
+ QUICHE_DCHECK_NE(response_headers.has_value(), response_sent_);
+
+ if (response_headers.has_value()) {
+ // Send the headers, with a FIN if there's nothing else to send.
+ bool send_fin = (body.empty() && response_trailers.empty());
+ QUIC_DLOG(INFO) << "Stream " << id()
+ << " writing headers (fin = " << send_fin
+ << ") : " << response_headers.value().DebugString();
+ WriteHeaders(std::move(response_headers).value(), send_fin, nullptr);
+ response_sent_ = true;
+ if (send_fin) {
+ // Nothing else to send.
+ return;
+ }
}
// Send the body, with a FIN if there's no trailers to send.
- send_fin = response_trailers.empty();
+ bool send_fin = response_trailers.empty();
QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
<< ") with size: " << body.size();
if (!body.empty() || send_fin) {
@@ -404,6 +480,11 @@ void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
WriteTrailers(std::move(response_trailers), nullptr);
}
+bool QuicSimpleServerStream::IsConnectRequest() const {
+ auto method_it = request_headers_.find(":method");
+ return method_it != request_headers_.end() && method_it->second == "CONNECT";
+}
+
void QuicSimpleServerStream::OnInvalidHeaders() {
QUIC_DVLOG(1) << "Invalid headers";
SendErrorResponse(400);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.h
index f3221c88b50..7b7859a8f5f 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream.h
@@ -5,8 +5,12 @@
#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_STREAM_H_
+#include <cstdint>
+
#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
+#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/quic/tools/quic_simple_server_backend.h"
@@ -55,10 +59,15 @@ class QuicSimpleServerStream : public QuicSpdyServerStreamBase,
QuicStreamId stream_id() const override;
std::string peer_host() const override;
void OnResponseBackendComplete(const QuicBackendResponse* response) override;
+ void SendStreamData(absl::string_view data, bool close_stream) override;
+ void TerminateStreamWithError(QuicResetStreamError error) override;
protected:
- // Sends a basic 200 response using SendHeaders for the headers and WriteData
- // for the body.
+ // Handles fresh body data whenever received when method is CONNECT.
+ void HandleRequestConnectData(bool fin_received);
+
+ // Sends a response using SendHeaders for the headers and WriteData for the
+ // body.
virtual void SendResponse();
// Sends a basic 500 response using SendHeaders for the headers and WriteData
@@ -70,23 +79,34 @@ class QuicSimpleServerStream : public QuicSpdyServerStreamBase,
// for the body.
void SendNotFoundResponse();
- // Sends the response header and body, but not the fin.
- void SendIncompleteResponse(spdy::Http2HeaderBlock response_headers,
- absl::string_view body);
+ // Sends the response header (if not `absl::nullopt`) and body, but not the
+ // fin.
+ void SendIncompleteResponse(
+ absl::optional<spdy::Http2HeaderBlock> response_headers,
+ absl::string_view body);
void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers,
absl::string_view body);
- void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers,
- absl::string_view body,
- spdy::Http2HeaderBlock response_trailers);
+ void SendHeadersAndBodyAndTrailers(
+ absl::optional<spdy::Http2HeaderBlock> response_headers,
+ absl::string_view body, spdy::Http2HeaderBlock response_trailers);
spdy::Http2HeaderBlock* request_headers() { return &request_headers_; }
+ // Returns true iff the request (per saved `request_headers_`) is a CONNECT or
+ // Extended CONNECT request.
+ bool IsConnectRequest() const;
+
const std::string& body() { return body_; }
// Writes the body bytes for the GENERATE_BYTES response type.
void WriteGeneratedBytes();
+ void set_quic_simple_server_backend_for_test(
+ QuicSimpleServerBackend* backend) {
+ quic_simple_server_backend_ = backend;
+ }
+
// The parsed headers received from the client.
spdy::Http2HeaderBlock request_headers_;
int64_t content_length_;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc
index c2aa58efd79..5d9ff15e3b2 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_simple_server_stream_test.cc
@@ -30,8 +30,10 @@
#include "quiche/quic/test_tools/quic_test_utils.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/quic/tools/quic_memory_cache_backend.h"
+#include "quiche/quic/tools/quic_simple_server_backend.h"
#include "quiche/quic/tools/quic_simple_server_session.h"
#include "quiche/common/simple_buffer_allocator.h"
+#include "quiche/spdy/core/spdy_header_block.h"
using testing::_;
using testing::AnyNumber;
@@ -51,12 +53,20 @@ class TestStream : public QuicSimpleServerStream {
TestStream(QuicStreamId stream_id, QuicSpdySession* session, StreamType type,
QuicSimpleServerBackend* quic_simple_server_backend)
: QuicSimpleServerStream(stream_id, session, type,
- quic_simple_server_backend) {}
+ quic_simple_server_backend) {
+ EXPECT_CALL(*this, WriteOrBufferBody(_, _))
+ .Times(AnyNumber())
+ .WillRepeatedly([this](absl::string_view data, bool fin) {
+ this->QuicSimpleServerStream::WriteOrBufferBody(data, fin);
+ });
+ }
~TestStream() override = default;
MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
MOCK_METHOD(void, WriteEarlyHintsHeadersMock, (bool fin), ());
+ MOCK_METHOD(void, WriteOrBufferBody, (absl::string_view data, bool fin),
+ (override));
size_t WriteHeaders(
spdy::Http2HeaderBlock header_block, bool fin,
@@ -89,6 +99,10 @@ class TestStream : public QuicSimpleServerStream {
return it->second;
}
+ void ReplaceBackend(QuicSimpleServerBackend* backend) {
+ set_quic_simple_server_backend_for_test(backend);
+ }
+
protected:
void SendResponse() override {
send_response_was_called_ = true;
@@ -256,6 +270,11 @@ class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
return VersionUsesHttp3(connection_->transport_version());
}
+ void ReplaceBackend(std::unique_ptr<QuicSimpleServerBackend> backend) {
+ replacement_backend_ = std::move(backend);
+ stream_->ReplaceBackend(replacement_backend_.get());
+ }
+
spdy::Http2HeaderBlock response_headers_;
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
@@ -265,6 +284,7 @@ class QuicSimpleServerStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
QuicCompressedCertsCache compressed_certs_cache_;
QuicMemoryCacheBackend memory_cache_backend_;
+ std::unique_ptr<QuicSimpleServerBackend> replacement_backend_;
StrictMock<MockQuicSimpleServerSession> session_;
StrictMock<TestStream>* stream_; // Owned by session_.
std::unique_ptr<QuicBackendResponse> quic_response_;
@@ -732,26 +752,115 @@ TEST_P(QuicSimpleServerStreamTest, InvalidHeadersWithFin) {
stream_->OnStreamFrame(frame);
}
-TEST_P(QuicSimpleServerStreamTest, ConnectSendsResponseBeforeFinReceived) {
- EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
- .WillRepeatedly(
- Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+// Basic QuicSimpleServerBackend that implements its behavior through mocking.
+class TestQuicSimpleServerBackend : public QuicSimpleServerBackend {
+ public:
+ TestQuicSimpleServerBackend() = default;
+ ~TestQuicSimpleServerBackend() override = default;
+
+ // QuicSimpleServerBackend:
+ bool InitializeBackend(const std::string& /*backend_url*/) override {
+ return true;
+ }
+ bool IsBackendInitialized() const override { return true; }
+ MOCK_METHOD(void, FetchResponseFromBackend,
+ (const spdy::Http2HeaderBlock&, const std::string&,
+ RequestHandler*),
+ (override));
+ MOCK_METHOD(void, HandleConnectHeaders,
+ (const spdy::Http2HeaderBlock&, RequestHandler*), (override));
+ MOCK_METHOD(void, HandleConnectData,
+ (absl::string_view, bool, RequestHandler*), (override));
+ void CloseBackendResponseStream(
+ RequestHandler* /*request_handler*/) override {}
+};
+
+ACTION_P(SendHeadersResponse, response_ptr) {
+ arg1->OnResponseBackendComplete(response_ptr);
+}
+
+ACTION_P(SendStreamData, data, close_stream) {
+ arg2->SendStreamData(data, close_stream);
+}
+
+ACTION_P(TerminateStream, error) { arg1->TerminateStreamWithError(error); }
+
+TEST_P(QuicSimpleServerStreamTest, ConnectSendsIntermediateResponses) {
+ auto test_backend = std::make_unique<TestQuicSimpleServerBackend>();
+ TestQuicSimpleServerBackend* test_backend_ptr = test_backend.get();
+ ReplaceBackend(std::move(test_backend));
+
+ constexpr absl::string_view kRequestBody = "\x11\x11";
+ spdy::Http2HeaderBlock response_headers;
+ response_headers[":status"] = "200";
+ QuicBackendResponse headers_response;
+ headers_response.set_headers(response_headers.Clone());
+ headers_response.set_response_type(QuicBackendResponse::INCOMPLETE_RESPONSE);
+ constexpr absl::string_view kBody1 = "\x22\x22";
+ constexpr absl::string_view kBody2 = "\x33\x33";
+
+ // Expect an initial headers-only request to result in a headers-only
+ // incomplete response. Then a data frame without fin, resulting in stream
+ // data. Then a data frame with fin, resulting in stream data with fin.
+ InSequence s;
+ EXPECT_CALL(*test_backend_ptr, HandleConnectHeaders(_, _))
+ .WillOnce(SendHeadersResponse(&headers_response));
+ EXPECT_CALL(*stream_, WriteHeadersMock(false));
+ EXPECT_CALL(*test_backend_ptr, HandleConnectData(kRequestBody, false, _))
+ .WillOnce(SendStreamData(kBody1,
+ /*close_stream=*/false));
+ EXPECT_CALL(*stream_, WriteOrBufferBody(kBody1, false));
+ EXPECT_CALL(*test_backend_ptr, HandleConnectData(kRequestBody, true, _))
+ .WillOnce(SendStreamData(kBody2,
+ /*close_stream=*/true));
+ EXPECT_CALL(*stream_, WriteOrBufferBody(kBody2, true));
+
QuicHeaderList header_list;
header_list.OnHeaderBlockStart();
header_list.OnHeader(":authority", "www.google.com:4433");
header_list.OnHeader(":method", "CONNECT");
header_list.OnHeaderBlockEnd(128, 128);
- EXPECT_CALL(*stream_, WriteHeadersMock(/*fin=*/false));
+
stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
- body_.length(), quiche::SimpleBufferAllocator::Get());
- std::string data =
- UsesHttp3() ? absl::StrCat(header.AsStringView(), body_) : body_;
+ kRequestBody.length(), quiche::SimpleBufferAllocator::Get());
+ std::string data = UsesHttp3()
+ ? absl::StrCat(header.AsStringView(), kRequestBody)
+ : std::string(kRequestBody);
stream_->OnStreamFrame(
QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, data));
- EXPECT_EQ("CONNECT", StreamHeadersValue(":method"));
- EXPECT_EQ(body_, StreamBody());
- EXPECT_TRUE(stream_->send_response_was_called());
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/true, data.length(), data));
+
+ // Expect to not go through SendResponse().
+ EXPECT_FALSE(stream_->send_response_was_called());
+ EXPECT_FALSE(stream_->send_error_response_was_called());
+}
+
+TEST_P(QuicSimpleServerStreamTest, ErrorOnUnhandledConnect) {
+ // Expect single set of failure response headers with FIN in response to the
+ // headers. Then, expect abrupt stream termination in response to the body.
+ EXPECT_CALL(*stream_, WriteHeadersMock(true));
+ EXPECT_CALL(session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
+
+ QuicHeaderList header_list;
+ header_list.OnHeaderBlockStart();
+ header_list.OnHeader(":authority", "www.google.com:4433");
+ header_list.OnHeader(":method", "CONNECT");
+ header_list.OnHeaderBlockEnd(128, 128);
+ constexpr absl::string_view kRequestBody = "\x11\x11";
+
+ stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
+ quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
+ kRequestBody.length(), quiche::SimpleBufferAllocator::Get());
+ std::string data = UsesHttp3()
+ ? absl::StrCat(header.AsStringView(), kRequestBody)
+ : std::string(kRequestBody);
+ stream_->OnStreamFrame(
+ QuicStreamFrame(stream_->id(), /*fin=*/true, /*offset=*/0, data));
+
+ // Expect failure to not go through SendResponse().
+ EXPECT_FALSE(stream_->send_response_was_called());
EXPECT_FALSE(stream_->send_error_response_was_called());
}
@@ -785,6 +894,30 @@ TEST_P(QuicSimpleServerStreamTest, ConnectWithInvalidHeader) {
EXPECT_TRUE(stream_->send_error_response_was_called());
}
+TEST_P(QuicSimpleServerStreamTest, BackendCanTerminateStream) {
+ auto test_backend = std::make_unique<TestQuicSimpleServerBackend>();
+ TestQuicSimpleServerBackend* test_backend_ptr = test_backend.get();
+ ReplaceBackend(std::move(test_backend));
+
+ EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
+ .WillRepeatedly(
+ Invoke(&session_, &MockQuicSimpleServerSession::ConsumeData));
+
+ QuicResetStreamError expected_error =
+ QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR);
+ EXPECT_CALL(*test_backend_ptr, HandleConnectHeaders(_, _))
+ .WillOnce(TerminateStream(expected_error));
+ EXPECT_CALL(session_,
+ MaybeSendRstStreamFrame(stream_->id(), expected_error, _));
+
+ QuicHeaderList header_list;
+ header_list.OnHeaderBlockStart();
+ header_list.OnHeader(":authority", "www.google.com:4433");
+ header_list.OnHeader(":method", "CONNECT");
+ header_list.OnHeaderBlockEnd(128, 128);
+ stream_->OnStreamHeaderList(/*fin=*/false, kFakeFrameLen, header_list);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_tcp_like_trace_converter.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_tcp_like_trace_converter.h
index aa0c0f2e53f..3aeaa0fd5aa 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_tcp_like_trace_converter.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_tcp_like_trace_converter.h
@@ -12,7 +12,6 @@
#include "quiche/quic/core/quic_interval.h"
#include "quiche/quic/core/quic_interval_set.h"
#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/platform/api/quic_containers.h"
namespace quic {
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_client.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_client.cc
index 9baccbf7b3d..790e26361ae 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_client.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_client.cc
@@ -230,18 +230,18 @@ QuicToyClient::QuicToyClient(ClientFactory* client_factory)
int QuicToyClient::SendRequestsAndPrintResponses(
std::vector<std::string> urls) {
QuicUrl url(urls[0], "https");
- std::string host = GetQuicFlag(FLAGS_host);
+ std::string host = quiche::GetQuicheCommandLineFlag(FLAGS_host);
if (host.empty()) {
host = url.host();
}
- int port = GetQuicFlag(FLAGS_port);
+ int port = quiche::GetQuicheCommandLineFlag(FLAGS_port);
if (port == 0) {
port = url.port();
}
quic::ParsedQuicVersionVector versions = quic::CurrentSupportedVersions();
- if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_quic_ietf_draft)) {
quic::QuicVersionInitializeSupportForIetfDraft();
versions = {};
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
@@ -252,7 +252,8 @@ int QuicToyClient::SendRequestsAndPrintResponses(
}
}
- std::string quic_version_string = GetQuicFlag(FLAGS_quic_version);
+ std::string quic_version_string =
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_version);
if (!quic_version_string.empty()) {
versions = quic::ParseQuicVersionVectorString(quic_version_string);
}
@@ -266,36 +267,40 @@ int QuicToyClient::SendRequestsAndPrintResponses(
quic::QuicEnableVersion(version);
}
- if (GetQuicFlag(FLAGS_force_version_negotiation)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_force_version_negotiation)) {
versions.insert(versions.begin(),
quic::QuicVersionReservedForNegotiation());
}
- const int32_t num_requests(GetQuicFlag(FLAGS_num_requests));
+ const int32_t num_requests(
+ quiche::GetQuicheCommandLineFlag(FLAGS_num_requests));
std::unique_ptr<quic::ProofVerifier> proof_verifier;
- if (GetQuicFlag(FLAGS_disable_certificate_verification)) {
+ if (quiche::GetQuicheCommandLineFlag(
+ FLAGS_disable_certificate_verification)) {
proof_verifier = std::make_unique<FakeProofVerifier>();
} else {
proof_verifier = quic::CreateDefaultProofVerifier(url.host());
}
std::unique_ptr<quic::SessionCache> session_cache;
- if (num_requests > 1 && GetQuicFlag(FLAGS_one_connection_per_request)) {
+ if (num_requests > 1 &&
+ quiche::GetQuicheCommandLineFlag(FLAGS_one_connection_per_request)) {
session_cache = std::make_unique<QuicClientSessionCache>();
}
QuicConfig config;
- std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
+ std::string connection_options_string =
+ quiche::GetQuicheCommandLineFlag(FLAGS_connection_options);
if (!connection_options_string.empty()) {
config.SetConnectionOptionsToSend(
ParseQuicTagVector(connection_options_string));
}
std::string client_connection_options_string =
- GetQuicFlag(FLAGS_client_connection_options);
+ quiche::GetQuicheCommandLineFlag(FLAGS_client_connection_options);
if (!client_connection_options_string.empty()) {
config.SetClientConnectionOptions(
ParseQuicTagVector(client_connection_options_string));
}
- if (GetQuicFlag(FLAGS_multi_packet_chlo)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_multi_packet_chlo)) {
// Make the ClientHello span multiple packets by adding a custom transport
// parameter.
constexpr auto kCustomParameter =
@@ -304,13 +309,16 @@ int QuicToyClient::SendRequestsAndPrintResponses(
config.custom_transport_parameters_to_send()[kCustomParameter] =
custom_value;
}
- config.set_max_time_before_crypto_handshake(QuicTime::Delta::FromMilliseconds(
- GetQuicFlag(FLAGS_max_time_before_crypto_handshake_ms)));
+ config.set_max_time_before_crypto_handshake(
+ QuicTime::Delta::FromMilliseconds(quiche::GetQuicheCommandLineFlag(
+ FLAGS_max_time_before_crypto_handshake_ms)));
int address_family_for_lookup = AF_UNSPEC;
- if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "4") {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_ip_version_for_host_lookup) ==
+ "4") {
address_family_for_lookup = AF_INET;
- } else if (GetQuicFlag(FLAGS_ip_version_for_host_lookup) == "6") {
+ } else if (quiche::GetQuicheCommandLineFlag(
+ FLAGS_ip_version_for_host_lookup) == "6") {
address_family_for_lookup = AF_INET6;
}
@@ -324,11 +332,13 @@ int QuicToyClient::SendRequestsAndPrintResponses(
return 1;
}
- if (!GetQuicFlag(FLAGS_default_client_cert).empty() &&
- !GetQuicFlag(FLAGS_default_client_cert_key).empty()) {
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_default_client_cert).empty() &&
+ !quiche::GetQuicheCommandLineFlag(FLAGS_default_client_cert_key)
+ .empty()) {
std::unique_ptr<ClientProofSource> proof_source =
- CreateTestClientProofSource(GetQuicFlag(FLAGS_default_client_cert),
- GetQuicFlag(FLAGS_default_client_cert_key));
+ CreateTestClientProofSource(
+ quiche::GetQuicheCommandLineFlag(FLAGS_default_client_cert),
+ quiche::GetQuicheCommandLineFlag(FLAGS_default_client_cert_key));
if (proof_source == nullptr) {
std::cerr << "Failed to create client proof source." << std::endl;
return 1;
@@ -336,22 +346,23 @@ int QuicToyClient::SendRequestsAndPrintResponses(
client->crypto_config()->set_proof_source(std::move(proof_source));
}
- int32_t initial_mtu = GetQuicFlag(FLAGS_initial_mtu);
+ int32_t initial_mtu = quiche::GetQuicheCommandLineFlag(FLAGS_initial_mtu);
client->set_initial_max_packet_length(
initial_mtu != 0 ? initial_mtu : quic::kDefaultMaxPacketSize);
- client->set_drop_response_body(GetQuicFlag(FLAGS_drop_response_body));
+ client->set_drop_response_body(
+ quiche::GetQuicheCommandLineFlag(FLAGS_drop_response_body));
const int32_t server_connection_id_length =
- GetQuicFlag(FLAGS_server_connection_id_length);
+ quiche::GetQuicheCommandLineFlag(FLAGS_server_connection_id_length);
if (server_connection_id_length >= 0) {
client->set_server_connection_id_length(server_connection_id_length);
}
const int32_t client_connection_id_length =
- GetQuicFlag(FLAGS_client_connection_id_length);
+ quiche::GetQuicheCommandLineFlag(FLAGS_client_connection_id_length);
if (client_connection_id_length >= 0) {
client->set_client_connection_id_length(client_connection_id_length);
}
const size_t max_inbound_header_list_size =
- GetQuicFlag(FLAGS_max_inbound_header_list_size);
+ quiche::GetQuicheCommandLineFlag(FLAGS_max_inbound_header_list_size);
if (max_inbound_header_list_size > 0) {
client->set_max_inbound_header_list_size(max_inbound_header_list_size);
}
@@ -366,7 +377,8 @@ int QuicToyClient::SendRequestsAndPrintResponses(
<< ". " << client->session()->error_details() << std::endl;
// 0: No error.
// 20: Failed to connect due to QUIC_INVALID_VERSION.
- return GetQuicFlag(FLAGS_version_mismatch_ok) ? 0 : 20;
+ return quiche::GetQuicheCommandLineFlag(FLAGS_version_mismatch_ok) ? 0
+ : 20;
}
std::cerr << "Failed to connect to " << host << ":" << port << ". "
<< quic::QuicErrorCodeToString(error) << " "
@@ -376,11 +388,12 @@ int QuicToyClient::SendRequestsAndPrintResponses(
std::cerr << "Connected to " << host << ":" << port << std::endl;
// Construct the string body from flags, if provided.
- std::string body = GetQuicFlag(FLAGS_body);
- if (!GetQuicFlag(FLAGS_body_hex).empty()) {
- QUICHE_DCHECK(GetQuicFlag(FLAGS_body).empty())
+ std::string body = quiche::GetQuicheCommandLineFlag(FLAGS_body);
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_body_hex).empty()) {
+ QUICHE_DCHECK(quiche::GetQuicheCommandLineFlag(FLAGS_body).empty())
<< "Only set one of --body and --body_hex.";
- body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex));
+ body = absl::HexStringToBytes(
+ quiche::GetQuicheCommandLineFlag(FLAGS_body_hex));
}
// Construct a GET or POST request for supplied URL.
@@ -391,7 +404,7 @@ int QuicToyClient::SendRequestsAndPrintResponses(
header_block[":path"] = url.PathParamsQuery();
// Append any additional headers supplied on the command line.
- const std::string headers = GetQuicFlag(FLAGS_headers);
+ const std::string headers = quiche::GetQuicheCommandLineFlag(FLAGS_headers);
for (absl::string_view sp : absl::StrSplit(headers, ';')) {
QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&sp);
if (sp.empty()) {
@@ -412,14 +425,14 @@ int QuicToyClient::SendRequestsAndPrintResponses(
client->SendRequestAndWaitForResponse(header_block, body, /*fin=*/true);
// Print request and response details.
- if (!GetQuicFlag(FLAGS_quiet)) {
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_quiet)) {
std::cout << "Request:" << std::endl;
std::cout << "headers:" << header_block.DebugString();
- if (!GetQuicFlag(FLAGS_body_hex).empty()) {
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_body_hex).empty()) {
// Print the user provided hex, rather than binary body.
std::cout << "body:\n"
- << QuicheTextUtils::HexDump(
- absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex)))
+ << QuicheTextUtils::HexDump(absl::HexStringToBytes(
+ quiche::GetQuicheCommandLineFlag(FLAGS_body_hex)))
<< std::endl;
} else {
std::cout << "body: " << body << std::endl;
@@ -436,7 +449,7 @@ int QuicToyClient::SendRequestsAndPrintResponses(
std::cout << "headers: " << client->latest_response_headers()
<< std::endl;
std::string response_body = client->latest_response_body();
- if (!GetQuicFlag(FLAGS_body_hex).empty()) {
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_body_hex).empty()) {
// Assume response is binary data.
std::cout << "body:\n"
<< QuicheTextUtils::HexDump(response_body) << std::endl;
@@ -458,7 +471,7 @@ int QuicToyClient::SendRequestsAndPrintResponses(
if (response_code >= 200 && response_code < 300) {
std::cout << "Request succeeded (" << response_code << ")." << std::endl;
} else if (response_code >= 300 && response_code < 400) {
- if (GetQuicFlag(FLAGS_redirect_is_success)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_redirect_is_success)) {
std::cout << "Request succeeded (redirect " << response_code << ")."
<< std::endl;
} else {
@@ -472,7 +485,7 @@ int QuicToyClient::SendRequestsAndPrintResponses(
}
if (i + 1 < num_requests) { // There are more requests to perform.
- if (GetQuicFlag(FLAGS_one_connection_per_request)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_one_connection_per_request)) {
std::cout << "Disconnecting client between requests." << std::endl;
client->Disconnect();
if (!client->Initialize()) {
@@ -485,7 +498,8 @@ int QuicToyClient::SendRequestsAndPrintResponses(
<< std::endl;
return 1;
}
- } else if (!GetQuicFlag(FLAGS_disable_port_changes)) {
+ } else if (!quiche::GetQuicheCommandLineFlag(
+ FLAGS_disable_port_changes)) {
// Change the ephemeral port.
if (!client->ChangeEphemeralPort()) {
std::cerr << "Failed to change ephemeral port." << std::endl;
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_server.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_server.cc
index 03f910c90fd..1e31b2e0124 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_server.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_toy_server.cc
@@ -45,14 +45,15 @@ namespace quic {
std::unique_ptr<quic::QuicSimpleServerBackend>
QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
auto memory_cache_backend = std::make_unique<QuicMemoryCacheBackend>();
- if (GetQuicFlag(FLAGS_generate_dynamic_responses)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_generate_dynamic_responses)) {
memory_cache_backend->GenerateDynamicResponses();
}
- if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
+ if (!quiche::GetQuicheCommandLineFlag(FLAGS_quic_response_cache_dir)
+ .empty()) {
memory_cache_backend->InitializeBackend(
- GetQuicFlag(FLAGS_quic_response_cache_dir));
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_response_cache_dir));
}
- if (GetQuicFlag(FLAGS_enable_webtransport)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_enable_webtransport)) {
memory_cache_backend->EnableWebTransport();
}
return memory_cache_backend;
@@ -64,7 +65,7 @@ QuicToyServer::QuicToyServer(BackendFactory* backend_factory,
int QuicToyServer::Start() {
ParsedQuicVersionVector supported_versions;
- if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
+ if (quiche::GetQuicheCommandLineFlag(FLAGS_quic_ietf_draft)) {
QuicVersionInitializeSupportForIetfDraft();
for (const ParsedQuicVersion& version : AllSupportedVersions()) {
// Add all versions that supports IETF QUIC.
@@ -76,7 +77,8 @@ int QuicToyServer::Start() {
} else {
supported_versions = AllSupportedVersions();
}
- std::string versions_string = GetQuicFlag(FLAGS_quic_versions);
+ std::string versions_string =
+ quiche::GetQuicheCommandLineFlag(FLAGS_quic_versions);
if (!versions_string.empty()) {
supported_versions = ParseQuicVersionVectorString(versions_string);
}
@@ -92,7 +94,8 @@ int QuicToyServer::Start() {
backend.get(), std::move(proof_source), supported_versions);
if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
- quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
+ quic::QuicIpAddress::Any6(),
+ quiche::GetQuicheCommandLineFlag(FLAGS_port)))) {
return 1;
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc
deleted file mode 100644
index 7fdcfe96b2c..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quiche/quic/tools/quic_transport_simple_server_dispatcher.h"
-
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/quic_connection.h"
-#include "quiche/quic/core/quic_dispatcher.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-
-QuicTransportSimpleServerDispatcher::QuicTransportSimpleServerDispatcher(
- const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- uint8_t expected_server_connection_id_length,
- std::vector<url::Origin> accepted_origins)
- : QuicDispatcher(config, crypto_config, version_manager, std::move(helper),
- std::move(session_helper), std::move(alarm_factory),
- expected_server_connection_id_length),
- accepted_origins_(accepted_origins) {}
-
-std::unique_ptr<QuicSession>
-QuicTransportSimpleServerDispatcher::CreateQuicSession(
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
- const ParsedQuicVersion& version,
- const ParsedClientHello& /*parsed_chlo*/) {
- auto connection = std::make_unique<QuicConnection>(
- server_connection_id, self_address, peer_address, helper(),
- alarm_factory(), writer(),
- /*owns_writer=*/false, Perspective::IS_SERVER,
- ParsedQuicVersionVector{version});
- auto session = std::make_unique<QuicTransportSimpleServerSession>(
- connection.release(), /*owns_connection=*/true, this, config(),
- GetSupportedVersions(), crypto_config(), compressed_certs_cache(),
- accepted_origins_);
- session->Initialize();
- return session;
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.h
deleted file mode 100644
index 98562a08f41..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_dispatcher.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
-
-#include "absl/strings/string_view.h"
-#include "url/origin.h"
-#include "quiche/quic/core/quic_dispatcher.h"
-#include "quiche/quic/tools/quic_transport_simple_server_session.h"
-
-namespace quic {
-
-// Dispatcher that creates a QuicTransportSimpleServerSession for every incoming
-// connection.
-class QuicTransportSimpleServerDispatcher : public QuicDispatcher {
- public:
- QuicTransportSimpleServerDispatcher(
- const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
- QuicVersionManager* version_manager,
- std::unique_ptr<QuicConnectionHelperInterface> helper,
- std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
- std::unique_ptr<QuicAlarmFactory> alarm_factory,
- uint8_t expected_server_connection_id_length,
- std::vector<url::Origin> accepted_origins);
-
- protected:
- std::unique_ptr<QuicSession> CreateQuicSession(
- QuicConnectionId server_connection_id,
- const QuicSocketAddress& self_address,
- const QuicSocketAddress& peer_address, absl::string_view alpn,
- const ParsedQuicVersion& version,
- const ParsedClientHello& parsed_chlo) override;
-
- std::vector<url::Origin> accepted_origins_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_DISPATCHER_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.cc
deleted file mode 100644
index fcd70ce541a..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "quiche/quic/tools/quic_transport_simple_server_session.h"
-
-#include <memory>
-
-#include "url/gurl.h"
-#include "url/origin.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_flags.h"
-#include "quiche/quic/platform/api/quic_logging.h"
-#include "quiche/quic/quic_transport/quic_transport_protocol.h"
-#include "quiche/quic/quic_transport/quic_transport_stream.h"
-#include "quiche/quic/tools/web_transport_test_visitors.h"
-#include "quiche/common/platform/api/quiche_mem_slice.h"
-#include "quiche/common/quiche_buffer_allocator.h"
-
-namespace quic {
-
-QuicTransportSimpleServerSession::QuicTransportSimpleServerSession(
- QuicConnection* connection, bool owns_connection, Visitor* owner,
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- std::vector<url::Origin> accepted_origins)
- : QuicTransportServerSession(connection, owner, config, supported_versions,
- crypto_config, compressed_certs_cache, this),
- owns_connection_(owns_connection),
- mode_(DISCARD),
- accepted_origins_(accepted_origins) {}
-
-QuicTransportSimpleServerSession::~QuicTransportSimpleServerSession() {
- if (owns_connection_) {
- DeleteConnection();
- }
-}
-
-void QuicTransportSimpleServerSession::OnIncomingDataStream(
- QuicTransportStream* stream) {
- switch (mode_) {
- case DISCARD:
- stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
- break;
-
- case ECHO:
- switch (stream->type()) {
- case BIDIRECTIONAL:
- QUIC_DVLOG(1) << "Opening bidirectional echo stream " << stream->id();
- stream->SetVisitor(
- std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
- break;
- case READ_UNIDIRECTIONAL:
- QUIC_DVLOG(1)
- << "Started receiving data on unidirectional echo stream "
- << stream->id();
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
- stream,
- [this](const std::string& s) { this->EchoStreamBack(s); }));
- break;
- default:
- QUIC_NOTREACHED();
- break;
- }
- break;
-
- case OUTGOING_BIDIRECTIONAL:
- stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
- ++pending_outgoing_bidirectional_streams_;
- MaybeCreateOutgoingBidirectionalStream();
- break;
- }
-}
-
-void QuicTransportSimpleServerSession::OnCanCreateNewOutgoingStream(
- bool unidirectional) {
- if (mode_ == ECHO && unidirectional) {
- MaybeEchoStreamsBack();
- } else if (mode_ == OUTGOING_BIDIRECTIONAL && !unidirectional) {
- MaybeCreateOutgoingBidirectionalStream();
- }
-}
-
-bool QuicTransportSimpleServerSession::CheckOrigin(url::Origin origin) {
- if (accepted_origins_.empty()) {
- return true;
- }
-
- for (const url::Origin& accepted_origin : accepted_origins_) {
- if (origin.IsSameOriginWith(accepted_origin)) {
- return true;
- }
- }
- return false;
-}
-
-bool QuicTransportSimpleServerSession::ProcessPath(const GURL& url) {
- if (url.path() == "/discard") {
- mode_ = DISCARD;
- return true;
- }
- if (url.path() == "/echo") {
- mode_ = ECHO;
- return true;
- }
- if (url.path() == "/receive-bidirectional") {
- mode_ = OUTGOING_BIDIRECTIONAL;
- return true;
- }
-
- QUIC_DLOG(WARNING) << "Unknown path requested: " << url.path();
- return false;
-}
-
-void QuicTransportSimpleServerSession::OnMessageReceived(
- absl::string_view message) {
- if (mode_ != ECHO) {
- return;
- }
- datagram_queue()->SendOrQueueDatagram(
- quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
- connection()->helper()->GetStreamSendBufferAllocator(), message)));
-}
-
-void QuicTransportSimpleServerSession::MaybeEchoStreamsBack() {
- while (!streams_to_echo_back_.empty() &&
- CanOpenNextOutgoingUnidirectionalStream()) {
- // Remove the stream from the queue first, in order to avoid accidentally
- // entering an infinite loop in case any of the following code calls
- // OnCanCreateNewOutgoingStream().
- std::string data = std::move(streams_to_echo_back_.front());
- streams_to_echo_back_.pop_front();
-
- auto stream_owned = std::make_unique<QuicTransportStream>(
- GetNextOutgoingUnidirectionalStreamId(), this, this);
- QuicTransportStream* stream = stream_owned.get();
- ActivateStream(std::move(stream_owned));
- QUIC_DVLOG(1) << "Opened echo response stream " << stream->id();
-
- stream->SetVisitor(
- std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(stream,
- data));
- stream->visitor()->OnCanWrite();
- }
-}
-
-void QuicTransportSimpleServerSession::
- MaybeCreateOutgoingBidirectionalStream() {
- while (pending_outgoing_bidirectional_streams_ > 0 &&
- CanOpenNextOutgoingBidirectionalStream()) {
- auto stream_owned = std::make_unique<QuicTransportStream>(
- GetNextOutgoingBidirectionalStreamId(), this, this);
- QuicTransportStream* stream = stream_owned.get();
- ActivateStream(std::move(stream_owned));
- QUIC_DVLOG(1) << "Opened outgoing bidirectional stream " << stream->id();
- stream->SetVisitor(
- std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
- if (!stream->Write("hello")) {
- QUIC_DVLOG(1) << "Write failed.";
- }
- --pending_outgoing_bidirectional_streams_;
- }
-}
-
-} // namespace quic
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.h
deleted file mode 100644
index 4d59f90a667..00000000000
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/quic_transport_simple_server_session.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
-#define QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
-
-#include <memory>
-#include <vector>
-
-#include "url/origin.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/core/quic_versions.h"
-#include "quiche/quic/platform/api/quic_containers.h"
-#include "quiche/quic/platform/api/quic_flags.h"
-#include "quiche/quic/quic_transport/quic_transport_server_session.h"
-#include "quiche/quic/quic_transport/quic_transport_stream.h"
-
-namespace quic {
-
-// QuicTransport simple server is a non-production server that can be used for
-// testing QuicTransport. It has two modes that can be changed using the
-// command line flags, "echo" and "discard".
-class QuicTransportSimpleServerSession
- : public QuicTransportServerSession,
- QuicTransportServerSession::ServerVisitor {
- public:
- enum Mode {
- // In DISCARD mode, any data on incoming streams is discarded and no
- // outgoing streams are initiated.
- DISCARD,
- // In ECHO mode, any data sent on a bidirectional stream is echoed back.
- // Any data sent on a unidirectional stream is buffered, and echoed back on
- // a server-initiated unidirectional stream that is sent as soon as a FIN is
- // received on the incoming stream.
- ECHO,
- // In OUTGOING_BIDIRECTIONAL mode, a server-originated bidirectional stream
- // is created on receipt of a unidirectional stream. The contents of the
- // unidirectional stream are disregarded. The bidirectional stream initially
- // sends "hello", then any received data is echoed back.
- // TODO(ricea): Maybe this should be replaced by a more general mechanism
- // where commands on the unidirectional stream trigger different behaviour?
- OUTGOING_BIDIRECTIONAL,
- };
-
- QuicTransportSimpleServerSession(
- QuicConnection* connection, bool owns_connection, Visitor* owner,
- const QuicConfig& config,
- const ParsedQuicVersionVector& supported_versions,
- const QuicCryptoServerConfig* crypto_config,
- QuicCompressedCertsCache* compressed_certs_cache,
- std::vector<url::Origin> accepted_origins);
- ~QuicTransportSimpleServerSession();
-
- void OnIncomingDataStream(QuicTransportStream* stream) override;
- void OnCanCreateNewOutgoingStream(bool unidirectional) override;
- bool CheckOrigin(url::Origin origin) override;
- bool ProcessPath(const GURL& url) override;
- void OnMessageReceived(absl::string_view message) override;
-
- void EchoStreamBack(const std::string& data) {
- streams_to_echo_back_.push_back(data);
- MaybeEchoStreamsBack();
- }
-
- private:
- void MaybeEchoStreamsBack();
- void MaybeCreateOutgoingBidirectionalStream();
-
- const bool owns_connection_;
- size_t pending_outgoing_bidirectional_streams_ = 0u;
- Mode mode_;
- std::vector<url::Origin> accepted_origins_;
- quiche::QuicheCircularDeque<std::string> streams_to_echo_back_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_TOOLS_QUIC_TRANSPORT_SIMPLE_SERVER_SESSION_H_
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.cc b/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.cc
index aa1e65e8838..ad9fea1a098 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.cc
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.cc
@@ -87,7 +87,7 @@ std::vector<uint8_t> SimpleTicketCrypter::Decrypt(absl::string_view in) {
void SimpleTicketCrypter::Decrypt(
absl::string_view in,
- std::unique_ptr<quic::ProofSource::DecryptCallback> callback) {
+ std::shared_ptr<quic::ProofSource::DecryptCallback> callback) {
callback->Run(Decrypt(in));
}
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.h
index f0395f0d1e8..b5ad16d6f96 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter.h
@@ -28,7 +28,7 @@ class QUIC_NO_EXPORT SimpleTicketCrypter
absl::string_view encryption_key) override;
void Decrypt(
absl::string_view in,
- std::unique_ptr<quic::ProofSource::DecryptCallback> callback) override;
+ std::shared_ptr<quic::ProofSource::DecryptCallback> callback) override;
private:
std::vector<uint8_t> Decrypt(absl::string_view in);
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/tools/web_transport_test_visitors.h b/chromium/net/third_party/quiche/src/quiche/quic/tools/web_transport_test_visitors.h
index 07d3161bbcc..e5b7fefda9d 100644
--- a/chromium/net/third_party/quiche/src/quiche/quic/tools/web_transport_test_visitors.h
+++ b/chromium/net/third_party/quiche/src/quiche/quic/tools/web_transport_test_visitors.h
@@ -9,6 +9,7 @@
#include "quiche/quic/core/web_transport_interface.h"
#include "quiche/quic/platform/api/quic_logging.h"
+#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
#include "quiche/common/quiche_circular_deque.h"
#include "quiche/common/simple_buffer_allocator.h"
@@ -123,7 +124,7 @@ class WebTransportUnidirectionalEchoReadVisitor
}
}
- void OnCanWrite() override { QUIC_NOTREACHED(); }
+ void OnCanWrite() override { QUICHE_NOTREACHED(); }
void OnResetStreamReceived(WebTransportStreamError /*error*/) override {}
void OnStopSendingReceived(WebTransportStreamError /*error*/) override {}
@@ -143,7 +144,7 @@ class WebTransportUnidirectionalEchoWriteVisitor
const std::string& data)
: stream_(stream), data_(data) {}
- void OnCanRead() override { QUIC_NOTREACHED(); }
+ void OnCanRead() override { QUICHE_NOTREACHED(); }
void OnCanWrite() override {
if (data_.empty()) {
return;